瀏覽代碼

init 10.012.1

bding 1 年之前
父節點
當前提交
781ae92a59
共有 100 個文件被更改,包括 13483 次插入703 次删除
  1. 9 0
      .babelrc
  2. 0 7
      .env.development
  3. 0 7
      .env.production
  4. 0 8
      .env.test
  5. 4 2
      .gitignore
  6. 0 2
      README.md
  7. 0 11
      babel.config.js
  8. 35 0
      build/build.js
  9. 38 0
      build/build.test.js
  10. 48 0
      build/check-versions.js
  11. 9 0
      build/dev-client.js
  12. 89 0
      build/dev-server.js
  13. 74 0
      build/utils.js
  14. 14 0
      build/vue-loader.conf.js
  15. 82 0
      build/webpack.base.conf.js
  16. 35 0
      build/webpack.dev.conf.js
  17. 18 0
      build/webpack.dll.config.js
  18. 132 0
      build/webpack.prod.conf.js
  19. 136 0
      build/webpack.prod.test.conf.js
  20. 13 0
      config/dev.env.js
  21. 77 0
      config/index.js
  22. 9 0
      config/prod.env.js
  23. 4 0
      config/prod.pre.env.js
  24. 11 0
      config/prod.test.env.js
  25. 63 0
      index.html
  26. 69 40
      package.json
  27. 0 6
      public/css/content.inline.min.css
  28. 二進制
      public/css/fonts/element-icons.ttf
  29. 二進制
      public/css/fonts/element-icons.woff
  30. 0 4
      public/css/iconfont.css
  31. 二進制
      public/css/iconfont.ttf
  32. 二進制
      public/css/iconfont.woff
  33. 0 0
      public/css/indexstyle.css
  34. 0 0
      public/css/jquery.dataTables.css
  35. 0 185
      public/css/reset.min.css
  36. 0 6
      public/css/skin.min.css
  37. 二進制
      public/fa.ico
  38. 0 54
      public/index.html
  39. 0 181
      public/js/jquery.dataTables.js
  40. 0 1
      public/js/jquery.min.js
  41. 3 8
      src/App.vue
  42. 5 5
      src/api/http.js
  43. 2 2
      src/components/calendar.vue
  44. 1 1
      src/components/mPage.vue
  45. 1 0
      src/components/pwdDlg.vue
  46. 4 2
      src/components/todo/roadShowFeedbackDia.vue
  47. 2 4
      src/main.js
  48. 2 2
      src/mixins/index.js
  49. 6 0
      src/routes/modules/ficcXcxRoutes.js
  50. 6 6
      src/routes/routes.js
  51. 0 18
      src/utils/MenuUtils.js
  52. 0 49
      src/utils/lazyLoading.js
  53. 11 20
      src/views/Home.vue
  54. 2 3
      src/views/Login.vue
  55. 1 1
      src/views/banner_manage/bannerlist.vue
  56. 1 1
      src/views/business_trip_manage/businessApproval.vue
  57. 1 1
      src/views/business_trip_manage/components/tripApplicationDia.vue
  58. 213 0
      src/views/chartRelevance_manage/components/addClassify.vue
  59. 307 0
      src/views/chartRelevance_manage/components/chartCard.vue
  60. 295 0
      src/views/chartRelevance_manage/components/fittingEquationSaveDia.vue
  61. 201 0
      src/views/chartRelevance_manage/components/saveChartTobaseDia.vue
  62. 227 0
      src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue
  63. 151 0
      src/views/chartRelevance_manage/components/selectTarget.vue
  64. 505 0
      src/views/chartRelevance_manage/fittingEquationChartEditor.vue
  65. 912 0
      src/views/chartRelevance_manage/fittingEquationList.vue
  66. 1076 0
      src/views/chartRelevance_manage/list.vue
  67. 449 0
      src/views/chartRelevance_manage/mixins/classifyMixin.js
  68. 876 0
      src/views/chartRelevance_manage/relevanceChartEditor.vue
  69. 765 0
      src/views/chartRelevance_manage/statisticFeatureChartEditor.vue
  70. 815 0
      src/views/chartRelevance_manage/statisticFeatureList.vue
  71. 3 3
      src/views/contract_manage/approvalList.vue
  72. 12 13
      src/views/contract_manage/contractList.vue
  73. 1 0
      src/views/custom_manage/approvalList.vue
  74. 2 2
      src/views/custom_manage/compontents/Capplydialog.vue
  75. 1 1
      src/views/custom_manage/compontents/Contactdialog.vue
  76. 1 1
      src/views/custom_manage/compontents/ReadDialog.vue
  77. 1 1
      src/views/custom_manage/compontents/accumulativeFrequencyDlg.vue
  78. 2 2
      src/views/custom_manage/compontents/clickNumberDetailDia.vue
  79. 2 2
      src/views/custom_manage/compontents/exportData.vue
  80. 1 1
      src/views/custom_manage/compontents/jurisdictionCheck.vue
  81. 3 3
      src/views/custom_manage/contacts/contactsList.vue
  82. 1 1
      src/views/custom_manage/contacts/mutualList.vue
  83. 1 1
      src/views/custom_manage/contacts/organizationList.vue
  84. 1 1
      src/views/custom_manage/contacts/wholeOrganization.vue
  85. 5 5
      src/views/custom_manage/customList/customAllList.vue
  86. 1 1
      src/views/custom_manage/customList/customDetail.vue
  87. 11 18
      src/views/custom_manage/customList/customList.vue
  88. 1 1
      src/views/custom_manage/customList/editCustom.vue
  89. 6 3
      src/views/custom_manage/listMatch.vue
  90. 2 1
      src/views/custom_manage/pickList.vue
  91. 3 3
      src/views/custom_manage/potentialList.vue
  92. 0 1
      src/views/custom_manage/saleAuthManage.vue
  93. 0 1
      src/views/custom_manage/trialApplication.vue
  94. 1001 0
      src/views/dataEntry_manage/addChart.vue
  95. 593 0
      src/views/dataEntry_manage/adjustdata/adjustData.vue
  96. 2832 0
      src/views/dataEntry_manage/chartSetting.vue
  97. 578 0
      src/views/dataEntry_manage/coal/index.vue
  98. 72 0
      src/views/dataEntry_manage/codecount/compoments/codeMirror.vue
  99. 64 0
      src/views/dataEntry_manage/codecount/compoments/dataTable.vue
  100. 473 0
      src/views/dataEntry_manage/codecount/index.vue

+ 9 - 0
.babelrc

@@ -0,0 +1,9 @@
+{
+  "presets": ["es2015", "stage-2"],
+  "plugins": [
+    "transform-runtime",
+    "transform-vue-jsx"
+  ],
+  "comments": false,
+  "compact": false
+}

+ 0 - 7
.env.development

@@ -1,7 +0,0 @@
-NODE_ENV='development'
-VUE_APP_BASE_API='/adminapi'
-Domain='brilliantstart.cn'
-VUE_APP_Login='http://localhost:8080/login'
-VUE_APP_CHART_LINK='https://charttest.hzinsights.com/chartshow'
-VUE_APP_HR_MANAGEMENT_SYSTEM='http://8.136.199.33:8391/login'
-VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM='http://8.136.199.33:8618/login'

+ 0 - 7
.env.production

@@ -1,7 +0,0 @@
-NODE_ENV='production'
-VUE_APP_BASE_API='https://admin.hzinsights.com/adminapi'  
-Domain='hzinsights.com'
-VUE_APP_Login='https://admin.hzinsights.com/login'
-VUE_APP_CHART_LINK='https://chartlib.hzinsights.com/chartshow'
-VUE_APP_HR_MANAGEMENT_SYSTEM='https://hr.hzinsights.com/login'
-VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM='https://fms.hzinsights.com/login'

+ 0 - 8
.env.test

@@ -1,8 +0,0 @@
-#测试环境
-NODE_ENV='test'
-VUE_APP_BASE_API='http://8.136.199.33:7777/adminapi'
-Domain='brilliantstart.cn'
-VUE_APP_Login='http://8.136.199.33:7777/login'
-VUE_APP_CHART_LINK='https://charttest.hzinsights.com/chartshow'
-VUE_APP_HR_MANAGEMENT_SYSTEM='http://8.136.199.33:8391/login'
-VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM='http://8.136.199.33:8618/login'

+ 4 - 2
.gitignore

@@ -9,12 +9,14 @@
 /admin.rar
 /admin.zip
 /vendor-manifest.json
+
+/testadmin
+/yarn-error.log
+
 /hz_crm_web
 /hz_crm_web.zip
 /hz_crm_web.rar
 
-/testadmin
-/yarn-error.log
 
 # Mac General
 .DS_Store

+ 0 - 2
README.md

@@ -1,2 +0,0 @@
-# 弘则CRM
-

+ 0 - 11
babel.config.js

@@ -1,11 +0,0 @@
-module.exports = {
-  presets: ["@vue/cli-plugin-babel/preset",["@babel/preset-env", {
-    "useBuiltIns": "entry"
-  }]],
-
-  env: {
-    development: {
-      plugins: ["dynamic-import-node"],
-    },
-  },
-};

+ 35 - 0
build/build.js

@@ -0,0 +1,35 @@
+require('./check-versions')()
+
+process.env.NODE_ENV = 'production'
+
+var ora = require('ora')
+var rm = require('rimraf')
+var path = require('path')
+var chalk = require('chalk')
+var webpack = require('webpack')
+var config = require('../config')
+var webpackConfig = require('./webpack.prod.conf')
+
+var spinner = ora('building for production...,打包后的静态资源在 hz_crm_web 文件夹中')
+spinner.start()
+
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
+  if (err) throw err
+  webpack(webpackConfig, function (err, stats) {
+    spinner.stop()
+    if (err) throw err
+    process.stdout.write(stats.toString({
+      colors: true,
+      modules: false,
+      children: false,
+      chunks: false,
+      chunkModules: false
+    }) + '\n\n')
+
+    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'
+    ))
+  })
+})

+ 38 - 0
build/build.test.js

@@ -0,0 +1,38 @@
+require('./check-versions')()
+
+process.env.NODE_ENV = 'production'
+
+var ora = require('ora')
+var rm = require('rimraf')
+var path = require('path')
+var chalk = require('chalk')
+var webpack = require('webpack')
+var config = require('../config')
+var webpackConfig = require('./webpack.prod.test.conf')
+
+var argv = process.argv.slice(2);
+var isPreProduction  = argv.indexOf('preProduction') !== -1;
+
+var spinner = isPreProduction ? ora('building for production.pre...,打包后的静态资源在 testadmin 文件夹中') : ora('building for production.test...,打包后的静态资源在 hz_crm_web 文件夹中')
+spinner.start()
+
+rm(path.join(config.test.assetsRoot, config.test.assetsSubDirectory), err => {
+  if (err) throw err
+  webpack(webpackConfig, function (err, stats) {
+    spinner.stop()
+    if (err) throw err
+    process.stdout.write(stats.toString({
+      colors: true,
+      modules: false,
+      children: false,
+      chunks: false,
+      chunkModules: false
+    }) + '\n\n')
+
+    console.log(chalk.cyan('  test 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'
+    ))
+  })
+})

+ 48 - 0
build/check-versions.js

@@ -0,0 +1,48 @@
+var chalk = require('chalk')
+var semver = require('semver')
+var packageConfig = require('../package.json')
+var shell = require('shelljs')
+function exec (cmd) {
+  return require('child_process').execSync(cmd).toString().trim()
+}
+
+var 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 () {
+  var warnings = []
+  for (var i = 0; i < versionRequirements.length; i++) {
+    var 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 (var i = 0; i < warnings.length; i++) {
+      var warning = warnings[i]
+      console.log('  ' + warning)
+    }
+    console.log()
+    process.exit(1)
+  }
+}

+ 9 - 0
build/dev-client.js

@@ -0,0 +1,9 @@
+/* eslint-disable */
+require('eventsource-polyfill')
+var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
+
+hotClient.subscribe(function (event) {
+  if (event.action === 'reload') {
+    window.location.reload()
+  }
+})

+ 89 - 0
build/dev-server.js

@@ -0,0 +1,89 @@
+require('./check-versions')()
+
+var config = require('../config')
+if (!process.env.NODE_ENV) {
+  process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
+}
+
+var opn = require('opn')
+var path = require('path')
+var express = require('express')
+var webpack = require('webpack')
+var proxyMiddleware = require('http-proxy-middleware')
+var webpackConfig = require('./webpack.dev.conf')
+
+// default port where dev server listens for incoming traffic
+var port = process.env.PORT || config.dev.port
+// automatically open browser, if not set will be false
+var autoOpenBrowser = !!config.dev.autoOpenBrowser
+// Define HTTP proxies to your custom API backend
+// https://github.com/chimurai/http-proxy-middleware
+var proxyTable = config.dev.proxyTable
+
+var app = express()
+var compiler = webpack(webpackConfig)
+
+var devMiddleware = require('webpack-dev-middleware')(compiler, {
+  publicPath: webpackConfig.output.publicPath,
+  quiet: true
+})
+
+var hotMiddleware = require('webpack-hot-middleware')(compiler, {
+  log: () => {}
+})
+// force page reload when html-webpack-plugin template changes
+compiler.plugin('compilation', function (compilation) {
+  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
+    hotMiddleware.publish({ action: 'reload' })
+    cb()
+  })
+})
+
+// proxy api requests
+Object.keys(proxyTable).forEach(function (context) {
+  var options = proxyTable[context]
+  if (typeof options === 'string') {
+    options = { target: options }
+  }
+  app.use(proxyMiddleware(options.filter || context, options))
+})
+
+// handle fallback for HTML5 history API
+app.use(require('connect-history-api-fallback')())
+
+// serve webpack bundle output
+app.use(devMiddleware)
+
+// enable hot-reload and state-preserving
+// compilation error display
+app.use(hotMiddleware)
+
+// serve pure static assets
+var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
+app.use(staticPath, express.static('./static'))
+
+var uri = 'http://localhost:' + port
+
+var _resolve
+var readyPromise = new Promise(resolve => {
+  _resolve = resolve
+})
+
+console.log('> Starting dev server...')
+devMiddleware.waitUntilValid(() => {
+  console.log('> Listening at ' + uri + '\n')
+  // when env is testing, don't need open it
+  if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
+    opn(uri)
+  }
+  _resolve()
+})
+
+var server = app.listen(port)
+
+module.exports = {
+  ready: readyPromise,
+  close: () => {
+    server.close()
+  }
+}

+ 74 - 0
build/utils.js

@@ -0,0 +1,74 @@
+var path = require('path')
+var config = require('../config')
+var ExtractTextPlugin = require('extract-text-webpack-plugin')
+
+exports.assetsPath = function (_path) {
+  var assetsSubDirectory = process.env.NODE_ENV === 'production'
+    ? config.build.assetsSubDirectory
+    : process.env.NODE_ENV === 'test'
+    ?config.test.assetsSubDirectory
+    :config.dev.assetsSubDirectory
+  return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function (options) {
+  options = options || {}
+
+  var cssLoader = {
+    loader: 'css-loader',
+    options: {
+      minimize: process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test',
+      sourceMap: options.sourceMap
+    }
+  }
+
+  // generate loader string to be used with extract text plugin
+  function generateLoaders (loader, loaderOptions) {
+    var loaders = [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',
+        publicPath: '../../'
+      })
+    } 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) {
+  var output = []
+  var loaders = exports.cssLoaders(options)
+  for (var extension in loaders) {
+    var loader = loaders[extension]
+    output.push({
+      test: new RegExp('\\.' + extension + '$'),
+      use: loader
+    })
+  }
+  return output
+}

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

@@ -0,0 +1,14 @@
+var utils = require('./utils')
+var config = require('../config')
+var isProduction = process.env.NODE_ENV === 'production'
+var isTest = process.env.NODE_ENV === 'test'
+
+module.exports = {
+  loaders: utils.cssLoaders({
+    sourceMap: isProduction
+      ? config.build.productionSourceMap
+      : isTest?config.test.cssSourceMap 
+      :config.dev.cssSourceMap,
+    extract: isProduction
+  })
+}

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

@@ -0,0 +1,82 @@
+var path = require('path')
+var utils = require('./utils')
+var config = require('../config')
+var vueLoaderConfig = require('./vue-loader.conf')
+const webpack = require('webpack')
+const manifest = require('../vendor-manifest.json')
+
+function resolve(dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+module.exports = {
+  entry: {
+    // app: './src/main.js',
+    app: ['babel-polyfill', './src/main.js']
+  },
+  output: {
+    path:process.env.NODE_ENV === 'production'? config.build.assetsRoot:config.test.assetsRoot,
+    filename: '[name].js',
+    publicPath: process.env.NODE_ENV === 'production'
+      ? config.build.assetsPublicPath
+      :process.env.NODE_ENV === 'test'
+      ?config.test.assetsPublicPath
+      :config.dev.assetsPublicPath
+  },
+  resolve: {
+    extensions: ['.js', '.vue', '.json'],
+    alias: {
+      'vue$': 'vue/dist/vue.esm.js',
+      '@': resolve('src'),
+      'scss_vars': '@/styles/vars.scss',
+      'index_scss': '@/styles/index.scss',
+      'api': '@/api',
+      'utils': '@/utils',
+      'components': '@/components',
+      'common': '@/common'
+    }
+  },
+  externals:{
+	  "vue":"Vue",
+    "echarts": 'echarts'
+  },
+  plugins: [
+    new webpack.DllReferencePlugin({
+      manifest
+    })
+  ],
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: vueLoaderConfig
+      },
+      {
+        test: /\.js$/,
+        loader: 'babel-loader',
+        include: [
+          resolve('src'),
+          resolve('static'),
+          resolve('/node_modules/element-ui'),
+        ]
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('img/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+        }
+      }
+    ]
+  }
+}

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

@@ -0,0 +1,35 @@
+var utils = require('./utils')
+var webpack = require('webpack')
+var config = require('../config')
+var merge = require('webpack-merge')
+var baseWebpackConfig = require('./webpack.base.conf')
+var HtmlWebpackPlugin = require('html-webpack-plugin')
+var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+
+// add hot-reload related code to entry chunks
+Object.keys(baseWebpackConfig.entry).forEach(function (name) {
+  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
+})
+
+module.exports = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
+  },
+  // cheap-module-eval-source-map is faster for development
+  devtool: '#cheap-module-eval-source-map',
+  plugins: [
+    new webpack.DefinePlugin({
+      'process.env': config.dev.env
+    }),
+    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
+    new webpack.HotModuleReplacementPlugin(),
+    new webpack.NoEmitOnErrorsPlugin(),
+    // https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: 'index.html',
+      inject: true
+    }),
+    new FriendlyErrorsPlugin()
+  ]
+})

+ 18 - 0
build/webpack.dll.config.js

@@ -0,0 +1,18 @@
+const path = require('path')
+const webpack = require('webpack')
+module.exports = {
+  entry: {
+    vendor: ['highcharts','@antv/x6','vue-router']
+  },
+  output: {
+    path: path.join(__dirname, '../static'),
+    filename: 'dll.[name].js',
+    library: '[name]'
+  },
+  plugins: [
+    new webpack.DllPlugin({
+      path: path.join(__dirname, '../', '[name]-manifest.json'),
+      name: '[name]'
+    })
+  ]
+}

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

@@ -0,0 +1,132 @@
+var path = require('path')
+var utils = require('./utils')
+var webpack = require('webpack')
+var config = require('../config')
+var merge = require('webpack-merge')
+var baseWebpackConfig = require('./webpack.base.conf')
+var CopyWebpackPlugin = require('copy-webpack-plugin')
+var HtmlWebpackPlugin = require('html-webpack-plugin')
+var ExtractTextPlugin = require('extract-text-webpack-plugin')
+var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
+const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
+
+var env = config.build.env
+
+var webpackConfig = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({
+      sourceMap: config.build.productionSourceMap,
+      extract: true
+    })
+  },
+  devtool: config.build.productionSourceMap ? '#source-map' : 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 webpack.optimize.UglifyJsPlugin({
+      compress: {
+        warnings: false,
+        drop_console:true
+      },
+      sourceMap: true
+    }), */
+    new ParallelUglifyPlugin({
+      // 传递给 UglifyJS的参数如下:
+      uglifyJS: {
+        output: {
+          beautify: false,
+          comments: false
+        },
+        warnings: false,
+      }
+    }),
+    // extract css into its own file
+    new ExtractTextPlugin({
+      filename: utils.assetsPath('css/[name].[contenthash].css')
+    }),
+    // Compress extracted CSS. We are using this plugin so that possible
+    // duplicated CSS from different components can be deduped.
+    new OptimizeCSSPlugin({
+      cssProcessorOptions: {
+        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'
+    }),
+    // split vendor js into its own file
+    // new webpack.optimize.CommonsChunkPlugin({
+    //   name: 'vendor',
+    //   minChunks: function (module, count) {
+    //     // 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',
+    //   chunks: ['vendor']
+    // }),
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.build.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ]
+})
+
+// if (config.build.productionGzip) {
+//   var 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) {
+  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
+}
+
+module.exports = webpackConfig

+ 136 - 0
build/webpack.prod.test.conf.js

@@ -0,0 +1,136 @@
+var path = require('path')
+var utils = require('./utils')
+var webpack = require('webpack')
+var config = require('../config')
+var merge = require('webpack-merge')
+var baseWebpackConfig = require('./webpack.base.conf')
+var CopyWebpackPlugin = require('copy-webpack-plugin')
+var HtmlWebpackPlugin = require('html-webpack-plugin')
+var ExtractTextPlugin = require('extract-text-webpack-plugin')
+var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
+const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
+
+var env = config.test.env
+var now_time = new Date().getTime()
+
+var webpackConfig = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({
+      sourceMap: config.test.productionSourceMap,
+      extract: true
+    })
+  },
+  devtool: config.test.productionSourceMap ? '#source-map' : false,
+  output: {
+    path: config.test.assetsRoot,
+    filename: utils.assetsPath('js/[name].[chunkhash].'+now_time+'.js'),
+    chunkFilename: utils.assetsPath('js/[id].[chunkhash].'+now_time+'.js')
+  },
+  plugins: [
+    // http://vuejs.github.io/vue-loader/en/workflow/production.html
+    new webpack.DefinePlugin({
+      'process.env': env
+    }),
+    // new webpack.optimize.UglifyJsPlugin({
+    //   compress: {
+    //     warnings: false,
+    //     drop_console:true
+    //   },
+    //   sourceMap: true
+    // }),
+    new ParallelUglifyPlugin({
+      // 传递给 UglifyJS的参数如下:
+      uglifyJS: {
+        output: {
+          beautify: false,
+          /*
+           是否保留代码中的注释,默认为保留,为了达到更好的压缩效果,可以设置为false
+          */
+          comments: false
+        },
+        warnings: false,
+      }
+    }),
+    // extract css into its own file
+    new ExtractTextPlugin({
+      filename: utils.assetsPath('css/[name].[contenthash].css')
+    }),
+    // Compress extracted CSS. We are using this plugin so that possible
+    // duplicated CSS from different components can be deduped.
+    new OptimizeCSSPlugin({
+      cssProcessorOptions: {
+        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.test.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'
+    }),
+    // split vendor js into its own file
+    // new webpack.optimize.CommonsChunkPlugin({
+    //   name: 'vendor',
+    //   minChunks: function (module, count) {
+    //     // 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',
+    //   chunks: ['vendor']
+    // }),
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.test.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ]
+})
+
+// if (config.test.productionGzip) {
+//   var CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+//   webpackConfig.plugins.push(
+//     new CompressionWebpackPlugin({
+//       asset: '[path].gz[query]',
+//       algorithm: 'gzip',
+//       test: new RegExp(
+//         '\\.(' +
+//         config.test.productionGzipExtensions.join('|') +
+//         ')$'
+//       ),
+//       threshold: 10240,
+//       minRatio: 0.8
+//     })
+//   )
+// }
+
+if (config.test.bundleAnalyzerReport) {
+  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
+}
+
+module.exports = webpackConfig

+ 13 - 0
config/dev.env.js

@@ -0,0 +1,13 @@
+var merge = require('webpack-merge');
+var prodEnv = require('./prod.env');
+
+module.exports = merge(prodEnv, {
+  NODE_ENV:'"development"',
+  API_ROOT:'"/adminapi"',  //生产环境
+  // API_ROOT:'"http://adminapi.brilliantstart.cn/admin"',  //生产环境
+  Domain:'"brilliantstart.cn"',
+  Login:'"http://localhost:7777/login"',
+  CHART_LINK:'"https://charttest.hzinsights.com/chartshow"',
+  HR_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8391/login"',
+  FINANCIAL_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8618/login"'
+});

+ 77 - 0
config/index.js

@@ -0,0 +1,77 @@
+// see http://vuejs-templates.github.io/webpack for documentation.
+var path = require('path')
+
+var argv = process.argv.slice(2);
+var isPreProduction  = argv.indexOf('preProduction') !== -1;
+
+console.log(argv,isPreProduction);
+
+module.exports = {
+  build: {
+    env: require('./prod.env'),
+    index: path.resolve(__dirname, '../hz_crm_web/index.html'),
+    assetsRoot: path.resolve(__dirname, '../hz_crm_web'),
+    assetsSubDirectory: 'static',
+//  assetsPublicPath: '/vue-admin/',
+		assetsPublicPath: './',
+    productionSourceMap: false,
+    // 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: true,
+    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
+  },
+  dev: {
+	//	原始配置
+    env: require('./dev.env'),
+    host: 'newadmin.brilliantstart.cn', // can be overwritten by process.env.HOST
+    port: 7777,
+    autoOpenBrowser: false,
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+    proxyTable:{
+		'/adminapi': {
+			// target:'http://rddpapi.brilliantstart.cn', // 接口的域名
+			// target:'https://admin.hzinsights.com', // 接口的域名
+	  	   target:'http://8.136.199.33:7777', // 接口的域名
+			// secure:false,  // 如果是https接口,需要配置这个参数
+			changeOrigin:true, // 如果接口跨域,需要进行这个参数配置
+			pathRewrite:{
+			  '^/adminapi':'/adminapi'
+			},
+		}
+	},
+    // CSS Sourcemaps off by default because relative paths are "buggy"
+    // with this option, according to the CSS-Loader README
+    // (https://github.com/webpack/css-loader#sourcemaps)
+    // In our experience, they generally work as expected,
+    // just be aware of this issue when enabling this option.
+    cssSourceMap: false
+  },
+  test: {
+    env: !isPreProduction ? require('./prod.test.env') : require('./prod.pre.env'),
+    index: !isPreProduction ? path.resolve(__dirname, '../hz_crm_web/index.html') : path.resolve(__dirname, '../testadmin/index.html') ,
+    assetsRoot: !isPreProduction ? path.resolve(__dirname, '../hz_crm_web') : path.resolve(__dirname, '../testadmin'),
+    assetsSubDirectory: 'static',
+//  assetsPublicPath: '/vue-admin/',
+		assetsPublicPath: './',
+    productionSourceMap: false,
+    // 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: true,
+    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
+  }
+}

+ 9 - 0
config/prod.env.js

@@ -0,0 +1,9 @@
+module.exports = {
+	NODE_ENV:'"production"',
+	API_ROOT:'"https://hzcrm.hzinsights.com/adminapi"',  //生产环境
+	Domain:'"hzinsights.com"',
+	Login:'"https://hzcrm.hzinsights.com/login"',
+	CHART_LINK:'"https://chartlib.hzinsights.com/chartshow"',
+	HR_MANAGEMENT_SYSTEM:'"https://hr.hzinsights.com/login"',
+	FINANCIAL_MANAGEMENT_SYSTEM:'"https://fms.hzinsights.com/login"'
+}

+ 4 - 0
config/prod.pre.env.js

@@ -0,0 +1,4 @@
+module.exports = {
+    NODE_ENV:'"test"',
+  	API_ROOT:'""',  //准生产环境
+}

+ 11 - 0
config/prod.test.env.js

@@ -0,0 +1,11 @@
+module.exports = {
+    NODE_ENV:'"test"',
+  	// API_ROOT:'"http://rddpapi.brilliantstart.cn/adminapi"',  //测试环境
+  	API_ROOT:'"http://8.136.199.33:7777/adminapi/"',  //测试环境
+	Domain:'"brilliantstart.cn"',
+	// Login:'"http://rddpapi.brilliantstart.cn/login"',
+	Login:'"http://8.136.199.33:7777/login"',
+	CHART_LINK:'"https://charttest.hzinsights.com/chartshow"',
+	HR_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8391/login"',
+  FINANCIAL_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8618/login"'
+}

+ 63 - 0
index.html

@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="utf-8">
+	<meta http-equiv="Cache-control" content="no-cache">
+	<meta name="renderer" content="webkit" />
+	<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
+	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+	<title>弘则管理后台</title>
+	<!-- 引入element样式 -->
+	<!-- <link rel="stylesheet" href="./static/css/indexstyle.css"/>  -->
+	<!-- <link rel="stylesheet" href="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css" /> -->
+	<!--<link rel="stylesheet" href="./static/css/reset.min.css">-->
+	<link rel="stylesheet" href="./static/css/iconfont.css"/>
+	<link rel="icon" type="image/x-icon" href="./static/fa.ico" id="icon"/>
+	<script src="./static/js/vue.js"></script>  <!-- 开发版,开发过程中使用此方案-->
+	<script src="./static/js/main.js"></script>  <!-- 生产版,打包的时候使用此方案 -->
+	<!-- 引入组件库 -->
+	<!-- <script src="./static/js/index.js"></script>  -->
+	<!-- <script type="text/javascript" src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script> -->
+	<!-- echart cdn -->
+	<script type="text/javascript" src="https://lib.baomitu.com/echarts/5.0.2/echarts.min.js"></script>
+	<!-- oss SDK -->
+	<script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
+	<!-- luckysheet cdn -->
+	<link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/css/pluginsCss.css' />
+	<link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/plugins.css' />
+	<link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/css/luckysheet.css' />
+	<link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/assets/iconfont/iconfont.css' />
+	
+	<!-- dataTables -->
+	<link rel="stylesheet" type="text/css" href="./static/css/jquery.dataTables.css"/>
+
+	<script>
+		var _hmt = _hmt || [];
+		(function() {
+		  var hm = document.createElement("script");
+		  hm.src = "https://hm.baidu.com/hm.js?2147f2700a1a306aa027116f80ef640d";
+		  var s = document.getElementsByTagName("script")[0]; 
+		  s.parentNode.insertBefore(hm, s);
+		})();
+	</script>	
+	<script>
+		window.addEventListener('error',(e)=>{
+			if(e.message=="Uncaught SyntaxError: Unexpected token '<'"){
+				window.alert('系统更新中,请稍后刷新重试!')
+				setTimeout(() => {
+					window.location.reload(true)
+				}, 1000);
+			}
+		})
+	</script>
+</head>
+<body>
+	<div id="app"></div>
+	<script type="text/javascript" src="./static/dll.vendor.js"></script>
+	<!-- built files will be auto injected -->
+	<script type="text/javascript" src="./static/js/jquery.min.js"></script>
+	<script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/js/plugin.js"></script>
+	<script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/luckysheet.umd.js"></script>
+	<script type="text/javascript" src="./static/js/jquery.dataTables.js"></script>
+</body>
+</html>

+ 69 - 40
package.json

@@ -1,13 +1,16 @@
 {
-  "name": "hz_crm_web",
-  "version": "0.1.0",
-  "private": true,
+  "name": "vueadmin",
+  "version": "1.0.5",
+  "description": "",
+  "author": "",
+  "license": "MIT",
   "scripts": {
-    "dev": "vue-cli-service serve",
-    "build": "vue-cli-service build --mode production",
-    "build.test": "vue-cli-service build --mode test",
-    "lint": "vue-cli-service lint",
-    "fix": "vue-cli-service lint --fix"
+    "dev": "node build/dev-server.js",
+    "start": "node build/dev-server.js",
+    "build": "node build/build.js",
+    "dll": "webpack -p --progress --config build/webpack.dll.config.js",
+    "build.pre": "node build/build.test.js preProduction",
+    "build.test": "node build/build.test.js"
   },
   "dependencies": {
     "@antv/x6": "^1.29.1",
@@ -16,10 +19,15 @@
     "@fullcalendar/vue": "^5.10.1",
     "@tinymce/tinymce-vue": "^2.1.0",
     "axios": "^0.15.3",
+    "babel-helper-vue-jsx-merge-props": "^2.0.3",
+    "babel-plugin-syntax-jsx": "^6.18.0",
+    "babel-plugin-transform-vue-jsx": "^3.7.0",
+    "babel-polyfill": "^6.16.0",
     "canvas2image": "^1.0.5",
     "clipboard": "^2.0.1",
-    "core-js": "^3.6.5",
     "crypto-js": "^3.1.9-1",
+    "dependencies": "^0.0.1",
+    "dll": "^0.2.0",
     "element-resize-detector": "^1.2.2",
     "element-ui": "2.13.0",
     "font-awesome": "^4.7.0",
@@ -28,16 +36,17 @@
     "himalaya": "^1.1.0",
     "html2canvas": "1.1.4",
     "js-md5": "^0.7.3",
+    "less-loader": "^4.1.0",
     "lodash": "^4.17.21",
-    "moment": "^2.22.2",
-    "monaco-editor-webpack-plugin": "^7.0.1",
     "pptxgenjs": "^3.10.0",
     "qrcode": "^1.4.4",
+    "sortablejs": "^1.15.0",
     "streamsaver": "^2.0.6",
     "tinymce": "^5.9.1",
     "url-slug": "^2.2.0",
     "v-distpicker": "^1.2.7",
-    "vue": "^2.7.0",
+    "vue": "^2.4.2",
+    "vue-aplayer": "^1.6.1",
     "vue-clipboard2": "^0.3.3",
     "vue-codemirror": "^4.0.6",
     "vue-count-to": "^1.0.13",
@@ -48,42 +57,62 @@
     "vue-router": "^2.7.0",
     "vue2-datepicker": "^3.8.0",
     "vuedraggable": "^2.24.3",
-    "vuex": "^3.6.2"
+    "vuex": "^2.0.0-rc.6",
+    "webpack-parallel-uglify-plugin": "1.0.0"
   },
   "devDependencies": {
-    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
-    "@vue/cli-plugin-babel": "~4.5.18",
-    "@vue/cli-plugin-eslint": "~4.5.18",
-    "@vue/cli-service": "~4.5.18",
-    "babel-eslint": "^10.1.0",
-    "compression-webpack-plugin": "^6.1.1",
-    "eslint": "^6.7.2",
-    "eslint-plugin-vue": "^6.2.2",
+    "@babel/runtime-corejs2": "^7.9.2",
+    "autoprefixer": "^6.7.2",
+    "axios-mock-adapter": "^1.7.1",
+    "babel-core": "^6.22.1",
+    "babel-loader": "^6.2.10",
+    "babel-plugin-transform-runtime": "^6.22.0",
+    "babel-preset-env": "^1.2.1",
+    "babel-preset-es2015": "^6.0.0",
+    "babel-preset-stage-2": "^6.22.0",
+    "babel-register": "^6.22.0",
+    "chalk": "^1.1.3",
+    "compression-webpack-plugin": "^1.1.11",
+    "connect-history-api-fallback": "^1.3.0",
+    "copy-webpack-plugin": "^4.0.1",
+    "css-loader": "^0.26.1",
+    "eventsource-polyfill": "^0.9.6",
+    "express": "^4.14.1",
+    "extract-text-webpack-plugin": "^2.1.2",
+    "file-loader": "^0.10.0",
+    "friendly-errors-webpack-plugin": "^1.1.3",
+    "function-bind": "^1.0.2",
+    "html-webpack-plugin": "^2.28.0",
+    "http-proxy-middleware": "^0.17.3",
+    "json-loader": "^0.5.4",
+    "less": "^4.1.0",
+    "moment": "^2.22.2",
     "node-sass": "^4.5.0",
-    "sass-loader": "^8.0.2",
-    "uglifyjs-webpack-plugin": "^2.2.0",
-    "vue-demi": "^0.13.1",
-    "vue-loader": "^15.10.0",
+    "opn": "^4.0.2",
+    "optimize-css-assets-webpack-plugin": "^1.3.0",
+    "ora": "^1.0.0",
+    "rimraf": "^2.6.0",
+    "sass-loader": "^6.0.0",
+    "semver": "^5.3.0",
+    "shelljs": "^0.7.6",
+    "url-loader": "^0.5.8",
+    "vue-loader": "^11.1.4",
+    "vue-style-loader": "^2.0.0",
+    "vue-template-compiler": "^2.2.4",
     "vue2-org-tree": "^1.3.5",
-    "webpack-bundle-analyzer": "^4.8.0"
+    "webpack": "^2.2.1",
+    "webpack-bundle-analyzer": "^2.2.1",
+    "webpack-dev-middleware": "^1.10.0",
+    "webpack-hot-middleware": "^2.16.1",
+    "webpack-merge": "^2.6.1"
   },
-  "eslintConfig": {
-    "root": true,
-    "env": {
-      "node": true
-    },
-    "extends": [
-      "plugin:vue/essential",
-      "eslint:recommended"
-    ],
-    "parserOptions": {
-      "parser": "babel-eslint"
-    },
-    "rules": {}
+  "engines": {
+    "node": ">= 4.0.0",
+    "npm": ">= 3.0.0"
   },
   "browserslist": [
     "> 1%",
     "last 2 versions",
-    "not dead"
+    "not ie <= 8"
   ]
 }

文件差異過大導致無法顯示
+ 0 - 6
public/css/content.inline.min.css


二進制
public/css/fonts/element-icons.ttf


二進制
public/css/fonts/element-icons.woff


文件差異過大導致無法顯示
+ 0 - 4
public/css/iconfont.css


二進制
public/css/iconfont.ttf


二進制
public/css/iconfont.woff


文件差異過大導致無法顯示
+ 0 - 0
public/css/indexstyle.css


文件差異過大導致無法顯示
+ 0 - 0
public/css/jquery.dataTables.css


+ 0 - 185
public/css/reset.min.css

@@ -1,185 +0,0 @@
-@charset "utf-8";
-body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, button, input, textarea, th, td {
-    margin: 0;
-    padding: 0
-}
-
-body {
-    font-size: 12px;
-    font-style: normal;
-    font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif,;
-
-}
-
-html {
-    // overflow: scroll;
-    overflow: auto;
-    min-width: 1000px;
-}
-
-small {
-    font-size: 12px
-}
-
-h1 {
-    font-size: 18px
-}
-
-h2 {
-    font-size: 16px
-}
-
-h3 {
-    font-size: 14px
-}
-
-h4, h5, h6 {
-    font-size: 100%
-}
-
-ul, ol {
-    list-style: none
-}
-
-a {
-    text-decoration: none;
-    background-color: transparent
-}
-
-a:hover, a:active {
-    outline-width: 0;
-    text-decoration: none
-}
-
-table {
-    border-collapse: collapse;
-    border-spacing: 0
-}
-
-hr {
-    border: 0;
-    height: 1px
-}
-
-img {
-    border-style: none
-}
-
-img:not([src]) {
-    display: none
-}
-
-svg:not(:root) {
-    overflow: hidden
-}
-
-html {
-    -webkit-touch-callout: none;
-    -webkit-text-size-adjust: 100%
-}
-
-input, textarea, button, a {
-    -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
-}
-
-article, aside, details, figcaption, figure, footer, header, main, menu, nav, section, summary {
-    display: block
-}
-
-audio, canvas, progress, video {
-    display: inline-block
-}
-
-audio:not([controls]), video:not([controls]) {
-    display: none;
-    height: 0
-}
-
-progress {
-    vertical-align: baseline
-}
-
-mark {
-    background-color: #ff0;
-    color: #000
-}
-
-sub, sup {
-    position: relative;
-    font-size: 75%;
-    line-height: 0;
-    vertical-align: baseline
-}
-
-sub {
-    bottom: -0.25em
-}
-
-sup {
-    top: -0.5em
-}
-
-button, input, select, textarea {
-    font-size: 100%;
-    outline: 0
-}
-
-button, input {
-    overflow: visible
-}
-
-button, select {
-    text-transform: none
-}
-
-textarea {
-    overflow: auto
-}
-
-button, html [type="button"], [type="reset"], [type="submit"] {
-    -webkit-appearance: button
-}
-
-button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner {
-    border-style: none;
-    padding: 0
-}
-
-button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring {
-    outline: 1px dotted ButtonText
-}
-
-[type="checkbox"], [type="radio"] {
-    box-sizing: border-box;
-    padding: 0
-}
-
-[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button {
-    height: auto
-}
-
-[type="search"] {
-    -webkit-appearance: textfield;
-    outline-offset: -2px
-}
-
-[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration {
-    -webkit-appearance: none
-}
-
-::-webkit-input-placeholder {
-    color: inherit;
-    opacity: .54
-}
-
-::-webkit-file-upload-button {
-    -webkit-appearance: button;
-    font: inherit
-}
-
-.clear:after {
-    display: block;
-    height: 0;
-    content: "";
-    clear: both
-}

文件差異過大導致無法顯示
+ 0 - 6
public/css/skin.min.css


二進制
public/fa.ico


+ 0 - 54
public/index.html

@@ -1,54 +0,0 @@
-<!DOCTYPE html>
-<html lang="">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <title>弘则管理后台</title>
-    <link rel="stylesheet" href="./css/iconfont.css"/>
-    <link rel="icon" type="image/x-icon" href="./fa.ico" id="icon"/>
-    <!-- 引入组件库 -->
-    <!-- echart cdn -->
-    <script type="text/javascript" src="https://lib.baomitu.com/echarts/5.0.2/echarts.min.js"></script>
-    <!-- oss SDK -->
-    <script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
-    <!-- luckysheet cdn -->
-    <link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/css/pluginsCss.css' />
-    <link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/plugins.css' />
-    <link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/css/luckysheet.css' />
-    <link rel='stylesheet' href='https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/assets/iconfont/iconfont.css' />
-    <!-- dataTables -->
-	  <link rel="stylesheet" type="text/css" href="./css/jquery.dataTables.css"/>
-
-    <link rel="stylesheet" type="text/css" href="./css/skin.min.css"/>
-    <link rel="stylesheet" type="text/css" href="./css/reset.min.css"/>
-    <link rel="stylesheet" type="text/css" href="./css/content.inline.min.css"/>
-    <script>
-      var _hmt = _hmt || [];
-      (function() {
-        var hm = document.createElement("script");
-        hm.src = "https://hm.baidu.com/hm.js?2147f2700a1a306aa027116f80ef640d";
-        var s = document.getElementsByTagName("script")[0]; 
-        s.parentNode.insertBefore(hm, s);
-      })();
-    </script>	
-    <script>
-      window.addEventListener('error',(e)=>{
-        if(e.message=="Uncaught SyntaxError: Unexpected token '<'"){
-          window.alert('系统更新中,请稍后刷新重试!')
-          setTimeout(() => {
-            window.location.reload(true)
-          }, 1000);
-        }
-      })
-    </script>
-  </head>
-  <body>
-    <div id="app"></div>
-    <!-- built files will be auto injected -->
-    <script type="text/javascript" src="./js/jquery.min.js"></script>
-    <script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/js/plugin.js"></script>
-    <script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/luckysheet.umd.js"></script>
-    <script type="text/javascript" src="./js/jquery.dataTables.js"></script>
-  </body>
-</html>

+ 0 - 181
public/js/jquery.dataTables.js

@@ -1,181 +0,0 @@
-/*!
-   Copyright 2008-2020 SpryMedia Ltd.
-
- This source file is free software, available under the following license:
-   MIT license - http://datatables.net/license
-
- This source file is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
-
- For details please refer to: http://www.datatables.net
- DataTables 1.10.21
- ©2008-2020 SpryMedia Ltd - datatables.net/license
-*/
-var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(f,y,w){f instanceof String&&(f=String(f));for(var n=f.length,H=0;H<n;H++){var L=f[H];if(y.call(w,L,H,f))return{i:H,v:L}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
-$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(f,y,w){f!=Array.prototype&&f!=Object.prototype&&(f[y]=w.value)};$jscomp.getGlobal=function(f){f=["object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global,f];for(var y=0;y<f.length;++y){var w=f[y];if(w&&w.Math==Math)return w}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
-$jscomp.polyfill=function(f,y,w,n){if(y){w=$jscomp.global;f=f.split(".");for(n=0;n<f.length-1;n++){var H=f[n];H in w||(w[H]={});w=w[H]}f=f[f.length-1];n=w[f];y=y(n);y!=n&&null!=y&&$jscomp.defineProperty(w,f,{configurable:!0,writable:!0,value:y})}};$jscomp.polyfill("Array.prototype.find",function(f){return f?f:function(f,w){return $jscomp.findInternal(this,f,w).v}},"es6","es3");
-(function(f){"function"===typeof define&&define.amd?define(["jquery"],function(y){return f(y,window,document)}):"object"===typeof exports?module.exports=function(y,w){y||(y=window);w||(w="undefined"!==typeof window?require("jquery"):require("jquery")(y));return f(w,y,y.document)}:f(jQuery,window,document)})(function(f,y,w,n){function H(a){var b,c,d={};f.each(a,function(e,h){(b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" ")&&(c=e.replace(b[0],b[2].toLowerCase()),
-d[c]=e,"o"===b[1]&&H(a[e]))});a._hungarianMap=d}function L(a,b,c){a._hungarianMap||H(a);var d;f.each(b,function(e,h){d=a._hungarianMap[e];d===n||!c&&b[d]!==n||("o"===d.charAt(0)?(b[d]||(b[d]={}),f.extend(!0,b[d],b[e]),L(a[d],b[d],c)):b[d]=b[e])})}function Fa(a){var b=q.defaults.oLanguage,c=b.sDecimal;c&&Ga(c);if(a){var d=a.sZeroRecords;!a.sEmptyTable&&d&&"No data available in table"===b.sEmptyTable&&M(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&d&&"Loading..."===b.sLoadingRecords&&M(a,a,
-"sZeroRecords","sLoadingRecords");a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&c!==a&&Ga(a)}}function ib(a){E(a,"ordering","bSort");E(a,"orderMulti","bSortMulti");E(a,"orderClasses","bSortClasses");E(a,"orderCellsTop","bSortCellsTop");E(a,"order","aaSorting");E(a,"orderFixed","aaSortingFixed");E(a,"paging","bPaginate");E(a,"pagingType","sPaginationType");E(a,"pageLength","iDisplayLength");E(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":
-"");"boolean"===typeof a.scrollX&&(a.scrollX=a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&L(q.models.oSearch,a[b])}function jb(a){E(a,"orderable","bSortable");E(a,"orderData","aDataSort");E(a,"orderSequence","asSorting");E(a,"orderDataType","sortDataType");var b=a.aDataSort;"number"!==typeof b||f.isArray(b)||(a.aDataSort=[b])}function kb(a){if(!q.__browser){var b={};q.__browser=b;var c=f("<div/>").css({position:"fixed",top:0,left:-1*f(y).scrollLeft(),height:1,width:1,
-overflow:"hidden"}).append(f("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(f("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}f.extend(a.oBrowser,q.__browser);a.oScroll.iBarWidth=q.__browser.barWidth}
-function lb(a,b,c,d,e,h){var g=!1;if(c!==n){var k=c;g=!0}for(;d!==e;)a.hasOwnProperty(d)&&(k=g?b(k,a[d],d,a):a[d],g=!0,d+=h);return k}function Ha(a,b){var c=q.defaults.column,d=a.aoColumns.length;c=f.extend({},q.models.oColumn,c,{nTh:b?b:w.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=f.extend({},q.models.oSearch,c[d]);la(a,d,f(b).data())}function la(a,b,c){b=a.aoColumns[b];
-var d=a.oClasses,e=f(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var h=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);h&&(b.sWidthOrig=h[1])}c!==n&&null!==c&&(jb(c),L(q.defaults.column,c,!0),c.mDataProp===n||c.mData||(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),c.sClass&&e.addClass(c.sClass),f.extend(b,c),M(b,c,"sWidth","sWidthOrig"),c.iDataSort!==n&&(b.aDataSort=[c.iDataSort]),M(b,c,"aDataSort"));var g=b.mData,k=T(g),
-l=b.mRender?T(b.mRender):null;c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=f.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=k(a,b,n,c);return l&&b?l(d,b,a,c):d};b.fnSetData=function(a,b,c){return Q(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==f.inArray("asc",b.asSorting);c=-1!==f.inArray("desc",b.asSorting);b.bSortable&&(a||c)?a&&!c?(b.sSortingClass=
-d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI):(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI="")}function Z(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ia(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;""===b.sY&&""===b.sX||ma(a);A(a,null,"column-sizing",[a])}function aa(a,b){a=na(a,"bVisible");return"number"===
-typeof a[b]?a[b]:null}function ba(a,b){a=na(a,"bVisible");b=f.inArray(b,a);return-1!==b?b:null}function V(a){var b=0;f.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==f(d.nTh).css("display")&&b++});return b}function na(a,b){var c=[];f.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ja(a){var b=a.aoColumns,c=a.aoData,d=q.ext.type.detect,e,h,g;var k=0;for(e=b.length;k<e;k++){var f=b[k];var m=[];if(!f.sType&&f._sManualType)f.sType=f._sManualType;else if(!f.sType){var p=0;for(h=
-d.length;p<h;p++){var v=0;for(g=c.length;v<g;v++){m[v]===n&&(m[v]=F(a,v,k,"type"));var u=d[p](m[v],a);if(!u&&p!==d.length-1)break;if("html"===u)break}if(u){f.sType=u;break}}f.sType||(f.sType="string")}}}function mb(a,b,c,d){var e,h,g,k=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){var l=b[e];var m=l.targets!==n?l.targets:l.aTargets;f.isArray(m)||(m=[m]);var p=0;for(h=m.length;p<h;p++)if("number"===typeof m[p]&&0<=m[p]){for(;k.length<=m[p];)Ha(a);d(m[p],l)}else if("number"===typeof m[p]&&0>m[p])d(k.length+
-m[p],l);else if("string"===typeof m[p]){var v=0;for(g=k.length;v<g;v++)("_all"==m[p]||f(k[v].nTh).hasClass(m[p]))&&d(v,l)}}if(c)for(e=0,a=c.length;e<a;e++)d(e,c[e])}function R(a,b,c,d){var e=a.aoData.length,h=f.extend(!0,{},q.models.oRow,{src:c?"dom":"data",idx:e});h._aData=b;a.aoData.push(h);for(var g=a.aoColumns,k=0,l=g.length;k<l;k++)g[k].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==n&&(a.aIds[b]=h);!c&&a.oFeatures.bDeferRender||Ka(a,e,c,d);return e}function oa(a,b){var c;b instanceof
-f||(b=f(b));return b.map(function(b,e){c=La(a,e);return R(a,c.data,e,c.cells)})}function F(a,b,c,d){var e=a.iDraw,h=a.aoColumns[c],g=a.aoData[b]._aData,k=h.sDefaultContent,f=h.fnGetData(g,d,{settings:a,row:b,col:c});if(f===n)return a.iDrawError!=e&&null===k&&(O(a,0,"Requested unknown parameter "+("function"==typeof h.mData?"{function}":"'"+h.mData+"'")+" for row "+b+", column "+c,4),a.iDrawError=e),k;if((f===g||null===f)&&null!==k&&d!==n)f=k;else if("function"===typeof f)return f.call(g);return null===
-f&&"display"==d?"":f}function nb(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}function Ma(a){return f.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\\./g,".")})}function T(a){if(f.isPlainObject(a)){var b={};f.each(a,function(a,c){c&&(b[a]=T(c))});return function(a,c,h,g){var d=b[c]||b._;return d!==n?d(a,c,h,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,h,g){return a(b,c,h,g)};if("string"!==typeof a||
--1===a.indexOf(".")&&-1===a.indexOf("[")&&-1===a.indexOf("("))return function(b,c){return b[a]};var c=function(a,b,h){if(""!==h){var d=Ma(h);for(var e=0,l=d.length;e<l;e++){h=d[e].match(ca);var m=d[e].match(W);if(h){d[e]=d[e].replace(ca,"");""!==d[e]&&(a=a[d[e]]);m=[];d.splice(0,e+1);d=d.join(".");if(f.isArray(a))for(e=0,l=a.length;e<l;e++)m.push(c(a[e],b,d));a=h[0].substring(1,h[0].length-1);a=""===a?m:m.join(a);break}else if(m){d[e]=d[e].replace(W,"");a=a[d[e]]();continue}if(null===a||a[d[e]]===
-n)return n;a=a[d[e]]}}return a};return function(b,e){return c(b,e,a)}}function Q(a){if(f.isPlainObject(a))return Q(a._);if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"!==typeof a||-1===a.indexOf(".")&&-1===a.indexOf("[")&&-1===a.indexOf("("))return function(b,d){b[a]=d};var b=function(a,d,e){e=Ma(e);var c=e[e.length-1];for(var g,k,l=0,m=e.length-1;l<m;l++){g=e[l].match(ca);k=e[l].match(W);if(g){e[l]=e[l].replace(ca,"");a[e[l]]=[];c=e.slice();
-c.splice(0,l+1);g=c.join(".");if(f.isArray(d))for(k=0,m=d.length;k<m;k++)c={},b(c,d[k],g),a[e[l]].push(c);else a[e[l]]=d;return}k&&(e[l]=e[l].replace(W,""),a=a[e[l]](d));if(null===a[e[l]]||a[e[l]]===n)a[e[l]]={};a=a[e[l]]}if(c.match(W))a[c.replace(W,"")](d);else a[c.replace(ca,"")]=d};return function(c,d){return b(c,d,a)}}function Na(a){return K(a.aoData,"_aData")}function pa(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function qa(a,b,c){for(var d=-1,e=0,h=a.length;e<
-h;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===n&&a.splice(d,1)}function da(a,b,c,d){var e=a.aoData[b],h,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=F(a,b,d,"display")};if("dom"!==c&&(c&&"auto"!==c||"dom"!==e.src)){var k=e.anCells;if(k)if(d!==n)g(k[d],d);else for(c=0,h=k.length;c<h;c++)g(k[c],c)}else e._aData=La(a,e,d,d===n?n:e._aData).data;e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==n)g[d].sType=null;else{c=0;for(h=g.length;c<h;c++)g[c].sType=null;
-Oa(a,e)}}function La(a,b,c,d){var e=[],h=b.firstChild,g,k=0,l,m=a.aoColumns,p=a._rowReadObject;d=d!==n?d:p?{}:[];var v=function(a,b){if("string"===typeof a){var c=a.indexOf("@");-1!==c&&(c=a.substring(c+1),Q(a)(d,b.getAttribute(c)))}},u=function(a){if(c===n||c===k)g=m[k],l=f.trim(a.innerHTML),g&&g._bAttrSrc?(Q(g.mData._)(d,l),v(g.mData.sort,a),v(g.mData.type,a),v(g.mData.filter,a)):p?(g._setter||(g._setter=Q(g.mData)),g._setter(d,l)):d[k]=l;k++};if(h)for(;h;){var q=h.nodeName.toUpperCase();if("TD"==
-q||"TH"==q)u(h),e.push(h);h=h.nextSibling}else for(e=b.anCells,h=0,q=e.length;h<q;h++)u(e[h]);(b=b.firstChild?b:b.nTr)&&(b=b.getAttribute("id"))&&Q(a.rowId)(d,b);return{data:d,cells:e}}function Ka(a,b,c,d){var e=a.aoData[b],h=e._aData,g=[],k,l;if(null===e.nTr){var m=c||w.createElement("tr");e.nTr=m;e.anCells=g;m._DT_RowIndex=b;Oa(a,e);var p=0;for(k=a.aoColumns.length;p<k;p++){var v=a.aoColumns[p];var n=(l=c?!1:!0)?w.createElement(v.sCellType):d[p];n._DT_CellIndex={row:b,column:p};g.push(n);if(l||
-!(c&&!v.mRender&&v.mData===p||f.isPlainObject(v.mData)&&v.mData._===p+".display"))n.innerHTML=F(a,b,p,"display");v.sClass&&(n.className+=" "+v.sClass);v.bVisible&&!c?m.appendChild(n):!v.bVisible&&c&&n.parentNode.removeChild(n);v.fnCreatedCell&&v.fnCreatedCell.call(a.oInstance,n,F(a,b,p),h,b,p)}A(a,"aoRowCreatedCallback",null,[m,h,b,g])}e.nTr.setAttribute("role","row")}function Oa(a,b){var c=b.nTr,d=b._aData;if(c){if(a=a.rowIdFn(d))c.id=a;d.DT_RowClass&&(a=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?
-sa(b.__rowc.concat(a)):a,f(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&f(c).attr(d.DT_RowAttr);d.DT_RowData&&f(c).data(d.DT_RowData)}}function ob(a){var b,c,d=a.nTHead,e=a.nTFoot,h=0===f("th, td",d).length,g=a.oClasses,k=a.aoColumns;h&&(c=f("<tr/>").appendTo(d));var l=0;for(b=k.length;l<b;l++){var m=k[l];var p=f(m.nTh).addClass(m.sClass);h&&p.appendTo(c);a.oFeatures.bSort&&(p.addClass(m.sSortingClass),!1!==m.bSortable&&(p.attr("tabindex",a.iTabIndex).attr("aria-controls",
-a.sTableId),Pa(a,m.nTh,l)));m.sTitle!=p[0].innerHTML&&p.html(m.sTitle);Qa(a,"header")(a,p,m,g)}h&&ea(a.aoHeader,d);f(d).find(">tr").attr("role","row");f(d).find(">tr>th, >tr>td").addClass(g.sHeaderTH);f(e).find(">tr>th, >tr>td").addClass(g.sFooterTH);if(null!==e)for(a=a.aoFooter[0],l=0,b=a.length;l<b;l++)m=k[l],m.nTf=a[l].cell,m.sClass&&f(m.nTf).addClass(m.sClass)}function fa(a,b,c){var d,e,h=[],g=[],k=a.aoColumns.length;if(b){c===n&&(c=!1);var l=0;for(d=b.length;l<d;l++){h[l]=b[l].slice();h[l].nTr=
-b[l].nTr;for(e=k-1;0<=e;e--)a.aoColumns[e].bVisible||c||h[l].splice(e,1);g.push([])}l=0;for(d=h.length;l<d;l++){if(a=h[l].nTr)for(;e=a.firstChild;)a.removeChild(e);e=0;for(b=h[l].length;e<b;e++){var m=k=1;if(g[l][e]===n){a.appendChild(h[l][e].cell);for(g[l][e]=1;h[l+k]!==n&&h[l][e].cell==h[l+k][e].cell;)g[l+k][e]=1,k++;for(;h[l][e+m]!==n&&h[l][e].cell==h[l][e+m].cell;){for(c=0;c<k;c++)g[l+c][e+m]=1;m++}f(h[l][e].cell).attr("rowspan",k).attr("colspan",m)}}}}}function S(a){var b=A(a,"aoPreDrawCallback",
-"preDraw",[a]);if(-1!==f.inArray(!1,b))J(a,!1);else{b=[];var c=0,d=a.asStripeClasses,e=d.length,h=a.oLanguage,g=a.iInitDisplayStart,k="ssp"==I(a),l=a.aiDisplay;a.bDrawing=!0;g!==n&&-1!==g&&(a._iDisplayStart=k?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);g=a._iDisplayStart;var m=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,J(a,!1);else if(!k)a.iDraw++;else if(!a.bDestroying&&!pb(a))return;if(0!==l.length)for(h=k?a.aoData.length:m,k=k?0:g;k<h;k++){var p=l[k],v=a.aoData[p];
-null===v.nTr&&Ka(a,p);var u=v.nTr;if(0!==e){var q=d[c%e];v._sRowStripe!=q&&(f(u).removeClass(v._sRowStripe).addClass(q),v._sRowStripe=q)}A(a,"aoRowCallback",null,[u,v._aData,c,k,p]);b.push(u);c++}else c=h.sZeroRecords,1==a.iDraw&&"ajax"==I(a)?c=h.sLoadingRecords:h.sEmptyTable&&0===a.fnRecordsTotal()&&(c=h.sEmptyTable),b[0]=f("<tr/>",{"class":e?d[0]:""}).append(f("<td />",{valign:"top",colSpan:V(a),"class":a.oClasses.sRowEmpty}).html(c))[0];A(a,"aoHeaderCallback","header",[f(a.nTHead).children("tr")[0],
-Na(a),g,m,l]);A(a,"aoFooterCallback","footer",[f(a.nTFoot).children("tr")[0],Na(a),g,m,l]);d=f(a.nTBody);d.children().detach();d.append(f(b));A(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function U(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&qb(a);d?ha(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;S(a);a._drawHold=!1}function rb(a){var b=a.oClasses,c=f(a.nTable);c=f("<div/>").insertBefore(c);var d=a.oFeatures,e=
-f("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var h=a.sDom.split(""),g,k,l,m,p,n,u=0;u<h.length;u++){g=null;k=h[u];if("<"==k){l=f("<div/>")[0];m=h[u+1];if("'"==m||'"'==m){p="";for(n=2;h[u+n]!=m;)p+=h[u+n],n++;"H"==p?p=b.sJUIHeader:"F"==p&&(p=b.sJUIFooter);-1!=p.indexOf(".")?(m=p.split("."),l.id=m[0].substr(1,m[0].length-1),l.className=m[1]):"#"==p.charAt(0)?l.id=p.substr(1,
-p.length-1):l.className=p;u+=n}e.append(l);e=f(l)}else if(">"==k)e=e.parent();else if("l"==k&&d.bPaginate&&d.bLengthChange)g=sb(a);else if("f"==k&&d.bFilter)g=tb(a);else if("r"==k&&d.bProcessing)g=ub(a);else if("t"==k)g=vb(a);else if("i"==k&&d.bInfo)g=wb(a);else if("p"==k&&d.bPaginate)g=xb(a);else if(0!==q.ext.feature.length)for(l=q.ext.feature,n=0,m=l.length;n<m;n++)if(k==l[n].cFeature){g=l[n].fnInit(a);break}g&&(l=a.aanFeatures,l[k]||(l[k]=[]),l[k].push(g),e.append(g))}c.replaceWith(e);a.nHolding=
-null}function ea(a,b){b=f(b).children("tr");var c,d,e;a.splice(0,a.length);var h=0;for(e=b.length;h<e;h++)a.push([]);h=0;for(e=b.length;h<e;h++){var g=b[h];for(c=g.firstChild;c;){if("TD"==c.nodeName.toUpperCase()||"TH"==c.nodeName.toUpperCase()){var k=1*c.getAttribute("colspan");var l=1*c.getAttribute("rowspan");k=k&&0!==k&&1!==k?k:1;l=l&&0!==l&&1!==l?l:1;var m=0;for(d=a[h];d[m];)m++;var p=m;var n=1===k?!0:!1;for(d=0;d<k;d++)for(m=0;m<l;m++)a[h+m][p+d]={cell:c,unique:n},a[h+m].nTr=g}c=c.nextSibling}}}
-function ta(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],ea(c,b)));b=0;for(var e=c.length;b<e;b++)for(var h=0,g=c[b].length;h<g;h++)!c[b][h].unique||d[h]&&a.bSortCellsTop||(d[h]=c[b][h].cell);return d}function ua(a,b,c){A(a,"aoServerParams","serverParams",[b]);if(b&&f.isArray(b)){var d={},e=/(.*?)\[\]$/;f.each(b,function(a,b){(a=b.name.match(e))?(a=a[0],d[a]||(d[a]=[]),d[a].push(b.value)):d[b.name]=b.value});b=d}var h=a.ajax,g=a.oInstance,k=function(b){A(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(f.isPlainObject(h)&&
-h.data){var l=h.data;var m="function"===typeof l?l(b,a):l;b="function"===typeof l&&m?m:f.extend(!0,b,m);delete h.data}m={data:b,success:function(b){var c=b.error||b.sError;c&&O(a,0,c);a.json=b;k(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c,d){d=A(a,null,"xhr",[a,null,a.jqXHR]);-1===f.inArray(!0,d)&&("parsererror"==c?O(a,0,"Invalid JSON response",1):4===b.readyState&&O(a,0,"Ajax error",7));J(a,!1)}};a.oAjaxData=b;A(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(g,
-a.sAjaxSource,f.map(b,function(a,b){return{name:b,value:a}}),k,a):a.sAjaxSource||"string"===typeof h?a.jqXHR=f.ajax(f.extend(m,{url:h||a.sAjaxSource})):"function"===typeof h?a.jqXHR=h.call(g,b,k,a):(a.jqXHR=f.ajax(f.extend(m,h)),h.data=l)}function pb(a){return a.bAjaxDataGet?(a.iDraw++,J(a,!0),ua(a,yb(a),function(b){zb(a,b)}),!1):!0}function yb(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,h=a.aoPreSearchCols,g=[],k=X(a);var l=a._iDisplayStart;var m=!1!==d.bPaginate?a._iDisplayLength:
--1;var p=function(a,b){g.push({name:a,value:b})};p("sEcho",a.iDraw);p("iColumns",c);p("sColumns",K(b,"sName").join(","));p("iDisplayStart",l);p("iDisplayLength",m);var n={draw:a.iDraw,columns:[],order:[],start:l,length:m,search:{value:e.sSearch,regex:e.bRegex}};for(l=0;l<c;l++){var u=b[l];var ra=h[l];m="function"==typeof u.mData?"function":u.mData;n.columns.push({data:m,name:u.sName,searchable:u.bSearchable,orderable:u.bSortable,search:{value:ra.sSearch,regex:ra.bRegex}});p("mDataProp_"+l,m);d.bFilter&&
-(p("sSearch_"+l,ra.sSearch),p("bRegex_"+l,ra.bRegex),p("bSearchable_"+l,u.bSearchable));d.bSort&&p("bSortable_"+l,u.bSortable)}d.bFilter&&(p("sSearch",e.sSearch),p("bRegex",e.bRegex));d.bSort&&(f.each(k,function(a,b){n.order.push({column:b.col,dir:b.dir});p("iSortCol_"+a,b.col);p("sSortDir_"+a,b.dir)}),p("iSortingCols",k.length));b=q.ext.legacy.ajax;return null===b?a.sAjaxSource?g:n:b?g:n}function zb(a,b){var c=function(a,c){return b[a]!==n?b[a]:b[c]},d=va(a,b),e=c("sEcho","draw"),h=c("iTotalRecords",
-"recordsTotal");c=c("iTotalDisplayRecords","recordsFiltered");if(e!==n){if(1*e<a.iDraw)return;a.iDraw=1*e}pa(a);a._iRecordsTotal=parseInt(h,10);a._iRecordsDisplay=parseInt(c,10);e=0;for(h=d.length;e<h;e++)R(a,d[e]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;S(a);a._bInitComplete||wa(a,b);a.bAjaxDataGet=!0;J(a,!1)}function va(a,b){a=f.isPlainObject(a.ajax)&&a.ajax.dataSrc!==n?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===a?b.aaData||b[a]:""!==a?T(a)(b):b}function tb(a){var b=a.oClasses,
-c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,h=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',k=d.sSearch;k=k.match(/_INPUT_/)?k.replace("_INPUT_",g):k+g;b=f("<div/>",{id:h.f?null:c+"_filter","class":b.sFilter}).append(f("<label/>").append(k));var l=function(){var b=this.value?this.value:"";b!=e.sSearch&&(ha(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,S(a))};h=null!==a.searchDelay?a.searchDelay:"ssp"===I(a)?400:0;var m=
-f("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",h?Ra(l,h):l).on("mouseup",function(a){setTimeout(function(){l.call(m[0])},10)}).on("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);f(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{m[0]!==w.activeElement&&m.val(e.sSearch)}catch(u){}});return b[0]}function ha(a,b,c){var d=a.oPreviousSearch,e=a.aoPreSearchCols,h=function(a){d.sSearch=a.sSearch;d.bRegex=
-a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive},g=function(a){return a.bEscapeRegex!==n?!a.bEscapeRegex:a.bRegex};Ja(a);if("ssp"!=I(a)){Ab(a,b.sSearch,c,g(b),b.bSmart,b.bCaseInsensitive);h(b);for(b=0;b<e.length;b++)Bb(a,e[b].sSearch,b,g(e[b]),e[b].bSmart,e[b].bCaseInsensitive);Cb(a)}else h(b);a.bFiltered=!0;A(a,null,"search",[a])}function Cb(a){for(var b=q.ext.search,c=a.aiDisplay,d,e,h=0,g=b.length;h<g;h++){for(var k=[],l=0,m=c.length;l<m;l++)e=c[l],d=a.aoData[e],b[h](a,d._aFilterData,
-e,d._aData,l)&&k.push(e);c.length=0;f.merge(c,k)}}function Bb(a,b,c,d,e,h){if(""!==b){var g=[],k=a.aiDisplay;d=Sa(b,d,e,h);for(e=0;e<k.length;e++)b=a.aoData[k[e]]._aFilterData[c],d.test(b)&&g.push(k[e]);a.aiDisplay=g}}function Ab(a,b,c,d,e,h){e=Sa(b,d,e,h);var g=a.oPreviousSearch.sSearch,k=a.aiDisplayMaster;h=[];0!==q.ext.search.length&&(c=!0);var f=Db(a);if(0>=b.length)a.aiDisplay=k.slice();else{if(f||c||d||g.length>b.length||0!==b.indexOf(g)||a.bSorted)a.aiDisplay=k.slice();b=a.aiDisplay;for(c=
-0;c<b.length;c++)e.test(a.aoData[b[c]]._sFilterRow)&&h.push(b[c]);a.aiDisplay=h}}function Sa(a,b,c,d){a=b?a:Ta(a);c&&(a="^(?=.*?"+f.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0)){var b=a.match(/^"(.*)"$/);a=b?b[1]:a}return a.replace('"',"")}).join(")(?=.*?")+").*$");return new RegExp(a,d?"i":"")}function Db(a){var b=a.aoColumns,c,d,e=q.ext.type.search;var h=!1;var g=0;for(c=a.aoData.length;g<c;g++){var k=a.aoData[g];if(!k._aFilterData){var f=[];var m=0;for(d=b.length;m<d;m++){h=
-b[m];if(h.bSearchable){var p=F(a,g,m,"filter");e[h.sType]&&(p=e[h.sType](p));null===p&&(p="");"string"!==typeof p&&p.toString&&(p=p.toString())}else p="";p.indexOf&&-1!==p.indexOf("&")&&(xa.innerHTML=p,p=$b?xa.textContent:xa.innerText);p.replace&&(p=p.replace(/[\r\n\u2028]/g,""));f.push(p)}k._aFilterData=f;k._sFilterRow=f.join("  ");h=!0}}return h}function Eb(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,caseInsensitive:a.bCaseInsensitive}}function Fb(a){return{sSearch:a.search,bSmart:a.smart,
-bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function wb(a){var b=a.sTableId,c=a.aanFeatures.i,d=f("<div/>",{"class":a.oClasses.sInfo,id:c?null:b+"_info"});c||(a.aoDrawCallback.push({fn:Gb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),f(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Gb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+1,e=a.fnDisplayEnd(),h=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),k=g?c.sInfo:c.sInfoEmpty;
-g!==h&&(k+=" "+c.sInfoFiltered);k+=c.sInfoPostFix;k=Hb(a,k);c=c.fnInfoCallback;null!==c&&(k=c.call(a.oInstance,a,d,e,h,g,k));f(b).html(k)}}function Hb(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,h=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,h)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(h/
-e)))}function ia(a){var b=a.iInitDisplayStart,c=a.aoColumns;var d=a.oFeatures;var e=a.bDeferLoading;if(a.bInitialised){rb(a);ob(a);fa(a,a.aoHeader);fa(a,a.aoFooter);J(a,!0);d.bAutoWidth&&Ia(a);var h=0;for(d=c.length;h<d;h++){var g=c[h];g.sWidth&&(g.nTh.style.width=B(g.sWidth))}A(a,null,"preInit",[a]);U(a);c=I(a);if("ssp"!=c||e)"ajax"==c?ua(a,[],function(c){var d=va(a,c);for(h=0;h<d.length;h++)R(a,d[h]);a.iInitDisplayStart=b;U(a);J(a,!1);wa(a,c)},a):(J(a,!1),wa(a))}else setTimeout(function(){ia(a)},
-200)}function wa(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Z(a);A(a,null,"plugin-init",[a,b]);A(a,"aoInitComplete","init",[a,b])}function Ua(a,b){b=parseInt(b,10);a._iDisplayLength=b;Va(a);A(a,null,"length",[a,b])}function sb(a){var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=f.isArray(d[0]),h=e?d[0]:d;d=e?d[1]:d;e=f("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect});for(var g=0,k=h.length;g<k;g++)e[0][g]=new Option("number"===typeof d[g]?a.fnFormatNumber(d[g]):d[g],h[g]);
-var l=f("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(l[0].id=c+"_length");l.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));f("select",l).val(a._iDisplayLength).on("change.DT",function(b){Ua(a,f(this).val());S(a)});f(a.nTable).on("length.dt.DT",function(b,c,d){a===c&&f("select",l).val(d)});return l[0]}function xb(a){var b=a.sPaginationType,c=q.ext.pager[b],d="function"===typeof c,e=function(a){S(a)};b=f("<div/>").addClass(a.oClasses.sPaging+b)[0];var h=
-a.aanFeatures;d||c.fnInit(a,b,e);h.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,g=a._iDisplayLength,f=a.fnRecordsDisplay(),p=-1===g;b=p?0:Math.ceil(b/g);g=p?1:Math.ceil(f/g);f=c(b,g);var n;p=0;for(n=h.p.length;p<n;p++)Qa(a,"pageButton")(a,h.p[p],p,f,b,g)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Wa(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,h=a.fnRecordsDisplay();0===h||-1===e?d=0:"number"===typeof b?(d=b*e,d>h&&(d=0)):
-"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e<h&&(d+=e):"last"==b?d=Math.floor((h-1)/e)*e:O(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(A(a,null,"page",[a]),c&&S(a));return b}function ub(a){return f("<div/>",{id:a.aanFeatures.r?null:a.sTableId+"_processing","class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function J(a,b){a.oFeatures.bProcessing&&f(a.aanFeatures.r).css("display",b?"block":"none");A(a,
-null,"processing",[a,b])}function vb(a){var b=f(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,h=a.oClasses,g=b.children("caption"),k=g.length?g[0]._captionSide:null,l=f(b[0].cloneNode(!1)),m=f(b[0].cloneNode(!1)),p=b.children("tfoot");p.length||(p=null);l=f("<div/>",{"class":h.sScrollWrapper}).append(f("<div/>",{"class":h.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?d?B(d):null:"100%"}).append(f("<div/>",{"class":h.sScrollHeadInner}).css({"box-sizing":"content-box",
-width:c.sXInner||"100%"}).append(l.removeAttr("id").css("margin-left",0).append("top"===k?g:null).append(b.children("thead"))))).append(f("<div/>",{"class":h.sScrollBody}).css({position:"relative",overflow:"auto",width:d?B(d):null}).append(b));p&&l.append(f("<div/>",{"class":h.sScrollFoot}).css({overflow:"hidden",border:0,width:d?d?B(d):null:"100%"}).append(f("<div/>",{"class":h.sScrollFootInner}).append(m.removeAttr("id").css("margin-left",0).append("bottom"===k?g:null).append(b.children("tfoot")))));
-b=l.children();var n=b[0];h=b[1];var u=p?b[2]:null;if(d)f(h).on("scroll.DT",function(a){a=this.scrollLeft;n.scrollLeft=a;p&&(u.scrollLeft=a)});f(h).css("max-height",e);c.bCollapse||f(h).css("height",e);a.nScrollHead=n;a.nScrollBody=h;a.nScrollFoot=u;a.aoDrawCallback.push({fn:ma,sName:"scrolling"});return l[0]}function ma(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY;b=b.iBarWidth;var h=f(a.nScrollHead),g=h[0].style,k=h.children("div"),l=k[0].style,m=k.children("table");k=a.nScrollBody;var p=f(k),v=
-k.style,u=f(a.nScrollFoot).children("div"),q=u.children("table"),t=f(a.nTHead),r=f(a.nTable),x=r[0],ya=x.style,w=a.nTFoot?f(a.nTFoot):null,y=a.oBrowser,A=y.bScrollOversize,ac=K(a.aoColumns,"nTh"),Xa=[],z=[],C=[],G=[],H,I=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};var D=k.scrollHeight>k.clientHeight;if(a.scrollBarVis!==D&&a.scrollBarVis!==n)a.scrollBarVis=D,Z(a);else{a.scrollBarVis=D;r.children("thead, tfoot").remove();if(w){var E=
-w.clone().prependTo(r);var F=w.find("tr");E=E.find("tr")}var J=t.clone().prependTo(r);t=t.find("tr");D=J.find("tr");J.find("th, td").removeAttr("tabindex");c||(v.width="100%",h[0].style.width="100%");f.each(ta(a,J),function(b,c){H=aa(a,b);c.style.width=a.aoColumns[H].sWidth});w&&N(function(a){a.style.width=""},E);h=r.outerWidth();""===c?(ya.width="100%",A&&(r.find("tbody").height()>k.offsetHeight||"scroll"==p.css("overflow-y"))&&(ya.width=B(r.outerWidth()-b)),h=r.outerWidth()):""!==d&&(ya.width=B(d),
-h=r.outerWidth());N(I,D);N(function(a){C.push(a.innerHTML);Xa.push(B(f(a).css("width")))},D);N(function(a,b){-1!==f.inArray(a,ac)&&(a.style.width=Xa[b])},t);f(D).height(0);w&&(N(I,E),N(function(a){G.push(a.innerHTML);z.push(B(f(a).css("width")))},E),N(function(a,b){a.style.width=z[b]},F),f(E).height(0));N(function(a,b){a.innerHTML='<div class="dataTables_sizing">'+C[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=Xa[b]},D);w&&N(function(a,b){a.innerHTML=
-'<div class="dataTables_sizing">'+G[b]+"</div>";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=z[b]},E);r.outerWidth()<h?(F=k.scrollHeight>k.offsetHeight||"scroll"==p.css("overflow-y")?h+b:h,A&&(k.scrollHeight>k.offsetHeight||"scroll"==p.css("overflow-y"))&&(ya.width=B(F-b)),""!==c&&""===d||O(a,1,"Possible column misalignment",6)):F="100%";v.width=B(F);g.width=B(F);w&&(a.nScrollFoot.style.width=B(F));!e&&A&&(v.height=B(x.offsetHeight+b));c=r.outerWidth();m[0].style.width=
-B(c);l.width=B(c);d=r.height()>k.clientHeight||"scroll"==p.css("overflow-y");e="padding"+(y.bScrollbarLeft?"Left":"Right");l[e]=d?b+"px":"0px";w&&(q[0].style.width=B(c),u[0].style.width=B(c),u[0].style[e]=d?b+"px":"0px");r.children("colgroup").insertBefore(r.children("thead"));p.trigger("scroll");!a.bSorted&&!a.bFiltered||a._drawHold||(k.scrollTop=0)}}function N(a,b,c){for(var d=0,e=0,h=b.length,g,k;e<h;){g=b[e].firstChild;for(k=c?c[e].firstChild:null;g;)1===g.nodeType&&(c?a(g,k,d):a(g,d),d++),g=
-g.nextSibling,k=c?k.nextSibling:null;e++}}function Ia(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,e=d.sY,h=d.sX,g=d.sXInner,k=c.length,l=na(a,"bVisible"),m=f("th",a.nTHead),p=b.getAttribute("width"),n=b.parentNode,u=!1,q,t=a.oBrowser;d=t.bScrollOversize;(q=b.style.width)&&-1!==q.indexOf("%")&&(p=q);for(q=0;q<l.length;q++){var r=c[l[q]];null!==r.sWidth&&(r.sWidth=Ib(r.sWidthOrig,n),u=!0)}if(d||!u&&!h&&!e&&k==V(a)&&k==m.length)for(q=0;q<k;q++)l=aa(a,q),null!==l&&(c[l].sWidth=B(m.eq(q).width()));else{k=
-f(b).clone().css("visibility","hidden").removeAttr("id");k.find("tbody tr").remove();var w=f("<tr/>").appendTo(k.find("tbody"));k.find("thead, tfoot").remove();k.append(f(a.nTHead).clone()).append(f(a.nTFoot).clone());k.find("tfoot th, tfoot td").css("width","");m=ta(a,k.find("thead")[0]);for(q=0;q<l.length;q++)r=c[l[q]],m[q].style.width=null!==r.sWidthOrig&&""!==r.sWidthOrig?B(r.sWidthOrig):"",r.sWidthOrig&&h&&f(m[q]).append(f("<div/>").css({width:r.sWidthOrig,margin:0,padding:0,border:0,height:1}));
-if(a.aoData.length)for(q=0;q<l.length;q++)u=l[q],r=c[u],f(Jb(a,u)).clone(!1).append(r.sContentPadding).appendTo(w);f("[name]",k).removeAttr("name");r=f("<div/>").css(h||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(k).appendTo(n);h&&g?k.width(g):h?(k.css("width","auto"),k.removeAttr("width"),k.width()<n.clientWidth&&p&&k.width(n.clientWidth)):e?k.width(n.clientWidth):p&&k.width(p);for(q=e=0;q<l.length;q++)n=f(m[q]),g=n.outerWidth()-n.width(),n=t.bBounding?Math.ceil(m[q].getBoundingClientRect().width):
-n.outerWidth(),e+=n,c[l[q]].sWidth=B(n-g);b.style.width=B(e);r.remove()}p&&(b.style.width=B(p));!p&&!h||a._reszEvt||(b=function(){f(y).on("resize.DT-"+a.sInstance,Ra(function(){Z(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0)}function Ib(a,b){if(!a)return 0;a=f("<div/>").css("width",B(a)).appendTo(b||w.body);b=a[0].offsetWidth;a.remove();return b}function Jb(a,b){var c=Kb(a,b);if(0>c)return null;var d=a.aoData[c];return d.nTr?d.anCells[b]:f("<td/>").html(F(a,c,b,"display"))[0]}function Kb(a,b){for(var c,
-d=-1,e=-1,h=0,g=a.aoData.length;h<g;h++)c=F(a,h,b,"display")+"",c=c.replace(bc,""),c=c.replace(/&nbsp;/g," "),c.length>d&&(d=c.length,e=h);return e}function B(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function X(a){var b=[],c=a.aoColumns;var d=a.aaSortingFixed;var e=f.isPlainObject(d);var h=[];var g=function(a){a.length&&!f.isArray(a[0])?h.push(a):f.merge(h,a)};f.isArray(d)&&g(d);e&&d.pre&&g(d.pre);g(a.aaSorting);e&&d.post&&g(d.post);for(a=0;a<h.length;a++){var k=
-h[a][0];g=c[k].aDataSort;d=0;for(e=g.length;d<e;d++){var l=g[d];var m=c[l].sType||"string";h[a]._idx===n&&(h[a]._idx=f.inArray(h[a][1],c[l].asSorting));b.push({src:k,col:l,dir:h[a][1],index:h[a]._idx,type:m,formatter:q.ext.type.order[m+"-pre"]})}}return b}function qb(a){var b,c=[],d=q.ext.type.order,e=a.aoData,h=0,g=a.aiDisplayMaster;Ja(a);var k=X(a);var f=0;for(b=k.length;f<b;f++){var m=k[f];m.formatter&&h++;Lb(a,m.col)}if("ssp"!=I(a)&&0!==k.length){f=0;for(b=g.length;f<b;f++)c[g[f]]=f;h===k.length?
-g.sort(function(a,b){var d,h=k.length,g=e[a]._aSortData,f=e[b]._aSortData;for(d=0;d<h;d++){var l=k[d];var m=g[l.col];var p=f[l.col];m=m<p?-1:m>p?1:0;if(0!==m)return"asc"===l.dir?m:-m}m=c[a];p=c[b];return m<p?-1:m>p?1:0}):g.sort(function(a,b){var h,g=k.length,f=e[a]._aSortData,l=e[b]._aSortData;for(h=0;h<g;h++){var m=k[h];var p=f[m.col];var n=l[m.col];m=d[m.type+"-"+m.dir]||d["string-"+m.dir];p=m(p,n);if(0!==p)return p}p=c[a];n=c[b];return p<n?-1:p>n?1:0})}a.bSorted=!0}function Mb(a){var b=a.aoColumns,
-c=X(a);a=a.oLanguage.oAria;for(var d=0,e=b.length;d<e;d++){var h=b[d];var g=h.asSorting;var k=h.sTitle.replace(/<.*?>/g,"");var f=h.nTh;f.removeAttribute("aria-sort");h.bSortable&&(0<c.length&&c[0].col==d?(f.setAttribute("aria-sort","asc"==c[0].dir?"ascending":"descending"),h=g[c[0].index+1]||g[0]):h=g[0],k+="asc"===h?a.sSortAscending:a.sSortDescending);f.setAttribute("aria-label",k)}}function Ya(a,b,c,d){var e=a.aaSorting,h=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===n&&(c=f.inArray(a[1],
-h));return c+1<h.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=f.inArray(b,K(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=h[b],e[c]._idx=b)):(e.push([b,h[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=h[b],e[0]._idx=b):(e.length=0,e.push([b,h[0]]),e[0]._idx=0);U(a);"function"==typeof d&&d(a)}function Pa(a,b,c,d){var e=a.aoColumns[c];Za(b,{},function(b){!1!==e.bSortable&&
-(a.oFeatures.bProcessing?(J(a,!0),setTimeout(function(){Ya(a,c,b.shiftKey,d);"ssp"!==I(a)&&J(a,!1)},0)):Ya(a,c,b.shiftKey,d))})}function za(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=X(a),e=a.oFeatures,h;if(e.bSort&&e.bSortClasses){e=0;for(h=b.length;e<h;e++){var g=b[e].src;f(K(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3))}e=0;for(h=d.length;e<h;e++)g=d[e].src,f(K(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Lb(a,b){var c=a.aoColumns[b],d=q.ext.order[c.sSortDataType],
-e;d&&(e=d.call(a.oInstance,a,b,ba(a,b)));for(var h,g=q.ext.type.order[c.sType+"-pre"],f=0,l=a.aoData.length;f<l;f++)if(c=a.aoData[f],c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)h=d?e[f]:F(a,f,b,"sort"),c._aSortData[b]=g?g(h):h}function Aa(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:f.extend(!0,[],a.aaSorting),search:Eb(a.oPreviousSearch),columns:f.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Eb(a.aoPreSearchCols[d])}})};
-A(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,b)}}function Nb(a,b,c){var d,e,h=a.aoColumns;b=function(b){if(b&&b.time){var g=A(a,"aoStateLoadParams","stateLoadParams",[a,b]);if(-1===f.inArray(!1,g)&&(g=a.iStateDuration,!(0<g&&b.time<+new Date-1E3*g||b.columns&&h.length!==b.columns.length))){a.oLoadedState=f.extend(!0,{},b);b.start!==n&&(a._iDisplayStart=b.start,a.iInitDisplayStart=b.start);b.length!==n&&(a._iDisplayLength=b.length);b.order!==
-n&&(a.aaSorting=[],f.each(b.order,function(b,c){a.aaSorting.push(c[0]>=h.length?[0,c[1]]:c)}));b.search!==n&&f.extend(a.oPreviousSearch,Fb(b.search));if(b.columns)for(d=0,e=b.columns.length;d<e;d++)g=b.columns[d],g.visible!==n&&(h[d].bVisible=g.visible),g.search!==n&&f.extend(a.aoPreSearchCols[d],Fb(g.search));A(a,"aoStateLoaded","stateLoaded",[a,b])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,a,b);g!==n&&b(g)}else c()}function Ba(a){var b=q.settings;a=f.inArray(a,
-K(b,"nTable"));return-1!==a?b[a]:null}function O(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+" - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+d);if(b)y.console&&console.log&&console.log(c);else if(b=q.ext,b=b.sErrMode||b.errMode,a&&A(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function M(a,b,c,d){f.isArray(c)?f.each(c,function(c,d){f.isArray(d)?M(a,b,d[0],d[1]):M(a,b,
-d)}):(d===n&&(d=c),b[c]!==n&&(a[d]=b[c]))}function $a(a,b,c){var d;for(d in b)if(b.hasOwnProperty(d)){var e=b[d];f.isPlainObject(e)?(f.isPlainObject(a[d])||(a[d]={}),f.extend(!0,a[d],e)):c&&"data"!==d&&"aaData"!==d&&f.isArray(e)?a[d]=e.slice():a[d]=e}return a}function Za(a,b,c){f(a).on("click.DT",b,function(b){f(a).trigger("blur");c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}function D(a,b,c,d){c&&a[b].push({fn:c,sName:d})}
-function A(a,b,c,d){var e=[];b&&(e=f.map(a[b].slice().reverse(),function(b,c){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=f.Event(c+".dt"),f(a.nTable).trigger(b,d),e.push(b.result));return e}function Va(a){var b=a._iDisplayStart,c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Qa(a,b){a=a.renderer;var c=q.ext.renderer[b];return f.isPlainObject(a)&&a[b]?c[a[b]]||c._:"string"===typeof a?c[a]||c._:c._}function I(a){return a.oFeatures.bServerSide?
-"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ja(a,b){var c=Ob.numbers_length,d=Math.floor(c/2);b<=c?a=Y(0,b):a<=d?(a=Y(0,c-2),a.push("ellipsis"),a.push(b-1)):(a>=b-1-d?a=Y(b-(c-2),b):(a=Y(a-d+2,a+d-1),a.push("ellipsis"),a.push(b-1)),a.splice(0,0,"ellipsis"),a.splice(0,0,0));a.DT_el="span";return a}function Ga(a){f.each({num:function(b){return Ca(b,a)},"num-fmt":function(b){return Ca(b,a,ab)},"html-num":function(b){return Ca(b,a,Da)},"html-num-fmt":function(b){return Ca(b,a,Da,ab)}},function(b,
-c){C.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(C.type.search[b+a]=C.type.search.html)})}function Pb(a){return function(){var b=[Ba(this[q.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return q.ext.internal[a].apply(this,b)}}var q=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new x(Ba(this[C.iApiIndex])):new x(this)};this.fnAddData=function(a,b){var c=this.api(!0);a=f.isArray(a)&&
-(f.isArray(a[0])||f.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===n||b)&&c.draw();return a.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===n||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&ma(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===n||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0);a=d.rows(a);var e=a.settings()[0],h=e.aoData[a[0][0]];
-a.remove();b&&b.call(this,e,h);(c===n||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,f){e=this.api(!0);null===b||b===n?e.search(a,c,d,f):e.column(b).search(a,c,d,f);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==n){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==n||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=
-function(a){var b=this.api(!0);return a!==n?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){a=this.api(!0).page(a);(b===n||
-b)&&a.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===n||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return Ba(this[C.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===n||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===n||e)&&h.columns.adjust();(d===n||d)&&h.draw();return 0};this.fnVersionCheck=C.fnVersionCheck;
-var b=this,c=a===n,d=this.length;c&&(a={});this.oApi=this.internal=C.internal;for(var e in q.ext.internal)e&&(this[e]=Pb(e));this.each(function(){var e={},g=1<d?$a(e,a,!0):a,k=0,l;e=this.getAttribute("id");var m=!1,p=q.defaults,v=f(this);if("table"!=this.nodeName.toLowerCase())O(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{ib(p);jb(p.column);L(p,p,!0);L(p.column,p.column,!0);L(p,f.extend(g,v.data()),!0);var u=q.settings;k=0;for(l=u.length;k<l;k++){var t=u[k];if(t.nTable==this||
-t.nTHead&&t.nTHead.parentNode==this||t.nTFoot&&t.nTFoot.parentNode==this){var w=g.bRetrieve!==n?g.bRetrieve:p.bRetrieve;if(c||w)return t.oInstance;if(g.bDestroy!==n?g.bDestroy:p.bDestroy){t.oInstance.fnDestroy();break}else{O(t,0,"Cannot reinitialise DataTable",3);return}}if(t.sTableId==this.id){u.splice(k,1);break}}if(null===e||""===e)this.id=e="DataTables_Table_"+q.ext._unique++;var r=f.extend(!0,{},q.models.oSettings,{sDestroyWidth:v[0].style.width,sInstance:e,sTableId:e});r.nTable=this;r.oApi=
-b.internal;r.oInit=g;u.push(r);r.oInstance=1===b.length?b:v.dataTable();ib(g);Fa(g.oLanguage);g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=f.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]);g=$a(f.extend(!0,{},p),g);M(r.oFeatures,g,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));M(r,g,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu",
-"sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"]]);M(r.oScroll,g,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);M(r.oLanguage,g,"fnInfoCallback");D(r,"aoDrawCallback",g.fnDrawCallback,
-"user");D(r,"aoServerParams",g.fnServerParams,"user");D(r,"aoStateSaveParams",g.fnStateSaveParams,"user");D(r,"aoStateLoadParams",g.fnStateLoadParams,"user");D(r,"aoStateLoaded",g.fnStateLoaded,"user");D(r,"aoRowCallback",g.fnRowCallback,"user");D(r,"aoRowCreatedCallback",g.fnCreatedRow,"user");D(r,"aoHeaderCallback",g.fnHeaderCallback,"user");D(r,"aoFooterCallback",g.fnFooterCallback,"user");D(r,"aoInitComplete",g.fnInitComplete,"user");D(r,"aoPreDrawCallback",g.fnPreDrawCallback,"user");r.rowIdFn=
-T(g.rowId);kb(r);var x=r.oClasses;f.extend(x,q.ext.classes,g.oClasses);v.addClass(x.sTable);r.iInitDisplayStart===n&&(r.iInitDisplayStart=g.iDisplayStart,r._iDisplayStart=g.iDisplayStart);null!==g.iDeferLoading&&(r.bDeferLoading=!0,e=f.isArray(g.iDeferLoading),r._iRecordsDisplay=e?g.iDeferLoading[0]:g.iDeferLoading,r._iRecordsTotal=e?g.iDeferLoading[1]:g.iDeferLoading);var y=r.oLanguage;f.extend(!0,y,g.oLanguage);y.sUrl&&(f.ajax({dataType:"json",url:y.sUrl,success:function(a){Fa(a);L(p.oLanguage,
-a);f.extend(!0,y,a);ia(r)},error:function(){ia(r)}}),m=!0);null===g.asStripeClasses&&(r.asStripeClasses=[x.sStripeOdd,x.sStripeEven]);e=r.asStripeClasses;var z=v.children("tbody").find("tr").eq(0);-1!==f.inArray(!0,f.map(e,function(a,b){return z.hasClass(a)}))&&(f("tbody tr",this).removeClass(e.join(" ")),r.asDestroyStripes=e.slice());e=[];u=this.getElementsByTagName("thead");0!==u.length&&(ea(r.aoHeader,u[0]),e=ta(r));if(null===g.aoColumns)for(u=[],k=0,l=e.length;k<l;k++)u.push(null);else u=g.aoColumns;
-k=0;for(l=u.length;k<l;k++)Ha(r,e?e[k]:null);mb(r,g.aoColumnDefs,u,function(a,b){la(r,a,b)});if(z.length){var B=function(a,b){return null!==a.getAttribute("data-"+b)?b:null};f(z[0]).children("th, td").each(function(a,b){var c=r.aoColumns[a];if(c.mData===a){var d=B(b,"sort")||B(b,"order");b=B(b,"filter")||B(b,"search");if(null!==d||null!==b)c.mData={_:a+".display",sort:null!==d?a+".@data-"+d:n,type:null!==d?a+".@data-"+d:n,filter:null!==b?a+".@data-"+b:n},la(r,a)}})}var C=r.oFeatures;e=function(){if(g.aaSorting===
-n){var a=r.aaSorting;k=0;for(l=a.length;k<l;k++)a[k][1]=r.aoColumns[k].asSorting[0]}za(r);C.bSort&&D(r,"aoDrawCallback",function(){if(r.bSorted){var a=X(r),b={};f.each(a,function(a,c){b[c.src]=c.dir});A(r,null,"order",[r,a,b]);Mb(r)}});D(r,"aoDrawCallback",function(){(r.bSorted||"ssp"===I(r)||C.bDeferRender)&&za(r)},"sc");a=v.children("caption").each(function(){this._captionSide=f(this).css("caption-side")});var b=v.children("thead");0===b.length&&(b=f("<thead/>").appendTo(v));r.nTHead=b[0];b=v.children("tbody");
-0===b.length&&(b=f("<tbody/>").appendTo(v));r.nTBody=b[0];b=v.children("tfoot");0===b.length&&0<a.length&&(""!==r.oScroll.sX||""!==r.oScroll.sY)&&(b=f("<tfoot/>").appendTo(v));0===b.length||0===b.children().length?v.addClass(x.sNoFooter):0<b.length&&(r.nTFoot=b[0],ea(r.aoFooter,r.nTFoot));if(g.aaData)for(k=0;k<g.aaData.length;k++)R(r,g.aaData[k]);else(r.bDeferLoading||"dom"==I(r))&&oa(r,f(r.nTBody).children("tr"));r.aiDisplay=r.aiDisplayMaster.slice();r.bInitialised=!0;!1===m&&ia(r)};g.bStateSave?
-(C.bStateSave=!0,D(r,"aoDrawCallback",Aa,"state_save"),Nb(r,g,e)):e()}});b=null;return this},C,t,z,bb={},Qb=/[\r\n\u2028]/g,Da=/<.*?>/g,cc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,dc=/(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\|\$|\^|\-)/g,ab=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,P=function(a){return a&&!0!==a&&"-"!==a?!1:!0},Rb=function(a){var b=parseInt(a,10);return!isNaN(b)&&isFinite(a)?b:null},Sb=function(a,b){bb[b]||(bb[b]=new RegExp(Ta(b),"g"));
-return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(bb[b],"."):a},cb=function(a,b,c){var d="string"===typeof a;if(P(a))return!0;b&&d&&(a=Sb(a,b));c&&d&&(a=a.replace(ab,""));return!isNaN(parseFloat(a))&&isFinite(a)},Tb=function(a,b,c){return P(a)?!0:P(a)||"string"===typeof a?cb(a.replace(Da,""),b,c)?!0:null:null},K=function(a,b,c){var d=[],e=0,h=a.length;if(c!==n)for(;e<h;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<h;e++)a[e]&&d.push(a[e][b]);return d},ka=function(a,b,c,d){var e=[],
-h=0,g=b.length;if(d!==n)for(;h<g;h++)a[b[h]][c]&&e.push(a[b[h]][c][d]);else for(;h<g;h++)e.push(a[b[h]][c]);return e},Y=function(a,b){var c=[];if(b===n){b=0;var d=a}else d=b,b=a;for(a=b;a<d;a++)c.push(a);return c},Ub=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},sa=function(a){a:{if(!(2>a.length)){var b=a.slice().sort();for(var c=b[0],d=1,e=b.length;d<e;d++){if(b[d]===c){b=!1;break a}c=b[d]}}b=!0}if(b)return a.slice();b=[];e=a.length;var h,g=0;d=0;a:for(;d<e;d++){c=
-a[d];for(h=0;h<g;h++)if(b[h]===c)continue a;b.push(c);g++}return b};q.util={throttle:function(a,b){var c=b!==n?b:200,d,e;return function(){var b=this,g=+new Date,f=arguments;d&&g<d+c?(clearTimeout(e),e=setTimeout(function(){d=n;a.apply(b,f)},c)):(d=g,a.apply(b,f))}},escapeRegex:function(a){return a.replace(dc,"\\$1")}};var E=function(a,b,c){a[b]!==n&&(a[c]=a[b])},ca=/\[.*?\]$/,W=/\(\)$/,Ta=q.util.escapeRegex,xa=f("<div>")[0],$b=xa.textContent!==n,bc=/<.*?>/g,Ra=q.util.throttle,Vb=[],G=Array.prototype,
-ec=function(a){var b,c=q.settings,d=f.map(c,function(a,b){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase()){var e=f.inArray(a,d);return-1!==e?[c[e]]:null}if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?b=f(a):a instanceof f&&(b=a)}else return[];if(b)return b.map(function(a){e=f.inArray(this,d);return-1!==e?c[e]:null}).toArray()};var x=function(a,b){if(!(this instanceof x))return new x(a,b);var c=[],d=function(a){(a=
-ec(a))&&c.push.apply(c,a)};if(f.isArray(a))for(var e=0,h=a.length;e<h;e++)d(a[e]);else d(a);this.context=sa(c);b&&f.merge(this,b);this.selector={rows:null,cols:null,opts:null};x.extend(this,this,Vb)};q.Api=x;f.extend(x.prototype,{any:function(){return 0!==this.count()},concat:G.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=this.context;return b.length>a?new x(b[a],this[a]):
-null},filter:function(a){var b=[];if(G.filter)b=G.filter.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);return new x(this.context,b)},flatten:function(){var a=[];return new x(this.context,a.concat.apply(a,this.toArray()))},join:G.join,indexOf:G.indexOf||function(a,b){b=b||0;for(var c=this.length;b<c;b++)if(this[b]===a)return b;return-1},iterator:function(a,b,c,d){var e=[],h,g,f=this.context,l,m=this.selector;"string"===typeof a&&(d=c,c=b,b=a,
-a=!1);var p=0;for(h=f.length;p<h;p++){var q=new x(f[p]);if("table"===b){var u=c.call(q,f[p],p);u!==n&&e.push(u)}else if("columns"===b||"rows"===b)u=c.call(q,f[p],this[p],p),u!==n&&e.push(u);else if("column"===b||"column-rows"===b||"row"===b||"cell"===b){var t=this[p];"column-rows"===b&&(l=Ea(f[p],m.opts));var w=0;for(g=t.length;w<g;w++)u=t[w],u="cell"===b?c.call(q,f[p],u.row,u.column,p,w):c.call(q,f[p],u,p,w,l),u!==n&&e.push(u)}}return e.length||d?(a=new x(f,a?e.concat.apply([],e):e),b=a.selector,
-b.rows=m.rows,b.cols=m.cols,b.opts=m.opts,a):this},lastIndexOf:G.lastIndexOf||function(a,b){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(a){var b=[];if(G.map)b=G.map.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new x(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:G.pop,push:G.push,reduce:G.reduce||function(a,b){return lb(this,a,b,0,this.length,1)},reduceRight:G.reduceRight||function(a,
-b){return lb(this,a,b,this.length-1,-1,-1)},reverse:G.reverse,selector:null,shift:G.shift,slice:function(){return new x(this.context,this)},sort:G.sort,splice:G.splice,toArray:function(){return G.slice.call(this)},to$:function(){return f(this)},toJQuery:function(){return f(this)},unique:function(){return new x(this.context,sa(this))},unshift:G.unshift});x.extend=function(a,b,c){if(c.length&&b&&(b instanceof x||b.__dt_wrapper)){var d,e=function(a,b,c){return function(){var d=b.apply(a,arguments);x.extend(d,
-d,c.methodExt);return d}};var h=0;for(d=c.length;h<d;h++){var f=c[h];b[f.name]="function"===f.type?e(a,f.val,f):"object"===f.type?{}:f.val;b[f.name].__dt_wrapper=!0;x.extend(a,b[f.name],f.propExt)}}};x.register=t=function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)x.register(a[c],b);else{d=a.split(".");var e=Vb,h;a=0;for(c=d.length;a<c;a++){var g=(h=-1!==d[a].indexOf("()"))?d[a].replace("()",""):d[a];a:{var k=0;for(var l=e.length;k<l;k++)if(e[k].name===g){k=e[k];break a}k=null}k||(k={name:g,
-val:{},methodExt:[],propExt:[],type:"object"},e.push(k));a===c-1?(k.val=b,k.type="function"===typeof b?"function":f.isPlainObject(b)?"object":"other"):e=h?k.methodExt:k.propExt}}};x.registerPlural=z=function(a,b,c){x.register(a,c);x.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof x?a.length?f.isArray(a[0])?new x(a.context,a[0]):a[0]:n:a})};var Wb=function(a,b){if(f.isArray(a))return f.map(a,function(a){return Wb(a,b)});if("number"===typeof a)return[b[a]];var c=
-f.map(b,function(a,b){return a.nTable});return f(c).filter(a).map(function(a){a=f.inArray(this,c);return b[a]}).toArray()};t("tables()",function(a){return a!==n&&null!==a?new x(Wb(a,this.context)):this});t("table()",function(a){a=this.tables(a);var b=a.context;return b.length?new x(b[0]):a});z("tables().nodes()","table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});z("tables().body()","table().body()",function(){return this.iterator("table",function(a){return a.nTBody},
-1)});z("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});z("tables().footer()","table().footer()",function(){return this.iterator("table",function(a){return a.nTFoot},1)});z("tables().containers()","table().container()",function(){return this.iterator("table",function(a){return a.nTableWrapper},1)});t("draw()",function(a){return this.iterator("table",function(b){"page"===a?S(b):("string"===typeof a&&(a="full-hold"===a?!1:!0),U(b,!1===
-a))})});t("page()",function(a){return a===n?this.page.info().page:this.iterator("table",function(b){Wa(b,a)})});t("page.info()",function(a){if(0===this.context.length)return n;a=this.context[0];var b=a._iDisplayStart,c=a.oFeatures.bPaginate?a._iDisplayLength:-1,d=a.fnRecordsDisplay(),e=-1===c;return{page:e?0:Math.floor(b/c),pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,serverSide:"ssp"===I(a)}});t("page.len()",function(a){return a===
-n?0!==this.context.length?this.context[0]._iDisplayLength:n:this.iterator("table",function(b){Ua(b,a)})});var Xb=function(a,b,c){if(c){var d=new x(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==I(a))U(a,b);else{J(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();ua(a,[],function(c){pa(a);c=va(a,c);for(var d=0,e=c.length;d<e;d++)R(a,c[d]);U(a,b);J(a,!1)})}};t("ajax.json()",function(){var a=this.context;if(0<a.length)return a[0].json});t("ajax.params()",function(){var a=this.context;if(0<
-a.length)return a[0].oAjaxData});t("ajax.reload()",function(a,b){return this.iterator("table",function(c){Xb(c,!1===b,a)})});t("ajax.url()",function(a){var b=this.context;if(a===n){if(0===b.length)return n;b=b[0];return b.ajax?f.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){f.isPlainObject(b.ajax)?b.ajax.url=a:b.ajax=a})});t("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Xb(c,!1===b,a)})});var db=function(a,b,c,d,e){var h=
-[],g,k,l;var m=typeof b;b&&"string"!==m&&"function"!==m&&b.length!==n||(b=[b]);m=0;for(k=b.length;m<k;m++){var p=b[m]&&b[m].split&&!b[m].match(/[\[\(:]/)?b[m].split(","):[b[m]];var q=0;for(l=p.length;q<l;q++)(g=c("string"===typeof p[q]?f.trim(p[q]):p[q]))&&g.length&&(h=h.concat(g))}a=C.selector[a];if(a.length)for(m=0,k=a.length;m<k;m++)h=a[m](d,e,h);return sa(h)},eb=function(a){a||(a={});a.filter&&a.search===n&&(a.search=a.filter);return f.extend({search:"none",order:"current",page:"all"},a)},fb=
-function(a){for(var b=0,c=a.length;b<c;b++)if(0<a[b].length)return a[0]=a[b],a[0].length=1,a.length=1,a.context=[a.context[b]],a;a.length=0;return a},Ea=function(a,b){var c=[],d=a.aiDisplay;var e=a.aiDisplayMaster;var h=b.search;var g=b.order;b=b.page;if("ssp"==I(a))return"removed"===h?[]:Y(0,e.length);if("current"==b)for(g=a._iDisplayStart,a=a.fnDisplayEnd();g<a;g++)c.push(d[g]);else if("current"==g||"applied"==g)if("none"==h)c=e.slice();else if("applied"==h)c=d.slice();else{if("removed"==h){var k=
-{};g=0;for(a=d.length;g<a;g++)k[d[g]]=null;c=f.map(e,function(a){return k.hasOwnProperty(a)?null:a})}}else if("index"==g||"original"==g)for(g=0,a=a.aoData.length;g<a;g++)"none"==h?c.push(g):(e=f.inArray(g,d),(-1===e&&"removed"==h||0<=e&&"applied"==h)&&c.push(g));return c},fc=function(a,b,c){var d;return db("row",b,function(b){var e=Rb(b),g=a.aoData;if(null!==e&&!c)return[e];d||(d=Ea(a,c));if(null!==e&&-1!==f.inArray(e,d))return[e];if(null===b||b===n||""===b)return d;if("function"===typeof b)return f.map(d,
-function(a){var c=g[a];return b(a,c._aData,c.nTr)?a:null});if(b.nodeName){e=b._DT_RowIndex;var k=b._DT_CellIndex;if(e!==n)return g[e]&&g[e].nTr===b?[e]:[];if(k)return g[k.row]&&g[k.row].nTr===b.parentNode?[k.row]:[];e=f(b).closest("*[data-dt-row]");return e.length?[e.data("dt-row")]:[]}if("string"===typeof b&&"#"===b.charAt(0)&&(e=a.aIds[b.replace(/^#/,"")],e!==n))return[e.idx];e=Ub(ka(a.aoData,d,"nTr"));return f(e).filter(b).map(function(){return this._DT_RowIndex}).toArray()},a,c)};t("rows()",function(a,
-b){a===n?a="":f.isPlainObject(a)&&(b=a,a="");b=eb(b);var c=this.iterator("table",function(c){return fc(c,a,b)},1);c.selector.rows=a;c.selector.opts=b;return c});t("rows().nodes()",function(){return this.iterator("row",function(a,b){return a.aoData[b].nTr||n},1)});t("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return ka(a.aoData,b,"_aData")},1)});z("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){b=b.aoData[c];return"search"===a?b._aFilterData:
-b._aSortData},1)});z("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",function(b,c){da(b,c,a)})});z("rows().indexes()","row().index()",function(){return this.iterator("row",function(a,b){return b},1)});z("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var k=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((!0===a?"#":"")+k)}return new x(c,b)});z("rows().remove()","row().remove()",function(){var a=
-this;this.iterator("row",function(b,c,d){var e=b.aoData,f=e[c],g,k;e.splice(c,1);var l=0;for(g=e.length;l<g;l++){var m=e[l];var p=m.anCells;null!==m.nTr&&(m.nTr._DT_RowIndex=l);if(null!==p)for(m=0,k=p.length;m<k;m++)p[m]._DT_CellIndex.row=l}qa(b.aiDisplayMaster,c);qa(b.aiDisplay,c);qa(a[d],c,!1);0<b._iRecordsDisplay&&b._iRecordsDisplay--;Va(b);c=b.rowIdFn(f._aData);c!==n&&delete b.aIds[c]});this.iterator("table",function(a){for(var b=0,d=a.aoData.length;b<d;b++)a.aoData[b].idx=b});return this});t("rows.add()",
-function(a){var b=this.iterator("table",function(b){var c,d=[];var f=0;for(c=a.length;f<c;f++){var k=a[f];k.nodeName&&"TR"===k.nodeName.toUpperCase()?d.push(oa(b,k)[0]):d.push(R(b,k))}return d},1),c=this.rows(-1);c.pop();f.merge(c,b);return c});t("row()",function(a,b){return fb(this.rows(a,b))});t("row().data()",function(a){var b=this.context;if(a===n)return b.length&&this.length?b[0].aoData[this[0]]._aData:n;var c=b[0].aoData[this[0]];c._aData=a;f.isArray(a)&&c.nTr&&c.nTr.id&&Q(b[0].rowId)(a,c.nTr.id);
-da(b[0],this[0],"data");return this});t("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});t("row.add()",function(a){a instanceof f&&a.length&&(a=a[0]);var b=this.iterator("table",function(b){return a.nodeName&&"TR"===a.nodeName.toUpperCase()?oa(b,a)[0]:R(b,a)});return this.row(b[0])});var gc=function(a,b,c,d){var e=[],h=function(b,c){if(f.isArray(b)||b instanceof f)for(var d=0,g=b.length;d<g;d++)h(b[d],c);else b.nodeName&&"tr"===b.nodeName.toLowerCase()?
-e.push(b):(d=f("<tr><td/></tr>").addClass(c),f("td",d).addClass(c).html(b)[0].colSpan=V(a),e.push(d[0]))};h(c,d);b._details&&b._details.detach();b._details=f(e);b._detailsShow&&b._details.insertAfter(b.nTr)},gb=function(a,b){var c=a.context;c.length&&(a=c[0].aoData[b!==n?b:a[0]])&&a._details&&(a._details.remove(),a._detailsShow=n,a._details=n)},Yb=function(a,b){var c=a.context;c.length&&a.length&&(a=c[0].aoData[a[0]],a._details&&((a._detailsShow=b)?a._details.insertAfter(a.nTr):a._details.detach(),
-hc(c[0])))},hc=function(a){var b=new x(a),c=a.aoData;b.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");0<K(c,"_details").length&&(b.on("draw.dt.DT_details",function(d,e){a===e&&b.rows({page:"current"}).eq(0).each(function(a){a=c[a];a._detailsShow&&a._details.insertAfter(a.nTr)})}),b.on("column-visibility.dt.DT_details",function(b,e,f,g){if(a===e)for(e=V(e),f=0,g=c.length;f<g;f++)b=c[f],b._details&&b._details.children("td[colspan]").attr("colspan",e)}),b.on("destroy.dt.DT_details",
-function(d,e){if(a===e)for(d=0,e=c.length;d<e;d++)c[d]._details&&gb(b,d)}))};t("row().child()",function(a,b){var c=this.context;if(a===n)return c.length&&this.length?c[0].aoData[this[0]]._details:n;!0===a?this.child.show():!1===a?gb(this):c.length&&this.length&&gc(c[0],c[0].aoData[this[0]],a,b);return this});t(["row().child.show()","row().child().show()"],function(a){Yb(this,!0);return this});t(["row().child.hide()","row().child().hide()"],function(){Yb(this,!1);return this});t(["row().child.remove()",
-"row().child().remove()"],function(){gb(this);return this});t("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var ic=/^([^:]+):(name|visIdx|visible)$/,Zb=function(a,b,c,d,e){c=[];d=0;for(var f=e.length;d<f;d++)c.push(F(a,e[d],b));return c},jc=function(a,b,c){var d=a.aoColumns,e=K(d,"sName"),h=K(d,"nTh");return db("column",b,function(b){var g=Rb(b);if(""===b)return Y(d.length);if(null!==g)return[0<=g?g:d.length+g];if("function"===
-typeof b){var l=Ea(a,c);return f.map(d,function(c,d){return b(d,Zb(a,d,0,0,l),h[d])?d:null})}var m="string"===typeof b?b.match(ic):"";if(m)switch(m[2]){case "visIdx":case "visible":g=parseInt(m[1],10);if(0>g){var p=f.map(d,function(a,b){return a.bVisible?b:null});return[p[p.length+g]]}return[aa(a,g)];case "name":return f.map(e,function(a,b){return a===m[1]?b:null});default:return[]}if(b.nodeName&&b._DT_CellIndex)return[b._DT_CellIndex.column];g=f(h).filter(b).map(function(){return f.inArray(this,
-h)}).toArray();if(g.length||!b.nodeName)return g;g=f(b).closest("*[data-dt-column]");return g.length?[g.data("dt-column")]:[]},a,c)};t("columns()",function(a,b){a===n?a="":f.isPlainObject(a)&&(b=a,a="");b=eb(b);var c=this.iterator("table",function(c){return jc(c,a,b)},1);c.selector.cols=a;c.selector.opts=b;return c});z("columns().header()","column().header()",function(a,b){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});z("columns().footer()","column().footer()",function(a,
-b){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});z("columns().data()","column().data()",function(){return this.iterator("column-rows",Zb,1)});z("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},1)});z("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ka(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});z("columns().nodes()",
-"column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ka(a.aoData,e,"anCells",b)},1)});z("columns().visible()","column().visible()",function(a,b){var c=this,d=this.iterator("column",function(b,c){if(a===n)return b.aoColumns[c].bVisible;var d=b.aoColumns,e=d[c],h=b.aoData,m;if(a!==n&&e.bVisible!==a){if(a){var p=f.inArray(!0,K(d,"bVisible"),c+1);d=0;for(m=h.length;d<m;d++){var q=h[d].nTr;b=h[d].anCells;q&&q.insertBefore(b[c],b[p]||null)}}else f(K(b.aoData,"anCells",
-c)).detach();e.bVisible=a}});a!==n&&this.iterator("table",function(d){fa(d,d.aoHeader);fa(d,d.aoFooter);d.aiDisplay.length||f(d.nTBody).find("td[colspan]").attr("colspan",V(d));Aa(d);c.iterator("column",function(c,d){A(c,null,"column-visibility",[c,d,a,b])});(b===n||b)&&c.columns.adjust()});return d});z("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===a?ba(b,c):c},1)});t("columns.adjust()",function(){return this.iterator("table",function(a){Z(a)},
-1)});t("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return aa(c,b);if("fromData"===a||"toVisible"===a)return ba(c,b)}});t("column()",function(a,b){return fb(this.columns(a,b))});var kc=function(a,b,c){var d=a.aoData,e=Ea(a,c),h=Ub(ka(d,e,"anCells")),g=f([].concat.apply([],h)),k,l=a.aoColumns.length,m,p,q,u,t,w;return db("cell",b,function(b){var c="function"===typeof b;if(null===b||b===n||c){m=[];p=0;for(q=e.length;p<q;p++)for(k=
-e[p],u=0;u<l;u++)t={row:k,column:u},c?(w=d[k],b(t,F(a,k,u),w.anCells?w.anCells[u]:null)&&m.push(t)):m.push(t);return m}if(f.isPlainObject(b))return b.column!==n&&b.row!==n&&-1!==f.inArray(b.row,e)?[b]:[];c=g.filter(b).map(function(a,b){return{row:b._DT_CellIndex.row,column:b._DT_CellIndex.column}}).toArray();if(c.length||!b.nodeName)return c;w=f(b).closest("*[data-dt-row]");return w.length?[{row:w.data("dt-row"),column:w.data("dt-column")}]:[]},a,c)};t("cells()",function(a,b,c){f.isPlainObject(a)&&
-(a.row===n?(c=a,a=null):(c=b,b=null));f.isPlainObject(b)&&(c=b,b=null);if(null===b||b===n)return this.iterator("table",function(b){return kc(b,a,eb(c))});var d=c?{page:c.page,order:c.order,search:c.search}:{},e=this.columns(b,d),h=this.rows(a,d),g,k,l,m;d=this.iterator("table",function(a,b){a=[];g=0;for(k=h[b].length;g<k;g++)for(l=0,m=e[b].length;l<m;l++)a.push({row:h[b][g],column:e[b][l]});return a},1);d=c&&c.selected?this.cells(d,c):d;f.extend(d.selector,{cols:b,rows:a,opts:c});return d});z("cells().nodes()",
-"cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=a.aoData[b])&&a.anCells?a.anCells[c]:n},1)});t("cells().data()",function(){return this.iterator("cell",function(a,b,c){return F(a,b,c)},1)});z("cells().cache()","cell().cache()",function(a){a="search"===a?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});z("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return F(b,c,d,a)},
-1)});z("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(a,b,c){return{row:b,column:c,columnVisible:ba(a,c)}},1)});z("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){da(b,c,a,d)})});t("cell()",function(a,b,c){return fb(this.cells(a,b,c))});t("cell().data()",function(a){var b=this.context,c=this[0];if(a===n)return b.length&&c.length?F(b[0],c[0].row,c[0].column):n;nb(b[0],c[0].row,c[0].column,a);da(b[0],c[0].row,
-"data",c[0].column);return this});t("order()",function(a,b){var c=this.context;if(a===n)return 0!==c.length?c[0].aaSorting:n;"number"===typeof a?a=[[a,b]]:a.length&&!f.isArray(a[0])&&(a=Array.prototype.slice.call(arguments));return this.iterator("table",function(b){b.aaSorting=a.slice()})});t("order.listener()",function(a,b,c){return this.iterator("table",function(d){Pa(d,a,b,c)})});t("order.fixed()",function(a){if(!a){var b=this.context;b=b.length?b[0].aaSortingFixed:n;return f.isArray(b)?{pre:b}:
-b}return this.iterator("table",function(b){b.aaSortingFixed=f.extend(!0,{},a)})});t(["columns().order()","column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];f.each(b[d],function(b,c){e.push([c,a])});c.aaSorting=e})});t("search()",function(a,b,c,d){var e=this.context;return a===n?0!==e.length?e[0].oPreviousSearch.sSearch:n:this.iterator("table",function(e){e.oFeatures.bFilter&&ha(e,f.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===
-c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});z("columns().search()","column().search()",function(a,b,c,d){return this.iterator("column",function(e,h){var g=e.aoPreSearchCols;if(a===n)return g[h].sSearch;e.oFeatures.bFilter&&(f.extend(g[h],{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),ha(e,e.oPreviousSearch,1))})});t("state()",function(){return this.context.length?this.context[0].oSavedState:null});t("state.clear()",function(){return this.iterator("table",
-function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});t("state.loaded()",function(){return this.context.length?this.context[0].oLoadedState:null});t("state.save()",function(){return this.iterator("table",function(a){Aa(a)})});q.versionCheck=q.fnVersionCheck=function(a){var b=q.version.split(".");a=a.split(".");for(var c,d,e=0,f=a.length;e<f;e++)if(c=parseInt(b[e],10)||0,d=parseInt(a[e],10)||0,c!==d)return c>d;return!0};q.isDataTable=q.fnIsDataTable=function(a){var b=f(a).get(0),c=!1;if(a instanceof
-q.Api)return!0;f.each(q.settings,function(a,e){a=e.nScrollHead?f("table",e.nScrollHead)[0]:null;var d=e.nScrollFoot?f("table",e.nScrollFoot)[0]:null;if(e.nTable===b||a===b||d===b)c=!0});return c};q.tables=q.fnTables=function(a){var b=!1;f.isPlainObject(a)&&(b=a.api,a=a.visible);var c=f.map(q.settings,function(b){if(!a||a&&f(b.nTable).is(":visible"))return b.nTable});return b?new x(c):c};q.camelToHungarian=L;t("$()",function(a,b){b=this.rows(b).nodes();b=f(b);return f([].concat(b.filter(a).toArray(),
-b.find(a).toArray()))});f.each(["on","one","off"],function(a,b){t(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0]=f.map(a[0].split(/\s/),function(a){return a.match(/\.dt\b/)?a:a+".dt"}).join(" ");var d=f(this.tables().nodes());d[b].apply(d,a);return this})});t("clear()",function(){return this.iterator("table",function(a){pa(a)})});t("settings()",function(){return new x(this.context,this.context)});t("init()",function(){var a=this.context;return a.length?a[0].oInit:null});t("data()",
-function(){return this.iterator("table",function(a){return K(a.aoData,"_aData")}).flatten()});t("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,h=b.nTBody,g=b.nTHead,k=b.nTFoot,l=f(e);h=f(h);var m=f(b.nTableWrapper),p=f.map(b.aoData,function(a){return a.nTr}),n;b.bDestroying=!0;A(b,"aoDestroyCallback","destroy",[b]);a||(new x(b)).columns().visible(!0);m.off(".DT").find(":not(tbody *)").off(".DT");f(y).off(".DT-"+b.sInstance);
-e!=g.parentNode&&(l.children("thead").detach(),l.append(g));k&&e!=k.parentNode&&(l.children("tfoot").detach(),l.append(k));b.aaSorting=[];b.aaSortingFixed=[];za(b);f(p).removeClass(b.asStripeClasses.join(" "));f("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);h.children().detach();h.append(p);g=a?"remove":"detach";l[g]();m[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),l.css("width",b.sDestroyWidth).removeClass(d.sTable),(n=b.asDestroyStripes.length)&&
-h.children().each(function(a){f(this).addClass(b.asDestroyStripes[a%n])}));c=f.inArray(b,q.settings);-1!==c&&q.settings.splice(c,1)})});f.each(["column","row","cell"],function(a,b){t(b+"s().every()",function(a){var c=this.selector.opts,e=this;return this.iterator(b,function(d,f,k,l,m){a.call(e[b](f,"cell"===b?k:c,"cell"===b?c:n),f,k,l,m)})})});t("i18n()",function(a,b,c){var d=this.context[0];a=T(a)(d.oLanguage);a===n&&(a=b);c!==n&&f.isPlainObject(a)&&(a=a[c]!==n?a[c]:a._);return a.replace("%d",c)});
-q.version="1.10.21";q.settings=[];q.models={};q.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};q.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};q.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,
-sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};q.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,
-bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){return{}}},
-fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",
-sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:f.extend({},q.models.oSearch),sAjaxDataProp:"data",
-sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};H(q.defaults);q.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};H(q.defaults.column);q.models.oSettings=
-{oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},
-aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,
-aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:n,oAjaxData:n,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==I(this)?1*this._iRecordsTotal:
-this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==I(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};q.ext=C={buttons:{},
-classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:q.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:q.version};f.extend(C,{afnFiltering:C.search,aTypes:C.type.detect,ofnSearch:C.type.search,oSort:C.type.order,afnSortData:C.order,aoFeatures:C.feature,oApi:C.internal,oStdClasses:C.classes,oPagination:C.pager});
-f.extend(q.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",
-sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",
-sJUIHeader:"",sJUIFooter:""});var Ob=q.ext.pager;f.extend(Ob,{simple:function(a,b){return["previous","next"]},full:function(a,b){return["first","previous","next","last"]},numbers:function(a,b){return[ja(a,b)]},simple_numbers:function(a,b){return["previous",ja(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ja(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ja(a,b),"last"]},_numbers:ja,numbers_length:7});f.extend(!0,q.ext.renderer,{pageButton:{_:function(a,b,
-c,d,e,h){var g=a.oClasses,k=a.oLanguage.oPaginate,l=a.oLanguage.oAria.paginate||{},m,p,q=0,t=function(b,d){var n,r=g.sPageButtonDisabled,u=function(b){Wa(a,b.data.action,!0)};var w=0;for(n=d.length;w<n;w++){var v=d[w];if(f.isArray(v)){var x=f("<"+(v.DT_el||"div")+"/>").appendTo(b);t(x,v)}else{m=null;p=v;x=a.iTabIndex;switch(v){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;case "first":m=k.sFirst;0===e&&(x=-1,p+=" "+r);break;case "previous":m=k.sPrevious;0===e&&(x=-1,p+=
-" "+r);break;case "next":m=k.sNext;if(0===h||e===h-1)x=-1,p+=" "+r;break;case "last":m=k.sLast;e===h-1&&(x=-1,p+=" "+r);break;default:m=v+1,p=e===v?g.sPageButtonActive:""}null!==m&&(x=f("<a>",{"class":g.sPageButton+" "+p,"aria-controls":a.sTableId,"aria-label":l[v],"data-dt-idx":q,tabindex:x,id:0===c&&"string"===typeof v?a.sTableId+"_"+v:null}).html(m).appendTo(b),Za(x,{action:v},u),q++)}}};try{var x=f(b).find(w.activeElement).data("dt-idx")}catch(lc){}t(f(b).empty(),d);x!==n&&f(b).find("[data-dt-idx="+
-x+"]").trigger("focus")}}});f.extend(q.ext.type.detect,[function(a,b){b=b.oLanguage.sDecimal;return cb(a,b)?"num"+b:null},function(a,b){if(a&&!(a instanceof Date)&&!cc.test(a))return null;b=Date.parse(a);return null!==b&&!isNaN(b)||P(a)?"date":null},function(a,b){b=b.oLanguage.sDecimal;return cb(a,b,!0)?"num-fmt"+b:null},function(a,b){b=b.oLanguage.sDecimal;return Tb(a,b)?"html-num"+b:null},function(a,b){b=b.oLanguage.sDecimal;return Tb(a,b,!0)?"html-num-fmt"+b:null},function(a,b){return P(a)||"string"===
-typeof a&&-1!==a.indexOf("<")?"html":null}]);f.extend(q.ext.type.search,{html:function(a){return P(a)?a:"string"===typeof a?a.replace(Qb," ").replace(Da,""):""},string:function(a){return P(a)?a:"string"===typeof a?a.replace(Qb," "):a}});var Ca=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Sb(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};f.extend(C.type.order,{"date-pre":function(a){a=Date.parse(a);return isNaN(a)?-Infinity:a},"html-pre":function(a){return P(a)?
-"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return P(a)?"":"string"===typeof a?a.toLowerCase():a.toString?a.toString():""},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,b){return a<b?1:a>b?-1:0}});Ga("");f.extend(!0,q.ext.renderer,{header:{_:function(a,b,c,d){f(a.nTable).on("order.dt.DT",function(e,f,g,k){a===f&&(e=c.idx,b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass("asc"==k[e]?d.sSortAsc:"desc"==k[e]?d.sSortDesc:
-c.sSortingClass))})},jqueryui:function(a,b,c,d){f("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(f("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);f(a.nTable).on("order.dt.DT",function(e,f,g,k){a===f&&(e=c.idx,b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass("asc"==k[e]?d.sSortAsc:"desc"==k[e]?d.sSortDesc:c.sSortingClass),b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass("asc"==
-k[e]?d.sSortJUIAsc:"desc"==k[e]?d.sSortJUIDesc:c.sSortingClassJUI))})}}});var hb=function(a){return"string"===typeof a?a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):a};q.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return hb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g,
-a)+f+(e||"")}}},text:function(){return{display:hb,filter:hb}}};f.extend(q.ext.internal,{_fnExternApiFunc:Pb,_fnBuildAjax:ua,_fnAjaxUpdate:pb,_fnAjaxParameters:yb,_fnAjaxUpdateDraw:zb,_fnAjaxDataSrc:va,_fnAddColumn:Ha,_fnColumnOptions:la,_fnAdjustColumnSizing:Z,_fnVisibleToColumnIndex:aa,_fnColumnIndexToVisible:ba,_fnVisbleColumns:V,_fnGetColumns:na,_fnColumnTypes:Ja,_fnApplyColumnDefs:mb,_fnHungarianMap:H,_fnCamelToHungarian:L,_fnLanguageCompat:Fa,_fnBrowserDetect:kb,_fnAddData:R,_fnAddTr:oa,_fnNodeToDataIndex:function(a,
-b){return b._DT_RowIndex!==n?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return f.inArray(c,a.aoData[b].anCells)},_fnGetCellData:F,_fnSetCellData:nb,_fnSplitObjNotation:Ma,_fnGetObjectDataFn:T,_fnSetObjectDataFn:Q,_fnGetDataMaster:Na,_fnClearTable:pa,_fnDeleteIndex:qa,_fnInvalidate:da,_fnGetRowElements:La,_fnCreateTr:Ka,_fnBuildHead:ob,_fnDrawHead:fa,_fnDraw:S,_fnReDraw:U,_fnAddOptionsHtml:rb,_fnDetectHeader:ea,_fnGetUniqueThs:ta,_fnFeatureHtmlFilter:tb,_fnFilterComplete:ha,_fnFilterCustom:Cb,
-_fnFilterColumn:Bb,_fnFilter:Ab,_fnFilterCreateSearch:Sa,_fnEscapeRegex:Ta,_fnFilterData:Db,_fnFeatureHtmlInfo:wb,_fnUpdateInfo:Gb,_fnInfoMacros:Hb,_fnInitialise:ia,_fnInitComplete:wa,_fnLengthChange:Ua,_fnFeatureHtmlLength:sb,_fnFeatureHtmlPaginate:xb,_fnPageChange:Wa,_fnFeatureHtmlProcessing:ub,_fnProcessingDisplay:J,_fnFeatureHtmlTable:vb,_fnScrollDraw:ma,_fnApplyToChildren:N,_fnCalculateColumnWidths:Ia,_fnThrottle:Ra,_fnConvertToWidth:Ib,_fnGetWidestNode:Jb,_fnGetMaxLenString:Kb,_fnStringToCss:B,
-_fnSortFlatten:X,_fnSort:qb,_fnSortAria:Mb,_fnSortListener:Ya,_fnSortAttachListener:Pa,_fnSortingClasses:za,_fnSortData:Lb,_fnSaveState:Aa,_fnLoadState:Nb,_fnSettingsFromNode:Ba,_fnLog:O,_fnMap:M,_fnBindAction:Za,_fnCallbackReg:D,_fnCallbackFire:A,_fnLengthOverflow:Va,_fnRenderer:Qa,_fnDataSource:I,_fnRowAttributes:Oa,_fnExtend:$a,_fnCalculateEnd:function(){}});f.fn.dataTable=q;q.$=f;f.fn.dataTableSettings=q.settings;f.fn.dataTableExt=q.ext;f.fn.DataTable=function(a){return f(this).dataTable(a).api()};
-f.each(q,function(a,b){f.fn.DataTable[a]=b});return f.fn.dataTable});

文件差異過大導致無法顯示
+ 0 - 1
public/js/jquery.min.js


+ 3 - 8
src/App.vue

@@ -32,9 +32,9 @@ export default {
     sessionStorage.removeItem('customListBack')
   },
 };
-// if (process.env.NODE_ENV === "production" || process.env.NODE_ENV === "test") {
-//   window.document.domain = "hzinsights.com";
-// }
+if (process.env.NODE_ENV === "production") {
+  window.document.domain = "hzinsights.com";
+}
 </script>
 
 <style lang="scss">
@@ -111,29 +111,24 @@ iframe {
   font-size: 14px;
   color: #409eff;
   cursor: pointer;
-  margin: 0 5px;
 }
 .deletesty {
   font-size: 14px;
   color: red;
   cursor: pointer;
-  margin: 0 5px;
 }
 .disty {
   font-size: 14px;
   color: #999;
   cursor: not-allowed;
-  margin: 0 5px;
 }
 .warnsty {
   font-size: 14px;
   color: #FF9900;
-  margin: 0 5px;
 }
 .successty {
   font-size: 14px;
   color: #1BB940;
-  margin: 0 5px;
 }
 
 .el-card__header {

+ 5 - 5
src/api/http.js

@@ -26,7 +26,7 @@ function postData(val,url){  //处理请求数据
 	// if( url=="/login" ){
 	// 	return val;
 	// }else{
-	// 	// window.location.href = process.env.VUE_APP_Login;
+	// 	// window.location.href = process.env.Login;
 	// }
 	return val;
 }
@@ -35,7 +35,7 @@ function getData(val,url){  //处理请求数据
 	// if( url=="/login" ){
 	// 	return val;
 	// }else{
-	// 	// window.location.href = process.env.VUE_APP_Login;
+	// 	// window.location.href = process.env.Login;
 	// }
 	return val;
 }
@@ -52,7 +52,7 @@ function checkStatus(response){  //处理响应数据
             bus.$alert(res.Msg,'提示',{
                 showClose: false
             }).then(() => {
-                window.location.href = process.env.VUE_APP_Login;
+                window.location.href = process.env.Login;
             });
         }
 		return res;
@@ -74,7 +74,7 @@ export default{
     	return axios({
       		method:'post',
 			url:url,
-			baseURL:process.env.VUE_APP_BASE_API,
+			baseURL:process.env.API_ROOT,
 			// baseURL:'/admin',
       		data:postData(data,url),
       		timeout,
@@ -88,7 +88,7 @@ export default{
 	get(url,data,responseType='json'){  //get请求方式
     	return axios({
 	      	method:'get',
-	      	baseURL:process.env.VUE_APP_BASE_API,
+	      	baseURL:process.env.API_ROOT,
 			// baseURL:'/admin',
 	      	url:url,
 	      	params:getData(data,url),

+ 2 - 2
src/components/calendar.vue

@@ -604,7 +604,7 @@ export default {
     }
     .right {
       display: flex;
-      justify-content: flex-end;
+      justify-content: end;
     }
     .center .el-button{
       width: 140px;
@@ -715,7 +715,7 @@ export default {
     }
   .handle-btn-icon {
     display: flex;
-    justify-content: flex-end;
+    justify-content: end;
     i {
       margin: 5px;
       font-size: 20px;

+ 1 - 1
src/components/mPage.vue

@@ -26,7 +26,7 @@ export default {
 			default:10
 		},
 		total: {
-			type:[Number,String],
+			type:Number,
 			default:0
 		},
 		pagercount: {

+ 1 - 0
src/components/pwdDlg.vue

@@ -7,6 +7,7 @@
       :close-on-click-modal="false"
       :close-on-press-escape="false"
       :show-close="false"
+      :before-close="handleClose"
       custom-class="reset-pwd-dlg"
       v-dialogDrag
     >

+ 4 - 2
src/components/todo/roadShowFeedbackDia.vue

@@ -18,6 +18,8 @@
       <el-table
         :data="feedbackList"
         height="60vh"
+        v-loading="tableLoading"
+        element-loading-text="数据加载中..." 
         style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2);margin-top:20px;"
         border
       >
@@ -99,7 +101,7 @@ export default {
       required: true
     },
     data: {
-      type: Array,
+      type: Boolean,
       required: true
     },
     title: {
@@ -142,7 +144,7 @@ export default {
         isShow: false,
         id: '',
         content: ''
-      },
+      }
     }
 	},
   watch: {

+ 2 - 4
src/main.js

@@ -1,3 +1,4 @@
+import 'babel-polyfill';
 import Vue from 'vue';
 import App from './App';
 import ElementUI from 'element-ui';
@@ -127,9 +128,6 @@ export const store = new Vuex.Store({
 // let data = JSON.stringify(meundata);
 import {getUserUuid} from "./api/api";
 router.beforeEach((to, from, next) => {
-	if(to.query.token){
-		localStorage.setItem('auth',to.query.token)
-	}
 	// 判断本地是否有uuid
     const uuid=localStorage.getItem('uuid')
     if(!uuid){
@@ -143,7 +141,7 @@ router.beforeEach((to, from, next) => {
 	// let rddp_admin_access_token=http.getCookie('rddp_admin_access_token') || false;
 	let auth = localStorage.getItem('auth') || false;
 	if( to.path!='/login'&&(!auth)){
-		window.location.href=process.env.VUE_APP_Login;
+		window.location.href=process.env.Login;
 		return false;
 	}
 	//面包屑

+ 2 - 2
src/mixins/index.js

@@ -27,10 +27,10 @@ const mixins = {
 				num1=str
 			}
 			return num1.replace(/(?!^)(?=(\d{3})+$)/g, ',')+num2
-		},
+		}
 	},
 	methods: {
-		formatterCol(row,column,cellvalue){
+		formatter(row,column,cellvalue){
 			return cellvalue ? http.dateFormatter(cellvalue) : '';
 		},
 		notHasTimeFormatter(row,column,cellvalue){

+ 6 - 0
src/routes/modules/ficcXcxRoutes.js

@@ -84,6 +84,12 @@ export default [
 				name:'标签库',
 				hidden:true
 			},
+			{
+				path:'sendlog',
+				component:()=> import('@/views/report_manage/reportEn/sendMsgLog.vue'),
+				name:'群发日志',
+				hidden:true
+			},
 
         ]
     }

+ 6 - 6
src/routes/routes.js

@@ -29,12 +29,12 @@ let routes = [
 		name: '',
 		hidden: true
 	},
-	{
-		path: '/temppage',
-		component: ()=>import('@/views/transferPage.vue'),
-		name: '',
-		hidden: true
-	},
+	// {
+	// 	path: '/temppage',
+	// 	component: ()=>import('@/views/transferPage.vue'),
+	// 	name: '',
+	// 	hidden: true
+	// },
 	{
 		path: '/404',
 		component: notFound,

+ 0 - 18
src/utils/MenuUtils.js

@@ -1,18 +0,0 @@
-import lazyLoading from './lazyLoading'
-export default(routers,data) => {
-	data = JSON.parse(data);
-	generaMenu(routers,data);
-}
-
-function generaMenu(routers,data){
-	data.forEach((item) => {
-		let menu = Object.assign({},item);
-		menu.component = lazyLoading(menu.remark);
-		if(item.children) {
-			menu.children = [];
-			let dataItem = item.children;
-			generaMenu(menu.children,dataItem);
-		}
-		routers.push(menu);
-	});
-}

+ 0 - 49
src/utils/lazyLoading.js

@@ -1,49 +0,0 @@
-const home = import('@/views/Home.vue');  //外层框架
-const main = import('@/views/Main.vue');  //登录后引导页
-
-// const accountmanage = import('@/views/authority_manage/account_manage.vue');  //设置-账号管理
-// const rolemanage = import('@/views/authority_manage/role_manage.vue');  //设置-角色管理
-// const sysorg = import('@/views/authority_manage/organization.vue');  //设置-组织架构
-
-// const user_list = import('@/views/users_manage/userlist.vue');  //用户列表
-// const userdetail = import('@/views/users_manage/userdetail.vue');  //用户详情
-// const vipmanagelist = import('@/views/users_manage/vipmanagelist.vue');  //会员管理列表
-// const ordermanagelist = import('@/views/users_manage/ordermanagelist.vue');  //订单管理列表
-// const dcclist = import('@/views/users_manage/dcclist.vue');  //会员账户列表
-
-function look(n){
-	switch(n){
-		case 'home':
-  			return home;
-  			break;
-		// case 'sysuser':
-		// 	return accountmanage;
-		// 	break;
-		// case 'sysrole':
-		// 	return rolemanage;
-		// 	break;
-		// case 'sysorg':
-		// 	return sysorg;
-		// 	break;
-		// case 'user_list':
-		// 	return user_list;
-		// 	break;
-		// case 'getusersdetails':
-		// 	return userdetail;
-		// 	break;
-		// case 'getorderlistsuccess':
-		// 	return vipmanagelist;
-		// 	break;
-		// case 'getorderlist':
-		// 	return ordermanagelist;
-		// 	break;
-		// case 'getdouchachalist':
-		// 	return dcclist;
-		// 	break;
-		default:
-			return main;
-			break;
-	}
-}
-
-export default (name) => () => look(name);

+ 11 - 20
src/views/Home.vue

@@ -49,7 +49,7 @@
                   <a :href="`/${item.level_path}`" class="el-level-path" :style="`display: block;color:${item.level_path===activePath ? '#FDB863 ' : '#fff'}`" @click="(e) => e.preventDefault() ">
                     <img :src="item.icon_path" alt="" style="width:24px;height:24px;" />
                     <span class="titleLetter" v-show="isCollapse">{{isCollapse?MenuLetterMap[item.name]||'':''}}</span>
-                    <span style="display:inline-block; width:96px; text-align:left;font-size:15px;margin-left:20px;">{{item.name}}</span>
+                    <span style="display:inline-block; width:96px; text-align:left;font-size:15px;margin-left:15px;">{{item.name}}</span>
                   </a>
                 </el-menu-item>
                 
@@ -57,7 +57,7 @@
                   <template slot="title">
                     <img :src="item.icon_path" alt="" style="width:24px;height:24px;" />
                     <span class="titleLetter" v-show="isCollapse">{{isCollapse?MenuLetterMap[item.name]||'':''}}</span>
-                    <span style="display:inline-block; width:96px; text-align:left;font-size:15px; margin-left:20px;"
+                    <span style="display:inline-block; width:96px; text-align:left;font-size:15px; margin-left:15px;"
                         >{{item.name}}</span>
                   </template>
                   <el-menu-item
@@ -192,8 +192,8 @@
                 <div  class="userinfo-fingerpost">
                   <el-button @click="toOperation('fingerpost')"  type="text"  v-if="isShowRole">帮助文档</el-button>
                 </div>
-                <span style="color:#409EFF;cursor: pointer;" @click="linkToOtherMS('VUE_APP_HR_MANAGEMENT_SYSTEM')">HR系统</span>
-                <span style="color:#409EFF;cursor: pointer;" @click="linkToOtherMS('VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM')">财务报表系统</span>
+                <span style="color:#409EFF;cursor: pointer;" @click="linkToOtherMS('HR_MANAGEMENT_SYSTEM')">HR系统</span>
+                <span style="color:#409EFF;cursor: pointer;" @click="linkToOtherMS('FINANCIAL_MANAGEMENT_SYSTEM')">财务报表系统</span>
               <el-dropdown trigger="click">
                 <span class="el-dropdown-link userinfo-inner">
                   <img src="~@/assets/img/set_m/user_img.png" />
@@ -362,7 +362,7 @@ export default {
         console.log(this.isShowApprovalNotice);
       }
       this.sysUserName =  localStorage.getItem('userName') || '';
-      // this.Role = localStorage.getItem('Role') || '';
+      this.Role = localStorage.getItem('Role') || '';
       this.RoleType = localStorage.getItem('RoleType') || '';
     }
   },
@@ -433,7 +433,7 @@ export default {
       issafariBrowser:
         /Safari/.test(navigator.userAgent) &&
         !/Chrome/.test(navigator.userAgent), //判断是否是苹果系统
-      // Role:'',//角色名称
+      Role:'',//角色名称
       RoleType:'',//角色类型
       sysUserName: "", //登录系统用户名
       sysUserAvatar: "", //登录系统用户头像
@@ -490,7 +490,7 @@ export default {
   },
   created() {
     this.isInitialPwd() //判断是否为初始密码 
-    // this.Role = localStorage.getItem('Role') || '';
+    this.Role = localStorage.getItem('Role') || '';
     this.RoleType = localStorage.getItem('RoleType') || '';
     this.sysUserName =  localStorage.getItem('userName') || '';
     this.sysUserAvatar = "../assets/img/userLogo.png";
@@ -670,10 +670,10 @@ export default {
     },
 
     // 操作指南的跳转
-    toOperation (url) {
-      // this.$router.replace({name: '/fingerpost', params: {id: 1}})
-      let {href} = this.$router.resolve({path:`/${url}`,query:{contractid:this.contractId}});
-			window.open(href,'_blank');
+     toOperation (url) {
+          // this.$router.replace({name: '/fingerpost', params: {id: 1}})
+          let {href} = this.$router.resolve({path:`/${url}`,query:{contractid:this.contractId}});
+			    window.open(href,'_blank');
     },
     // 跳转去其他的系统
     linkToOtherMS(key){
@@ -996,14 +996,6 @@ export default {
       text-align: center;
       z-index: 10;
       margin-left: -1px;
-      .el-menu-item{
-        padding-left: 10px !important;
-      }
-      .el-menu--collapse{
-        .el-menu-item{
-          padding-left: 20px !important;
-        }
-      }
       .el-menu {
         width: 200px;
         height: 100%;
@@ -1055,7 +1047,6 @@ export default {
         //padding-left: 0 !important;
         display: flex;
         align-items: center;
-        padding: 0 10px !important;
       }
       .el-level-path{
           position:relative;

+ 2 - 3
src/views/Login.vue

@@ -165,7 +165,7 @@ export default {
 								localStorage.removeItem('checkPass')
 							}
 
-							let path = await this.getOtherRolePath();
+							let path = await this.getOtherRolePath('myCalendar');
 							// switch(res.Data.RoleTypeCode) {
 							// 	case 'rai_researcher':
 							// 	case 'ficc_researcher':
@@ -184,7 +184,6 @@ export default {
 							// 	default: 
 							// 		path = await this.getOtherRolePath('myCalendar')
 							// }
-							console.log(path);
 							this.$router.push({path})
 						}
 						that.logining = false
@@ -213,7 +212,7 @@ export default {
 
 					for (let i = 0; i < menuList.length; i++) {
 						const element = menuList[i];
-						if(element.children?.some(it => it.path == pathVal)){
+						if(element.children.some(it => it.path == pathVal)){
 							resolvePath='/'+pathVal
 							break
 						}

+ 1 - 1
src/views/banner_manage/bannerlist.vue

@@ -18,7 +18,7 @@
 					<el-table-column prop="ClassifyName" label="跳转地址" align="center" min-width="140">
 						<template slot-scope="scope"> <span>{{scope.row.JumpUrl}}</span> </template>
 					</el-table-column>
-					<el-table-column prop="ModifyTime" label="更新时间" min-width="110" :formatter="formatterCol" sortable align="center"></el-table-column>
+					<el-table-column prop="ModifyTime" label="更新时间" min-width="110" :formatter="formatter" sortable align="center"></el-table-column>
 					<el-table-column label="操作" align="center">
 						<template slot-scope="scope">
 							<div style="color:#4099ef; font-size:24px;">

+ 1 - 1
src/views/business_trip_manage/businessApproval.vue

@@ -2,7 +2,7 @@
   <div class="trip-approve-container">
     <div class="trip-approve-top">
       <el-select v-model="searchParams.Status" placeholder="请选择审批状态" style="width: 240px;" @change="searchList">
-        <el-option :label="item.label" :value="item.value" v-for="item in statusList" :key="item.value" ></el-option>
+        <el-option :label="item.label" :value="item.value" v-for="item in statusList" :key="item" ></el-option>
       </el-select>
     </div>
     <el-table :data="tableData" border >

+ 1 - 1
src/views/business_trip_manage/components/tripApplicationDia.vue

@@ -49,7 +49,7 @@
       </el-form-item>
       <el-form-item label="同行人" prop="companion" >
         <el-cascader :options="userList" v-model="companionSelectList" filterable 
-        ref="companionCascader"
+        ref="companionCascader" @remove-tag="removeTag"
         :props="{
 					label: 'RealName',
 					value: 'AdminId', 

+ 213 - 0
src/views/chartRelevance_manage/components/addClassify.vue

@@ -0,0 +1,213 @@
+<template>
+	<div class="chartDialog-box">
+		<el-dialog
+		:visible.sync="isOpenDialog"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="cancelHandle"
+		custom-class="dialog"
+		center
+		width="560px"
+		v-dialogDrag>
+			<div slot="title" style="display:flex;alignItems:center;">
+				<img :src="title=='添加'?$icons.add:title=='编辑'?$icons.edit:''" style="color:#fff;width:16px;height:16px;marginRight:5px;">
+				<span style="fontSize:16px;">{{title}}</span>
+			</div>
+			<div class="dialog-main">
+				<el-form
+				ref="diaForm"
+				label-position="left"
+				hide-required-asterisk
+				label-width="80px"
+				:model="formData"
+				:rules="formRules">
+					<!-- 添加/编辑1级目录 -->
+					<template 
+					v-if="(title=='添加'&&formData.level === 0)
+					|| (title=='编辑'&&formData.level === 1)">
+						<el-form-item label="分类名称" prop="level_1">
+							<el-input
+							v-model="formData.level_1"
+							style="width: 80%"
+							placeholder="必填项"></el-input>
+						</el-form-item>
+					</template>
+					<!-- 添加/编辑2级目录 -->
+					<template 
+					v-else-if="(title=='添加'&&formData.level === 1)
+					|| (title=='编辑'&&formData.level === 2)">
+						<el-form-item label="一级目录" prop="level_1">
+							<span>{{formData.level_1}}</span>
+						</el-form-item>
+						<el-form-item label="分类名称" prop="level_2">
+							<el-input
+							v-model="formData.level_2"
+							style="width: 80%"
+							placeholder="必填项"></el-input>
+						</el-form-item>
+					</template>
+					<!-- 添加/编辑三级目录 -->
+				<!-- 	<template v-else-if="(title=='添加'&&formData.level === 2)
+					|| (title=='编辑'&&formData.level === 3)">
+						<el-form-item label="一级目录" prop="level_1">
+							<span>{{formData.level_1}}</span>
+						</el-form-item>
+						<el-form-item label="二级目录" prop="level_2">
+							<span>{{formData.level_2}}</span>
+						</el-form-item>
+						<el-form-item label="分类名称" prop="level_3">
+							<el-input
+							v-model="formData.level_3"
+							style="width: 80%"
+							placeholder="必填项"></el-input>
+						</el-form-item>
+					</template> -->
+				</el-form>
+			</div>
+			<div class="dia-bot">
+				<el-button type="primary" style="margin-right:20px" @click="saveHandle">保存</el-button>
+				<el-button type="primary" plain @click="cancelHandle">取消</el-button>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import { formRules } from '@/utils/defaultOptions'
+export default {
+	props: {
+		isOpenDialog: {
+			type: Boolean,
+		},
+		//标题
+		title: {
+			type: String,
+			default: '添加'
+		},
+		formData: {
+			type: Object,
+		}
+	},
+	watch: {
+		'isOpenDialog': {
+			handler(newval) {
+				if((newval && this.formData.level === 3)) {
+					this.getMenu();
+				}
+				// console.log(this.formData);
+			}
+		}
+	},
+	data () {
+		return {			
+			formRules,
+			options:  [],
+			levelProps: {
+				label: 'ChartClassifyName',
+				value: 'ChartClassifyId',
+				children: 'Children',
+			},
+
+		};
+	},
+	methods: {
+		saveHandle() {
+			this.$refs.diaForm.validate((valid) => {
+				if(valid) {
+					this.title==='添加' && dataBaseInterface.addChartClassify({
+						ChartClassifyName: this.formData.level === 0 
+							? this.formData.level_1
+							: this.formData.level === 1
+							? this.formData.level_2
+							:'',
+						ParentId:this.formData.parent_id || 0,
+						Level: this.formData.level
+					}).then(res => {
+						if(res.Ret === 200) {
+							this.$message.success(res.Msg);
+							this.callbackHandle('add');
+						}
+					})
+					//修改图表
+					if(this.title==='编辑' && this.formData.level===3) {
+						dataBaseInterface.chartEdit({
+							ChartClassifyId: this.formData.level_menu[this.formData.level_menu.length - 1],
+							ChartInfoId: this.formData.chart_id,
+							ChartName: this.formData.level_4
+						}).then(res => {
+							if(res.Ret === 200) {
+								this.$message.success(res.Msg);
+								this.callbackHandle('update');
+							}
+						})
+					}else if(this.title==='编辑' && this.formData.level!==3) {
+						//修改目录
+						dataBaseInterface.editChartClassify({
+							ChartClassifyName: this.formData.level === 1
+								? this.formData.level_1
+								: this.formData.level === 2
+								? this.formData.level_2
+								:'',
+							ChartClassifyId:this.formData.classify_id || 0
+						}).then(res => {
+							if(res.Ret === 200) {
+								this.$message.success(res.Msg);
+								this.callbackHandle();
+							}
+						})
+					}
+
+					// this.title === '选择分类' && this.$emit('addClassifyCallBack',this.formData.level_menu[2])
+				}
+			})
+		},
+		/* 成功回调 */
+		callbackHandle(type) {
+			this.$refs.diaForm.resetFields();
+			this.$emit('sucessCallback',type)
+		},
+		/* 取消 */
+		cancelHandle() {
+			this.$refs.diaForm.resetFields();
+			this.$emit('closeDia')
+		},
+		/* 获取目录结构 */
+		getMenu() {
+			dataBaseInterface.chartClassify().then(res => {
+				if(res.Ret === 200) {
+					this.filterNodes(res.Data.AllNodes);
+					this.options = res.Data.AllNodes || [];
+				}
+			})
+		},
+		// 递归改变第三级目录结构
+		filterNodes(arr) {
+			arr.length && arr.forEach(item => {
+				item.Children.length && this.filterNodes(item.Children)
+				if(item.Level === 2) {
+					delete item.Children
+				}
+			})
+		}
+	},
+	created() {},
+	mounted() {},
+}
+</script>
+<style lang='scss'>
+.chartDialog-box {
+	.dialog-main {
+		padding-left: 50px;
+	}
+	.el-cascader .el-input {
+		width: 100%;
+	}
+	.dia-bot {
+		margin: 52px 0 30px;
+		display: flex;
+		justify-content: center;
+
+	}
+}
+</style>

+ 307 - 0
src/views/chartRelevance_manage/components/chartCard.vue

@@ -0,0 +1,307 @@
+<template>
+  <div class="card-item">
+    <div class="top" v-if="options.series&&isHaveButton">
+      <div class="title text_twoLine">
+         <span>{{cardTitle}}</span>
+      </div>
+      <div style="flex-shrink: 0">
+        <template v-if="isHaveEdbHandle">
+          <el-dropdown 
+            v-if="isEdbAdd" 
+            split-button 
+            type="primary" 
+            @click="updateEdbHandle(entryType)" 
+            @command="edbCommandHandle"
+          >
+            更新指标
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item :command="{entryType,scence:'saveOther'}">指标另存为</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+          <el-button type="primary" v-else @click="saveEdb(entryType)">保存指标</el-button>
+        </template>
+
+        <el-dropdown 
+          v-if="isChartAdd" 
+          split-button 
+          type="primary" 
+          @click="updateChartHandle(entryType)" 
+          @command="chartCommandHandle"
+        >
+          更新
+          <el-dropdown-menu slot="dropdown" v-if="isHaveSaveOtherHandle">
+            <el-dropdown-item :command="{entryType,scence:'saveOther'}">另存为</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+        <el-button type="primary" @click="saveChart(entryType)" v-else>保存</el-button>
+
+      </div>
+    </div>
+    <div class="chartWrapper">
+      <div class="title text_twoLine">
+        <span v-if="$route.path==='/fittingEquationChartEditor'">{{chartInfo.ChartName}}</span>
+      </div>
+      <Chart
+        v-if="options.series"
+        :options="options"
+        :index="entryType"
+        :ref="`chartRef${entryType}`"
+        :height="350"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
+import { dataBaseInterface } from '@/api/api.js';
+import chartRelevanceApi,{statisticFeatureInterface} from '@/api/modules/chartRelevanceApi.js';
+import Chart from '@/views/dataEntry_manage/components/chart';
+export default {
+  components: { Chart },
+  mixins: [chartSetMixin],
+  computed: {
+    isHaveButton() {
+      let routes = ['/relevancechartEditor','/statisticFeatureChartEditor']
+      return routes.includes(this.$route.path)
+    },
+    cardTitle() {
+      let title='';
+      if(this.$route.path==='/relevancechartEditor') {
+        title = [3,4].includes(this.entryType) ? `滚动相关性${this.entryType-2}` : this.entryType===1 ? this.chartInfo.ChartName : ''
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        title = this.chartInfo.ChartName
+      }
+      return title
+    },
+    isHaveEdbHandle() { //有指标操作的区域
+      //相关性 3,4区域可保存指标 统计图 2,3区域
+      return (([3,4].includes(this.entryType)&&this.$route.path==='/relevancechartEditor')
+        || ([2,3].includes(this.entryType)&&this.$route.path==='/statisticFeatureChartEditor'))
+    },
+    isHaveSaveOtherHandle() {//有图表另存的区域
+        //相关性 1,2区域有另存 统计图 4个区域都有另存
+      return (([1,2].includes(this.entryType) && this.$route.path==='/relevancechartEditor')
+       || (this.$route.path==='/statisticFeatureChartEditor'))
+    }
+  },
+  watch: {
+    data(nval) {
+      this.setRenderChartData(nval)
+    }
+  },
+  props: {
+    entryType: { //位置 1 2 3 4
+      required: true,
+      type:Number
+    },
+    data: {
+      type:Object
+    },
+    isChartAdd: {
+      type:Boolean,
+      default: false
+    },
+    isEdbAdd: {
+      type:Boolean,
+      default: false
+    },
+    settings: {
+      type: Object
+    }
+
+  },
+  data() {
+    return {
+      chartInfo: {}
+    }
+  },
+
+  methods: {
+
+    //设置图依赖数据
+    setRenderChartData(data) {
+      console.log(data)
+      switch(data.ChartInfo.Source) {//1曲线 
+        case 1:
+          this.chartInfo = data.ChartInfo;
+          this.setDefaultChart(data.EdbInfoList);
+          break
+        case 3: //3相关性 4滚动相关性
+        case 4:
+          this.chartInfo = data.ChartInfo;
+          this.relevanceChartData={
+            ChartInfo:data.ChartInfo,
+            EdbInfoList:data.EdbInfoList,
+            XEdbIdValue:data.XEdbIdValue || data.XDateTimeValue,
+            CorrelationChartInfo:data.CorrelationChartInfo,
+            YDataList:[
+              {
+                Value:data.YDataList[0].Value,
+                Color:'#00f',
+                Name:data.ChartInfo.ChartName,
+                NameEn:''
+              }
+            ]
+          }
+          this.tableData=data.EdbInfoList||[]
+          this.initRelevanceChartData()
+          break
+        case 6: //弹性系数
+          this.initFittingEquation(data);
+          break
+        case 7: //7标准差 8百分比
+        case 8: 
+          this.chartInfo = data.ChartInfo;
+          this.setDefaultChart([data.DataResp]);
+          break
+        case 9: 
+          this.chartInfo = data.ChartInfo;
+          this.tableData=data.EdbInfoList||[]
+          this.statisticFrequencyData = data.DataResp;
+          this.setStatisticFrequency();
+          break
+      }
+    },
+
+    /* 拟合方程曲线 */
+    initFittingEquation(data) {
+      const { ChartInfo,EdbInfo } = data;
+      this.chartInfo = ChartInfo;
+      this.setDefaultChart([EdbInfo]);
+    },
+
+    // 指标下拉菜单
+    edbCommandHandle({entryType,scence}) {
+      const typeMap = {
+        'saveOther': this.saveEdb
+      }
+      typeMap[scence](entryType,scence)
+    },
+
+    //图表下拉菜单
+    chartCommandHandle({entryType,scence}) {
+      const typeMap = {
+        'saveOther': this.saveChart
+      }
+      typeMap[scence](entryType,scence)
+    },
+
+    /* 保存指标入库 */
+    saveEdb(type,scence='') {
+      this.$emit('saveEdb',{type,chartData: this.chartInfo,scence})
+    },
+
+    /* 保存图表 另存为图表 */
+    saveChart(type,scence='') {
+      this.$emit('saveChart',{type,chartData: this.chartInfo,scence})
+    },
+
+    /* 设置图表封面图片 */
+    setChartImage(entryType,id) {
+      let otherOptions = this.chartInfo.Source===3 ? {
+        chart: {
+          width:340,
+          height:230,
+        },
+        xAxis:[{
+          ...this.options.xAxis,
+          offset: -65,
+        }]//这里记得要写成你渲染的图的配置项一样的 单独就配置一个offset无效
+      } : {
+        chart: {
+          width:340,
+          height:230,
+        }
+      }
+
+      let svg = this.$refs[`chartRef${entryType}`].chart.getSVG(otherOptions);
+      let form = new FormData();
+      form.append('Img', svg);
+      this.setImageHandle(form,id);
+    },
+
+    async setImageHandle(form,id) {
+      let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      await dataBaseInterface.setChartImage({
+        ChartInfoId: id,
+        ImageUrl: Data.ResourceUrl,
+      });
+    },
+
+    /* 更新图表 */
+    async updateChartHandle(entryType) {
+      //统计图的2 3 4对应source8 9 10但其实图表source又是7 8 9 别问为什么这样搞问后端 我也乱的一批
+      const sourceMap = {
+        1: 1,
+        2: 8,
+        3: 9,
+        4: 10
+      }
+      let Source;
+      if(this.$route.path==='/relevancechartEditor') {
+        Source = entryType;
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        Source = sourceMap[entryType]
+      }
+
+      let params = {
+        Source,
+        IsSaveAs: false,
+        ...this.settings
+      }
+      let res = null;
+      if(this.$route.path==='/relevancechartEditor') {
+        res = await chartRelevanceApi.saveChart(params)
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        res = await statisticFeatureInterface.saveChart(params);
+      } 
+
+      if(res.Ret !== 200) return
+
+      this.$message.success('更新成功');
+    },
+
+    /* 更新指标 */
+    async updateEdbHandle(entryType) {
+      //统计图的2 3 4对应source8 9 10但其实图表source又是7 8 9 别问为什么这样搞问后端 我也乱的一批
+      const sourceMap = {
+        1: 1,
+        2: 8,
+        3: 9,
+        4: 10
+      }
+      let Source;
+      if(this.$route.path==='/relevancechartEditor') {
+        Source = entryType;
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        Source = sourceMap[entryType]
+      }
+      
+      let params = {
+				Source,
+				IsSaveAs: false,
+        ...this.settings
+			}
+      
+      let res = null;
+      if(this.$route.path==='/relevancechartEditor') {
+        res = await chartRelevanceApi.saveEdb(params)
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        res = await statisticFeatureInterface.saveEdb(params);
+      }
+
+			if(res.Ret !== 200) return
+			this.$message.success('更新成功');
+    }
+  },
+
+  mounted() {
+    this.setRenderChartData(this.data);
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 295 - 0
src/views/chartRelevance_manage/components/fittingEquationSaveDia.vue

@@ -0,0 +1,295 @@
+<template>
+    <el-dialog
+      :visible.sync="isShow"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      title="保存"
+      @close="cancelHandle"
+      custom-class="savechart-dialog"
+      center
+      width="650px"
+      v-dialogDrag
+    >
+      <div class="dialog-min">
+        <div class="top">
+          <el-checkbox-group v-model="checkCharts" style="margin-bottom: 10px;">
+            <el-checkbox :label="item.key" v-for="item in chartsType" :key="item.key">{{item.name}}</el-checkbox>
+          </el-checkbox-group>
+
+          <el-cascader
+            v-model="form.classify"
+            :options="classifyOptions"
+            :props="{
+              label: 'ChartClassifyName',
+              value: 'ChartClassifyId',
+              children: 'Children',
+              emitPath: false
+            }"
+            style="width: 100%"
+            placeholder="请选择所属分类"
+            clearable
+            @change="setClassifyAll"
+          />
+        </div>
+        <el-form
+          ref="diaForm"
+          label-position="left"
+          label-width="120px"
+          :model="form"
+          :rules="formRules"
+        >
+          <el-form-item label="弹性系数(a)" prop="aName" v-if="checkCharts.includes(5)">
+            <el-input
+              v-model="form.aName"
+              style="width: 40%"
+              placeholder="请填写图表名称"
+              clearable
+            />
+            <el-cascader
+              v-model="form.aClassify"
+              :options="classifyOptions"
+              :props="{
+                label: 'ChartClassifyName',
+                value: 'ChartClassifyId',
+                children: 'Children',
+                emitPath: false
+              }"
+              style="width: 40%"
+              placeholder="请选择所属分类"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item label="截距(b)" prop="bName" v-if="checkCharts.includes(6)">
+            <el-input
+              v-model="form.bName"
+              style="width: 40%"
+              placeholder="请填写图表名称"
+              clearable
+            />
+            <el-cascader
+              v-model="form.bClassify"
+              :options="classifyOptions"
+              :props="{
+                label: 'ChartClassifyName',
+                value: 'ChartClassifyId',
+                children: 'Children',
+                emitPath: false
+              }"
+              style="width: 40%"
+              placeholder="请选择所属分类"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item label="相关系数(r²)" prop="relevanceName" v-if="checkCharts.includes(7)">
+            <el-input
+              v-model="form.relevanceName"
+              style="width: 40%"
+              placeholder="请填写图表名称"
+              clearable
+            />
+             <el-cascader
+              v-model="form.relevanceClassify"
+              :options="classifyOptions"
+              :props="{
+                label: 'ChartClassifyName',
+                value: 'ChartClassifyId',
+                children: 'Children',
+                emitPath: false
+              }"
+              style="width: 40%"
+              placeholder="请选择所属分类"
+              clearable
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="dia-bot">
+        <el-button type="primary" style="margin-right: 20px" @click="saveHandle"
+          >保存</el-button
+        >
+        <el-button type="primary" plain @click="cancelHandle">取消</el-button>
+      </div>
+    </el-dialog>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
+export default {
+	name:'',
+	props: {
+		isShow: {
+			type: Boolean
+		},
+    initData: {
+      type: Array
+    }
+	},
+	watch: {
+		isShow(newval) {
+			if(newval) {
+				this.getMenu();
+        if(!this.initData.length) return
+        this.checkCharts = this.initData.map(_ => _.Source);
+        this.form = {
+          aName: this.initData.find(_ => _.Source===5) ? this.initData.find(_ => _.Source===5).ChartName : '',
+          bName: this.initData.find(_ => _.Source===6) ? this.initData.find(_ => _.Source===6).ChartName : '',
+          relevanceName: this.initData.find(_ => _.Source===7) ? this.initData.find(_ => _.Source===7).ChartName : '',
+          classify: '',
+          aClassify: this.initData.find(_ => _.Source===5) ? this.initData.find(_ => _.Source===5).ChartClassifyId : '',
+          bClassify: this.initData.find(_ => _.Source===6) ? this.initData.find(_ => _.Source===6).ChartClassifyId : '',
+          relevanceClassify: this.initData.find(_ => _.Source===7) ? this.initData.find(_ => _.Source===7).ChartClassifyId : ''
+        }
+			}
+		},
+	},
+	data () {
+		return {
+			classifyOptions:[],//分类列表
+
+      checkCharts: [5,6,7],
+      chartsType: [
+        { name: '弹性系数a',key: 5 },
+        { name: '截距b',key: 6 },
+        { name: '相关系数r²',key: 7 },
+      ],
+
+      form: {
+        aName: '',
+        bName: '',
+        relevanceName: '',
+        classify: '',
+        aClassify: '',
+        bClassify: '',
+        relevanceClassify: ''
+      },
+      formRules: {
+				aName:[
+					{ required: true, message: '图表名称不能为空', trigger: 'blur' },
+				],
+				bName:[
+					{ required: true, message: '图表名称不能为空', trigger: 'blur' },
+				],
+				relevanceName:[
+					{ required: true, message: '图表名称不能为空', trigger: 'blur' },
+				],
+				classify:[
+					{ required: true, message: '图表分类不能为空', trigger: 'blur' },
+				],
+			},
+		};
+	},
+	methods: {
+		/* 获取分类列表 */
+		async getMenu() {
+      const res = await fittingEquationInterface.classifyOne();
+      if(res.Ret !== 200) return
+      this.classifyOptions = res.Data.AllNodes;
+		},
+
+    /* 同步全部分类 */
+    setClassifyAll() {
+      if(this.form.classify) {
+        this.form.aClassify = this.form.classify;
+        this.form.bClassify = this.form.classify;
+        this.form.relevanceClassify = this.form.classify;
+
+      }
+    },
+
+    /* 加入图库 */
+    async saveHandle() {
+      if(!this.checkCharts.length) return this.$message.warning('请至少选择一个图表')
+      await this.$refs.diaForm.validate();
+
+      const { MultipleGraphConfigId,DateType,date,xEdbs,yEdbs } = this.$parent.leftOption;
+      console.log(this.$parent.leftOption.xEdbs,this.$parent.leftOption.yEdbs)
+      const {  
+        aName,
+        bName,
+        relevanceName,
+        classify,
+        aClassify,
+        bClassify,
+        relevanceClassify,
+      } = this.form;
+      let nameMap = {
+        5: {
+          name: aName,
+          classify: aClassify
+        },
+        6: {
+          name: bName,
+          classify: bClassify
+        },
+        7: {
+          name: relevanceName,
+          classify: relevanceClassify
+        },
+      }
+
+      let params = {
+        MultipleGraphConfigId,
+        ExtraConfig: {
+          DateType,
+          StartDate: date[0] || '',
+          EndDate: date[1] || '',
+          XEdbInfoIdList: xEdbs.map(_ => _.id),
+				  YEdbInfoIdList: yEdbs.map(_ => _.id)
+        },
+        BatchAddChart: this.checkCharts.map(_ => ({
+          Source: _,
+          ChartClassifyId: nameMap[_].classify,
+          ChartName: nameMap[_].name
+        }))
+      }
+      console.log(params)
+      let res = await fittingEquationInterface.chartEdit(params)
+      if(res.Ret !== 200) return
+
+      this.$message.success('保存成功')
+
+      this.cancelHandle();
+      this.$emit('saveBack',{code: res.Data.UniqueCode,id: res.Data.ChartInfoId})
+    },
+    
+		cancelHandle() {
+      this.$refs.diaForm.resetFields();
+      this.form = {
+        aName: '',
+        bName: '',
+        relevanceName: '',
+        classify: '',
+        aClassify: '',
+        bClassify: '',
+        relevanceClassify: ''
+      },
+			this.$emit('update:isShow',false)
+		}
+	},
+}
+</script>
+<style lang="scss" scoped>
+.savechart-dialog {
+  .el-dialog--center .el-dialog__body {
+    padding: 25px 25px 30px !important;
+  }
+  .dialog-min {
+    padding: 20px 0 0 30px;
+    .top {
+      margin-bottom: 15px;
+    }
+  }
+  .dia-bot {
+    margin: 52px 0 30px;
+    display: flex;
+    justify-content: center;
+  }
+}
+</style>
+<style lang="scss">
+.savechart-dialog {
+  .el-input{ width: 100%; }
+  .el-form-item { margin-bottom: 22px; }
+}
+</style>

+ 201 - 0
src/views/chartRelevance_manage/components/saveChartTobaseDia.vue

@@ -0,0 +1,201 @@
+<template>
+    <el-dialog
+      :visible.sync="isShow"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      :title="saveScence==='saveOther'?'图表另存为':'保存'"
+      @close="cancelHandle"
+      custom-class="dialog savechart-dialog"
+      center
+      width="560px"
+      v-dialogDrag
+    >
+      <div class="dialog-min">
+        <el-form
+          ref="diaForm"
+          label-position="left"
+          label-width="80px"
+          :model="form"
+          :rules="formRules"
+        >
+          <el-form-item label="图表名称" prop="name">
+            <el-input
+              v-model="form.name"
+              style="width: 80%"
+              placeholder="必填项"
+              clearable
+            />
+          </el-form-item>
+          <el-form-item label="图表分类" prop="classify">
+            <el-cascader
+              v-model="form.classify"
+              :options="classifyOptions"
+              :props="{
+                label: 'ChartClassifyName',
+                value: 'ChartClassifyId',
+                children: 'Children',
+                emitPath: false
+              }"
+              style="width: 80%"
+              placeholder="请选择所属分类"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="dia-bot">
+        <el-button type="primary" style="margin-right: 20px" @click="saveHandle"
+          >保存</el-button
+        >
+        <el-button type="primary" plain @click="cancelHandle">取消</el-button>
+      </div>
+    </el-dialog>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import chartRelevanceApi,{statisticFeatureInterface} from '@/api/modules/chartRelevanceApi.js';
+export default {
+	name:'',
+	props: {
+		isShow: {
+			type: Boolean,
+		},
+    source: {
+      type: Number
+    },
+    saveScence: { //saveOther另存为 ''保存
+      type:String,
+      default: ''
+    },
+    chartData: {
+      type: Object
+    }
+	},
+	watch: {
+		isShow(newval) {
+			if(newval) {
+				this.getMenu();
+        this.form = {
+          name: this.saveScence==='saveOther' ? `${this.chartData.ChartName}(1)` : this.chartData.ChartName,
+          classify: this.chartData.ChartClassifyId || '',
+        }
+			}
+		},
+	},
+	data () {
+		return {
+			classifyOptions:[],//分类列表
+
+      form: {
+        name: '',
+        classify: ''
+      },
+      formRules: {
+				name:[
+					{ required: true, message: '图表名称不能为空', trigger: 'blur' },
+				],
+				classify:[
+					{ required: true, message: '图表分类不能为空', trigger: 'blur' },
+				],
+			},
+		};
+	},
+	methods: {
+		/* 获取分类列表 */
+		async getMenu() {
+      
+      let res = null;
+      if(this.chartData.Source===1) {
+        res = await dataBaseInterface.chartClassify();
+      }else if(this.$route.path==='/relevancechartEditor'&&this.chartData.Source!==1) {
+        res = await chartRelevanceApi.classifyList();
+      }else if(this.$route.path==='/statisticFeatureChartEditor'&&this.chartData.Source!==1) {
+        res = await statisticFeatureInterface.classifyList();
+      }
+
+      if(res.Ret !== 200) return
+      this.filterNodes(res.Data.AllNodes,this.chartData.Source===1?2:1)
+
+			this.classifyOptions = res.Data.AllNodes || [];
+    
+		},
+
+		// 递归改变第三级目录结构
+		filterNodes(arr,n) {
+			arr.length && arr.forEach(item => {
+				item.Children && item.Children.length && this.filterNodes(item.Children,n)
+				if(item.Level === n) {
+					delete item.Children
+				}
+			})
+		},
+
+    /* 加入图库 */
+    async saveHandle() {
+      await this.$refs.diaForm.validate();
+      const { name,classify } = this.form;
+
+      //统计图的2 3 4对应source8 9 10但其实图表source又是7 8 9 别问为什么这样搞问后端 我也乱的一批
+      const sourceMap = {
+        1: 1,
+        2: 8,
+        3: 9,
+        4: 10
+      }
+      let Source;
+      if(this.$route.path==='/relevancechartEditor') {
+        Source = this.source;
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        Source = sourceMap[this.source]
+      }
+
+      let params = {
+        Source,
+        IsSaveAs: this.saveScence==='saveOther',
+        ChartName: name,
+        ClassifyId: classify,
+        ...this.$parent.chartInfo
+      }
+
+      let res = null;
+      if(this.$route.path==='/relevancechartEditor') {
+        res = await chartRelevanceApi.saveChart(params)
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        res = await statisticFeatureInterface.saveChart(params);
+      } 
+      if(res.Ret !== 200) return
+
+      this.$emit('saveBack',{source:this.source,id: res.Data.ChartInfoId})
+      this.cancelHandle();
+    },
+    
+		cancelHandle() {
+      this.$refs.diaForm.resetFields();
+			this.$emit('update:isShow',false)
+		}
+	},
+	created() {},
+	mounted() {},
+}
+</script>
+<style lang="scss" scoped>
+.savechart-dialog {
+  .el-dialog--center .el-dialog__body {
+    padding: 25px 25px 30px !important;
+  }
+  .dialog-min {
+    padding: 20px 0 0 30px;
+  }
+  .dia-bot {
+    margin: 52px 0 30px;
+    display: flex;
+    justify-content: center;
+  }
+}
+</style>
+<style lang="scss">
+.savechart-dialog {
+  .el-input{ width: 100%; }
+  .el-form-item { margin-bottom: 22px; }
+}
+</style>

+ 227 - 0
src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue

@@ -0,0 +1,227 @@
+<template>
+	<div class="editTargetDiaBase-box">
+		<el-dialog
+		:visible.sync="isShow"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="cancelHandle"
+		custom-class="dialog"
+		center
+		width="700px"
+    :title="saveScence==='saveOther' ? '指标另存为':'保存指标'"
+		v-dialogDrag>
+			<div class="dialog-main">
+				<el-form
+				ref="targetForm"
+				label-position="left"
+				label-width="80px"
+				hide-required-asterisk
+				:model="formData"
+				:rules="formRules">
+					<el-form-item label="指标名称" prop="edb_name">
+						<el-input
+						v-model="formData.edb_name"
+						style="width: 80%"
+						placeholder="指标名称"></el-input>
+					</el-form-item>
+					<el-form-item label="所属目录" prop="menu">
+						<el-cascader
+						v-model="formData.menu"
+						:options="options"
+						:props="levelProps"
+						style="width: 80%"
+						clearable
+						placeholder="请选择所属目录"/>
+					</el-form-item>
+					<el-form-item label="频率" prop="frequency">
+						<span slot="label">频&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;率</span>
+						<el-select 
+						v-model="formData.frequency" 
+						placeholder="请选择频率" 
+						style="width:80%"
+						clearable>
+							<el-option
+								v-for="item in frequencyArr"
+								:key="item"
+								:label="item"
+								:value="item">
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="单位" prop="unit">
+						<span slot="label">单&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;位</span>
+						<selectUnit 
+							v-model="formData.unit" 
+							style="width: 80%"
+						/>
+					</el-form-item>
+				</el-form>
+			</div>
+			<div class="dia-bot">
+				<el-button type="primary" style="margin-right:20px" @click="addTarget">保存</el-button>
+				<el-button type="primary" plain @click="cancelHandle">取消</el-button>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+import chartRelevanceApi,{ statisticFeatureInterface } from '@/api/modules/chartRelevanceApi.js';
+import { unitArr } from '@/utils/defaultOptions';
+import selectUnit from '@/components/selectUnit.vue';
+export default {
+	components: { selectUnit },
+	props: {
+		isShow: {
+			type: Boolean,
+		},
+		chartData: {
+			type: Object,
+		},
+		source: {
+			type: Number
+		},
+		saveScence: { //saveOther另存为 ''保存
+      type:String,
+      default: ''
+    },
+	},
+	watch: {
+		'isShow': {
+			handler(newval) {
+				newval && this.getMenu();
+				const { ChartName } = this.chartData;
+				this.formData.edb_name = this.saveScence==='saveOther' ? `${ChartName}(1)` : ChartName;
+			}
+		}
+	},
+	data () {
+		return {
+			formData: {
+				edb_name:'',
+				menu:'',
+				frequency: '',
+				unit:''
+			},
+			formRules: {
+				edb_name:[
+					{ required: true, message: '指标名称不能为空', trigger: 'blur' },
+				],
+				menu:[
+					{ required: true, message: '所属目录不能为空', trigger: 'blur' },
+				],
+				frequency:[
+					{ required: true, message: '频率不能为空', trigger: 'blur' },
+				],
+				unit:[
+					{ required: true, message: '单位不能为空', trigger: 'blur' },
+				],
+			},
+			options:  [],
+			unitArr,
+			levelProps: {
+				label: 'ClassifyName',
+				value: 'ClassifyId',
+				children: 'Children',
+				emitPath: false
+			},
+			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
+		};
+	},
+	methods: {
+		/* 获取目录结构 */
+		async getMenu() {
+			let res;
+			//统计特征区分原指标是否预测,保存到预测指标库或/eta指标库
+			if(this.$route.path==='/statisticFeatureChartEditor'&&this.$parent.oldEdbInfoType) {
+        res = await preDictEdbInterface.classifyList()
+				if(res.Ret !== 200) return
+				this.filterNodes(res.Data.AllNodes,1);
+      }else {
+				res = await dataBaseInterface.menuList()
+				if(res.Ret !== 200) return
+				this.filterNodes(res.Data.AllNodes,2);
+			}
+
+			this.options = res.Data.AllNodes || [];
+		},
+		filterNodes(arr,n) {
+			arr.length && arr.forEach(item => {
+				item.Children && item.Children.length && this.filterNodes(item.Children,n)
+				if(item.Level === n) {
+					delete item.Children
+				}
+			})
+		},
+		/* 保存 */
+		async addTarget() {
+			await this.$refs.targetForm.validate()
+			const { edb_name,menu,frequency,unit } = this.formData;
+
+			//统计图的2 3 4对应source8 9 10但其实图表source又是7 8 9 别问为什么这样搞问后端 我也乱的一批
+      const sourceMap = {
+				1: 1, 
+        2: 8,
+        3: 9,
+        4: 10
+      }
+      let Source;
+      if(this.$route.path==='/relevancechartEditor') {
+        Source = this.source;
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        Source = sourceMap[this.source]
+      }
+
+			let params = {
+				Source,
+				IsSaveAs: this.saveScence==='saveOther',
+        EdbName: edb_name,
+				Frequency: frequency,
+				Unit: unit,
+        ClassifyId: menu,
+        ...this.$parent.chartInfo
+			}
+
+			let res = null;
+      if(this.$route.path==='/relevancechartEditor') {
+        res = await chartRelevanceApi.saveEdb(params);
+      }else if(this.$route.path==='/statisticFeatureChartEditor') {
+        res = await statisticFeatureInterface.saveEdb(params);
+      }
+			
+			if(res.Ret !== 200) return
+			this.$message.success('保存成功');
+			this.cancelHandle();
+			this.$emit('saveBack',{source:this.source})
+      
+		},
+		cancelHandle() {
+			this.formData = {
+				edb_name:'',
+				menu:'',
+				frequency: '',
+				unit:''
+			}
+			this.$emit('update:isShow',false)
+		}
+	},
+}
+</script>
+<style lang='scss'>
+.editTargetDiaBase-box {
+	.dialog-main {
+		padding-left: 50px;
+	}
+	.el-cascader .el-input {
+		width: 100%;
+	}
+	.dia-bot {
+		margin: 52px 0 30px;
+		display: flex;
+		justify-content: center;
+
+	}
+}
+</style>

+ 151 - 0
src/views/chartRelevance_manage/components/selectTarget.vue

@@ -0,0 +1,151 @@
+<template>
+  <div style="flex: 1">
+    <el-select
+      style="width: 100%"
+      v-model="targetType"
+      placeholder="请选择指标种类"
+      @change="targetTypeChange"
+      v-if="selectStyleType===1"
+    >
+      <el-option
+        v-for="item in etaTypeOpt"
+        :key="item.val"
+        :label="item.label"
+        :value="item.val"
+      />
+    </el-select>
+    <div v-else>
+      <label>选择指标:</label>
+      <el-radio-group v-model="targetType" @change="targetTypeChange">
+        <el-radio  
+          v-for="item in etaTypeOpt"
+          :key="item.val"
+          :label="item.val"
+        >{{item.label}}</el-radio>
+      </el-radio-group>
+    </div>
+    <el-select
+      v-model="search_txt"
+      v-loadMore="searchLoad"
+      :filterable="!search_txt"
+      remote
+      clearable
+      placeholder="请选择指标名称"
+      style="width: 100%; margin-top: 20px"
+      :remote-method="searchHandle"
+      @click.native="inputFocusHandle"
+      @change="handleSelectTarget"
+    >
+      <i slot="prefix" class="el-input__icon el-icon-search"></i>
+      <el-option
+        v-for="item in searchOptions"
+        :key="item.EdbInfoId"
+        :label="item.EdbName"
+        :value="item.EdbInfoId"
+      >
+        <edbDetailPopover :info="item">
+          <div slot="reference">{{item.EdbName}}</div>
+        </edbDetailPopover>
+      </el-option>
+    </el-select>
+  </div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+export default {
+    props:{
+      defaultId:{
+        default:''
+      },
+      defaultOpt:{
+        default:[]
+      },
+      defaultType:{
+        default:''
+      },
+      selectStyleType: {
+        default: 1
+      }
+    },
+    watch:{
+      defaultId(){
+        this.search_txt=this.defaultId||''
+        this.searchOptions=this.defaultOpt||[]
+        this.current_search=this.defaultOpt[0]?this.defaultOpt[0].EdbName:''
+        this.targetType=this.defaultType==1?'2':'1' //EdbInfoCategoryType 0普通 1预测
+      }
+    },
+    data() {
+        return {
+            targetType:'1',//1:ETA指标 2:ETA预测指标
+            etaTypeOpt:[
+                {
+                    label:'ETA指标',
+                    val:'1'
+                },
+                {
+                    label:'ETA预测指标',
+                    val:'2'
+                },
+            ],
+            search_txt: this.defaultId||'',
+            searchOptions: this.defaultOpt||[],
+            search_have_more: true,
+            search_page: 1,
+            current_search: this.defaultOpt[0]?this.defaultOpt[0].EdbName:'',
+        }
+    },
+    methods: {
+        /* 搜索 */
+        searchHandle(query) {
+            this.search_page = 1;
+            this.current_search = query;
+            this.searchApi(this.current_search)
+        },
+
+        async searchApi(query, page = 1) {
+            let params = {
+                KeyWord: query,
+                CurrentIndex: page,
+            }
+            const res = this.targetType=='1'?await dataBaseInterface.targetSearchByPage(params):await preDictEdbInterface.edbSearch(params)
+
+            if (res.Ret !== 200) return
+            const { List, Paging } = res.Data;
+            this.search_have_more = page < Paging.Pages;
+            this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
+        },
+
+        /* 聚焦获取当前检索 */
+        inputFocusHandle(e) {
+            this.search_page = 1;
+            this.current_search = e.target.value;
+            this.searchApi(this.current_search);
+        },
+
+        searchLoad() {
+            if (!this.search_have_more) return;
+            this.searchApi(this.current_search, ++this.search_page);
+        },
+
+        //要搜索的指标类型变化
+        targetTypeChange(){
+          this.searchOptions=[]
+          this.search_page = 1;
+          this.search_txt=''
+          this.$emit('select','')
+        },
+
+        // 指标选择
+        handleSelectTarget(e){
+            let arr=this.searchOptions.filter(_item=>_item.EdbInfoId==e)
+            this.$emit('select',arr[0])
+        },
+    },
+}
+</script>
+
+<style>
+</style>

+ 505 - 0
src/views/chartRelevance_manage/fittingEquationChartEditor.vue

@@ -0,0 +1,505 @@
+<template>
+  <div class="fittingEquation-chart-editor-container" id="box">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+    <div class="left-cont" v-show="!isSlideLeft" id="left">
+      <div class="left-top">
+        <el-button type="primary" @click="saveHandle">保存</el-button>
+        <el-button type="primary" plain @click="$router.replace({
+					path: '/fittingEquationList',
+					query: $route.query
+				})">取消</el-button>
+      </div>
+			<div class="left-min">
+				<div class="section-item">
+					<label style="display: block">时间:</label>
+					<el-select
+							style="width: 120px;margin: 10px 0"
+							v-model="leftOption.DateType"
+							placeholder="请选择"
+							@change="leftOption.date=[]"
+					>
+						<el-option
+								v-for="item in yearSelector"
+								:key="item.value"
+								:label="item.name"
+								:value="item.value"
+						/>
+					</el-select>
+					<date-picker
+						v-model="leftOption.date"
+						v-show="leftOption.DateType===5"
+						style="width:120px;"
+						type="date"
+						range
+						value-type="format"
+						placeholder="请选择时间段"
+						@change="dateChange"
+					/>
+				</div>
+        
+        <el-collapse v-model="activeNames" class="targetset-cont">
+          <el-collapse-item  
+            class="series-li"
+            :name="0"
+          >
+            <template slot="title">
+              <el-button type="text" size="small" style="font-size: 15px;">X值指标</el-button>
+            </template>
+            <div class="setting-wrapper">
+              <selectTarget
+								ref="xSelectRef"
+                @select="chooseXEdbs"
+              />
+
+              <ul class="edb-list">
+                <li v-for="(item,index) in leftOption.xEdbs" :key="item.id">
+                  <div class="info">
+										<el-popover
+											placement="top-start"
+											width="200"
+											trigger="hover"
+											:content="item.name">
+											<div class="text_oneLine" slot="reference" style="max-width:200px;">
+												<span>{{index+1}}:</span>
+												<span>{{item.name}}</span>
+											</div>
+										</el-popover>
+										<i class="el-icon-delete deletesty" @click="removeTarget('x',index)"></i>
+                  </div>
+                </li>
+              </ul>
+            </div>
+          </el-collapse-item>
+          <el-collapse-item  
+            class="series-li"
+            :name="1"
+          >
+            <template slot="title">
+              <el-button type="text" size="small" style="font-size: 15px;">Y轴指标</el-button>
+            </template>
+            <div class="setting-wrapper">
+              <selectTarget
+								ref="ySelectRef"
+                @select="chooseYEdbs"
+              />
+
+              <ul class="edb-list">
+                <li v-for="(item,index) in leftOption.yEdbs" :key="item.id">
+                  <div class="info">
+										<el-popover
+											placement="top-start"
+											width="200"
+											trigger="hover"
+											:content="item.name">
+											<div class="text_oneLine" slot="reference" style="max-width:200px;">
+												<span>{{index+1}}:</span>
+												<span>{{item.name}}</span>
+											</div>
+										</el-popover>
+										<i class="el-icon-delete deletesty" @click="removeTarget('y',index)"></i>
+                  </div>
+                </li>
+              </ul>
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+        
+        <el-button type="primary" @click="getPreviewData">确定</el-button>
+			</div>
+      <span
+        class="move-btn resize"
+        v-drag
+        id="resize"
+        @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+      ></span>
+      <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+				<i class="el-icon-d-arrow-left"></i>
+			</span>
+    </div>
+    <div class="right-cont" id="right" :style="isSlideLeft ? 'width:100%' : `width:80%`">
+			<div class="chart-min-cont" v-if="chartBatchData.length">
+				<div class="card-wrapper" v-for="(item,index) in chartBatchData" :key="index">
+            <chartCard 
+              :entryType="index+1"
+              :ref="`chartCard${index+1}`"
+              :data="item"
+            />
+
+				</div>
+      </div>
+			
+			<div class="nodata" v-else>
+				<img
+          src="~@/assets/img/data_m/table_no.png"
+          alt=""
+          style="
+            display: block;
+            width: 140px;
+            height: 148px;
+						margin: 0 auto;
+          "
+        />
+        暂无信息
+			</div>
+		</div>
+
+    <!-- 保存弹窗 -->
+    <fittingEquationSaveDia
+      :isShow.sync="isSaveDialog"
+			:initData="leftOption.ChartMappingList"
+			@saveBack="editChartBackHandle"
+    />
+
+  </div>
+</template>
+
+<script>
+import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
+import { yearSelector } from '@/utils/defaultOptions';
+import Chart from '@/views/dataEntry_manage/components/chart';
+import selectTarget from './components/selectTarget.vue';
+import fittingEquationSaveDia from './components/fittingEquationSaveDia.vue';
+import chartCard from './components/chartCard.vue';
+export default {
+  components: { Chart,selectTarget,fittingEquationSaveDia,chartCard },
+	directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 300 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    },
+  },
+	computed: {
+		roleName() {
+			return localStorage.getItem('userName');
+		}
+	},
+  data() {
+    return {
+			chart_code: this.$route.query.code || '',
+			isSlideLeft: false,
+			activeNames:[0],
+
+			chartBatchData: [],
+			yearSelector: [
+        ...yearSelector,
+        { name: '自定义',value: 5 }
+      ],
+			dateSelector: [
+				{ name: '过去1年',value: 1 },
+				{ name: '过去2年',value: 2 },
+				{ name: '过去3年',value: 3 },
+				{ name: '过去5年',value: 4 },
+				{ name: '过去10年',value: 5 },
+				{ name: '自定义',value: 6 },
+				
+			],
+
+      leftOption: {
+				MultipleGraphConfigId: 0,
+				ChartMappingList:[],
+        DateType: yearSelector[0].value,
+				date: [],
+        xEdbs: [],
+        yEdbs: []
+      },
+
+			classifyOptions: [],//分类option
+
+			isSaveDialog: false
+
+    };
+  },
+  methods: {
+
+		/* 获取图表详情 */
+		getChartInfo() {
+			fittingEquationInterface.getConfigSetting({
+				UniqueCode: this.chart_code,
+			}).then((res) => {
+				if (res.Ret !== 200) return;
+				
+				const { ChartMappingList,EdbInfoList,LineChartInfoConfig,MultipleGraphConfigId } = res.Data;
+				this.leftOption = {
+					MultipleGraphConfigId,
+					ChartMappingList,
+					DateType: LineChartInfoConfig.DateType,
+					date: [LineChartInfoConfig.StartDate,LineChartInfoConfig.EndDate],
+					xEdbs: LineChartInfoConfig.XEdbInfoIdList.map(_ => ({ id: _,name:EdbInfoList.find(_edb =>_edb.EdbInfoId===_).EdbName })),
+					yEdbs: LineChartInfoConfig.YEdbInfoIdList.map(_ => ({ id: _,name:EdbInfoList.find(_edb =>_edb.EdbInfoId===_).EdbName })),
+				}
+
+				this.getPreviewData();
+			});
+		},
+
+    /* 获取数据 */
+		getPreviewData() {
+			if(!this.leftOption.xEdbs.length || !this.leftOption.yEdbs.length) return this.$message.warning('请先选择指标');
+			if(this.leftOption.xEdbs.length < 2 || this.leftOption.yEdbs.length < 2) return this.$message.warning('指标数量不得少于2组')
+			if(this.leftOption.yEdbs.length !== this.leftOption.xEdbs.length) return this.$message.warning('X轴与Y轴指标数量不一致');
+
+			const { DateType,date,xEdbs,yEdbs } = this.leftOption;
+			let params = {
+				DateType,
+				StartDate: date[0]||'',
+				EndDate: date[1]||'',
+				XEdbInfoIdList: xEdbs.map(_ => _.id),
+				YEdbInfoIdList: yEdbs.map(_ => _.id)
+			}
+
+			const chartNameMap = {
+				1: this.leftOption.ChartMappingList.find(_ => _.Source===5) ? this.leftOption.ChartMappingList.find(_ => _.Source===5).ChartName : '',
+				2: this.leftOption.ChartMappingList.find(_ => _.Source===6) ? this.leftOption.ChartMappingList.find(_ => _.Source===6).ChartName : '',
+				3: this.leftOption.ChartMappingList.find(_ => _.Source===7) ? this.leftOption.ChartMappingList.find(_ => _.Source===7).ChartName : '',
+			}
+
+			fittingEquationInterface.previewData(params).then(res => {
+				if(res.Ret !== 200) return
+
+				this.chartBatchData = res.Data.List ? res.Data.List.map((_,index) =>({
+					ChartInfo: { Source: 6,ChartName: chartNameMap[index+1] },
+					EdbInfo: {
+						..._,
+						ChartColor:'#00f',
+						ChartStyle:'spline',
+						PredictChartColor: '#00f',
+						ChartType:0,
+						ChartWidth:3,
+						EdbName:_.Name,
+						EdbNameEn: _.NameEn,
+						IsAxis:1
+					}
+				})) : [];
+			})
+		},
+
+    // 选择指标
+    chooseXEdbs(edb) {
+			if(edb){
+				this.leftOption.xEdbs.push({
+					id: edb.EdbInfoId,
+					name: edb.EdbName,
+				})
+				this.$refs.xSelectRef.search_txt = '';
+			}
+    },
+
+    chooseYEdbs(edb) {
+			if(edb) {
+				if(this.leftOption.yEdbs)
+				this.leftOption.yEdbs.push({
+					id: edb.EdbInfoId,
+					name: edb.EdbName,
+				})
+				this.$refs.ySelectRef.search_txt = '';
+			}
+    },
+
+		/* 删除指标 */
+    removeTarget(type,index) {
+      type === 'x' ? this.leftOption.xEdbs.splice(index,1) : this.leftOption.yEdbs.splice(index,1);
+    },
+
+    reloadRightWid() {
+			let total_wid = $('#box')[0].offsetWidth;
+      let left = $('#left')[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + 'px';
+      $('#right')[0].style.width = rigtWid;
+		},
+
+		/* 保存 */
+		async saveHandle() {
+			if(!this.leftOption.xEdbs.length || !this.leftOption.yEdbs.length) return this.$message.warning('请先选择指标');
+			if(this.leftOption.xEdbs.length < 2 || this.leftOption.yEdbs.length < 2) return this.$message.warning('指标数量不得少于2组')
+			if(this.leftOption.yEdbs.length !== this.leftOption.xEdbs.length) return this.$message.warning('X轴与Y轴指标数量不一致');
+      this.isSaveDialog = true;
+
+		},
+
+		/* 保存成功跳列表 */
+		editChartBackHandle(query) {
+			this.$router.replace({
+        path: '/fittingEquationList',
+        query
+      })
+		}
+	},
+  mounted() {
+		this.chart_code && this.getChartInfo();
+		window.addEventListener('resize', this.reloadRightWid);
+	},
+	destroyed() {
+		window.removeEventListener('resize', this.reloadRightWid);
+	}
+};
+</script>
+<style lang="scss">
+.fittingEquation-chart-editor-container {
+	$font-small: 12px; $font-normal: 14px;
+
+  display: flex;
+	*{ box-sizing: border-box; }
+	.el-date-editor .el-range-separator {
+		width: 10%;
+	}
+	.slide-icon {
+		padding: 20px 0;
+		/* display: block; */
+		box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+		border-radius: 5px;
+		cursor: pointer;
+		position: absolute;
+		top: 50%;
+		transform: translateY(-50%);
+		z-index: 99;
+		&:hover {
+			background-color: rgba(0, 0, 0, 0.05);
+		}
+		&.slide-left {
+			right: 0;
+		}
+		&.slide-right {
+			left: 0;
+		}
+	}
+  .left-cont {
+    width: 400px;
+    min-width: 300px;
+    background: #fff;
+    margin-right: 20px;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    height: calc(100vh - 113px);
+    overflow: hidden;
+    position: relative;
+    box-sizing: border-box;
+    .left-top {
+      padding: 15px 20px;
+      border: 1px solid #ececec;
+      box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+    }
+		.left-min {
+			padding: 30px 20px;
+			max-height: calc(100vh - 194px);
+			overflow-y: auto;
+
+			.targetset-cont {
+        border: 1px solid #DCDFE6;
+        margin: 20px 0;
+        
+				.el-collapse-item.is-disabled .el-collapse-item__header {
+					color: #333;
+				}
+				.setting-wrapper {
+					padding: 15px;
+				}
+				.el-collapse-item__header {
+					background-color: #F0F2F5;
+					margin-bottom: 0;
+					border-bottom: 1px solid #DCDFE6;
+					padding: 0 30px;
+					.el-collapse-item__arrow {
+						position: absolute;
+						left: 8px;
+					}
+				}
+				.edb-list {
+					margin: 10px 0;
+					.info {
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+						margin-bottom: 10px;
+						color: #666;
+					}
+				}
+			}
+		}
+		.move-btn {
+			height: 100%;
+			width: 4px;
+			position: absolute;
+			right: 0px;
+			top: 0;
+			&:hover {
+				cursor: col-resize;
+			}
+		}
+  }
+	.right-cont {
+		width: 80%;
+    .mx-datepicker {
+      width: 220px !important;
+    }
+
+		.chart-min-cont {
+      background: #fff;
+      height: calc(100vh - 118px);
+			border: 1px solid #ececec;
+      overflow-y: auto;
+			display: flex;
+			flex-wrap: wrap;
+			.card-wrapper {
+				width: 50%;
+        margin-bottom: 20px;
+        min-height: 350px;
+				.card-item {
+					padding: 20px;
+					.top {
+						display: flex;
+						justify-content: space-between;
+						align-items: center;
+					}
+					.chartWrapper {
+						.title {
+							font-size: 15px;
+							text-align: center;
+							margin: 10px 0;
+						}
+					}
+				}
+			}
+    }
+    .nodata {
+      height: calc(100vh - 120px);
+			background-color: #fff;
+      text-align: center;
+      font-size: 16px;
+      color: #666;
+			padding: 100px 0;
+    }
+	}
+}
+</style>
+<style lang="scss">
+.edb-item-style .el-input__icon {
+	line-height: 27px;
+}
+</style>

+ 912 - 0
src/views/chartRelevance_manage/fittingEquationList.vue

@@ -0,0 +1,912 @@
+<template>
+	<div class="fittingEquation-chart-container" v-if="showData">
+		<span
+			class="slide-icon slide-right"
+			@click="isSlideLeft = !isSlideLeft"
+			v-show="isSlideLeft"
+		>
+			<i class="el-icon-d-arrow-right"></i>
+		</span>
+
+		<div class="data-sheet-main" id="box">
+      <div class="main-left left" id="left" v-show="!isSlideLeft">
+				<div class="datasheet_top">
+						<el-button type="primary" @click="goAddChart">添加图表</el-button>
+				</div>
+
+				<div class="search-cont">
+					<el-checkbox v-model="isShowMe"  @change="() => { getTreeData();getPublicList() }">只看我的</el-checkbox>
+					<el-select
+						v-model="search_txt"
+						v-loadMore="searchLoad"
+						:filterable="!search_txt"
+						remote
+						clearable
+						placeholder="请输入图表名称"
+						style="width: 100%; margin-top: 20px"
+						:remote-method="searchHandle"
+						@click.native="inputFocusHandle"
+					>
+						<i slot="prefix" class="el-input__icon el-icon-search"></i>
+						<el-option
+							v-for="item in searchOptions"
+							:key="item.ChartInfoId"
+							:label="item.ChartName"
+							:value="item.ChartInfoId"
+						>
+						</el-option>
+					</el-select>
+				</div>
+				<div class="tree-cont">
+					<el-tree
+						ref="treeRef"
+						class="target_tree"
+						:data="treeData"
+						node-key="UniqueCode"
+						:props="defaultProp"
+						:allow-drag="canDragHandle"
+						:allow-drop="canDropHandle"
+						:current-node-key="select_node"
+						:default-expanded-keys="defaultShowNodes"
+						draggable
+						:expand-on-click-node="false"
+						check-strictly
+						empty-text="暂无分类"
+						@node-expand="handleNodeExpand"
+						@node-collapse="handleNodeCollapse"
+						@current-change="nodeChange"
+						@node-drop="dropOverHandle"
+						@node-drag-end="dropMouseLeave"
+						@node-drag-leave="dropMouseLeave"
+						@node-drag-enter="dropMouseOver"
+					>
+						<span class="custom-tree-node" slot-scope="{ node, data }">
+							<el-input
+								ref="editVal"
+								style="width: 90px"
+								placeholder="请输入值"
+								class="label-input"
+								v-model="new_label"
+								v-if="data.isEdit"
+								@blur="changeValue(data)"
+							/>
+							<span
+								@dblclick.stop="editNodeLabel(data)"
+								v-else
+								class="text_oneLine node_label"
+								:style="`width:${
+									(select_node === data.UniqueCode && node.Nodewidth) || ''
+								}`"
+							>
+								<span>{{ data.ChartClassifyName }}</span>
+							</span>
+							<span
+								style="display: flex; align-items: center"
+								v-if="select_node === data.UniqueCode"
+							>
+								<img
+									src="~@/assets/img/data_m/move_ico.png"
+									alt=""
+									style="width: 14px; height: 14px; margin-right: 8px"
+								/>
+								<img
+									src="~@/assets/img/set_m/edit.png"
+									alt=""
+									style="width: 15px; height: 14px; margin-right: 8px"
+									@click.stop="editNode(node, data)"
+									v-if="!data.ChartInfoId"
+								/>
+								<img
+									slot="reference"
+									src="~@/assets/img/set_m/del.png"
+									alt=""
+									style="width: 14px; height: 14px"
+									@click.stop="removeNode(node, data)"
+									v-if="!data.ChartInfoId"
+								/>
+							</span>
+						</span>
+					</el-tree>
+					<div
+						class="noDepart"
+						@click="addLevelOneHandle"
+					>
+						<img
+							src="~@/assets/img/set_m/add_ico.png"
+							alt=""
+							style="width: 16px; height: 16px; margin-right: 10px"
+						/>
+						<span>添加图表分类</span>
+					</div>
+				</div>
+				<span
+					class="move-btn resize"
+					v-drag
+					id="resize"
+					@mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+				></span>
+				<span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+					<i class="el-icon-d-arrow-left"></i>
+				</span>
+      </div>
+
+			<div class="main-right" id="right" :style="isSlideLeft ? 'width:100%' : 'width:80%'">
+
+				<!-- 图表详情 -->
+				<div class="chart-detail-wrapper" v-if="chartInfo.ChartInfoId">
+					<el-row class="bottom-min">
+              <el-col
+                :span="21"
+                style="padding: 20px 0;"
+              >
+                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
+                <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
+                  <div class="chartWrapper" id="chartWrapper">
+                    <h2 class="chart-title">{{ chartInfo.ChartName }}</h2>
+                    <Chart 
+											:options="options"
+											minHeight="440px" 
+											height="500px"
+											ref="chartRef"
+										/>
+                  </div>
+                  <span class="chart-author">作者:{{ chartInfo.SysUserRealName}}</span>
+                </div>
+
+                <!-- 异常显示 -->
+                <p class="error-tip" style="min-height: 400px;" v-if="chartInfo.WarnMsg">{{chartInfo.WarnMsg}}</p>
+              </el-col>
+              <el-col :span="3" style="position: absolute;height: 100%;right: 0;">
+                <!-- 操作 -->
+								<chartHandlesWrap
+									:chartInfo="chartInfo"
+									:linkUrl="linkUrl"
+									@copyChartConfirm="copyChartConfirm"
+									@addMychartHandle="addMychartHandle"
+									@refreshHandle="refreshHandle"
+									@saveChartOtherHandle="saveChartOtherHandle"
+									@editChartHandle="editChartHandle"
+									@openEnNameDia="openEnNameDia"
+									@delChartHandle="delChartHandle"
+								/>
+              </el-col>
+          </el-row>
+				</div>
+
+				<!-- 列表 -->
+				<chartListWrap
+					v-else
+          :total="chart_total" 
+          :list="chartList" 
+          @loadMoreHandle="loadMoreHandle"
+          @detailShowHandle="detailShowHandle"
+          @addMychartHandle="addMychartHandle"
+          ref="chartListWrap"
+        />
+			</div>
+		</div>
+
+
+		<!-- 分类弹窗 -->
+		<classify-dia
+			:isOpenDialog.sync="classifyDia"
+			:title="dialog_title"
+			:form="classifyForm"
+			@successCallback="getTreeData"
+		/>
+
+		 <!-- 加入我的图库弹窗 -->
+    <addMyClassifyDia
+      :isAddMyDialog="isAddMyChart"
+      :add_id="add_chart_id"
+      :add_ids="add_ids"
+      @cancel="isAddMyChart = false"
+      @addSuccess="addMySuccess"
+    />
+
+		 <!-- 图表另存 -->
+    <SaveChartOther 
+      :show.sync="isShowSaveOther" 
+      fromType="chartsetting"
+			source="fitting_equation"
+      :data="chartInfo"
+      @ensure="getTreeData"
+    />
+
+		<!-- 输入英文指标弹窗 -->
+		<set-en-name-dia 
+			:isOpenDialog="setEnName" 
+		  :formData="formItemArray"
+			@cancel="setEnName=false"
+   	  @updateEnName="updateEnName"
+		/>
+
+	</div>
+</template>
+
+<script>
+import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
+import leftMixin from './mixins/classifyMixin';
+import Chart from '@/views/dataEntry_manage/components/chart';
+import changeLang from "@/views/dataEntry_manage/components/changeLang.vue"
+import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
+import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
+import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
+import setEnNameDia from '@/views/dataEntry_manage/components/setEnNameDia.vue'
+import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
+import { copyOtherOptions } from '@/utils/defaultOptions';
+export default {
+	components: { 
+		changeLang,
+		classifyDia,
+		Chart,
+		addMyClassifyDia,
+		SaveChartOther,
+		setEnNameDia
+	},
+	mixins:[ leftMixin,chartSetMixin ],
+	computed: {
+		/* 分享地址 */
+    linkUrl() {
+      const LINK_CHART_URL = process.env.CHART_LINK;
+      return `${LINK_CHART_URL}?code=${this.chartInfo.UniqueCode}&fromType=share?&lang=${this.currentLang}`
+    }
+	},
+	data () {
+		return {
+			showData: false,
+			refreshLoading: false,
+			isShowMe: false,
+			search_txt: '',
+			searchOptions:[],
+			isSlideLeft: false,//左侧分类收起
+
+			select_node: '',//节点唯一标识code
+			select_classify: '',
+			new_label:'',//双击修改的value
+			treeData: [], //分类数据
+      defaultShowNodes: [], //展开节点
+      defaultProp: {
+        label: 'ChartClassifyName',
+        children: 'Children',
+      }, //树结构配置项
+			dynamicNode: null,
+
+			/* 分类弹窗 */
+			dialog_title:'',
+			classifyDia: false, //
+			classifyForm: {},
+
+			select_id: '',//选中的图表id
+			chartInfo: {},
+			chart_title:'',//图表标题 双击标题修改时来存储最新值
+
+			isAddMyChart: false, //加入图库弹窗
+      add_chart_id: '', //要加入的图表
+			add_ids:[],//加入时已有的分类
+
+			/* 图表列表 */
+			publicHaveMove: true,//是否还有列表数据
+			chartList: [],
+			chart_total: 0,
+			chart_page: 1,
+			chart_pages_size: 16,
+
+			search_page: 1,
+			search_have_more: false,
+			current_search:'',
+		};
+	},
+	methods: {
+
+		/* 添加图表 */
+		goAddChart() {
+			if(!this.treeData.length) return this.$message.warning('请先添加分类');
+			this.$router.push({ path: '/fittingEquationChartEditor' });
+		},
+
+		/* 获取分类 */
+		getTreeData(params=null) {
+			fittingEquationInterface.classifyList({IsShowMe:this.isShowMe}).then(res => {
+				const { Ret,Data } = res;
+				if(Ret !== 200) return
+
+				this.showData = true;
+				this.treeData = Data.AllNodes || [];
+				this.$nextTick(() => {
+					/* 新增完成后 处理树展开和选中 */
+					params && this.selectCurrentNode(params);
+				});
+
+			})
+		},
+
+		/* 搜索 */
+		searchHandle(query) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search)
+		},
+
+		searchApi(query,page=1) {
+      /* 查找列表 */
+      fittingEquationInterface
+        .searchChart({
+          Keyword: query,
+          IsShowMe:this.isShowMe,
+          CurrentIndex: page
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return
+          const { List,Paging } = res.Data;
+          this.search_have_more = page < Paging.Pages;
+          this.searchOptions = page === 1 ? List : [...this.searchOptions,...List];
+        });
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+      if(this.current_search) {
+        this.searchApi(this.current_search)
+      }else {
+        this.searchOptions = [];
+      }
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page);
+		},
+
+		/* 选中分类变化时 */
+		nodeChange({ UniqueCode,ChartInfoId,ChartClassifyId },node) {
+			this.search_txt = '';
+			this.select_node = UniqueCode;
+			this.select_classify = !ChartInfoId ? ChartClassifyId : 0;
+			// if(this.select_id !== ChartInfoId) {
+				this.select_id = ChartInfoId || 0;
+			// }
+			this.resetNodeStyle(node);
+			this.dynamicNode = node;
+		},
+
+		/* 添加一级目录 */
+		addLevelOneHandle() {
+			this.dialog_title = '添加';
+			this.classifyForm = {
+				classify_name: '',
+			}
+			this.classifyDia = true;
+		},
+
+    /* 编辑节点 */
+    editNode(node, { ChartClassifyName,ChartClassifyId }) {
+
+      this.dialog_title = '编辑';
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: ChartClassifyName,
+        classify_id: ChartClassifyId,
+      };
+      this.classifyDia = true;
+    },
+
+		 /* 删除节点校验 */
+    async removeNode(node, { ChartClassifyId,ChartInfoId }) {
+
+			const { Data } = await fittingEquationInterface.classifyDelCheck({ ChartClassifyId })
+
+			const { DeleteStatus } = Data;
+
+			DeleteStatus === 1 
+			? this.$confirm('该分类下关联表图表不可删除', '删除失败', {
+				confirmButtonText: '知道了',
+				showCancelButton: false,
+				type: 'error',
+			}) : DeleteStatus === 0
+			?  this.$confirm('确定删除当前分类吗?', '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning',
+			}).then(() => {
+				this.delApi(ChartClassifyId,ChartInfoId)
+			}): null;
+
+    },
+
+		 /* 删除方法 */
+    delApi(ChartClassifyId,ChartInfoId,type='') {
+      fittingEquationInterface
+        .classifyDel({
+          ChartClassifyId,
+					ChartInfoId
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return
+					this.$message.success(res.Msg);
+
+					if (!res.Data.ChartInfoId) this.select_id = '';
+
+					//删除自动显示下一张
+					type=='del_chart' && res.Data.ChartInfoId
+						? this.getTreeData({
+								code: res.Data.UniqueCode,
+								id: res.Data.ChartInfoId
+							})
+						: this.getTreeData();
+        });
+    },
+
+		/* 分类成功回调 */
+		classifyCallback(type) {
+			this.getTreeData();
+
+			if (type === 'add') {
+        //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
+        let code = this.add_parent_id;
+        let flag = this.defaultShowNodes.some(item => item === code);
+        // console.log(flag)
+        !flag && this.defaultShowNodes.push(code);
+        this.add_parent_id = '';
+
+      }
+		},
+
+		/* 保存图表 */
+		saveChartHandle: _.debounce(async function() {
+			const { Ret } = await fittingEquationInterface.chartSave({
+				ChartInfoId: this.chartInfo.ChartInfoId,
+				LeftMin: String(this.chartLimit.min),
+				LeftMax: String(this.chartLimit.max),
+			})
+
+			if(Ret!==200) return
+			this.$message.success('保存成功');
+			this.getTreeData();
+			//关联图表和图片
+			this.setChartImage();
+		},300),
+
+		/* 获取图表列表 */
+		getPublicList() {
+			fittingEquationInterface.getChartList({
+				CurrentIndex: this.chart_page,
+				PageSize: this.chart_pages_size,
+        ChartClassifyId: this.select_classify || 0,
+				IsShowMe: this.isShowMe
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				this.publicHaveMove = res.Data
+            ? this.chart_page < res.Data.Paging.Pages
+            : false;
+          this.chartList = res.Data
+            ? this.chart_page === 1
+              ? res.Data.List
+              : [...this.chartList, ...res.Data.List]
+            : [];
+        this.chart_total = res.Data ? res.Data.Paging.Totals : 0;
+			})
+		},
+
+		getChartInfo() {
+			this.getDetailHandle();
+		},
+
+		/* 获取图表详情 */
+		getDetailHandle() {
+			fittingEquationInterface.chartDetail({
+				ChartInfoId: this.select_id
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				const { ChartInfo,DataResp } = res.Data;
+				this.chartInfo = ChartInfo;
+				this.setDefaultChart([DataResp]);
+
+				!ChartInfo.ChartImage && this.$nextTick(() => {
+					//关联图表和图片
+					 this.setChartImage();
+				})
+			})
+		},
+
+		/* 删除图表 */
+		delChartHandle() {
+			const { ChartClassifyId,ChartInfoId } = this.chartInfo;
+			this.$confirm('删除后该图表将不能再引用,确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          this.delApi(ChartClassifyId,ChartInfoId,'del_chart');
+        })
+        .catch(() => {});
+		},
+
+		/* 刷新图表 */
+		refreshHandle() {
+			this.refreshLoading = this.$loading({
+        lock: true,
+        target: '.main-right',
+        text: '刷新图表中...',
+        spinner: 'el-icon-loading',
+        background: 'rgba(255, 255, 255, 0.8)',
+      });
+      fittingEquationInterface
+        .refreshChart({
+          ChartInfoId: this.chartInfo.ChartInfoId,
+        })
+        .then((res) => {
+          this.refreshLoading.close();
+          if (res.Ret === 200) {
+            this.getDetailHandle();
+            this.$message.success(res.Msg);
+          }
+        });
+		},
+
+		/* 编辑图表 */
+		editChartHandle() {
+			this.$router.push({
+        path: '/fittingEquationChartEditor',
+        query: {
+          code: this.chartInfo.UniqueCode,
+					id: this.chartInfo.ChartInfoId
+        }
+      })
+		},
+
+		copyChartHandle:_.debounce(function(type){
+      let chartsName = this.currentLang=='ch'?this.chartInfo.ChartName:this.chartInfo.ChartNameEn
+      let { heightNum, widthNum , newTitle , dynamic_copyOptions} = this.dynamicWidthAndHeight(type,this.chartInfo.ChartType,chartsName,1)
+      const chartType = 'seasonLegend';
+      // 英文转SVG设置变动
+      if(this.currentLang == 'en'){
+        // 如果竖轴坐标单位为'英文单位',表示客户没填,转成svg时置为空
+        this.$refs.chartRef.chart.options.yAxis.forEach(it => {
+          if(it.title.text == '英文单位') it.title.text='' 
+        });
+      }
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart:{
+          width:widthNum,
+          height:heightNum,
+          backgroundColor:"rgba(255, 255, 255, 0)",
+        },
+        title: {
+          text: newTitle,
+          margin: 10,
+          style: {
+            fontSize: '18px'
+          }
+        },
+        legend:{
+          ...copyOtherOptions[chartType],
+          ...dynamic_copyOptions[chartType]
+          }
+      });
+      this.copyBlobItem(widthNum,heightNum,svg,type);
+    },500),
+	},
+	mounted() {
+
+		if(this.$route.query.code) {
+      this.getTreeData({code: this.$route.query.code,id: Number(this.$route.query.id)})
+    } else {
+      this.getTreeData();
+      this.getPublicList();
+    }
+
+		window.addEventListener('resize', this.reloadRightWid);
+	},
+	destroyed() {
+		window.removeEventListener('resize', this.reloadRightWid);
+	}
+}
+</script>
+<style lang='scss' scoped>
+*{ box-sizing: border-box;}
+$mini-font: 12px; $normal-font: 14px;
+.fittingEquation-chart-container {
+	.slide-icon {
+		padding: 20px 0;
+		/* display: block; */
+		box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+		border-radius: 5px;
+		cursor: pointer;
+		position: absolute;
+		top: 50%;
+		transform: translateY(-50%);
+		z-index: 99;
+		&:hover {
+			background-color: rgba(0, 0, 0, 0.05);
+		}
+		&.slide-left {
+			right: 0;
+		}
+		&.slide-right {
+			left: 0;
+		}
+	}
+	.data-sheet-main {
+		display: flex;
+
+		.main-left {
+			width: 400px;
+			min-width: 300px;
+			background: #fff;
+			margin-right: 20px;
+			border: 1px solid #ececec;
+			border-radius: 4px;
+			box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+			height: calc(100vh - 120px);
+			overflow: hidden;
+			position: relative;
+			box-sizing: border-box;
+
+			.datasheet_top {
+				padding: 20px;
+				background: #fff;
+				border: 1px solid #ececec;
+				box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+				margin-bottom: 20px;
+			}
+			.search-cont {
+				padding: 0 20px;
+			}
+
+
+
+			.tree-cont {
+				padding: 30px 20px;
+				max-height: calc(100vh - 280px);
+				overflow: auto;
+			}
+			.target_tree {
+				color: #333;
+				.custom-tree-node {
+					display: flex !important;
+					justify-content: space-between;
+					align-items: center;
+					display: block;
+					flex: 1;
+					.node_label {
+						margin-right: 2px;
+					}
+					.el-icon-view {
+						color: #409EFF;
+						font-size: 18px;
+						margin-left: 5px;
+					}
+				}
+			}
+			.noDepart {
+				margin: 60px 0;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				color: #409eff;
+				font-size: 16px;
+				cursor: pointer;
+			}
+			.move-btn {
+				height: 100%;
+				width: 4px;
+				/* opacity: 0; */
+				position: absolute;
+				right: 0px;
+				top: 0;
+				&:hover {
+				cursor: col-resize;
+					/* background-color: orange */
+				}
+			}
+		}
+
+		.main-right {
+			width: 80%;
+			.chart-detail-wrapper {
+				height: calc(100vh - 120px);
+				border: 1px solid #ececec;
+				border-radius: 4px;
+				box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+				overflow: auto;
+				background: #fff;
+				padding: 30px;
+				.bottom-min {
+					border: 1px solid #DCDFE6;
+					margin-bottom: 20px;
+					.right-actions {
+						/* max-width: 160px; */
+						height: 100%;
+						padding: 20px 10px;
+						border-left: 1px solid #DCDFE6;
+						li {
+							margin-bottom: 15px;
+						}
+						@media screen and (max-width: 1710px) {
+							font-size: 12px;
+						}
+						.span-item {
+							color: #409eff;
+							cursor: pointer;
+							&:hover {
+								text-decoration: underline;
+							}
+							.el-icon-collection,
+							.el-icon-document-copy {
+								color: #409eff;
+							}
+						}
+					}
+					.chart-show-cont {
+              padding: 0 160px 0 120px;
+              position: relative;
+							min-height: 400px;
+              .chart-title {
+                font-size: 16px;
+                font-weight: normal;
+                text-align: center;
+                margin-bottom: 10px;
+              }
+              .chart-author {
+                font-size: 14px;
+                color: #333;
+                position: absolute;
+                bottom: 0;
+                right: 50px;
+              }
+              .chartWrapper {
+                position: relative;
+                .range-cont {
+                  position: absolute;
+                  top: 13%;
+                  .min-data-input {
+                    width: 60px;
+                    display: block;
+                  }
+                  &.left {
+                    left: -80px;
+                  }
+                  &.right {
+                    right: -65px;
+                  }
+                  &.rightTwo {
+                    right: -130px;
+                  }
+                }
+              }
+          }
+				}
+			}
+
+			.chart-list-cont {
+				color: #333;
+				.el-card .el-card__header,
+				.el-card__body {
+					padding: 10px;
+				}
+
+				.chartList-wrapper {
+					margin-top: 10px;
+					display: flex;
+					flex-wrap: wrap;
+					max-height: calc(100vh - 143px);
+					overflow: hidden;
+					overflow-y: auto;
+					.drag-cont {
+						width: 100%;
+						display: flex;
+						flex-wrap: wrap;
+					}
+					.dragShdow {
+						box-shadow: 0 1px 8px rgba(64, 158, 255, 0.8);
+						opacity: 0.5;
+					}
+					.sheet-item {
+						position: relative;
+						.item-top {
+							display: flex;
+							justify-content: space-between;
+							align-items: center;
+							font-size: 16px;
+							font-weight: 600;
+						}
+						.chart-img {
+							width: 100%;
+							height: 230px;
+							object-fit: contain !important;
+							cursor: pointer;
+						}
+						.item-bottom {
+							margin-top: 10px;
+							display: flex;
+							justify-content: space-between;
+							font-size: 12px;
+							color: #666;
+							.collected {
+								color: #f00;
+								cursor: pointer;
+							}
+							.join_txt {
+								color: #409eff;
+								cursor: pointer;
+							}
+						}
+					}
+				}
+				.nodata {
+					text-align: center;
+				}
+			}
+		}
+		
+		@media screen and (min-width: 1711px){
+			.min-data-input {
+				margin-top: 360px;
+			}
+		}
+		@media screen and (max-width: 1710px){
+			.min-data-input {
+				margin-top: 290px;
+			}
+		}
+	}
+}
+</style>
+
+<style lang="scss">
+.fittingEquation-chart-container {
+	.label-input .el-input__inner {
+		height: 25px;
+		line-height: 25px;
+		padding: 0 10px;
+	}
+
+	.range-cont .el-input__inner {
+		padding: 0 3px;
+	}
+
+	.el-tree__drop-indicator{
+		height:3px;
+		background-color:#409EFF;
+	}
+	.el-tree-node__content {
+		margin-bottom: 14px !important;
+	}
+	.el-tree-node__children {
+		.el-tree-node {
+			/* margin-bottom: 8px !important; */
+			margin-bottom: 0px !important;
+			padding-left: 18px;
+		}
+		.el-tree-node__content {
+			margin-bottom: 5px !important;
+			padding-left: 0 !important;
+		}
+	}
+	.expanded.el-icon-caret-right:before {
+		content: url('../../assets/img/set_m/down.png') !important;
+	}
+	.el-icon-caret-right:before {
+		content: url('../../assets/img/set_m/slide.png') !important;
+	}
+	.el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+		content: '' !important;
+	}
+	.el-tree-node__expand-icon.expanded {
+		-webkit-transform: rotate(0deg);
+		transform: rotate(0deg);
+	}
+	.el-tree-node.is-current > .el-tree-node__content {
+		background-color: #f0f4ff !important;
+	}
+	.el-tree-node__content {
+		padding-right: 10px !important;
+	}
+}
+</style>

+ 1076 - 0
src/views/chartRelevance_manage/list.vue

@@ -0,0 +1,1076 @@
+<template>
+  <div class="comodity-chart-container" v-if="showData">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+
+    <div class="data-sheet-main" id="box">
+      <div class="main-left left" id="left" v-show="!isSlideLeft">
+        <div class="datasheet_top">
+          <el-button type="primary" @click="goAddChart">添加图表</el-button>
+        </div>
+        <div
+          style="padding: 0 20px; display: flex; justify-content: space-between"
+        >
+          <span>目录</span>
+          <el-checkbox v-model="isOnlyMe" @change="onlyMeHandler"
+            >只看我的</el-checkbox
+          >
+        </div>
+        <div class="search-cont">
+          <el-select
+            v-model="search_txt"
+            v-loadMore="searchLoad"
+            :filterable="!search_txt"
+            remote
+            clearable
+            placeholder="请输入图表名称"
+            style="width: 100%; margin-top: 20px"
+            :remote-method="searchHandle"
+            @click.native="inputFocusHandle"
+          >
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+            <el-option
+              v-for="item in searchOptions"
+              :key="item.ChartInfoId"
+              :label="item.ChartName"
+              :value="item.ChartInfoId"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <ul class="left-tab">
+          <li
+            :class="['tab', { act: classify_tab === index }]"
+            v-for="(tab, index) in ['相关性', '滚动相关性']"
+            :key="tab"
+            @click="changeTab(index)"
+          >
+            {{ tab }}
+          </li>
+        </ul>
+        <div class="tree-cont">
+          <el-tree
+            ref="treeRef"
+            class="target_tree"
+            :data="treeData"
+            node-key="UniqueCode"
+            :props="defaultProp"
+            :allow-drag="canDragHandle"
+            :allow-drop="canDropHandle"
+            :current-node-key="select_node"
+            :default-expanded-keys="defaultShowNodes"
+            draggable
+            :expand-on-click-node="false"
+            check-strictly
+            empty-text="暂无分类"
+            @node-expand="handleNodeExpand"
+            @node-collapse="handleNodeCollapse"
+            @current-change="nodeChange"
+            @node-drop="dropOverHandle"
+            @node-drag-end="dropMouseLeave"
+            @node-drag-leave="dropMouseLeave"
+            @node-drag-enter="dropMouseOver"
+          >
+            <span class="custom-tree-node" slot-scope="{ node, data }">
+              <el-input
+                ref="editVal"
+                style="width: 90px"
+                placeholder="请输入值"
+                class="label-input"
+                v-model="new_label"
+                v-if="data.isEdit"
+                @blur="changeValue(data)"
+              />
+              <span
+                @dblclick.stop="editNodeLabel(data)"
+                v-else
+                class="text_oneLine node_label"
+                :style="`width:${
+                  (select_node === data.UniqueCode && node.Nodewidth) || ''
+                }`"
+              >
+                <span>{{ data.ChartClassifyName }}</span>
+              </span>
+              <span
+                style="display: flex; align-items: center"
+                v-if="select_node === data.UniqueCode"
+              >
+                <img
+                  src="~@/assets/img/data_m/move_ico.png"
+                  alt=""
+                  style="width: 14px; height: 14px; margin-right: 8px"
+                />
+                <img
+                  src="~@/assets/img/set_m/edit.png"
+                  alt=""
+                  style="width: 15px; height: 14px; margin-right: 8px"
+                  @click.stop="editNode(node, data)"
+                  v-if="!data.ChartInfoId"
+                />
+                <img
+                  slot="reference"
+                  src="~@/assets/img/set_m/del.png"
+                  alt=""
+                  style="width: 14px; height: 14px"
+                  @click.stop="removeNode(node, data)"
+                  v-if="!data.ChartInfoId"
+                />
+              </span>
+            </span>
+          </el-tree>
+          <div class="noDepart" @click="addLevelOneHandle">
+            <img
+              src="~@/assets/img/set_m/add_ico.png"
+              alt=""
+              style="width: 16px; height: 16px; margin-right: 10px"
+            />
+            <span>添加图表分类</span>
+          </div>
+        </div>
+        <span
+          class="move-btn resize"
+          v-drag
+          id="resize"
+          @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+        ></span>
+        <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+          <i class="el-icon-d-arrow-left"></i>
+        </span>
+      </div>
+
+      <div
+        class="main-right"
+        id="right"
+        :style="isSlideLeft ? 'width:100%' : 'width:80%'"
+      >
+        <!-- 图表详情 -->
+        <div class="chart-detail-wrapper" v-if="chartInfo.ChartInfoId">
+          <el-row class="bottom-min">
+            <el-col :span="21" style="padding: 20px 0">
+              <div
+                class="chartEn-mark"
+                v-show="chartInfo.IsEnChart"
+                style="top: 0; left: 0"
+              >
+                En
+              </div>
+              <div class="chart-show-cont" v-if="!chartInfo.WarnMsg">
+                <div class="chartWrapper" id="chartWrapper">
+                  <h2 class="chart-title">
+                    {{ chartInfo.ChartName }}
+                  </h2>
+                  <Chart
+                    :options="options"
+                    minHeight="440px"
+                    height="500px"
+                    ref="chartRef"
+                  />
+                </div>
+                <span class="chart-author"
+                  >作者:{{ chartInfo.SysUserRealName }}</span
+                >
+              </div>
+
+              <!-- 异常显示 -->
+              <p
+                class="error-tip"
+                style="min-height: 400px"
+                v-if="chartInfo.WarnMsg"
+              >
+                {{ chartInfo.WarnMsg }}
+              </p>
+            </el-col>
+            <el-col
+              :span="3"
+              style="position: absolute; height: 100%; right: 0"
+            >
+              <!-- 操作 -->
+              <chartHandlesWrap
+                :chartInfo="chartInfo"
+                :linkUrl="linkUrl"
+                @copyChartConfirm="copyChartConfirm"
+                @addMychartHandle="addMychartHandle"
+                @refreshHandle="refreshHandle"
+                @saveChartOtherHandle="saveChartOtherHandle"
+                @editChartHandle="editChartHandle"
+                @openEnNameDia="openEnNameDia"
+                @delChartHandle="delChartHandle"
+              />
+            </el-col>
+          </el-row>
+          <el-table
+            :data="tableData"
+            ref="tableRef"
+            highlight-current-row
+            border
+          >
+            <el-table-column
+              v-for="item in tableColums"
+              :key="item.label"
+              :label="item.label"
+              :width="item.widthsty"
+              :min-width="item.minwidthsty"
+              align="center"
+            >
+              <template slot-scope="scope">
+                <div v-if="item.key === 'EdbName' && chartInfo.ChartType === 7">
+                  <!-- 奇怪柱状图用别名 -->
+                  <el-input
+                    v-model="scope.row.EdbAliasName"
+                    placeholder="指标别名"
+                    class="target-other-name"
+                    clearable
+                  />
+                </div>
+                <span v-else>{{ scope.row[item.key] }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" key="Copy" align="center" width="140">
+              <template slot-scope="scope">
+                <!-- <span @click="delTarget(scope.row)" class="deletesty">删除&nbsp;</span> -->
+                <span class="editsty" @click="copyCode(scope.row)">
+                  <i class="el-icon-document-copy" />&nbsp;复制数据</span
+                ><br />
+                <span class="editsty" @click="viewTarget(scope.row)"
+                  >查看数据</span
+                >
+              </template>
+            </el-table-column>
+            <div slot="empty">
+              <img
+                src="~@/assets/img/data_m/table_no.png"
+                alt=""
+                style="
+                  display: block;
+                  width: 135px;
+                  height: 90px;
+                  margin: 20px auto 10px;
+                "
+              />
+              <span>暂无指标</span>
+            </div>
+          </el-table>
+        </div>
+
+        <!-- 列表 -->
+        <chartListWrap
+          v-else
+          :total="chart_total" 
+          :list="chartList" 
+          @loadMoreHandle="loadMoreHandle"
+          @detailShowHandle="detailShowHandle"
+          @addMychartHandle="addMychartHandle"
+          ref="chartListWrap"
+        />
+      </div>
+    </div>
+
+    <!-- 分类弹窗 -->
+    <classify-dia
+      :isOpenDialog.sync="classifyDia"
+      :title="dialog_title"
+      :form="classifyForm"
+      @successCallback="getTreeData"
+    />
+
+    <!-- 加入我的图库弹窗 -->
+    <addMyClassifyDia
+      :isAddMyDialog="isAddMyChart"
+      :add_id="add_chart_id"
+      :add_ids="add_ids"
+      @cancel="isAddMyChart = false"
+      @addSuccess="addMySuccess"
+    />
+
+    <!-- 图表另存 -->
+    <SaveChartOther
+      :show.sync="isShowSaveOther"
+      fromType="chartsetting"
+      source="relevance_chart"
+      :data="chartInfo"
+      @ensure="getTreeData"
+    />
+
+    <!-- 输入英文指标弹窗 -->
+    <set-en-name-dia
+      :isOpenDialog="setEnName"
+      :formData="formItemArray"
+      @cancel="setEnName = false"
+      @updateEnName="updateEnName"
+    />
+  </div>
+</template>
+
+<script>
+import chartRelevanceApi from "@/api/modules/chartRelevanceApi.js";
+import leftMixin from "./mixins/classifyMixin";
+import Chart from "@/views/dataEntry_manage/components/chart";
+import changeLang from "@/views/dataEntry_manage/components/changeLang.vue";
+import classifyDia from "@/views/datasheet_manage/components/sheetClassifyDia.vue";
+import addMyClassifyDia from "@/views/dataEntry_manage/components/addMyClassifyDia";
+import SaveChartOther from "@/views/dataEntry_manage/components/SaveChartOther";
+import setEnNameDia from "@/views/dataEntry_manage/components/setEnNameDia.vue";
+import { chartSetMixin } from "@/views/dataEntry_manage/mixins/chartPublic";
+import { copyOtherOptions } from '@/utils/defaultOptions';
+export default {
+  components: {
+    changeLang,
+    classifyDia,
+    Chart,
+    addMyClassifyDia,
+    SaveChartOther,
+    setEnNameDia,
+  },
+  mixins: [leftMixin, chartSetMixin],
+  computed: {
+    /* 分享地址 */
+    linkUrl() {
+      const LINK_CHART_URL = process.env.CHART_LINK;
+      return `${LINK_CHART_URL}?code=${this.chartInfo.UniqueCode}&fromType=share?&lang=${this.currentLang}`;
+    },
+  },
+  data() {
+    return {
+      showData: false,
+      refreshLoading: false,
+      search_txt: "",
+      searchOptions: [],
+      isSlideLeft: false, //左侧分类收起
+
+      select_node: "", //节点唯一标识code
+      select_classify: "",
+      new_label: "", //双击修改的value
+      treeData: [], //分类数据
+      defaultShowNodes: [], //展开节点
+      defaultProp: {
+        label: "ChartClassifyName",
+        children: "Children",
+      }, //树结构配置项
+      dynamicNode: null,
+
+      /* 分类弹窗 */
+      dialog_title: "",
+      classifyDia: false, //
+      classifyForm: {},
+
+      select_id: "", //选中的图表id
+      chartInfo: {},
+      chart_title: "", //图表标题 双击标题修改时来存储最新值
+
+      isAddMyChart: false, //加入图库弹窗
+      add_chart_id: "", //要加入的图表
+      add_ids: [], //加入时已有的分类
+
+      /* 图表列表 */
+      publicHaveMove: true, //是否还有列表数据
+      chartList: [],
+      chart_total: 0,
+      chart_page: 1,
+      chart_pages_size: 16,
+
+      search_page: 1,
+      search_have_more: false,
+      current_search: "",
+
+      isOnlyMe: false, //仅仅看我的
+
+      classify_tab: 0, //分类类型
+    };
+  },
+  methods: {
+    /* 添加图表 */
+    goAddChart() {
+      if (!this.treeData.length) return this.$message.warning("请先添加分类");
+      this.$router.push({ path: "/relevancechartEditor" });
+    },
+
+    /* 获取分类 */
+    getTreeData(params = null) {
+      chartRelevanceApi
+        .classifyList({
+          IsShowMe: this.isOnlyMe,
+          Source: this.classify_tab ? 4 : 3,
+        })
+        .then((res) => {
+          const { Ret, Data } = res;
+          if (Ret !== 200) return;
+
+          this.showData = true;
+          this.treeData = Data.AllNodes || [];
+          this.$nextTick(() => {
+            /* 新增完成后 处理树展开和选中 */
+            params && this.selectCurrentNode(params);
+          });
+        });
+    },
+
+    changeTab(index) {
+      (this.classify_tab = index), this.getTreeData();
+      this.select_id = "";
+      this.chart_page = 1;
+      this.getPublicList();
+    },
+
+    /* 搜索 */
+    searchHandle(query) {
+      this.search_page = 1;
+      this.current_search = query;
+      this.searchApi(this.current_search);
+    },
+
+    searchApi(query, page = 1) {
+      /* 查找列表 */
+      chartRelevanceApi
+        .searchChart({
+          Keyword: query,
+          IsShowMe: this.isOnlyMe,
+          Source: this.classify_tab ? 4 : 3,
+          CurrentIndex: page,
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          const { List, Paging } = res.Data;
+          this.search_have_more = page < Paging.Pages;
+          this.searchOptions =
+            page === 1 ? List : [...this.searchOptions, ...List];
+        });
+    },
+
+    /* 聚焦获取当前检索 */
+    inputFocusHandle(e) {
+      this.search_page = 1;
+      this.current_search = e.target.value;
+      if (this.current_search) {
+        this.searchApi(this.current_search);
+      } else {
+        this.searchOptions = [];
+      }
+    },
+
+    searchLoad() {
+      if (!this.search_have_more) return;
+      this.searchApi(this.current_search, ++this.search_page);
+    },
+
+    /* 选中分类变化时 */
+    nodeChange({ UniqueCode, ChartInfoId, ChartClassifyId }, node) {
+      this.search_txt = "";
+      this.select_node = UniqueCode;
+      this.select_classify = !ChartInfoId ? ChartClassifyId : 0;
+      // if(this.select_id !== ChartInfoId) {
+      this.select_id = ChartInfoId || 0;
+      // }
+      this.resetNodeStyle(node);
+      this.dynamicNode = node;
+    },
+
+    /* 添加一级目录 */
+    addLevelOneHandle() {
+      this.dialog_title = "添加";
+      this.classifyForm = {
+        classify_name: "",
+      };
+      this.classifyDia = true;
+    },
+
+    /* 编辑节点 */
+    editNode(node, { ChartClassifyName, ChartClassifyId }) {
+      this.dialog_title = "编辑";
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: ChartClassifyName,
+        classify_id: ChartClassifyId,
+      };
+      this.classifyDia = true;
+    },
+
+    /* 删除节点校验 */
+    async removeNode(node, { ChartClassifyId, ChartInfoId }) {
+      const { Data } = await chartRelevanceApi.classifyDelCheck({
+        ChartClassifyId,
+      });
+
+      const { DeleteStatus } = Data;
+
+      DeleteStatus === 1
+        ? this.$confirm("该分类下关联表图表不可删除", "删除失败", {
+            confirmButtonText: "知道了",
+            showCancelButton: false,
+            type: "error",
+          })
+        : DeleteStatus === 0
+        ? this.$confirm("确定删除当前分类吗?", "提示", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+          }).then(() => {
+            this.delApi(ChartClassifyId, ChartInfoId);
+          })
+        : null;
+    },
+
+    /* 删除方法 */
+    delApi(ChartClassifyId, ChartInfoId, type = "") {
+      chartRelevanceApi
+        .classifyDel({
+          ChartClassifyId,
+          ChartInfoId,
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          this.$message.success(res.Msg);
+
+          if (!res.Data.ChartInfoId) this.select_id = "";
+
+          //删除自动显示下一张
+          type == "del_chart" && res.Data.ChartInfoId
+            ? this.getTreeData({
+                code: res.Data.UniqueCode,
+                id: res.Data.ChartInfoId,
+              })
+            : this.getTreeData();
+        });
+    },
+
+    /* 分类成功回调 */
+    classifyCallback(type) {
+      this.getTreeData();
+
+      if (type === "add") {
+        //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
+        let code = this.add_parent_id;
+        let flag = this.defaultShowNodes.some((item) => item === code);
+        // console.log(flag)
+        !flag && this.defaultShowNodes.push(code);
+        this.add_parent_id = "";
+      }
+    },
+
+    /* 保存图表 */
+    saveChartHandle: _.debounce(async function () {
+      const { Ret } = await chartRelevanceApi.chartSave({
+        ChartInfoId: this.chartInfo.ChartInfoId,
+        LeftMin: String(this.chartLimit.min),
+        LeftMax: String(this.chartLimit.max),
+      });
+
+      if (Ret !== 200) return;
+      this.$message.success("保存成功");
+      this.getTreeData();
+      //关联图表和图片
+      this.setChartImage();
+    }, 300),
+
+    //只看我的状态切换
+    onlyMeHandler() {
+      this.getTreeData();
+      this.getPublicList();
+    },
+
+    /* 获取图表列表 */
+    getPublicList() {
+      chartRelevanceApi
+        .getChartList({
+          CurrentIndex: this.chart_page,
+          PageSize: this.chart_pages_size,
+          ChartClassifyId: this.select_classify || 0,
+          IsShowMe: this.isOnlyMe,
+          Source: this.classify_tab ? 4 : 3,
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+
+          this.publicHaveMove = res.Data
+            ? this.chart_page < res.Data.Paging.Pages
+            : false;
+          this.chartList = res.Data
+            ? this.chart_page === 1
+              ? res.Data.List
+              : [...this.chartList, ...res.Data.List]
+            : [];
+          this.chart_total = res.Data ? res.Data.Paging.Totals : 0;
+        });
+    },
+
+    getChartInfo() {
+      this.getDetailHandle();
+    },
+
+    /* 获取图表详情 */
+    getDetailHandle() {
+      chartRelevanceApi
+        .chartDetail({
+          ChartInfoId: this.select_id,
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+
+          this.chartInfo = res.Data.ChartInfo;
+          this.tableData = res.Data.EdbInfoList;
+          this.relevanceChartData = {
+            ChartInfo: res.Data.ChartInfo,
+            EdbInfoList: res.Data.EdbInfoList,
+            XEdbIdValue:
+              this.chartInfo.Source === 3
+                ? res.Data.XEdbIdValue
+                : res.Data.DataResp.XDateTimeValue,
+            CorrelationChartInfo: res.Data.CorrelationChartInfo,
+            YDataList: [
+              {
+                Value:
+                  this.chartInfo.Source === 3
+                    ? res.Data.YDataList[0].Value
+                    : res.Data.DataResp.YDataList[0].Value,
+                Color: "#00f",
+                Name: res.Data.ChartInfo.ChartName,
+                NameEn: res.Data.ChartInfo.ChartNameEn,
+              },
+            ],
+          };
+          this.initRelevanceChartData();
+        });
+    },
+
+    /* 删除图表 */
+    delChartHandle() {
+      const { ChartClassifyId, ChartInfoId } = this.chartInfo;
+      this.$confirm("删除后该图表将不能再引用,确认删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.delApi(ChartClassifyId, ChartInfoId, "del_chart");
+        })
+        .catch(() => {});
+    },
+
+    /* 刷新图表 */
+    refreshHandle() {
+      this.refreshLoading = this.$loading({
+        lock: true,
+        target: ".main-right",
+        text: "刷新图表中...",
+        spinner: "el-icon-loading",
+        background: "rgba(255, 255, 255, 0.8)",
+      });
+      chartRelevanceApi
+        .refreshChart({
+          ChartInfoId: this.chartInfo.ChartInfoId,
+        })
+        .then((res) => {
+          this.refreshLoading.close();
+          if (res.Ret === 200) {
+            this.getDetailHandle();
+            this.$message.success(res.Msg);
+          }
+        });
+    },
+
+    /* 编辑图表 */
+    editChartHandle() {
+      this.$router.push({
+        path: "/relevancechartEditor",
+        query: {
+          code: this.chartInfo.UniqueCode,
+        },
+      });
+    },
+
+    /* 点击复制先用canvas画出 转成图片在放到粘贴板中 */
+    copyChartHandle: _.debounce(function (type) {
+        let chartsName =
+          this.currentLang == "ch"
+            ? this.chartInfo.ChartName
+            : this.chartInfo.ChartNameEn;
+        let { heightNum, widthNum, newTitle, dynamic_copyOptions } =
+          this.dynamicWidthAndHeight(
+            type,
+            this.chartInfo.ChartType,
+            chartsName,
+            this.relevanceChartData.EdbInfoList.length
+          );
+        const chartType = "seasonLegend";
+        // 英文转SVG设置变动
+        if (this.currentLang == "en") {
+          // 如果竖轴坐标单位为'英文单位',表示客户没填,转成svg时置为空
+          this.$refs.chartRef.chart.options.yAxis.forEach((it) => {
+            if (it.title.text == "英文单位") it.title.text = "";
+          });
+        }
+        // widthNum=this.$refs.chartRef.chart.chartWidth*2
+        // heightNum=(this.$refs.chartRef.chart.chartHeight*2)+36
+        let svg = this.$refs.chartRef.chart.getSVG({
+          chart: {
+            width: widthNum,
+            height: heightNum,
+            backgroundColor: "rgba(255, 255, 255, 0)",
+          },
+          title: {
+            text: newTitle,
+            margin: 10,
+            style: {
+              fontSize: "18px",
+            },
+          },
+          xAxis: [
+            {
+              ...this.options.xAxis,
+              offset: -(heightNum - 136) / 2,
+            },
+          ],
+          legend: {
+            ...copyOtherOptions[chartType],
+            ...dynamic_copyOptions[chartType],
+          },
+        });
+        // console.log(svg);
+        this.copyBlobItem(widthNum, heightNum, svg, type);
+    }, 500),
+  },
+  mounted() {
+    if (this.$route.query.code) {
+      this.getTreeData({
+        code: this.$route.query.code,
+        id: Number(this.$route.query.id),
+      });
+    } else {
+      this.getTreeData();
+      this.getPublicList();
+    }
+
+    window.addEventListener("resize", this.reloadRightWid);
+  },
+  destroyed() {
+    window.removeEventListener("resize", this.reloadRightWid);
+  },
+};
+</script>
+<style lang="scss" scoped>
+* {
+  box-sizing: border-box;
+}
+$mini-font: 12px;
+$normal-font: 14px;
+.comodity-chart-container {
+  .slide-icon {
+    padding: 20px 0;
+    /* display: block; */
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+    border-radius: 5px;
+    cursor: pointer;
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: 99;
+    &:hover {
+      background-color: rgba(0, 0, 0, 0.05);
+    }
+    &.slide-left {
+      right: 0;
+    }
+    &.slide-right {
+      left: 0;
+    }
+  }
+  .data-sheet-main {
+    display: flex;
+
+    .main-left {
+      width: 400px;
+      min-width: 300px;
+      background: #fff;
+      margin-right: 20px;
+      border: 1px solid #ececec;
+      border-radius: 4px;
+      box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+      height: calc(100vh - 120px);
+      overflow: hidden;
+      position: relative;
+      box-sizing: border-box;
+
+      .datasheet_top {
+        padding: 20px;
+        background: #fff;
+        border: 1px solid #ececec;
+        box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+        margin-bottom: 20px;
+      }
+      .search-cont {
+        padding: 0 20px;
+      }
+
+      .left-tab {
+        display: flex;
+        align-items: center;
+        padding: 20px 20px 0;
+        .tab {
+          cursor: pointer;
+          font-size: 16px;
+          border-bottom: 2px solid transparent;
+          margin-right: 40px;
+          padding-bottom: 5px;
+          &.act {
+            color: #409eff;
+            border-color: #409eff;
+          }
+          &:hover {
+            color: #409eff;
+          }
+        }
+      }
+
+      .tree-cont {
+        padding: 30px 20px;
+        max-height: calc(100vh - 320px);
+        overflow: auto;
+      }
+      .target_tree {
+        color: #333;
+        .custom-tree-node {
+          display: flex !important;
+          justify-content: space-between;
+          align-items: center;
+          display: block;
+          flex: 1;
+          .node_label {
+            margin-right: 2px;
+          }
+          .el-icon-view {
+            color: #409eff;
+            font-size: 18px;
+            margin-left: 5px;
+          }
+        }
+      }
+      .noDepart {
+        margin: 60px 0;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: #409eff;
+        font-size: 16px;
+        cursor: pointer;
+      }
+      .move-btn {
+        height: 100%;
+        width: 4px;
+        /* opacity: 0; */
+        position: absolute;
+        right: 0px;
+        top: 0;
+        &:hover {
+          cursor: col-resize;
+          /* background-color: orange */
+        }
+      }
+    }
+
+    .main-right {
+      width: 80%;
+      .chart-detail-wrapper {
+        height: calc(100vh - 120px);
+        border: 1px solid #ececec;
+        border-radius: 4px;
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+        overflow: auto;
+        background: #fff;
+        padding: 30px;
+        .bottom-min {
+          border: 1px solid #dcdfe6;
+          margin-bottom: 20px;
+          .right-actions {
+            /* max-width: 160px; */
+            height: 100%;
+            padding: 20px 10px;
+            border-left: 1px solid #dcdfe6;
+            li {
+              margin-bottom: 15px;
+            }
+            @media screen and (max-width: 1710px) {
+              font-size: 12px;
+            }
+            .span-item {
+              color: #409eff;
+              cursor: pointer;
+              &:hover {
+                text-decoration: underline;
+              }
+              .el-icon-collection,
+              .el-icon-document-copy {
+                color: #409eff;
+              }
+            }
+          }
+          .chart-show-cont {
+            padding: 0 160px 0 120px;
+            position: relative;
+            min-height: 400px;
+            .chart-title {
+              font-size: 16px;
+              font-weight: normal;
+              text-align: center;
+              margin-bottom: 10px;
+            }
+            .chart-author {
+              font-size: 14px;
+              color: #333;
+              position: absolute;
+              bottom: 0;
+              right: 50px;
+            }
+            .chartWrapper {
+              position: relative;
+              .range-cont {
+                position: absolute;
+                top: 13%;
+                .min-data-input {
+                  width: 60px;
+                  display: block;
+                }
+                &.left {
+                  left: -80px;
+                }
+                &.right {
+                  right: -65px;
+                }
+                &.rightTwo {
+                  right: -130px;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      .chart-list-cont {
+        color: #333;
+        .el-card .el-card__header,
+        .el-card__body {
+          padding: 10px;
+        }
+
+        .chartList-wrapper {
+          margin-top: 10px;
+          display: flex;
+          flex-wrap: wrap;
+          max-height: calc(100vh - 143px);
+          overflow: hidden;
+          overflow-y: auto;
+          .drag-cont {
+            width: 100%;
+            display: flex;
+            flex-wrap: wrap;
+          }
+          .dragShdow {
+            box-shadow: 0 1px 8px rgba(64, 158, 255, 0.8);
+            opacity: 0.5;
+          }
+          .sheet-item {
+            position: relative;
+            .item-top {
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+              font-size: 16px;
+              font-weight: 600;
+            }
+            .chart-img {
+              width: 100%;
+              height: 230px;
+              object-fit: contain !important;
+              cursor: pointer;
+            }
+            .item-bottom {
+              margin-top: 10px;
+              display: flex;
+              justify-content: space-between;
+              font-size: 12px;
+              color: #666;
+              .collected {
+                color: #f00;
+                cursor: pointer;
+              }
+              .join_txt {
+                color: #409eff;
+                cursor: pointer;
+              }
+            }
+          }
+        }
+        .nodata {
+          text-align: center;
+        }
+      }
+    }
+
+    @media screen and (min-width: 1711px) {
+      .min-data-input {
+        margin-top: 360px;
+      }
+    }
+    @media screen and (max-width: 1710px) {
+      .min-data-input {
+        margin-top: 290px;
+      }
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.comodity-chart-container {
+  .label-input .el-input__inner {
+    height: 25px;
+    line-height: 25px;
+    padding: 0 10px;
+  }
+
+  .range-cont .el-input__inner {
+    padding: 0 3px;
+  }
+
+  .el-tree__drop-indicator {
+    height: 3px;
+    background-color: #409eff;
+  }
+  .el-tree-node__content {
+    margin-bottom: 14px !important;
+  }
+  .el-tree-node__children {
+    .el-tree-node {
+      /* margin-bottom: 8px !important; */
+      margin-bottom: 0px !important;
+      padding-left: 18px;
+    }
+    .el-tree-node__content {
+      margin-bottom: 5px !important;
+      padding-left: 0 !important;
+    }
+  }
+  .expanded.el-icon-caret-right:before {
+    content: url("../../assets/img/set_m/down.png") !important;
+  }
+  .el-icon-caret-right:before {
+    content: url("../../assets/img/set_m/slide.png") !important;
+  }
+  .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+    content: "" !important;
+  }
+  .el-tree-node__expand-icon.expanded {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  .el-tree-node.is-current > .el-tree-node__content {
+    background-color: #f0f4ff !important;
+  }
+  .el-tree-node__content {
+    padding-right: 10px !important;
+  }
+}
+</style>

+ 449 - 0
src/views/chartRelevance_manage/mixins/classifyMixin.js

@@ -0,0 +1,449 @@
+import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
+import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { dataBaseInterface } from '@/api/api.js';
+
+export default {
+  data() {
+    return {};
+  },
+  watch: {
+    /* 设置动态右侧区域宽度 */
+    isSlideLeft(newval) {
+      this.$nextTick(() => {
+        this.reloadRightWid();
+      });
+    },
+    /* 图表id */
+    select_id(newval) {
+      if (newval) {
+        this.currentLang = "ch";
+        this.getDetailHandle();
+      } else {
+        this.chartInfo = {};
+      }
+    },
+
+    select_classify(newval) {
+      if (this.$refs.chartListWrap) this.$refs.chartListWrap.$refs.listRef.scrollTop = 0;
+      if (newval) {
+        this.chart_page = 1;
+        this.getPublicList();
+      }
+    },
+
+    /* 搜索关键词 */
+    search_txt(newval) {
+      if (newval) {
+        let search_obj = this.searchOptions.find(
+          (_) => _.ChartInfoId === newval
+        );
+        let deep_arr = _.cloneDeep(this.treeData);
+        // 查找图表的分类父级id
+
+        let arr = this.findParentNodeHandle(deep_arr, search_obj.UniqueCode)
+          .slice(1)
+          .reverse(); // 父的父的父-父的父-父
+        this.defaultShowNodes = arr;
+        this.select_node = search_obj.UniqueCode;
+        this.$refs.treeRef.setCurrentKey(this.select_node);
+        // 重置筛选状态
+        this.select_id = newval;
+      }
+    },
+  },
+  directives: {
+    drag(el, bindings) {
+      el.onmousedown = function(e) {
+				var init = e.clientX;
+				var box = $("#box")[0]
+				let total_wid = box.offsetWidth
+        var left = $("#left")[0];
+        var right = $("#right")[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function(e) {
+          var end = e.clientX;
+					if(end > 310){
+            var newWidth = end - init + initWidth;
+						// right.style.width = total_wid-end+80 +'px'
+						right.style.width = total_wid - newWidth + 'px'
+            left.style.width = newWidth + "px";
+          }else{
+            end = 350;
+            // 最小宽度300
+            left.style.width = 300 + "px";
+						// right.style.width = total_wid-300-20 +'px'
+          }
+        };
+        document.onmouseup = function() {
+          document.onmousemove = document.onmouseup = null;
+					e.releaseCapture && e.releaseCapture();
+        };
+				e.setCapture && e.setCapture();
+				return false;
+      };
+    }
+  },
+
+  methods: {
+    /* 根据unicode展开树结构并选中当前图表 重置图表配置 日期区间 */
+    selectCurrentNode({ code, id, type }) {
+      let deep_arr = _.cloneDeep(this.treeData);
+      // 查找图表的分类父级id
+      let arr = this.findParentNodeHandle(deep_arr, code).slice(1).reverse(); // 父的父的父-父的父-父
+      this.defaultShowNodes = arr;
+      this.select_node = code;
+      this.$refs.treeRef.setCurrentKey(this.select_node);
+      // // 重置筛选状态
+      this.select_id = id;
+    },
+
+    // 查找树节点所有父节点
+    findParentNodeHandle(arr, id) {
+      // 遍历取父级code push数组
+      for (let i of arr) {
+        if (i.UniqueCode === id) {
+          return [i.UniqueCode];
+        }
+        if (i.Children) {
+          let node = this.findParentNodeHandle(i.Children, id);
+          if (node) {
+            return node.concat(i.UniqueCode);
+          }
+        }
+      }
+    },
+
+    /* 拖动时node宽度跟随变化 */
+    resetNodeStyle: _.debounce(function(node) {
+			const tree = $('.target_tree')[0];
+			let width = tree.offsetWidth;
+			// let label_wid = width > 500 ? 'auto' : (width <= 300 && width < 360) ?  100 : 0.7*width;
+			let label_wid =
+				width > 500
+					? 'auto'
+					: width <= 260
+					? 90
+					: 0.7 * width;
+			this.$set(node, 'Nodewidth', label_wid + 'px');
+		},200),
+
+    	/* 双击label出现input修改框 */
+		editNodeLabel(data,type='') {
+        //目录名称可以双击修改
+        if(data.ChartInfoId) return
+        this.$set(data,'isEdit',true)
+        this.new_label = data.ChartClassifyName;
+        this.$nextTick(() => {
+          this.$refs.editVal.focus();
+        });
+		},
+
+    /* input失去焦点恢复node 修改最新的值*/
+		async changeValue(data) {
+      if(!this.new_label) return this.$message.warning('名称不能为空');
+      this.$set(data,'isEdit',false)
+
+      if(this.new_label !== data.ClassifyName) {
+        let res = this.$route.path === '/fittingEquationList'
+          ? await fittingEquationInterface.classifyEdit({
+              ChartClassifyId: data.ChartClassifyId,
+              ChartClassifyName: this.new_label
+            })
+          : this.$route.path === '/statisticFeatureList'
+          ? await statisticFeatureInterface.classifyEdit({
+              ChartClassifyId: data.ChartClassifyId,
+              ChartClassifyName: this.new_label
+            })
+          :await chartRelevanceApi.classifyEdit({
+              ChartClassifyId: data.ChartClassifyId,
+              ChartClassifyName: this.new_label
+            })
+
+        if(res.Ret !== 200) return
+  
+        this.getTreeData();
+      }
+    },
+
+    /* 拖拽完成 */
+    dropOverHandle(b, a, i, e) {
+      // console.log(i, a);
+      // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
+      // 一/二级目录
+      if ([1].includes(b.level)) this.handleMoveCatalogue(b, a, i, e);
+
+      // 指标层
+      if (b.level === 2) this.handleMoveSheet(b, a, i, e);
+    },
+
+    // 移动的为一级目录
+    async handleMoveCatalogue(b, a, i, e) {
+      let list = a.parent.childNodes,
+        targetIndex = 0,
+        PrevClassifyId = 0,
+        NextClassifyId = 0;
+
+      list.forEach((item, index) => {
+        if (item.data.ChartClassifyId === b.data.ChartClassifyId) {
+          targetIndex = index;
+          return;
+        }
+      });
+
+      if (targetIndex === 0) {
+        PrevClassifyId = 0;
+        NextClassifyId = list[targetIndex + 1].data.ChartClassifyId;
+      } else if (targetIndex === list.length - 1) {
+        PrevClassifyId = list[targetIndex - 1].data.ChartClassifyId;
+        NextClassifyId = 0;
+      } else {
+        PrevClassifyId = list[targetIndex - 1].data.ChartClassifyId;
+        NextClassifyId = list[targetIndex + 1].data.ChartClassifyId;
+      }
+
+      let params = {
+        ClassifyId: b.data.ChartClassifyId,
+        PrevClassifyId: PrevClassifyId,
+        NextClassifyId: NextClassifyId,
+      }
+
+      let res;
+      if(this.$route.path === '/chartrelevance') {
+        res=await chartRelevanceApi.classifyMove(params)
+      }else if(this.$route.path === '/fittingEquationList') {
+        res=await fittingEquationInterface.classifyMove(params)
+      }else if(this.$route.path === '/statisticFeatureList') {
+        res=await statisticFeatureInterface.classifyMove(params)
+      }
+
+      if (res.Ret !== 200) return;
+      this.$message.success("移动成功!");
+      this.getTreeData();
+    },
+
+    // 移动的为图表
+    async handleMoveSheet(b, a, i, e) {
+      let PrevChartId = 0,
+        NextChartId = 0,
+        targetIndex = 0,
+        list = a.parent.data.Children;
+      if (i === "inner") {
+        PrevChartId = 0;
+        NextChartId =
+          a.data.Children.length > 1 ? a.data.Children[1].ChartInfoId : 0;
+      } else {
+        list.forEach((item, index) => {
+          if (item.ChartInfoId === b.data.ChartInfoId) {
+            targetIndex = index;
+            return;
+          }
+        });
+
+        if (targetIndex === 0) {
+          PrevChartId = 0;
+          NextChartId = list[targetIndex + 1].ChartInfoId;
+        } else if (targetIndex === list.length - 1) {
+          PrevChartId = list[targetIndex - 1].ChartInfoId;
+          NextChartId = 0;
+        } else {
+          PrevChartId = list[targetIndex - 1].ChartInfoId;
+          NextChartId = list[targetIndex + 1].ChartInfoId;
+        }
+      }
+      let params = {
+        ChartClassifyId: a.data.ChartClassifyId,
+        ChartInfoId: b.data.ChartInfoId,
+        PrevChartInfoId: PrevChartId,
+        NextChartInfoId: NextChartId,
+      }
+
+      let res;
+      if(this.$route.path === '/chartrelevance') {
+        res=await chartRelevanceApi.chartMove(params)
+      }else if(this.$route.path === '/fittingEquationList') {
+        res=await fittingEquationInterface.chartMove(params)
+      }else if(this.$route.path === '/statisticFeatureList') {
+        res=await statisticFeatureInterface.chartMove(params)
+      }
+      
+      if (res.Ret !== 200) return;
+      this.$message.success("移动成功!");
+      this.getTreeData();
+
+    },
+
+    /* 拖拽覆盖添加背景色 */
+    dropMouseOver(node1, node2, e) {
+      if (
+        (node1.level === 2 && node2.level === 1) &&
+        (e.target.childNodes[0].className.includes("el-tree-node__content") ||
+          e.target.className.includes("el-tree-node__content"))
+      ) {
+        e.target.childNodes[0].className.includes("el-tree-node__content")
+          ? (e.target.childNodes[0].style.backgroundColor = "#409eff")
+          : (e.target.style.backgroundColor = "#409eff");
+      }
+    },
+
+    /* 拖拽离开/拖拽完成重置背景色 */
+    dropMouseLeave(node1, node2, e) {
+      let arrs = $(".el-tree-node__content");
+      for (let a of arrs) {
+        a.style.backgroundColor = "transparent";
+      }
+    },
+
+    // 树节点展开
+    handleNodeExpand(data) {
+      // 保存当前展开的节点
+      let flag = this.defaultShowNodes.some((item) => item === data.UniqueCode);
+
+      if (!flag) {
+        // 不存在则存到数组里
+        this.defaultShowNodes.push(data.UniqueCode);
+      }
+    },
+
+    // 树节点关闭
+    handleNodeCollapse(data) {
+      this.defaultShowNodes.some((item, index) => {
+        if (item === data.UniqueCode) {
+          // 删除关闭节点
+          this.defaultShowNodes.length = index;
+        }
+      });
+    },
+
+    /* 判断节点是否能被拖拽 */
+    canDragHandle(node) {
+      let canMove = true;
+      return canMove;
+    },
+
+    /* 判断节点是否能被拖入 */
+    canDropHandle(draggingNode, dropNode, type) {
+      let canDrop = false;
+      // 移动的是一级目录
+      if (draggingNode.level === 1 && dropNode.level === 1 &&type!=='inner') {
+        canDrop = true;
+      }
+
+      // 二级
+      if (draggingNode.level === 2) {
+        if (
+          (dropNode.level === 1 && type === "inner") ||
+          (dropNode.level === 2 && type !== "inner")
+        ) {
+          canDrop = true;
+        }
+      }
+
+      return canDrop;
+    },
+
+    /* 加载更多 */
+		loadMoreHandle: _.throttle(function() {
+			let scrollTop = this.$refs.chartListWrap.$refs.listRef.scrollTop;
+      let clientHeight = this.$refs.chartListWrap.$refs.listRef.clientHeight;
+      let scrollHeight = this.$refs.chartListWrap.$refs.listRef.scrollHeight;
+			if(scrollTop + clientHeight >= scrollHeight-10 && this.publicHaveMove){
+				this.chart_page++;
+				this.getPublicList();
+			}
+		},300),
+
+    /* 展开对应菜单 显示详情 */
+    detailShowHandle({ UniqueCode, ChartInfoId }) {
+      let params = {
+        code: UniqueCode,
+        id: ChartInfoId,
+      };
+      this.selectCurrentNode(params);
+      this.select_classify = 0;
+    },
+
+    /* 加入我的图库 */
+    addMychartHandle(item) {
+      this.add_chart_id = item.ChartInfoId;
+      //已有的分类ids
+      this.add_ids = item.MyChartClassifyId
+        ? item.MyChartClassifyId.split(",").map((item) => Number(item))
+        : [];
+      this.isAddMyChart = true;
+    },
+
+    /* 加入我的图库成功 */
+    addMySuccess(params) {
+      this.isAddMyChart = false;
+
+      /* 判断是详情还是图库列表 */
+      if (this.select_id) {
+        this.chartInfo.IsAdd = true;
+        this.chartInfo.MyChartId = params.MyChartInfoId;
+        this.chartInfo.MyChartClassifyId = params.MyChartClassifyId;
+      } else {
+        this.chartList.forEach((item) => {
+          if (item.ChartInfoId === this.add_chart_id) {
+            item.IsAdd = true;
+            item.MyChartId = params.MyChartInfoId;
+            item.MyChartClassifyId = params.MyChartClassifyId;
+          }
+        });
+      }
+    },
+
+    /* 重绘右侧区域宽度 */
+    reloadRightWid() {
+      let total_wid = $('.data-sheet-main')[0].offsetWidth;
+      let left = $('#left')[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + 'px';
+      $('#right')[0].style.width = rigtWid;
+
+    },
+
+    /* 点击保存时关联图表和截取的图片 */
+    setChartImage() {
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart: {
+          width: this.$refs.chartRef.chart.chartWidth,
+          height: this.$refs.chartRef.chart.chartHeight,
+        },
+      });
+      let form = new FormData();
+      form.append("Img", svg);
+      this.setImageHandle(form);
+    },
+
+    async setImageHandle(form) {
+      let { Data } = await dataBaseInterface.uploadImgSvg(form);
+
+      await dataBaseInterface.setChartImage({
+        ChartInfoId: this.select_id,
+        ImageUrl: Data.ResourceUrl,
+      });
+    },
+
+    copyChartConfirm(type) {
+      type !== "url" && this.copyChartHandle(type);
+      
+      type == "url" && this.shareUrl();
+    },
+
+    /* 分享图表 */
+    shareUrl() {
+      var clipboard = new this.Clipboard(".shareLink");
+      clipboard.on("success", (e) => {
+        console.log(e);
+        this.$message.success("复制链接成功");
+        e.clearSelection(); // 释放内存
+        clipboard.destroy();
+      });
+      // // 浏览器不支持
+      clipboard.on("error", (e) => {
+        this.$message.warning("浏览器暂不支持");
+        // 释放内存
+        clipboard.destroy();
+      });
+    },
+  },
+};

+ 876 - 0
src/views/chartRelevance_manage/relevanceChartEditor.vue

@@ -0,0 +1,876 @@
+<template>
+  <div class="commodity-chart-editor-container" id="box">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+    <div class="left-cont" v-show="!isSlideLeft" id="left">
+      <div class="left-top">
+        <el-button type="primary" plain @click="$router.back()">取消</el-button>
+      </div>
+      <div class="left-min">
+        <el-form
+          ref="diaForm"
+          label-position="top"
+          label-width="80px"
+          :model="chartInfo"
+          :rules="chartRules"
+        >
+          <el-form-item class="label-left" label="指标A" prop="EdbInfoIdA">
+              <selectTarget  
+                :defaultId="chartInfoData.EdbInfoList?chartInfoData.EdbInfoList[0].EdbInfoId:''"
+                :defaultOpt="chartInfoData.EdbInfoList?[chartInfoData.EdbInfoList[0]]:[]"
+                :defaultType="chartInfoData.EdbInfoList?chartInfoData.EdbInfoList[0].EdbInfoCategoryType:''"
+                @select="handleSelectTargetA"
+              />
+          </el-form-item>
+          <el-form-item class="label-left" label="指标B" prop="EdbInfoIdB">
+              <selectTarget 
+                :defaultId="chartInfoData.EdbInfoList?chartInfoData.EdbInfoList[1].EdbInfoId:''"
+                :defaultOpt="chartInfoData.EdbInfoList?[chartInfoData.EdbInfoList[1]]:[]" 
+                :defaultType="chartInfoData.EdbInfoList?chartInfoData.EdbInfoList[1].EdbInfoCategoryType:''"
+                @select="handleSelectTargetB"
+              />
+          </el-form-item>
+        </el-form>
+
+        <div class="section">
+          <div>曲线图</div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:50px;">时间:</span>
+            <el-select
+                style="max-width: 120px;flex:1;"
+                v-model="chartInfo.Curve.DateType"
+                placeholder="请选择"
+                @change="getPreviewSplineChart"
+            >
+              <el-option
+                  v-for="item in yearSelector"
+                  :key="item.value"
+                  :label="item.name"
+                  :value="item.value"
+              />
+            </el-select>
+            <date-picker
+              v-model="chartInfo.Curve.Date"
+              v-show="chartInfo.Curve.DateType===5"
+              style="width:150px;margin-left:10px;"
+              type="month"
+              range
+              value-type="format"
+              placeholder="请选择时间段"
+              @change="dateChange"
+            />
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:50px;">左轴:</span>
+            <el-input
+              style="flex:2;margin-left:5px;margin-right:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Curve.LeftMin"
+              @change="val => { chartInfo.Curve.LeftMin=Number(val);changeSplineOption() }"
+            />
+            <span>至</span>
+            <el-input
+              style="flex:2;margin-left:5px;"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Curve.LeftMax"
+              @change="val => { chartInfo.Curve.LeftMax=Number(val);changeSplineOption() }"
+            />
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:50px;">右轴:</span>
+            <el-input
+              style="flex:2;margin-left:5px;margin-right:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Curve.RightMin"
+              @change="val => { chartInfo.Curve.RightMin=Number(val);changeSplineOption() }"
+            />
+            <span>至</span>
+            <el-input
+              style="flex:2;margin-left:5px;"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Curve.RightMax"
+              @change="val => { chartInfo.Curve.RightMax=Number(val);changeSplineOption() }"
+            />
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:50px;">指标B:</span>
+            <el-checkbox v-model="chartInfo.Curve.IsOrder"  @change="getPreviewSplineChart">逆序</el-checkbox>
+          </div>
+          <div class="section-item" style="align-items: flex-start;margin-left:50px;">
+            <el-radio
+              v-model="chartInfo.Curve.EdbInfoType"
+              :label="true"
+              style="margin-right:10px;"
+              @change="getPreviewSplineChart"
+            >标准指标</el-radio>
+            <div>
+              <el-radio
+                v-model="chartInfo.Curve.EdbInfoType"
+                :label="false"
+                @change="getPreviewSplineChart"
+              >领先指标</el-radio>
+              <div style="margin-top: 10px;" v-if="chartInfo.Curve.EdbInfoType===false">
+                领先
+                <el-input
+                  style="width: 60px"
+                  size="mini"
+                  type="number"
+                  v-model="chartInfo.Curve.LeadValue"
+                  @change="(val) => { chartInfo.Curve.LeadValue = Number(val);getPreviewSplineChart()}"
+                ></el-input>
+                <el-select
+                  v-model="chartInfo.Curve.LeadUnit"
+                  placeholder=""
+                  size="mini"
+                  style="width: 60px"
+                  @change="getPreviewSplineChart"
+                >
+                  <el-option
+                      v-for="item in unitOpt"
+                      :key="item.val"
+                      :label="item.label"
+                      :value="item.val"
+                  />
+                </el-select>
+              </div>
+            </div>
+          </div>
+        </div>  
+
+        <div class="section">
+          <div>相关性</div>
+          <div class="section-item">
+            <div style="flex-shrink:0;min-width:70px"><span style="color:red;font-size:18px;">*</span>计算窗口</div>
+            <el-input
+              style="flex:2;margin-left:5px;margin-right:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Correlation.CalculateValue"
+              @change="val => { chartInfo.Correlation.CalculateValue = Number(val); }"
+            />
+            <el-select
+                style="flex:1"
+                v-model="chartInfo.Correlation.CalculateUnit"
+                placeholder="请选择"
+            >
+            <el-option
+                v-for="item in unitOpt"
+                :key="item.val"
+                :label="item.label"
+                :value="item.val"
+            />
+            </el-select>
+          </div>
+          <div class="section-item">
+            <div style="flex-shrink:0;min-width:70px"><span style="color:red;font-size:18px;">*</span>分析周期</div>
+            <el-input
+              style="flex:2;margin-left:5px;margin-right:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Correlation.LeadValue"
+              @change="val => { chartInfo.Correlation.LeadValue = Number(val); }"
+            />
+            <el-select
+                style="flex:1"
+                v-model="chartInfo.Correlation.LeadUnit"
+                placeholder="请选择"
+            >
+            <el-option
+                v-for="item in unitOpt"
+                :key="item.val"
+                :label="item.label"
+                :value="item.val"
+            />
+            </el-select>
+          </div>
+        </div>
+
+
+      <div class="section" v-for="(item,index) in chartInfo.RollingCorrelation" :key="index">
+        <div>滚动相关性{{index+1}}</div>
+        <div class="section-item">
+          <span style="flex-shrink:0;min-width:70px">计算窗口</span>
+          <el-input
+            style="flex:2;margin-left:5px;margin-right:10px"
+            :step="1"
+            type="number"
+            v-model="item.CalculateValue"
+            @change="val => { item.CalculateValue = Number(val); }"
+          />
+          <el-select
+              style="flex:1"
+              v-model="item.CalculateUnit"
+              placeholder="请选择"
+          >
+          <el-option
+              v-for="item in unitOpt"
+              :key="item.val"
+              :label="item.label"
+              :value="item.val"
+          />
+          </el-select>
+        </div>
+        <div class="section-item">
+          <span style="flex-shrink:0;min-width:70px">B领先A</span>
+          <el-input
+            style="flex:2;margin-left:5px;margin-right:10px"
+            :step="1"
+            type="number"
+            v-model="item.LeadValue"
+            @change="val => { item.LeadValue = Number(val); }"
+          />
+          <el-select
+              style="flex:1"
+              v-model="item.LeadUnit"
+              placeholder="请选择"
+          >
+          <el-option
+              v-for="item in unitOpt"
+              :key="item.val"
+              :label="item.label"
+              :value="item.val"
+          />
+          </el-select>
+        </div>
+      </div>
+
+        <el-button type="primary" style="float:right" @click="handlePreviewChart">确定</el-button>
+      </div>
+      <span
+        class="move-btn resize"
+        v-drag
+        id="resize"
+        @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+      ></span>
+      <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+        <i class="el-icon-d-arrow-left"></i>
+      </span>
+    </div>
+    <div
+      class="right-cont"
+      id="right"
+      :style="isSlideLeft ? 'width:100%' : `width:80%`"
+    >
+      <div
+        class="chart-min-cont"
+        v-if="chartBatchData"
+      >
+        <!-- v-if="chartBatchData" -->
+        <!-- <el-row> -->
+          <div class="card-wrapper">
+            <chartCard 
+              :entryType="1"
+              ref="chartCard1"
+              :data="chartBatchData.CurveData"
+              :settings="chartInfo"
+              :isChartAdd="buttonAuth.isCurveChartAdd"
+              @saveChart="saveChartToBaseHandle"
+            />
+          </div>
+          <div class="card-wrapper" v-if="chartBatchData.CorrelationData">
+            <chartCard 
+              :entryType="2"
+              ref="chartCard2"
+              :data="chartBatchData.CorrelationData"
+              :settings="chartInfo"
+              :isChartAdd="buttonAuth.isRelevanceChartAdd"
+              @saveChart="saveChartToBaseHandle"
+            />
+          </div>
+          <template v-if="chartBatchData.RollingCorrelationData">
+            <div class="card-wrapper" v-if="chartBatchData.RollingCorrelationData[0]">
+              <chartCard 
+                :entryType="3"
+                ref="chartCard3"
+                :data="chartBatchData.RollingCorrelationData[0]"
+                :settings="chartInfo"
+                :isChartAdd="buttonAuth.isRollChartAdd"
+                :isEdbAdd="buttonAuth.isRollEdbAdd"
+                @saveChart="saveChartToBaseHandle"
+                @saveEdb="saveEdbToBaseHandle"
+              />
+            </div>
+            <div class="card-wrapper" v-if="chartBatchData.RollingCorrelationData[1]">
+              <chartCard 
+                :entryType="4"
+                ref="chartCard4"
+                :data="chartBatchData.RollingCorrelationData[1]"
+                :settings="chartInfo"
+                :isChartAdd="buttonAuth.isRollChartTwoAdd"
+                :isEdbAdd="buttonAuth.isRollEdbTwoAdd"
+                @saveChart="saveChartToBaseHandle"
+                @saveEdb="saveEdbToBaseHandle"
+              />
+            </div>
+          </template>
+      </div>
+
+      <div class="nodata" v-else>
+        <img
+          src="~@/assets/img/data_m/table_no.png"
+          alt=""
+          style="display: block; width: 140px; height: 148px; margin: 0 auto"
+        />
+        暂无信息
+      </div>
+    </div>
+
+    <!-- 图表保存入库 -->
+    <saveChartToBase
+      :isShow.sync="isSaveChartToBase"
+      :source="saveSource"
+      :saveScence="saveScence"
+      :chartData="chartData"
+      @saveBack="saveChartBack"
+    />
+
+    <!-- 指标保存入库 -->
+    <saveEdbToBase
+      :isShow.sync="isSaveEdbToBase"
+      :source="saveSource"
+      :saveScence="saveScence"
+      :chartData="chartData"
+      @saveBack="saveEdbBack"
+    />
+  </div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+import {yearSelector} from '@/utils/defaultOptions';
+import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
+import selectTarget from './components/selectTarget.vue'
+import chartCard from './components/chartCard.vue';
+import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
+import saveChartToBase from './components/saveChartTobaseDia.vue';
+import saveEdbToBase from './components/saveEdbToBaseDia.vue'
+export default {
+  components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase },
+  directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 300 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    },
+  },
+  data() {
+    return {
+      chart_code: this.$route.query.code || '',
+      isSlideLeft: false,
+      chartInfoData: {},
+      chartBatchData:null,
+
+      yearSelector: [
+        ...yearSelector,
+        { name: '自定义',value: 5 }
+      ],
+      chartInfo: {
+        MultipleGraphConfigId: 0,
+        EdbInfoIdA: 0,
+        EdbInfoIdB: 0,
+        Curve: {
+          DateType:yearSelector[0].value,
+          Date: [],
+          StartDate: '',
+          EndDate: '',
+          LeftMin: 0,
+          LeftMax: 0,
+          RightMin: 0,
+          RightMax: 0,
+          IsOrder: false,
+          EdbInfoType: true,
+          LeadValue: 0,
+          LeadUnit: '天'
+        },
+        Correlation: {
+          LeadValue: 0,
+          LeadUnit: '天',
+          CalculateValue: 0,
+          CalculateUnit: '天'
+        },
+        RollingCorrelation: [
+          {
+            LeadValue: 0,
+            LeadUnit: '天',
+            CalculateValue: 0,
+            CalculateUnit: '天'
+          },
+          {
+            LeadValue: 0,
+            LeadUnit: '天',
+            CalculateValue: 0,
+            CalculateUnit: '天'
+          }
+        ]
+      },
+      unitOpt:[
+          {label:'年',val:'年'},
+          {label:'季',val:'季'},
+          {label:'月',val:'月'},
+          {label:'周',val:'周'},
+          {label:'天',val:'天'},
+      ],
+      operationType:'preview',
+      chartRules: {
+        EdbInfoIdA:[
+          {required: true, message: '指标A不能为空', trigger: 'blur'}
+        ],
+        EdbInfoIdB:[
+          {required: true, message: '指标B不能为空', trigger: 'blur'}
+        ],
+        leadValue: [
+          { required: true, message: '分析不能为空', trigger: 'blur' },
+        ],
+        timeValue:[
+            {required: true, message: '时间不能为空', trigger: 'blur'}
+        ]
+      },
+
+      isSave:false,//正在保存
+      buttonAuth: { //按钮控制
+        isCurveChartAdd: false,
+        isRelevanceChartAdd: false,
+        isRollChartAdd: false,
+        isRollEdbAdd: false,
+        isRollChartTwoAdd: false,
+        isRollEdbTwoAdd: false,
+      },
+
+      isShowSaveOther: false,
+
+      /* 图表入库 */
+      isSaveChartToBase: false,
+      saveSource:0,//图表位置1 2 3 4
+      chartData: {},
+      saveScence: '',//另存为
+
+       /* 指标入库 */
+      isSaveEdbToBase: false,
+
+    };
+  },
+  methods: {
+
+    async getOptionDetail() {
+      if(!this.chart_code) return
+      const res = await chartRelevanceApi.getOptionByCode({ UniqueCode: this.chart_code });
+
+      if(res.Ret !== 200) return 
+
+      this.chartInfoData = {
+        EdbInfoList: res.Data.EdbInfoList
+      }
+
+      const { MultipleGraphConfigId,EdbInfoIdA,EdbInfoIdB,Curve,Correlation,RollingCorrelation } = res.Data.MultipleGraphConfig;
+      this.chartInfo = {
+        MultipleGraphConfigId,
+        EdbInfoIdA,
+        EdbInfoIdB,
+        Curve: {
+          ...JSON.parse(Curve),
+          Date: [JSON.parse(Curve).StartDate,JSON.parse(Curve).EndDate],
+        },
+        Correlation: JSON.parse(Correlation),
+        RollingCorrelation: JSON.parse(RollingCorrelation)
+      }
+
+      this.buttonAuth =  {
+        isCurveChartAdd: res.Data.ChartMappingList.some(_ => _.MultipleLocationSource===1),
+        isRelevanceChartAdd: res.Data.ChartMappingList.some(_ => _.MultipleLocationSource===2),
+        isRollChartAdd: res.Data.ChartMappingList.some(_ => _.MultipleLocationSource===3),
+        isRollEdbAdd: res.Data.EdbMappingList.some(_ => _.MultipleLocationSource===3),
+        isRollChartTwoAdd: res.Data.ChartMappingList.some(_ => _.MultipleLocationSource===4),
+        isRollEdbTwoAdd: res.Data.EdbMappingList.some(_ => _.MultipleLocationSource===4)
+      }
+
+      this.getPreviewChartData(); 
+    },
+
+    //校验规则
+    checkValue() {
+      //只用于校验规则条件大小
+      let checkBool = true;
+      const valueMap = {
+        '年': 365,
+        '季': 90,
+        '月': 30,
+        '周': 7,
+        '天': 1
+      }
+      const { Correlation,RollingCorrelation } = this.chartInfo;
+      if(Correlation.CalculateValue*valueMap[Correlation.CalculateUnit] < Correlation.LeadValue*valueMap[Correlation.LeadUnit]*2) {
+        this.chartInfo.Correlation.CalculateValue = '';
+        this.$message.warning('相关性计算窗口必须≥2*分析周期')
+        checkBool = false
+      }
+      // else if(RollingCorrelation[0].CalculateValue*valueMap[RollingCorrelation[0].CalculateUnit] >= Correlation.CalculateValue*valueMap[Correlation.CalculateUnit]) {
+      //   this.chartInfo.RollingCorrelation[0].CalculateValue = '';
+      //   this.$message.warning('滚动相关性1计算窗口必须小于相关性计算窗口')
+      //   checkBool = false
+      // }
+      // else if(RollingCorrelation[1].CalculateValue*valueMap[RollingCorrelation[1].CalculateUnit] >= Correlation.CalculateValue*valueMap[Correlation.CalculateUnit]) {
+      //   this.chartInfo.RollingCorrelation[1].CalculateValue = '';
+      //   this.$message.warning('滚动相关性2计算窗口必须小于相关性计算窗口')
+      //   checkBool = false
+      // }
+      
+      return checkBool
+    },
+
+    dateChange(val) {
+      this.chartInfo.Curve.DateType = 5;
+      if(val[0]) {
+        this.chartInfo.Curve.StartDate = val[0];
+        this.chartInfo.Curve.EndDate = val[1];
+      }else {
+        this.chartInfo.Curve.StartDate = '';
+        this.chartInfo.Curve.EndDate = '';
+      }
+    },
+
+    // 确定保存图表配置
+    async handlePreviewChart(){
+      await this.$refs.diaForm.validate();
+      let checkBool = this.checkValue();
+  
+      if(!checkBool) return
+      let params = {
+       ...this.chartInfo 
+      }
+      const res = await chartRelevanceApi.chartOptionsSet(params);
+      if(res.Ret !== 200) return
+
+      const { MultipleGraphConfigId } = res.Data;
+      this.chartInfo.MultipleGraphConfigId = MultipleGraphConfigId;
+      this.getPreviewChartData()
+      
+    },
+
+    async getPreviewChartData(){
+      let params = {
+       ...this.chartInfo 
+      }
+      const res = await chartRelevanceApi.previewChartBatch(params);
+      if(res.Ret !== 200) return
+      this.chartBatchData = res.Data;
+          
+    },
+
+    /* 动态获取曲线图数据 */
+    async getPreviewSplineChart() {
+      if(!this.chartInfo.EdbInfoIdA || !this.chartInfo.EdbInfoIdB) return
+      let params = {
+       ...this.chartInfo 
+      }
+      const res = await chartRelevanceApi.previewSplineChart(params);
+      if(res.Ret !== 200) return
+      this.chartBatchData = this.chartBatchData ? {
+        ...this.chartBatchData,
+        CurveData: res.Data.CurveData
+      } : { CurveData: res.Data.CurveData};
+    },
+
+    /* 曲线配置变化时重绘 */
+    changeSplineOption() {
+      const { LeftMin,LeftMax,RightMin,RightMax,IsOrder } = this.chartInfo.Curve;
+      console.log(this.$refs.chartCard1.options)
+      this.$refs.chartCard1.options.yAxis[0].max = Number(LeftMax);
+      this.$refs.chartCard1.options.yAxis[0].min = Number(LeftMin);
+
+      this.$refs.chartCard1.options.yAxis[1].max = Number(RightMax);
+      this.$refs.chartCard1.options.yAxis[1].min = Number(RightMin);
+      this.chartBatchData.CurveData.EdbInfoList[1].IsOrder = IsOrder;
+    },
+
+    // A指标选择
+    async handleSelectTargetA(e){
+      if(!e) return
+      this.chartInfo.EdbInfoIdA=e.EdbInfoId;
+      const {max,min} = await this.getEdbDetail(e);
+      this.chartInfo.Curve.LeftMin = min;
+      this.chartInfo.Curve.LeftMax = max;
+      this.getPreviewSplineChart()
+    },
+
+    //选择指标后填入上下限
+    async getEdbDetail({EdbInfoId,EdbInfoType}) {
+       
+      const { Data } = EdbInfoType 
+      ? await preDictEdbInterface.edbDetail({EdbInfoId})
+      : await dataBaseInterface.calculateDetail({EdbInfoId})
+
+      return { 
+        max: EdbInfoType ? Data.MaxValue : Data.EdbInfoDetail.MaxValue,
+        min: EdbInfoType ? Data.MinValue : Data.EdbInfoDetail.MinValue,
+      }
+    },
+
+    // B指标选择
+    async handleSelectTargetB(e){
+      if(!e) return
+      this.chartInfo.EdbInfoIdB=e.EdbInfoId;
+      const {max,min} = await this.getEdbDetail(e);
+      this.chartInfo.Curve.RightMin = min;
+      this.chartInfo.Curve.RightMax = max;
+      this.getPreviewSplineChart()
+    },
+
+    reloadRightWid() {
+      let total_wid = $('#box')[0].offsetWidth;
+      let left = $('#left')[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + 'px';
+      $('#right')[0].style.width = rigtWid;
+    },
+
+    /* 保存指标入库 */
+    saveEdbToBaseHandle({type,chartData,scence}) {
+      this.saveSource = type;
+      this.chartData = chartData;
+      this.saveScence = scence;
+      this.isSaveEdbToBase = true;
+    },
+
+    /* 保存完指标 按钮控制 */
+    saveEdbBack({source}) {
+      if(source===3) this.buttonAuth.isRollEdbAdd = true;
+      else if(source===4)  this.buttonAuth.isRollEdbTwoAdd = true;
+    },
+
+    /* 保存图表 */
+    saveChartToBaseHandle({type,chartData,scence}) {
+      this.saveSource = type;
+      this.chartData = chartData;
+      this.saveScence = scence;
+      this.isSaveChartToBase = true;
+    },
+
+
+    /* 保存完图表 */
+    saveChartBack({source,id}) {
+      this.$message.success('保存成功');
+      this.setButtonAuth(source);
+      //封面图
+      this.$refs[`chartCard`+source].setChartImage(source,id)
+    },
+    
+    /* 保存图表后按钮控制 */
+    setButtonAuth(source) {
+      const sourceMap = {
+        1: 'isCurveChartAdd',
+        2: 'isRelevanceChartAdd',
+        3: 'isRollChartAdd',
+        4: 'isRollChartTwoAdd'
+      }
+      this.buttonAuth[sourceMap[source]] = true;
+    }
+  },
+  mounted() {
+    this.getOptionDetail();
+    window.addEventListener('resize', this.reloadRightWid);
+  },
+  destroyed() {
+    window.removeEventListener('resize', this.reloadRightWid);
+  }
+};
+</script>
+<style lang="scss">
+.commodity-chart-editor-container {
+  $font-small: 12px;
+  $font-normal: 14px;
+
+  display: flex;
+  * {
+    box-sizing: border-box;
+  }
+  .el-form--label-top .el-form-item__label {
+    padding: 0;
+  }
+  .label-left{
+      display: flex;
+      margin-top: 20px;
+      .el-form-item__label{
+          flex-shrink: 0;
+          margin-right: 10px;
+      }
+      .el-date-editor.el-input, .el-date-editor.el-input__inner{
+          width: auto;
+      }
+  }
+  .el-input-number .el-input__inner {
+    // padding: 0 34px 0 4px;
+  }
+  .target-other-name .el-input__inner {
+    padding: 0 30px 0 5px !important;
+    height: 40px !important;
+    line-height: 40px !important;
+  }
+  .el-color-picker--mini .el-color-picker__trigger {
+    width: 60px;
+    height: 25px;
+    padding: 0;
+  }
+  .el-color-picker--mini .el-color-picker__mask {
+    width: 60px;
+    height: 25px;
+  }
+
+  .slide-icon {
+    padding: 20px 0;
+    /* display: block; */
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+    border-radius: 5px;
+    cursor: pointer;
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: 99;
+    &:hover {
+      background-color: rgba(0, 0, 0, 0.05);
+    }
+    &.slide-left {
+      right: 0;
+    }
+    &.slide-right {
+      left: 0;
+    }
+  }
+  .left-cont {
+    width: 380px;
+    min-width: 380px;
+    background: #fff;
+    margin-right: 20px;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    height: calc(100vh - 113px);
+    overflow: hidden;
+    position: relative;
+    box-sizing: border-box;
+    .left-top {
+      padding: 15px 20px;
+      border-bottom: 1px solid #ececec;
+      box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+    }
+    .left-min {
+      padding: 20px;
+      max-height: calc(100vh - 190px);
+      overflow-y: auto;
+      
+      .section {
+        border-top: 1px dashed #DCDFE6;
+        margin-top: 20px;
+        padding-top: 15px;
+        .section-item{
+          display: flex;
+          align-items: center;
+          font-size: 14px;
+          color: #606266;
+          margin: 10px 0;
+        }
+      }
+
+      .left-bottom {
+        margin-top: 20px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+      }
+     
+    }
+    .move-btn {
+      height: 100%;
+      width: 4px;
+      position: absolute;
+      right: 0px;
+      top: 0;
+      &:hover {
+        cursor: col-resize;
+      }
+    }
+  }
+  .right-cont {
+    width: 80%;
+    /* =================== */
+    .chart-min-cont {
+      /* background: #fff; */
+      height: calc(100vh - 118px);
+      overflow-y: auto;
+      display: flex;
+      flex-wrap: wrap;
+      .card-wrapper {
+        width: 48%;
+        border: 1px solid #ececec;
+        border-radius: 4px;
+        background: #fff;
+        margin-bottom: 20px;
+        min-height: 350px;
+        &:nth-child(2n) {
+          margin-left: 15px;
+        } 
+        .card-item {
+          padding: 20px;
+          .top {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            margin-bottom: 15px;
+          }
+          .title {
+            /* max-width: 250px; */
+            font-size: 15px;
+            text-align: left;
+            margin: 10px 0;
+          }
+        }
+      }
+    }
+    .nodata {
+      height: calc(100vh - 120px);
+      background-color: #fff;
+      text-align: center;
+      font-size: 16px;
+      color: #666;
+      padding: 100px 0;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.commodity-chart-editor-container  {
+  .edb-item-style .el-input__icon {
+    line-height: 27px;
+  }
+  .mx-datepicker {
+    width: 200px !important;
+  }
+}
+</style>

+ 765 - 0
src/views/chartRelevance_manage/statisticFeatureChartEditor.vue

@@ -0,0 +1,765 @@
+<template>
+  <div class="commodity-chart-editor-container" id="box">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+    <div class="left-cont" v-show="!isSlideLeft" id="left">
+      <div class="left-top">
+        <el-button type="primary" plain @click="$router.back()">取消</el-button>
+      </div>
+      <div class="left-min">
+        <div class="search-cont">
+					<selectTarget  
+            :defaultId="chartInfoData.EdbInfoList?chartInfoData.EdbInfoList[0].EdbInfoId:''"
+            :defaultOpt="chartInfoData.EdbInfoList?[chartInfoData.EdbInfoList[0]]:[]"
+            :defaultType="chartInfoData.EdbInfoList?chartInfoData.EdbInfoList[0].EdbInfoCategoryType:''"
+            :selectStyleType="2"
+            @select="handleSelectTarget"
+          />
+				</div>
+
+        <div class="section">
+          <div>曲线图</div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:50px;">时间:</span>
+            <el-select
+                style="max-width: 110px;flex-shink:0;"
+                v-model="chartInfo.Curve.DateType"
+                placeholder="请选择"
+                @change="getPreviewSplineChart"
+            >
+              <el-option
+                  v-for="item in yearSelector"
+                  :key="item.value"
+                  :label="item.name"
+                  :value="item.value"
+              />
+            </el-select>
+            <date-picker
+              v-model="chartInfo.Curve.Date"
+              v-show="chartInfo.Curve.DateType===5"
+              style="width:150px;margin-left:10px;"
+              type="month"
+              range
+              value-type="format"
+              placeholder="请选择时间段"
+              @change="dateChange"
+            />
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:50px;">上下限:</span>
+            <el-input
+              style="flex:2;margin-left:5px;margin-right:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Curve.LeftMin"
+              @change="val => { chartInfo.Curve.LeftMin=Number(val);changeSplineOption() }"
+            />
+            <span>至</span>
+            <el-input
+              style="flex:2;margin-left:5px;"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Curve.LeftMax"
+              @change="val => { chartInfo.Curve.LeftMax=Number(val);changeSplineOption() }"
+            />
+          </div>
+        </div>
+
+        <div class="section">
+          <div>标准差
+            <el-tooltip effect="dark" placement="right">
+              <div
+                slot="content"
+                v-html="ruleTips.StandardDeviation"
+                style="line-height: 20px;width:300px"
+              ></div>
+              <i class="el-icon-question" style="color: #666" />
+            </el-tooltip>
+          </div>
+          <div class="section-item">
+            <div>滚动期数:</div>
+            <el-input
+              style="max-width:100px;margin-left:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.StandardDeviation.CalculateValue"
+              @change="val => { chartInfo.StandardDeviation.CalculateValue = Number(val); }"
+            />
+          </div>
+        </div>
+
+        <div class="section">
+          <div>百分位
+            <el-tooltip effect="dark" placement="right">
+              <div
+                slot="content"
+                v-html="ruleTips.Percentile"
+                style="line-height: 20px;width:300px"
+              ></div>
+              <i class="el-icon-question" style="color: #666" />
+            </el-tooltip>
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:70px">时间长度:</span>
+            <el-input
+              style="width:100px;margin-left:5px;margin-right:10px"
+              :step="1"
+              type="number"
+              v-model="chartInfo.Percentile.CalculateValue"
+              @change="val => { chartInfo.Percentile.CalculateValue = Number(val); }"
+            />
+            <el-select
+                style="flex:1"
+                v-model="chartInfo.Percentile.CalculateUnit"
+                placeholder="请选择"
+            >
+            <el-option
+                v-for="item in unitOpt"
+                :key="item.val"
+                :label="item.label"
+                :value="item.val"
+            />
+            </el-select>
+          </div>
+        </div>
+
+        <div class="section">
+          <div>频率分布
+            <el-tooltip effect="dark" placement="right">
+              <div
+                slot="content"
+                v-html="ruleTips.FrequencyDistribution"
+                style="line-height: 20px;width:300px"
+              ></div>
+              <i class="el-icon-question" style="color: #666" />
+            </el-tooltip>
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:70px">时间段:</span>
+            <el-select
+                style="max-width: 110px;flex-shink:0;"
+                v-model="chartInfo.FrequencyDistribution.DateType"
+                placeholder="请选择"
+            >
+            <el-option
+                v-for="item in frequencyDateOption"
+                :key="item.value"
+                :label="item.name"
+                :value="item.value"
+            />
+            </el-select>
+            <date-picker
+              v-model="chartInfo.FrequencyDistribution.Date"
+              v-show="chartInfo.FrequencyDistribution.DateType==8"
+              style="width:150px;margin-left:10px;"
+              type="month"
+              range
+              value-type="format"
+              placeholder="请选择时间段"
+              @change="dateChange($event,'frequecny')"
+            />
+          </div>
+          <div class="section-item">
+            <span style="flex-shrink:0;min-width:70px">频段数</span>
+            <el-select
+                style="max-width: 110px;flex-shink:0;"
+                v-model="chartInfo.FrequencyDistribution.FrequencyValue"
+                placeholder="请选择频段数"
+            >
+              <el-option
+                :label="10"
+                :value="10"
+              />
+              <el-option
+                :label="20"
+                :value="20"
+              />
+            </el-select>
+          </div>
+        </div>
+
+        <el-button type="primary" style="float:right" @click="handlePreviewChart">确定</el-button>
+      </div>
+      <span
+        class="move-btn resize"
+        v-drag
+        id="resize"
+        @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+      ></span>
+      <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+        <i class="el-icon-d-arrow-left"></i>
+      </span>
+    </div>
+    <div
+      class="right-cont"
+      id="right"
+      :style="isSlideLeft ? 'width:100%' : `width:80%`"
+    >
+      <div
+        class="chart-min-cont"
+        v-if="chartBatchData"
+      >
+          <div class="card-wrapper">
+            <chartCard 
+              :entryType="1"
+              ref="chartCard1"
+              :data="chartBatchData.CurveData"
+              :settings="chartInfo"
+              :isChartAdd="buttonAuth.isCurveChartAdd"
+              @saveChart="saveChartToBaseHandle"
+            />
+          </div>
+          <div class="card-wrapper" v-if="chartBatchData.StandardDeviationData">
+            <chartCard 
+              :entryType="2"
+              ref="chartCard2"
+              :data="chartBatchData.StandardDeviationData"
+              :settings="chartInfo"
+              :isChartAdd="buttonAuth.isStandardChartAdd"
+              :isEdbAdd="buttonAuth.isStandardEdbAdd"
+              @saveChart="saveChartToBaseHandle"
+              @saveEdb="saveEdbToBaseHandle"
+            />
+          </div>
+          <div class="card-wrapper" v-if="chartBatchData.PercentileData">
+            <chartCard 
+              :entryType="3"
+              ref="chartCard3"
+              :data="chartBatchData.PercentileData"
+              :settings="chartInfo"
+              :isChartAdd="buttonAuth.isPercentileChartAdd"
+              :isEdbAdd="buttonAuth.isPercentileEdbAdd"
+              @saveChart="saveChartToBaseHandle"
+              @saveEdb="saveEdbToBaseHandle"
+            />
+          </div>
+          <div class="card-wrapper" v-if="chartBatchData.FrequencyDistributionData">
+            <chartCard 
+              :entryType="4"
+              ref="chartCard4"
+              :data="chartBatchData.FrequencyDistributionData"
+              :settings="chartInfo"
+              :isChartAdd="buttonAuth.isFrequencyChartAdd"
+              @saveChart="saveChartToBaseHandle"
+            />
+          </div>
+      </div>
+
+      <div class="nodata" v-else>
+        <img
+          src="~@/assets/img/data_m/table_no.png"
+          alt=""
+          style="display: block; width: 140px; height: 148px; margin: 0 auto"
+        />
+        暂无信息
+      </div>
+    </div>
+
+    <!-- 图表保存入库 -->
+    <saveChartToBase
+      :isShow.sync="isSaveChartToBase"
+      :source="saveSource"
+      :saveScence="saveScence"
+      :chartData="chartData"
+      @saveBack="saveChartBack"
+    />
+
+    <!-- 指标保存入库 -->
+    <saveEdbToBase
+      :isShow.sync="isSaveEdbToBase"
+      :source="saveSource"
+      :saveScence="saveScence"
+      :chartData="chartData"
+      @saveBack="saveEdbBack"
+    />
+  </div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+import {yearSelector} from '@/utils/defaultOptions';
+import {statisticFeatureInterface} from '@/api/modules/chartRelevanceApi';
+import selectTarget from './components/selectTarget.vue'
+import chartCard from './components/chartCard.vue';
+import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
+import saveChartToBase from './components/saveChartTobaseDia.vue';
+import saveEdbToBase from './components/saveEdbToBaseDia.vue'
+export default {
+  components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase },
+  directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 300 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    },
+  },
+  data() {
+    return {
+      chart_code: this.$route.query.code || '',
+      isSlideLeft: false,
+      chartInfoData: {},
+      chartBatchData:null,
+
+      yearSelector: [
+        ...yearSelector,
+        { name: '自定义',value: 5 }
+      ],
+
+      frequencyDateOption: [
+        { name: '最近3月',value:1 },
+        { name: '最近6月',value:2 },
+        { name: '最近1年',value:3 },
+        { name: '最近2年',value:4 },
+        { name: '最近3年',value:5 },
+        { name: '最近5年',value:6 },
+        { name: '最近10年',value:7 },
+        { name: '自定义',value:8 },
+      ],
+      chartInfo: {
+        MultipleGraphConfigId: 0,
+        EdbInfoId: 0,
+        Curve: {
+          DateType:yearSelector[0].value,
+          Date: [],
+          StartDate: '',
+          EndDate: '',
+          LeftMin: 0,
+          LeftMax: 0
+        },
+        StandardDeviation: {
+          CalculateValue: 0
+        },
+        Percentile: {
+          CalculateValue: 0,
+          CalculateUnit: '天'
+        },
+        FrequencyDistribution: {
+          DateType: 1,
+          Date: [],
+          StartDate: '',
+          EndDate: '',
+          FrequencyValue: 10,
+        }
+      },
+      unitOpt:[
+        {label:'年',val:'年'},
+        {label:'季',val:'季'},
+        {label:'月',val:'月'},
+        {label:'周',val:'周'},
+        {label:'天',val:'天'},
+      ],
+
+      buttonAuth: { //按钮控制
+        isCurveChartAdd: false,
+        isStandardChartAdd: false,
+        isStandardEdbAdd: false,
+        isPercentileChartAdd: false,
+        isPercentileEdbAdd: false,
+        isFrequencyChartAdd: false,
+      },
+
+      ruleTips: {
+        StandardDeviation: `计算所选时间范围内数据的样本标准差s,s=sqrt(((x1-x)^2 (x2-x)^2 ......(xn-x)^2)/(n-1)),n表示数据个数。`,
+        Percentile: `对所选时间范围内的数据,取最大值Max,最小值Min,计算Max-Min,百分位=(现值-Min)/(Max-Min),Max=Min时不予计算。`,
+        FrequencyDistribution: `在所选时间范围内,取最大值和最小值,根据频段数划分多个间距相同的区间(左闭右开,最后一个区间为左闭右闭),统计数据值落在每个区间的数据个数,频率=落在某区间数据个数/所选时间段内数据总个数,累计频率为从最小值所在区间对应的频率开始累加。`
+      },
+
+      /* 图表入库 */
+      isSaveChartToBase: false,
+      saveSource:0,//图表位置1 2 3 4
+      chartData: {},
+      saveScence: '',//另存为
+
+       /* 指标入库 */
+      isSaveEdbToBase: false,
+
+      oldEdbInfoType: 0,//原指标来源
+    };
+  },
+  methods: {
+
+    async getOptionDetail() {
+      if(!this.chart_code) return
+      const res = await statisticFeatureInterface.getOptionByCode({ UniqueCode: this.chart_code });
+
+      if(res.Ret !== 200) return 
+
+      const { 
+        MultipleGraphConfigId,
+        Curve,
+        Percentile,
+        StandardDeviation,
+        FrequencyDistribution,
+        EdbInfoList,
+        ChartMappingList,
+        EdbMappingList
+      } = res.Data;
+
+      this.chartInfoData = {
+        EdbInfoList: EdbInfoList
+      }
+      this.oldEdbInfoType = EdbInfoList[0].EdbInfoCategoryType;
+
+      this.chartInfo = {
+        MultipleGraphConfigId,
+        EdbInfoId:EdbInfoList[0].EdbInfoId,
+        Curve: {
+          ...Curve,
+          Date: [Curve.StartDate,Curve.EndDate],
+        },
+        StandardDeviation,
+        Percentile,
+        FrequencyDistribution: {
+          ...FrequencyDistribution,
+          Date: [FrequencyDistribution.StartDate,FrequencyDistribution.EndDate],
+        }
+      }
+
+
+      //统计图的2 3 4对应source8 9 10但其实图表source又是7 8 9 别问为什么这样搞问后端 我也乱的一批
+      this.buttonAuth =  {
+        isCurveChartAdd: ChartMappingList.some(_ => _.MultipleLocationSource===1),
+        isStandardChartAdd: ChartMappingList.some(_ => _.MultipleLocationSource===8),
+        isStandardEdbAdd: EdbMappingList.some(_ => _.MultipleLocationSource===8),
+        isPercentileChartAdd: ChartMappingList.some(_ => _.MultipleLocationSource===9),
+        isPercentileEdbAdd: EdbMappingList.some(_ => _.MultipleLocationSource===9),
+        isFrequencyChartAdd: ChartMappingList.some(_ => _.MultipleLocationSource===10),
+      }
+
+      this.getPreviewChartData(); 
+    },
+
+    // 确定保存图表配置
+    async handlePreviewChart(){
+      let params = {
+       ...this.chartInfo 
+      }
+      const res = await statisticFeatureInterface.chartOptionsSet(params);
+      if(res.Ret !== 200) return
+
+      const { MultipleGraphConfigId } = res.Data;
+      this.chartInfo.MultipleGraphConfigId = MultipleGraphConfigId;
+      this.getPreviewChartData()
+      
+    },
+
+    async getPreviewChartData(){
+      if(!this.chartInfo.EdbInfoId) return this.$message.warning('请选择指标')
+      let params = {
+       ...this.chartInfo 
+      }
+      const res = await statisticFeatureInterface.previewChartBatch(params);
+      if(res.Ret !== 200) return
+      this.chartBatchData = res.Data;
+          
+    },
+
+    /* 获取曲线图数据 */
+    async getPreviewSplineChart() {
+      if(!this.chartInfo.EdbInfoId) return
+      let params = {
+       ...this.chartInfo 
+      }
+      const res = await statisticFeatureInterface.previewSpline(params);
+      if(res.Ret !== 200) return
+      this.chartBatchData = this.chartBatchData ? {
+        ...this.chartBatchData,
+        CurveData: res.Data.CurveData
+      } : { CurveData: res.Data.CurveData};
+    },
+
+    /* 曲线配置变化重绘图 */
+    changeSplineOption() {
+      const { LeftMin,LeftMax } = this.chartInfo.Curve;
+      if(this.$refs.chartCard1) {
+        this.$refs.chartCard1.options.yAxis[0].max = Number(LeftMax);
+        this.$refs.chartCard1.options.yAxis[0].min = Number(LeftMin);
+      }
+    },
+
+    dateChange(val,type='') {
+      if(type === 'frequecny') {
+        this.chartInfo.FrequencyDistribution.StartDate = val[0] || '';
+        this.chartInfo.FrequencyDistribution.EndDate = val[1] || '';
+      }else {
+        this.chartInfo.Curve.StartDate = val[0] || '';
+        this.chartInfo.Curve.EndDate = val[1] || '';
+        this.getPreviewSplineChart()
+      }
+    },
+
+    // 指标选择
+    async handleSelectTarget(e){
+      if(!e) return
+      this.chartInfo.EdbInfoId=e.EdbInfoId;
+      const {max,min} = await this.getEdbDetail(e);
+      this.chartInfo.Curve.LeftMin = min;
+      this.chartInfo.Curve.LeftMax = max;
+      this.getPreviewSplineChart()
+    },
+
+    //选择指标后填入上下限
+    async getEdbDetail({EdbInfoId,EdbInfoType}) {
+      this.oldEdbInfoType = EdbInfoType;
+      const { Data } = EdbInfoType 
+      ? await preDictEdbInterface.edbDetail({EdbInfoId})
+      : await dataBaseInterface.calculateDetail({EdbInfoId})
+
+      return { 
+        max: EdbInfoType ? Data.MaxValue : Data.EdbInfoDetail.MaxValue,
+        min: EdbInfoType ? Data.MinValue : Data.EdbInfoDetail.MinValue,
+      }
+    },
+
+    reloadRightWid() {
+      let total_wid = $('#box')[0].offsetWidth;
+      let left = $('#left')[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + 'px';
+      $('#right')[0].style.width = rigtWid;
+    },
+
+    /* 保存指标入库 */
+    saveEdbToBaseHandle({type,chartData,scence}) {
+      this.saveSource = type;
+      this.chartData = chartData;
+      this.saveScence = scence;
+      this.isSaveEdbToBase = true;
+    },
+
+    /* 保存完指标 按钮控制 */
+    saveEdbBack({source}) {
+
+      if(source===2) this.buttonAuth.isStandardEdbAdd = true;
+      else if(source===3)  this.buttonAuth.isPercentileEdbAdd = true;
+    },
+
+    /* 保存图表 */
+    saveChartToBaseHandle({type,chartData,scence}) {
+      this.saveSource = type;
+      this.chartData = chartData;
+      this.saveScence = scence;
+      this.isSaveChartToBase = true;
+    },
+
+
+    /* 保存完图表 */
+    saveChartBack({source,id}) {
+      this.$message.success('保存成功');
+      this.setButtonAuth(source);
+      //封面图
+      this.$refs[`chartCard`+source].setChartImage(source,id)
+    },
+    
+    /* 保存图表后按钮控制 */
+    setButtonAuth(source) {
+      const sourceMap = {
+        1: 'isCurveChartAdd',
+        2: 'isStandardChartAdd',
+        3: 'isPercentileChartAdd',
+        4: 'isFrequencyChartAdd'
+      }
+      this.buttonAuth[sourceMap[source]] = true;
+    }
+  },
+  mounted() {
+    this.getOptionDetail();
+    window.addEventListener('resize', this.reloadRightWid);
+  },
+  destroyed() {
+    window.removeEventListener('resize', this.reloadRightWid);
+  }
+};
+</script>
+<style lang="scss">
+.commodity-chart-editor-container {
+  $font-small: 12px;
+  $font-normal: 14px;
+
+  display: flex;
+  * {
+    box-sizing: border-box;
+  }
+  .el-form--label-top .el-form-item__label {
+    padding: 0;
+  }
+  .label-left{
+      display: flex;
+      margin-top: 20px;
+      .el-form-item__label{
+          flex-shrink: 0;
+          margin-right: 10px;
+      }
+      .el-date-editor.el-input, .el-date-editor.el-input__inner{
+          width: auto;
+      }
+  }
+  
+  .target-other-name .el-input__inner {
+    padding: 0 30px 0 5px !important;
+    height: 40px !important;
+    line-height: 40px !important;
+  }
+  .el-color-picker--mini .el-color-picker__trigger {
+    width: 60px;
+    height: 25px;
+    padding: 0;
+  }
+  .el-color-picker--mini .el-color-picker__mask {
+    width: 60px;
+    height: 25px;
+  }
+
+  .slide-icon {
+    padding: 20px 0;
+    /* display: block; */
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+    border-radius: 5px;
+    cursor: pointer;
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: 99;
+    &:hover {
+      background-color: rgba(0, 0, 0, 0.05);
+    }
+    &.slide-left {
+      right: 0;
+    }
+    &.slide-right {
+      left: 0;
+    }
+  }
+  .left-cont {
+    width: 380px;
+    min-width: 380px;
+    background: #fff;
+    margin-right: 20px;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    height: calc(100vh - 113px);
+    overflow: hidden;
+    position: relative;
+    box-sizing: border-box;
+    .left-top {
+      padding: 15px 20px;
+      border-bottom: 1px solid #ececec;
+      box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+    }
+    .left-min {
+      padding: 20px;
+      max-height: calc(100vh - 190px);
+      overflow-y: auto;
+      
+      .section {
+        border-top: 1px dashed #DCDFE6;
+        margin-top: 20px;
+        padding-top: 15px;
+        .section-item{
+          display: flex;
+          align-items: center;
+          font-size: 14px;
+          color: #606266;
+          margin: 10px 0;
+        }
+      }
+
+      .left-bottom {
+        margin-top: 20px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+      }
+     
+    }
+    .move-btn {
+      height: 100%;
+      width: 4px;
+      position: absolute;
+      right: 0px;
+      top: 0;
+      &:hover {
+        cursor: col-resize;
+      }
+    }
+  }
+  .right-cont {
+    width: 80%;
+    /* =================== */
+    .chart-min-cont {
+      /* background: #fff; */
+      height: calc(100vh - 118px);
+      overflow-y: auto;
+      display: flex;
+      flex-wrap: wrap;
+      .card-wrapper {
+        width: 48%;
+        margin-bottom: 20px;
+        min-height: 350px;
+        &:nth-child(2n) {
+          margin-left: 15px;
+        } 
+        .card-item {
+          padding: 20px;
+          background: #fff;
+          .top {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            margin-bottom: 15px;
+          }
+          .title {
+            /* max-width: 250px; */
+            font-size: 15px;
+            text-align: left;
+            margin: 10px 0;
+          }
+        }
+      }
+    }
+    .nodata {
+      height: calc(100vh - 120px);
+      background-color: #fff;
+      text-align: center;
+      font-size: 16px;
+      color: #666;
+      padding: 100px 0;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.commodity-chart-editor-container  {
+  .edb-item-style .el-input__icon {
+    line-height: 27px;
+  }
+  .mx-datepicker {
+    width: 200px !important;
+  }
+}
+</style>

+ 815 - 0
src/views/chartRelevance_manage/statisticFeatureList.vue

@@ -0,0 +1,815 @@
+<template>
+	<div class="fittingEquation-chart-container" v-if="showData">
+		<span
+			class="slide-icon slide-right"
+			@click="isSlideLeft = !isSlideLeft"
+			v-show="isSlideLeft"
+		>
+			<i class="el-icon-d-arrow-right"></i>
+		</span>
+
+		<div class="data-sheet-main" id="box">
+      <div class="main-left left" id="left" v-show="!isSlideLeft">
+				<div class="datasheet_top">
+						<el-button type="primary" @click="goAddChart">添加图表</el-button>
+				</div>
+
+				<div class="search-cont">
+					<el-checkbox v-model="isShowMe"  @change="() => { getTreeData();getPublicList() }">只看我的</el-checkbox>
+					<el-select
+						v-model="search_txt"
+						v-loadMore="searchLoad"
+						:filterable="!search_txt"
+						remote
+						clearable
+						placeholder="请输入图表名称"
+						style="width: 100%; margin-top: 20px"
+						:remote-method="searchHandle"
+						@click.native="inputFocusHandle"
+					>
+						<i slot="prefix" class="el-input__icon el-icon-search"></i>
+						<el-option
+							v-for="item in searchOptions"
+							:key="item.ChartInfoId"
+							:label="item.ChartName"
+							:value="item.ChartInfoId"
+						>
+						</el-option>
+					</el-select>
+				</div>
+				<div class="tree-cont">
+					<el-tree
+						ref="treeRef"
+						class="target_tree"
+						:data="treeData"
+						node-key="UniqueCode"
+						:props="defaultProp"
+						:allow-drag="canDragHandle"
+						:allow-drop="canDropHandle"
+						:current-node-key="select_node"
+						:default-expanded-keys="defaultShowNodes"
+						draggable
+						:expand-on-click-node="false"
+						check-strictly
+						empty-text="暂无分类"
+						@node-expand="handleNodeExpand"
+						@node-collapse="handleNodeCollapse"
+						@current-change="nodeChange"
+						@node-drop="dropOverHandle"
+						@node-drag-end="dropMouseLeave"
+						@node-drag-leave="dropMouseLeave"
+						@node-drag-enter="dropMouseOver"
+					>
+						<span class="custom-tree-node" slot-scope="{ node, data }">
+							<el-input
+								ref="editVal"
+								style="width: 90px"
+								placeholder="请输入值"
+								class="label-input"
+								v-model="new_label"
+								v-if="data.isEdit"
+								@blur="changeValue(data)"
+							/>
+							<span
+								@dblclick.stop="editNodeLabel(data)"
+								v-else
+								class="text_oneLine node_label"
+								:style="`width:${
+									(select_node === data.UniqueCode && node.Nodewidth) || ''
+								}`"
+							>
+								<span>{{ data.ChartClassifyName }}</span>
+							</span>
+							<span
+								style="display: flex; align-items: center"
+								v-if="select_node === data.UniqueCode"
+							>
+								<img
+									src="~@/assets/img/data_m/move_ico.png"
+									alt=""
+									style="width: 14px; height: 14px; margin-right: 8px"
+								/>
+								<img
+									src="~@/assets/img/set_m/edit.png"
+									alt=""
+									style="width: 15px; height: 14px; margin-right: 8px"
+									@click.stop="editNode(node, data)"
+									v-if="!data.ChartInfoId"
+								/>
+								<img
+									slot="reference"
+									src="~@/assets/img/set_m/del.png"
+									alt=""
+									style="width: 14px; height: 14px"
+									@click.stop="removeNode(node, data)"
+									v-if="!data.ChartInfoId"
+								/>
+							</span>
+						</span>
+					</el-tree>
+					<div
+						class="noDepart"
+						@click="addLevelOneHandle"
+					>
+						<img
+							src="~@/assets/img/set_m/add_ico.png"
+							alt=""
+							style="width: 16px; height: 16px; margin-right: 10px"
+						/>
+						<span>添加图表分类</span>
+					</div>
+				</div>
+				<span
+					class="move-btn resize"
+					v-drag
+					id="resize"
+					@mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+				></span>
+				<span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+					<i class="el-icon-d-arrow-left"></i>
+				</span>
+      </div>
+
+			<div class="main-right" id="right" :style="isSlideLeft ? 'width:100%' : 'width:80%'">
+
+				<!-- 图表详情 -->
+				<div class="chart-detail-wrapper" v-if="chartInfo.ChartInfoId">
+					<el-row class="bottom-min">
+              <el-col
+                :span="21"
+                style="padding: 20px 0;"
+              >
+                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
+                <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
+                  <div class="chartWrapper" id="chartWrapper">
+                    <h2 class="chart-title">{{ chartInfo.ChartName }}</h2>
+                    <Chart 
+											:options="options"
+											minHeight="440px" 
+											height="500px"
+											ref="chartRef"
+										/>
+                  </div>
+                  <span class="chart-author">作者:{{ chartInfo.SysUserRealName}}</span>
+                </div>
+
+                <!-- 异常显示 -->
+                <p class="error-tip" style="min-height: 400px;" v-if="chartInfo.WarnMsg">{{chartInfo.WarnMsg}}</p>
+              </el-col>
+              <el-col :span="3" style="position: absolute;height: 100%;right: 0;">
+								<!-- 操作 -->
+								<chartHandlesWrap
+									:chartInfo="chartInfo"
+									:linkUrl="linkUrl"
+									@copyChartConfirm="copyChartConfirm"
+									@addMychartHandle="addMychartHandle"
+									@refreshHandle="refreshHandle"
+									@saveChartOtherHandle="saveChartOtherHandle"
+									@editChartHandle="editChartHandle"
+									@openEnNameDia="openEnNameDia"
+									@delChartHandle="delChartHandle"
+								/>
+              </el-col>
+          </el-row>
+				</div>
+				<!-- 列表 -->
+				<chartListWrap
+          v-else 
+          :total="chart_total"
+          :list="chartList" 
+          @loadMoreHandle="loadMoreHandle"
+          @detailShowHandle="detailShowHandle"
+          @addMychartHandle="addMychartHandle"
+          ref="chartListWrap"
+        />
+			</div>
+		</div>
+
+
+		<!-- 分类弹窗 -->
+		<classify-dia
+			:isOpenDialog.sync="classifyDia"
+			:title="dialog_title"
+			:form="classifyForm"
+			@successCallback="getTreeData"
+		/>
+
+		 <!-- 加入我的图库弹窗 -->
+    <addMyClassifyDia
+      :isAddMyDialog="isAddMyChart"
+      :add_id="add_chart_id"
+      :add_ids="add_ids"
+      @cancel="isAddMyChart = false"
+      @addSuccess="addMySuccess"
+    />
+
+		 <!-- 图表另存 -->
+    <SaveChartOther 
+      :show.sync="isShowSaveOther" 
+      fromType="chartsetting"
+			source="statistic_feature"
+      :data="chartInfo"
+      @ensure="getTreeData"
+    />
+
+		<!-- 输入英文指标弹窗 -->
+		<set-en-name-dia 
+			:isOpenDialog="setEnName" 
+		  :formData="formItemArray"
+			@cancel="setEnName=false"
+   	  @updateEnName="updateEnName"
+		/>
+
+	</div>
+</template>
+
+<script>
+
+import { statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import leftMixin from './mixins/classifyMixin';
+import Chart from '@/views/dataEntry_manage/components/chart';
+import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
+import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
+import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
+import setEnNameDia from '@/views/dataEntry_manage/components/setEnNameDia.vue'
+import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
+import { copyOtherOptions } from '@/utils/defaultOptions';
+export default {
+	components: {
+		classifyDia,
+		Chart,
+		addMyClassifyDia,
+		SaveChartOther,
+		setEnNameDia
+	},
+	mixins:[ leftMixin,chartSetMixin ],
+	computed: {
+		/* 分享地址 */
+    linkUrl() {
+      const LINK_CHART_URL = process.env.CHART_LINK;
+      return `${LINK_CHART_URL}?code=${this.chartInfo.UniqueCode}&fromType=share?&lang=${this.currentLang}`
+    }
+	},
+	data () {
+		return {
+			showData: false,
+			refreshLoading: false,
+			isShowMe: false,
+			search_txt: '',
+			searchOptions:[],
+			isSlideLeft: false,//左侧分类收起
+
+			select_node: '',//节点唯一标识code
+			select_classify: '',
+			new_label:'',//双击修改的value
+			treeData: [], //分类数据
+      defaultShowNodes: [], //展开节点
+      defaultProp: {
+        label: 'ChartClassifyName',
+        children: 'Children',
+      }, //树结构配置项
+			dynamicNode: null,
+
+			/* 分类弹窗 */
+			dialog_title:'',
+			classifyDia: false, //
+			classifyForm: {},
+
+			select_id: '',//选中的图表id
+			chartInfo: {},
+			chart_title:'',//图表标题 双击标题修改时来存储最新值
+
+			isAddMyChart: false, //加入图库弹窗
+      add_chart_id: '', //要加入的图表
+			add_ids:[],//加入时已有的分类
+
+			/* 图表列表 */
+			publicHaveMove: true,//是否还有列表数据
+			chartList: [],
+			chart_total: 0,
+			chart_page: 1,
+			chart_pages_size: 16,
+
+			search_page: 1,
+			search_have_more: false,
+			current_search:'',
+		};
+	},
+	methods: {
+
+		/* 添加图表 */
+		goAddChart() {
+			if(!this.treeData.length) return this.$message.warning('请先添加分类');
+			this.$router.push({ path: '/statisticFeatureChartEditor' });
+		},
+
+		/* 获取分类 */
+		getTreeData(params=null) {
+			statisticFeatureInterface.classifyList({IsShowMe:this.isShowMe}).then(res => {
+				const { Ret,Data } = res;
+				if(Ret !== 200) return
+
+				this.showData = true;
+				this.treeData = Data.AllNodes || [];
+				this.$nextTick(() => {
+					/* 新增完成后 处理树展开和选中 */
+					params && this.selectCurrentNode(params);
+				});
+
+			})
+		},
+
+		/* 搜索 */
+		searchHandle(query) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search)
+		},
+
+		searchApi(query,page=1) {
+      /* 查找列表 */
+      statisticFeatureInterface
+        .searchChart({
+          Keyword: query,
+          IsShowMe:this.isShowMe,
+          CurrentIndex: page
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return
+          const { List,Paging } = res.Data;
+          this.search_have_more = page < Paging.Pages;
+          this.searchOptions = page === 1 ? List : [...this.searchOptions,...List];
+        });
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+      if(this.current_search) {
+        this.searchApi(this.current_search)
+      }else {
+        this.searchOptions = [];
+      }
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page);
+		},
+
+		/* 选中分类变化时 */
+		nodeChange({ UniqueCode,ChartInfoId,ChartClassifyId },node) {
+			this.search_txt = '';
+			this.select_node = UniqueCode;
+			this.select_classify = !ChartInfoId ? ChartClassifyId : 0;
+			this.select_id = ChartInfoId || 0;
+			this.resetNodeStyle(node);
+			this.dynamicNode = node;
+		},
+
+		/* 添加一级目录 */
+		addLevelOneHandle() {
+			this.dialog_title = '添加';
+			this.classifyForm = {
+				classify_name: '',
+			}
+			this.classifyDia = true;
+		},
+
+    /* 编辑节点 */
+    editNode(node, { ChartClassifyName,ChartClassifyId }) {
+
+      this.dialog_title = '编辑';
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: ChartClassifyName,
+        classify_id: ChartClassifyId,
+      };
+      this.classifyDia = true;
+    },
+
+		 /* 删除节点校验 */
+    async removeNode(node, { ChartClassifyId,ChartInfoId }) {
+
+			const { Data } = await statisticFeatureInterface.classifyDelCheck({ ChartClassifyId })
+
+			const { DeleteStatus } = Data;
+
+			DeleteStatus === 1 
+			? this.$confirm('该分类下关联表图表不可删除', '删除失败', {
+				confirmButtonText: '知道了',
+				showCancelButton: false,
+				type: 'error',
+			}) : DeleteStatus === 0
+			?  this.$confirm('确定删除当前分类吗?', '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning',
+			}).then(() => {
+				this.delApi(ChartClassifyId,ChartInfoId)
+			}): null;
+
+    },
+
+		 /* 删除方法 */
+    delApi(ChartClassifyId,ChartInfoId,type='') {
+      statisticFeatureInterface
+        .classifyDel({
+          ChartClassifyId,
+					ChartInfoId
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return
+					this.$message.success(res.Msg);
+
+					if (!res.Data.ChartInfoId) this.select_id = '';
+
+					//删除自动显示下一张
+					type=='del_chart' && res.Data.ChartInfoId
+						? this.getTreeData({
+								code: res.Data.UniqueCode,
+								id: res.Data.ChartInfoId
+							})
+						: this.getTreeData();
+        });
+    },
+
+		/* 分类成功回调 */
+		classifyCallback(type) {
+			this.getTreeData();
+
+			if (type === 'add') {
+        //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
+        let code = this.add_parent_id;
+        let flag = this.defaultShowNodes.some(item => item === code);
+        // console.log(flag)
+        !flag && this.defaultShowNodes.push(code);
+        this.add_parent_id = '';
+
+      }
+		},
+
+		/* 获取图表列表 */
+		getPublicList() {
+			statisticFeatureInterface.getChartList({
+				CurrentIndex: this.chart_page,
+				PageSize: this.chart_pages_size,
+        ChartClassifyId: this.select_classify || 0,
+				IsShowMe: this.isShowMe
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				this.publicHaveMove = res.Data
+            ? this.chart_page < res.Data.Paging.Pages
+            : false;
+          this.chartList = res.Data
+            ? this.chart_page === 1
+              ? res.Data.List
+              : [...this.chartList, ...res.Data.List]
+            : [];
+        this.chart_total = res.Data ? res.Data.Paging.Totals : 0;
+			})
+		},
+
+		getChartInfo() {
+			this.getDetailHandle();
+		},
+
+		/* 获取图表详情 */
+		getDetailHandle() {
+			statisticFeatureInterface.chartDetail({
+				ChartInfoId: this.select_id
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				const { ChartInfo,DataResp } = res.Data;
+				this.chartInfo = ChartInfo;
+				if(ChartInfo.Source===9) {
+          this.statisticFrequencyData = DataResp;
+          this.setStatisticFrequency();
+				}else {
+					this.setDefaultChart([DataResp])
+				}
+
+				!ChartInfo.ChartImage && this.$nextTick(() => {
+					//关联图表和图片
+					 this.setChartImage();
+				})
+			})
+		},
+
+		/* 删除图表 */
+		delChartHandle() {
+			const { ChartClassifyId,ChartInfoId } = this.chartInfo;
+			this.$confirm('删除后该图表将不能再引用,确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          this.delApi(ChartClassifyId,ChartInfoId,'del_chart');
+        })
+        .catch(() => {});
+		},
+
+		/* 刷新图表 */
+		refreshHandle() {
+			this.refreshLoading = this.$loading({
+        lock: true,
+        target: '.main-right',
+        text: '刷新图表中...',
+        spinner: 'el-icon-loading',
+        background: 'rgba(255, 255, 255, 0.8)',
+      });
+      statisticFeatureInterface
+        .refreshChart({
+          ChartInfoId: this.chartInfo.ChartInfoId,
+        })
+        .then((res) => {
+          this.refreshLoading.close();
+          if (res.Ret === 200) {
+            this.getDetailHandle();
+            this.$message.success(res.Msg);
+          }
+        });
+		},
+
+		/* 编辑图表 */
+		editChartHandle() {
+			this.$router.push({
+        path: '/statisticFeatureChartEditor',
+        query: {
+          code: this.chartInfo.UniqueCode,
+					id: this.chartInfo.ChartInfoId
+        }
+      })
+		},
+
+		copyChartHandle:_.debounce(function(type){
+      let chartsName = this.currentLang=='ch'?this.chartInfo.ChartName:this.chartInfo.ChartNameEn
+      let { heightNum, widthNum , newTitle , dynamic_copyOptions} = this.dynamicWidthAndHeight(type,this.chartInfo.ChartType,chartsName,1)
+      const chartType = 'seasonLegend';
+      // 英文转SVG设置变动
+      if(this.currentLang == 'en'){
+        // 如果竖轴坐标单位为'英文单位',表示客户没填,转成svg时置为空
+        this.$refs.chartRef.chart.options.yAxis.forEach(it => {
+          if(it.title.text == '英文单位') it.title.text='' 
+        });
+      }
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart:{
+          width:widthNum,
+          height:heightNum,
+          backgroundColor:"rgba(255, 255, 255, 0)",
+        },
+        title: {
+          text: newTitle,
+          margin: 10,
+          style: {
+            fontSize: '18px'
+          }
+        },
+        legend:{
+          ...copyOtherOptions[chartType],
+          ...dynamic_copyOptions[chartType]
+          }
+      });
+      this.copyBlobItem(widthNum,heightNum,svg,type);
+    },500),
+	},
+	mounted() {
+
+		if(this.$route.query.code) {
+      this.getTreeData({code: this.$route.query.code,id: Number(this.$route.query.id)})
+    } else {
+      this.getTreeData();
+      this.getPublicList();
+    }
+
+		window.addEventListener('resize', this.reloadRightWid);
+	},
+	destroyed() {
+		window.removeEventListener('resize', this.reloadRightWid);
+	}
+}
+</script>
+<style lang='scss' scoped>
+*{ box-sizing: border-box;}
+$mini-font: 12px; $normal-font: 14px;
+.fittingEquation-chart-container {
+	.slide-icon {
+		padding: 20px 0;
+		/* display: block; */
+		box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+		border-radius: 5px;
+		cursor: pointer;
+		position: absolute;
+		top: 50%;
+		transform: translateY(-50%);
+		z-index: 99;
+		&:hover {
+			background-color: rgba(0, 0, 0, 0.05);
+		}
+		&.slide-left {
+			right: 0;
+		}
+		&.slide-right {
+			left: 0;
+		}
+	}
+	.data-sheet-main {
+		display: flex;
+
+		.main-left {
+			width: 400px;
+			min-width: 300px;
+			background: #fff;
+			margin-right: 20px;
+			border: 1px solid #ececec;
+			border-radius: 4px;
+			box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+			height: calc(100vh - 120px);
+			overflow: hidden;
+			position: relative;
+			box-sizing: border-box;
+
+			.datasheet_top {
+				padding: 20px;
+				background: #fff;
+				border: 1px solid #ececec;
+				box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+				margin-bottom: 20px;
+			}
+			.search-cont {
+				padding: 0 20px;
+			}
+
+
+
+			.tree-cont {
+				padding: 30px 20px;
+				max-height: calc(100vh - 280px);
+				overflow: auto;
+			}
+			.target_tree {
+				color: #333;
+				.custom-tree-node {
+					display: flex !important;
+					justify-content: space-between;
+					align-items: center;
+					display: block;
+					flex: 1;
+					.node_label {
+						margin-right: 2px;
+					}
+					.el-icon-view {
+						color: #409EFF;
+						font-size: 18px;
+						margin-left: 5px;
+					}
+				}
+			}
+			.noDepart {
+				margin: 60px 0;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				color: #409eff;
+				font-size: 16px;
+				cursor: pointer;
+			}
+			.move-btn {
+				height: 100%;
+				width: 4px;
+				/* opacity: 0; */
+				position: absolute;
+				right: 0px;
+				top: 0;
+				&:hover {
+				cursor: col-resize;
+					/* background-color: orange */
+				}
+			}
+		}
+
+		.main-right {
+			width: 80%;
+			.chart-detail-wrapper {
+				height: calc(100vh - 120px);
+				border: 1px solid #ececec;
+				border-radius: 4px;
+				box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+				overflow: auto;
+				background: #fff;
+				padding: 30px;
+				.bottom-min {
+					border: 1px solid #DCDFE6;
+					margin-bottom: 20px;
+					.chart-show-cont {
+              padding: 0 160px 0 120px;
+              position: relative;
+							min-height: 400px;
+              .chart-title {
+                font-size: 16px;
+                font-weight: normal;
+                text-align: center;
+                margin-bottom: 10px;
+              }
+              .chart-author {
+                font-size: 14px;
+                color: #333;
+                position: absolute;
+                bottom: 0;
+                right: 50px;
+              }
+              .chartWrapper {
+                position: relative;
+                .range-cont {
+                  position: absolute;
+                  top: 13%;
+                  .min-data-input {
+                    width: 60px;
+                    display: block;
+                  }
+                  &.left {
+                    left: -80px;
+                  }
+                  &.right {
+                    right: -65px;
+                  }
+                  &.rightTwo {
+                    right: -130px;
+                  }
+                }
+              }
+          }
+				}
+			}
+		}
+		
+		@media screen and (min-width: 1711px){
+			.min-data-input {
+				margin-top: 360px;
+			}
+		}
+		@media screen and (max-width: 1710px){
+			.min-data-input {
+				margin-top: 290px;
+			}
+		}
+	}
+}
+</style>
+
+<style lang="scss">
+.fittingEquation-chart-container {
+	.label-input .el-input__inner {
+		height: 25px;
+		line-height: 25px;
+		padding: 0 10px;
+	}
+
+	.range-cont .el-input__inner {
+		padding: 0 3px;
+	}
+
+	.el-tree__drop-indicator{
+		height:3px;
+		background-color:#409EFF;
+	}
+	.el-tree-node__content {
+		margin-bottom: 14px !important;
+	}
+	.el-tree-node__children {
+		.el-tree-node {
+			/* margin-bottom: 8px !important; */
+			margin-bottom: 0px !important;
+			padding-left: 18px;
+		}
+		.el-tree-node__content {
+			margin-bottom: 5px !important;
+			padding-left: 0 !important;
+		}
+	}
+	.expanded.el-icon-caret-right:before {
+		content: url('../../assets/img/set_m/down.png') !important;
+	}
+	.el-icon-caret-right:before {
+		content: url('../../assets/img/set_m/slide.png') !important;
+	}
+	.el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+		content: '' !important;
+	}
+	.el-tree-node__expand-icon.expanded {
+		-webkit-transform: rotate(0deg);
+		transform: rotate(0deg);
+	}
+	.el-tree-node.is-current > .el-tree-node__content {
+		background-color: #f0f4ff !important;
+	}
+	.el-tree-node__content {
+		padding-right: 10px !important;
+	}
+}
+</style>

+ 3 - 3
src/views/contract_manage/approvalList.vue

@@ -97,7 +97,7 @@
           <template slot-scope="scope">{{ scope.row.Price|formatPriceHasPoint }}</template>
         </el-table-column>
         <el-table-column align="center" prop="CompanyName" label="客户名称" ></el-table-column>
-        <el-table-column align="center" prop="CreateTimeStr" label="提交审批时间" width="160" :formatter="formatterCol"></el-table-column>
+        <el-table-column align="center" prop="CreateTimeStr" label="提交审批时间" width="160" :formatter="formatter"></el-table-column>
         <el-table-column align="center"  label="审批时间" width="160" v-if="constractStatusVal!=='待审批'">
           <template slot-scope="scope">
             <span v-if="scope.row.Status === '待审批'">- -</span>
@@ -148,7 +148,7 @@
     </div>
 
     <!-- 审批弹窗 -->
-    <el-dialog width="58%" top="5vh" v-dialogDrag :visible.sync="show" :modal-append-to-body="false">
+    <el-dialog width="58%" top="5vh" v-dialogDrag :visible.sync="show" :modal-append-to-body="false" @close="handleClose">
       <div slot="title" v-if="approvalData">
         <span>合同编号: {{ approvalData.ContractInfo.ContractCode }}</span>
       </div>
@@ -355,7 +355,7 @@ export default {
   },
   computed:{
     exportExcel(){
-      let baseUrl=process.env.VUE_APP_BASE_API+'/contract/approval/list'
+      let baseUrl=process.env.API_ROOT+'/contract/approval/list'
       let token=localStorage.getItem('auth')||''
       let paramStr=''
       let obj={

+ 12 - 13
src/views/contract_manage/contractList.vue

@@ -1,15 +1,15 @@
 <template>
   <div class="contractlist-container">
     <div class="top-wrap">
-      <div v-if="RoleType === 'ficc_seller' || RoleType === 'rai_seller'" style="marginRight:10px;display:inline-block">
+      <blcok v-if="RoleType === 'ficc_seller' || RoleType === 'rai_seller'"   style="margin-right:10px;">
         <el-button type="primary" @click="showAddTypeDia=true">添加合同</el-button>
         <el-button type="primary" plain @click="handleDownloadContractTemplate">合同操作指南</el-button>
-      </div>
-      <div v-if="!(RoleType === 'ficc_seller' || RoleType === 'rai_seller')" style="marginRight:10px;display:inline-block">
+      </blcok>
+      <block v-if="!(RoleType === 'ficc_seller' || RoleType === 'rai_seller')" >
         <a :href="exportExcel" download>
           <el-button type="primary">下载EXCEL</el-button>
         </a>
-      </div>
+      </block>
 
       <el-input placeholder="合同编号/客户名称/社会信用码" v-model="searchVal" style="max-width: 400px; float: right" @input="handleSearch" clearable>
         <i slot="prefix" class="el-input__icon el-icon-search"></i>
@@ -30,7 +30,7 @@
         <el-select clearable v-model="constractStatusVal" @change="handleSelectChange" placeholder="合同状态" style="margin-bottom: 20px;margin-right:20px">
           <el-option v-for="item in constractStatusOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
         </el-select>
-        <template v-if="RoleType === 'admin'||RoleType==='compliance'||RoleType==='finance'">
+        <block v-if="RoleType === 'admin'||RoleType==='compliance'||RoleType==='finance'">
           <el-select clearable v-model="constractBelongVal" @change="handleSelectChange" placeholder="合同归属" style="margin-bottom: 20px;margin-right:20px">
             <el-option v-for="item in constractBelongOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
           </el-select>
@@ -49,13 +49,12 @@
             filterable
             @change="handleSelectChange">
           </el-cascader>
-        </template>
+        </block>
       </div>
       <ul class="tabs-wrap">
         <li 
-          v-for="item in tabs"
-          :key="item.name" 
-          :class="['tab',tabsActive === item.name?'act':'']"
+          v-for="item in tabs" 
+          :class="['tab',{'act':tabsActive === item.name}]"
           @click="handleChangeTabs(item.name)"
         >{{item.name}}</li>
       </ul>
@@ -89,7 +88,7 @@
             <span :style="{ color: scope.row.Status === '已驳回'||scope.row.Status === '已解约' ? '#FF0000' : null }">{{ scope.row.Status }}</span>
           </template>
         </el-table-column>
-        <el-table-column key="更新时间" align="center" prop="ModifyTimeStr" label="更新时间" width="160" :formatter="formatterCol"></el-table-column>
+        <el-table-column key="更新时间" align="center" prop="ModifyTimeStr" label="更新时间" width="160" :formatter="formatter"></el-table-column>
         <el-table-column key="seller操作" align="center" label="操作" width="200" v-if="RoleType === 'ficc_seller' || RoleType === 'rai_seller'">
           <template slot-scope="scope">
             <div v-if="scope.row.Status === '待提交'">
@@ -180,7 +179,7 @@
       <div slot="title" style="font-size:15px">{{tabsActive==='业务合同'?'付款方列表':'代付方列表'}}</div>
       <ul class="precontract-list">
         <li 
-          v-for="item in preContractList"
+          v-for="item in preContractList" 
           :key="ContractId+PaymentOnBehalfContractId"
           @click="handleGoContractdtl(tabsActive==='业务合同'?item.PaymentOnBehalfContractId:item.ContractId)"
         >{{item.CompanyName}}</li>
@@ -255,7 +254,7 @@ export default {
   },
   computed: {
     exportExcel() {
-      let baseUrl = process.env.VUE_APP_BASE_API + "/contract/list";
+      let baseUrl = process.env.API_ROOT + "/contract/list";
       let token = localStorage.getItem("auth") || "";
       let paramStr = "";
       let obj = {
@@ -758,7 +757,7 @@ export default {
       }
 
       if(type==='downloadTem'){
-        let baseUrl = process.env.VUE_APP_BASE_API + "/contract/downLoad/tmpContract";
+        let baseUrl = process.env.API_ROOT + "/contract/downLoad/tmpContract";
         let token = localStorage.getItem("auth") || "";
         let path=`${baseUrl}?${token}&ContractId=${e.ContractId}`
         let link = document.createElement("a");

+ 1 - 0
src/views/custom_manage/approvalList.vue

@@ -130,6 +130,7 @@
 					:current-page="page_no"
 					@current-change="handleCurrentChange"
 					:page-size="pageSize" 
+					@size-change="handleSizeChange" 
 					:total="total"
 					style="float:right;">
 					</el-pagination>

+ 2 - 2
src/views/custom_manage/compontents/Capplydialog.vue

@@ -166,7 +166,7 @@ export default {
 		/* 客户信息 */
 		formdata:{
 			type:Object,
-			default:()=>{}
+			default:{}
 		},
 		/* 标题 */
 		title:{
@@ -177,7 +177,7 @@ export default {
 		},
 		contactFormData:{
 			type:Object,
-			default:()=>{}
+			default:{}
 		}
 	},
 	watch: {

+ 1 - 1
src/views/custom_manage/compontents/Contactdialog.vue

@@ -263,7 +263,7 @@ export default {
       default: false
     },
     custom_name:{
-      type:String,
+      type:Object,
       default: '',
     }
   },

+ 1 - 1
src/views/custom_manage/compontents/ReadDialog.vue

@@ -69,7 +69,7 @@ export default {
 			type:String
 		},
 		readId: {
-			type:String,
+			type:Number,
 			// required:true
 		}
 	},

+ 1 - 1
src/views/custom_manage/compontents/accumulativeFrequencyDlg.vue

@@ -68,4 +68,4 @@ export default {
   },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="less"></style>

+ 2 - 2
src/views/custom_manage/compontents/clickNumberDetailDia.vue

@@ -11,7 +11,7 @@
               placeholder="请选择所属模块" 
               @change="handleClickTypeChange" 
               clearable 
-              style="width:180px;margin-right:5px"
+              style="width:180px"
               v-if="type=='contacts'"
             >
               <el-option label="英文研报" :value="0"></el-option>
@@ -132,7 +132,7 @@ import { customInterence,reportVarietyENInterence } from '@/api/api.js'
         required:true
       },
       id:{
-        type:[Number,String],
+        type:Number,
         required:true
       },
       type:{

+ 2 - 2
src/views/custom_manage/compontents/exportData.vue

@@ -74,7 +74,7 @@ export default {
           url = item.Url;
         }
       });
-      this.exportUrl = process.env.VUE_APP_BASE_API + url  + "&CompanyId=" + Number(this.companyId)+'&' + (localStorage.getItem("auth") || "");
+      this.exportUrl = process.env.API_ROOT + url  + "&CompanyId=" + Number(this.companyId)+'&' + (localStorage.getItem("auth") || "");
     },
     cancelHandle() {
       this.exportUrl = "";
@@ -96,4 +96,4 @@ export default {
   },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="less"></style>

+ 1 - 1
src/views/custom_manage/compontents/jurisdictionCheck.vue

@@ -362,7 +362,7 @@ export default {
   },
 };
 </script>
-<style lang="scss" scoped>
+<style lang="less" scoped>
 .container-check {
   display: flex;
   .table-wrap {

+ 3 - 3
src/views/custom_manage/contacts/contactsList.vue

@@ -98,9 +98,9 @@
               <el-tag
                 size="mini"
                 style="margin: 5px 8px; cursor: pointer"
-                v-for="(item, index) in lookLabelListNumber(row)"
-                :key="index"
-                :type="userLabel == item ? 'danger' : ''"
+                v-for="item in lookLabelListNumber(row)"
+                :key="item"
+                :type="userLabel == item && 'danger'"
                 @click="labelChildren(item, row)"
               >
                 {{ item }}

+ 1 - 1
src/views/custom_manage/contacts/mutualList.vue

@@ -95,7 +95,7 @@ export default {
   props: {},
   computed: {
     exportExcel() {
-      let baseUrl = process.env.VUE_APP_BASE_API + "/cygx/user/export/interaction";
+      let baseUrl = process.env.API_ROOT + "/cygx/user/export/interaction";
       let token = localStorage.getItem("auth") || "";
       let paramStr = "";
       let params = {

+ 1 - 1
src/views/custom_manage/contacts/organizationList.vue

@@ -104,7 +104,7 @@ export default {
   mixins: [mutualMixin],
   computed: {
     exportExcel() {
-      let baseUrl = process.env.VUE_APP_BASE_API + "/cygx/user/company/export/interaction";
+      let baseUrl = process.env.API_ROOT + "/cygx/user/company/export/interaction";
       let token = localStorage.getItem("auth") || "";
       let paramStr = "";
       let params = {

+ 1 - 1
src/views/custom_manage/contacts/wholeOrganization.vue

@@ -113,7 +113,7 @@ export default {
   mixins: [mutualMixin],
   computed: {
     exportExcel() {
-      let baseUrl = process.env.VUE_APP_BASE_API + "/cygx/user/companyList/export/interaction";
+      let baseUrl = process.env.API_ROOT + "/cygx/user/companyList/export/interaction";
       let token = localStorage.getItem("auth") || "";
       let salesArr = [];
       if (this.sales.length) {

+ 5 - 5
src/views/custom_manage/customList/customAllList.vue

@@ -21,7 +21,7 @@
                     <el-select v-model="type" placeholder="请选择客户类型"
                         style="width:200px;marginRight:10px;marginBottom:8px;" clearable
                         v-if="Role=='finance'||Role=='admin'" @change="changeType">
-                        <el-option v-for="item in typeArr" :key="item.name" :label="item.name" :value="item.name">
+                        <el-option v-for="item in typeArr" :key="item" :label="item.name" :value="item.name">
                         </el-option>
                     </el-select>
                     <el-select v-model="trade" placeholder="请选择行业"
@@ -156,7 +156,7 @@
                         </template>
                         <template slot-scope="scope">
                             <p :style="scope.row.IsSuspend===1?'color:#bbb;margin:3px 0':'margin:3px 0'"
-                                v-for="(item,index) in scope.row.Status.split('/')" :key="index">
+                                v-for="(item,index) in scope.row.Status.split('/')" :key="item">
                                 {{ item }}
                                 <template v-if="item === '试用' && scope.row.TryStageSlice">
                                     <el-select v-model="scope.row.TryStageSlice[index].TryStage"
@@ -310,7 +310,7 @@
                 </el-table>
                 <div class="toolbar fixedbar">
                     <el-pagination layout="prev,pager,next" background :current-page="page_no"
-                        @current-change="handleCurrentChange" :page-size="pageSize"
+                        @current-change="handleCurrentChange" :page-size="pageSize" @size-change="handleSizeChange"
                         :total="total" style="float:right;">
                     </el-pagination>
                 </div>
@@ -460,8 +460,8 @@
         },
         data() {
             return {
-                exportUrl: process.env.VUE_APP_BASE_API + '/custom/full/export', //导出数据
-                exportUser: process.env.VUE_APP_BASE_API + '/custom/full/user/export', //导出联系人
+                exportUrl: process.env.API_ROOT + '/custom/full/export', //导出数据
+                exportUser: process.env.API_ROOT + '/custom/full/user/export', //导出联系人
                 defaultprops: {
                     multiple: true,
                     label: 'ClassifyName',

+ 1 - 1
src/views/custom_manage/customList/customDetail.vue

@@ -694,7 +694,7 @@ export default {
 
 
 			showData:false,//
-			downTemplate:process.env.VUE_APP_BASE_API+'/custom/template?'+localStorage.getItem('auth')||'',//下载模板
+			downTemplate:process.env.API_ROOT+'/custom/template?'+localStorage.getItem('auth')||'',//下载模板
 			activeNames:'1',//默认展开
 			companyId:this.$route.query.id,
             IsFullCompany:Number(this.$route.query.IsFullCompany)||0,

+ 11 - 18
src/views/custom_manage/customList/customList.vue

@@ -27,7 +27,7 @@
 					<el-select v-model="type" placeholder="请选择客户类型" style="width:200px;marginRight:10px;marginBottom:8px;" clearable v-if="Role=='finance'||Role=='admin'" @change="changeType">
 						<el-option
 							v-for="item in typeArr"
-							:key="item.name"
+							:key="item"
 							:label="item.name"
 							:value="item.name">
 						</el-option>
@@ -118,12 +118,12 @@
 				</el-row>
 			</div>
 			<ul class="tabs_cont">
-				<li :class="['tab',act_status === item.Status?'act':'']" v-for="(item,index) in tabs" :key="index" @click="changeStatus(item,index)">
+				<li :class="['tab',{'act':act_status === item.Status}]" v-for="(item,index) in tabs" :key="index" @click="changeStatus(item,index)">
 					{{item.Status+'('+item.Count+')'}}
 				</li>
 			</ul>
 			<ul class="tabs_cont trial-ul" v-if="act_status === '试用'">
-				<li :class="['trial-item',act_trialTag === item.TryStage?'act':'']" v-for="item in trialTagArr" :key="item.TryStage" @click="changeTagStatus(item)">
+				<li :class="['trial-item',{'act':act_trialTag === item.TryStage}]" v-for="item in trialTagArr" :key="item.TryStage" @click="changeTagStatus(item)">
 					{{item.TryStageStr+'('+item.Count+')'}}
 				</li>
 			</ul>
@@ -141,8 +141,9 @@
 					align="center"
 					min-width="7.14%"
 					>
-						<template slot-scope="scope"> 
-						<div :class="[scope.row.IsShared?'isShared':'']">
+						<template slot-scope="scope"
+						:class="{'isShared':scope.row.IsShared}"
+						> 
 							<span 
 							v-if="scope.row.IsSuspend ===1 || scope.row.Status=='潜在'"
 							@click="goDetail(scope.row)"
@@ -155,7 +156,6 @@
 							:class="{'isShared':scope.row.IsShared,'color-red':act_status==='正式'&&scope.row.Status.includes('正式')&&scope.row.WeekViewActive===0}"
 							>{{scope.row.CompanyName}}</span>
 							<img width="15" src="../../../assets/img/icons/remark.png" alt="" v-if="scope.row.RenewalReason||(scope.row.Status==='冻结'&&scope.row.FreezeReason)">
-						</div>
 						</template>
 					</el-table-column>
 					<el-table-column label="To-Do" prop="todo" align="center" min-width="5.14%" sortable="custom">
@@ -262,7 +262,7 @@
 					</template>
 					<template slot-scope="scope"> 
 						<!-- <span :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.Status+(scope.row.ApproveStatus?'('+scope.row.ApproveStatus+')':'')}}</span>  -->
-						<p :style="scope.row.IsSuspend===1?'color:#bbb;margin:3px 0':'margin:3px 0'" v-for="(item,index) in scope.row.Status.split('/')" :key="index">
+						<p :style="scope.row.IsSuspend===1?'color:#bbb;margin:3px 0':'margin:3px 0'" v-for="(item,index) in scope.row.Status.split('/')" :key="item">
 							{{ item }}
 							<template v-if="item === '试用' && scope.row.TryStageSlice">
 								<el-select 
@@ -405,10 +405,9 @@
 							</span> 
 						</template>
 					</el-table-column>
-					<!-- :label="act_status=='冻结'?'冻结时间':act_status=='正式'?'转正时间':act_status=='流失'?'流失时间':'创建时间'" -->
 					<el-table-column
 					prop="createTime"
-					:label="setTableTimeLabel"
+					:label="act_status=='冻结'?'冻结时间':act_status=='正式'?'转正时间':act_status=='流失'?'流失时间':'创建时间'"
 					sortable="custom"
 					align="center" min-width="6.14%">
 						<template slot-scope="scope">
@@ -481,6 +480,7 @@
 					:current-page="page_no"
 					@current-change="handleCurrentChange"
 					:page-size="pageSize" 
+					@size-change="handleSizeChange" 
 					:total="total"
 					style="float:right;">
 					</el-pagination>
@@ -751,13 +751,6 @@ export default {
 		ModifyToDoDialog, CheckToDoDialog,HistoryToDoDialog,TotalDayDialog,permissionView,
 ShareListDialog},
 	computed:{
-		setTableTimeLabel(){
-			// :label="act_status=='冻结'?'冻结时间':act_status=='正式'?'转正时间':act_status=='流失'?'流失时间':'创建时间'"
-			if(this.act_status=='冻结') return '冻结时间'
-			if(this.act_status=='正式') return '转正时间'
-			if(this.act_status=='流失') return '流失时间'
-			return '创建时间'
-		},
 		Role() {
 			let role = localStorage.getItem('Role') || '';
 			return role;
@@ -878,8 +871,8 @@ ShareListDialog},
 				cusdata:null,//客户信息(列表用户数据)
 			},//申请转正、续约申请、补充协议 合同信息弹窗
 
-			exportUrl:process.env.VUE_APP_BASE_API+'/custom/export',//导出数据
-			exportUser:process.env.VUE_APP_BASE_API+'/custom/user/export',//导出联系人
+			exportUrl:process.env.API_ROOT+'/custom/export',//导出数据
+			exportUser:process.env.API_ROOT+'/custom/user/export',//导出联系人
 			defaultprops:{
 				multiple: true,
 				label:'ClassifyName',

+ 1 - 1
src/views/custom_manage/customList/editCustom.vue

@@ -528,7 +528,7 @@ export default {
 
 
 			showData:false,
-			downTemplate:process.env.VUE_APP_BASE_API+'/custom/template?'+localStorage.getItem('auth')||'',//下载模板
+			downTemplate:process.env.API_ROOT+'/custom/template?'+localStorage.getItem('auth')||'',//下载模板
 			roleDepart:'',//账号所属部门
 			companyList:[],
 			activeNames:'1',//默认展开

+ 6 - 3
src/views/custom_manage/listMatch.vue

@@ -6,9 +6,12 @@
 				style="display:inline-block"
 				:before-upload="beforeUploadFile"
 				:headers="headerConfig"
+				:file-list="fileList"
 				:on-success="handleSuccess"
+				:on-progress="handleStarting"
 				:action="importUrl"
 				accept=".xlsx"
+				:data="params"
 				name="File"
 				:show-file-list="false"
 			>
@@ -39,15 +42,15 @@
 export default {
     computed: {
         downloadUrl(){
-            const url=process.env.VUE_APP_BASE_API+'/custom/list/match/download'
+            const url=process.env.API_ROOT+'/custom/list/match/download'
             return url+'?Code='+this.code+'&'+localStorage.getItem('auth')
         }
     },
     data() {
         return {
             templateUrl:'https://hzstatic.hzinsights.com/static/admin/excel/客户名单匹配模板.xlsx',
-            importUrl:process.env.VUE_APP_BASE_API+'/custom/list/match/import',
-            // downloadUrl:process.env.VUE_APP_BASE_API+'/custom/list/match/download',
+            importUrl:process.env.API_ROOT+'/custom/list/match/import',
+            // downloadUrl:process.env.API_ROOT+'/custom/list/match/download',
             headerConfig:{
 				Authorization:localStorage.getItem('auth')
 			},

+ 2 - 1
src/views/custom_manage/pickList.vue

@@ -110,7 +110,8 @@
 					background 
 					:current-page="page_no"
 					@current-change="handleCurrentChange"
-					:page-size="pageSize"
+					:page-size="pageSize" 
+					@size-change="handleSizeChange" 
 					:total="total"
 					style="float:right;">
 					</el-pagination>

+ 3 - 3
src/views/custom_manage/potentialList.vue

@@ -14,7 +14,7 @@
         >
           <el-option
             v-for="item in statusArr"
-            :key="item.id"
+            :key="item"
             :label="item.name"
             :value="item.id"
           >
@@ -362,7 +362,7 @@ export default {
     exportUser() {
       let param_token = localStorage.getItem("auth") || "";
       return (
-        process.env.VUE_APP_BASE_API +
+        process.env.API_ROOT +
         "/custom/potential/user/export?ApplyMethod=" +
         this.status +
         "&KeyWord=" +
@@ -378,7 +378,7 @@ export default {
   },
   data() {
     return {
-      // exportUser:process.env.VUE_APP_BASE_API+'/custom/potential/user/export',
+      // exportUser:process.env.API_ROOT+'/custom/potential/user/export',
       status: "", //状态
       statusArr: [
         {

+ 0 - 1
src/views/custom_manage/saleAuthManage.vue

@@ -95,7 +95,6 @@ import { customInterence } from "@/api/api.js";
 export default {
   data() {
     return {
-      modifySales:0,//用于重新渲染选择销售级联选择窗
       sales: "",
       salesArr: [],
       defaultSalesProps: {

+ 0 - 1
src/views/custom_manage/trialApplication.vue

@@ -222,7 +222,6 @@ export default {
   data() {
     //这里存放数据
     return {
-	  exportUser:null,
       search_txt: "",
       isShowloadding: false,
       tableData: [], //表格数据

+ 1001 - 0
src/views/dataEntry_manage/addChart.vue

@@ -0,0 +1,1001 @@
+<template>
+  <div class="addchart-container" id="box">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+    <div class="left-cont" v-show="!isSlideLeft" id="left">
+      <div class="left-top">
+        <el-button 
+					type="primary" 
+					@click="saveHandle"
+					:disabled="chartInfo.ChartType === 5 && tableData.length !== 2"
+				>保存</el-button>
+        <el-button type="primary" plain @click="$router.back()">取消</el-button>
+      </div>
+			<div class="left-min">
+				<el-form
+					ref="diaForm"
+					label-position="top"
+					label-width="80px"
+					:model="chartInfo"
+					:rules="chartRules"
+				>
+					<el-form-item label="图表生成样式" prop="ChartType">
+						<el-select
+							v-model="chartInfo.ChartType"
+							placeholder="请选择生成样式"
+							style="width: 90%"
+						>
+							<el-option
+								v-for="item in styleArr"
+								:key="item.key"
+								:label="item.label"
+								:value="item.key"
+							>
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="图表名称" prop="ChartName">
+						<el-input
+							v-model="chartInfo.ChartName"
+							style="width: 90%"
+							placeholder="必填项"
+							clearable
+						/>
+					</el-form-item>
+					<el-form-item label="图表分类" prop="classify">
+						<el-cascader
+							v-model="chartInfo.classify"
+							:options="classifyOptions"
+							:props="levelProps"
+							style="width: 90%"
+							placeholder="请选择所属分类"
+						/>
+					</el-form-item>
+				</el-form>
+
+				<div class="search-cont" v-if="chartInfo.ChartType!==10">
+					<div>
+						<label>选择指标:</label>
+						<el-radio-group v-model="edbFromType">
+							<el-radio :label="0" style="margin-right: 15px">ETA指标</el-radio>
+							<el-radio :label="1">ETA预测指标</el-radio>
+						</el-radio-group>
+					</div>
+					<el-select
+						v-model="search_txt"
+						v-loadMore="searchLoad"
+						ref="searchRef"
+						:filterable="!search_txt"
+						remote
+						clearable
+						placeholder="指标ID/指标名称"
+						style="width:90%;margin-top: 10px;display: block;"
+						:remote-method="searchHandle"
+						@click.native="inputFocusHandle"
+						@change="selectTarget($event && searchOptions.find(_ => _.EdbInfoId === $event))"
+					>
+						<i slot="prefix" class="el-input__icon el-icon-search"></i>
+						<el-option
+							v-for="item in searchOptions"
+							:key="item.EdbInfoId"
+							:label="chart_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
+							:value="item.EdbInfoId"
+						>
+							<edbDetailPopover :info="item">
+								<div slot="reference">{{chart_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName }}</div>
+							</edbDetailPopover>
+						</el-option>
+					</el-select>
+				</div>
+
+				<div class="targetset-cont">
+					<!-- 仅用于散点图配置 -->
+					<div class="scatter-setting" v-if="chartInfo.ChartType === 5 && tableData.length">
+						<div style="display: flex;margin-right: 15px;">
+							<span style="margin-right: 3px">线条颜色:</span>
+							<el-color-picker
+								v-model="tableData[0].ChartColor"
+								size="mini"
+								show-alpha
+								:predefine="predefineColors"
+							></el-color-picker>
+						</div>
+						<el-checkbox v-model="tableData[0].IsOrder">逆序</el-checkbox>
+					</div>
+					
+          <el-collapse v-model="activeNames" class="target-list" v-if="tableData.length&&![7,10].includes(chartInfo.ChartType)">
+            <el-collapse-item v-for="(item,index) in tableData" :key="item.EdbInfoId" :disabled="[2,5].includes(chartInfo.ChartType)">
+              <template slot="title">
+                <span class="text_oneLine">{{item.EdbName}}</span>
+								<i class="el-icon-delete del-icon" @click.stop="delTarget(item)"></i>
+              </template>
+              <ul class="setting-cont" v-if="sameOptionType.includes(chartInfo.ChartType)">
+
+								<!-- 堆叠图 或组合图中的堆叠类型 非第一项隐藏配置 -->
+								<template v-if="showYOptionsHandle(item,index)">
+									<li>
+										<el-checkbox v-model="item.IsOrder">逆序</el-checkbox>
+									</li>
+									<li>
+										<el-radio-group v-model="item.IsAxis" size="mini">
+											<el-radio-button :label="1">左轴</el-radio-button>
+											<el-radio-button :label="0">右轴</el-radio-button>
+
+											<!-- 指标有右轴时才可以选右2轴 不然没有右2这个概念的意义 -->
+											<el-radio-button 
+												v-if="[1,6].includes(chartInfo.ChartType)"
+												:label="2" 
+												:disabled="(tableData.findIndex(_ => _.IsAxis===0) === -1) 
+												|| (tableData.findIndex(_ => _.IsAxis===0) === index 
+														&& tableData.filter(_ => _.IsAxis===0).length === 1)"
+											>右2轴</el-radio-button>
+										</el-radio-group>
+									</li>
+								</template>
+                <li style="min-width: 250px">
+                  <el-radio
+                    v-model="item.EdbInfoType"
+                    :label="1"
+                    @change="refreshTarget"
+                    >标准指标</el-radio
+                  >
+                  <div style="margin-top: 15px">
+                    <el-radio
+                      v-model="item.EdbInfoType"
+                      :label="0"
+                      style="margin-right: 10px"
+                      @change="refreshTarget"
+                      >领先指标</el-radio
+                    >
+                    <template v-if="item.EdbInfoType === 0">
+                      领先
+                      <el-input
+                        style="width: 60px"
+                        size="mini"
+                        type="number"
+												min="0"
+                        v-model="item.LeadValue"
+                        @change="refreshTarget"
+                        @keyup.native="filterCode(item)"
+                      ></el-input>
+                      <el-select
+                        v-model="item.LeadUnit"
+                        placeholder=""
+                        style="width: 60px"
+                        size="mini"
+                        @change="refreshTarget"
+                      >
+                        <el-option
+                          v-for="item in fre_options"
+                          :key="item"
+                          :label="item"
+                          :value="item"
+                        >
+                        </el-option>
+                      </el-select>
+                    </template>
+                  </div>
+                </li>
+                <li>
+                  <div style="display: flex">
+                    <span style="margin-right: 3px">线条颜色:</span>
+                    <el-color-picker
+                      v-model="item.ChartColor"
+                      size="mini"
+											show-alpha
+                      :predefine="predefineColors"
+                    ></el-color-picker>
+                  </div>
+									<div style="display: flex;margin-top: 12px" v-if="item.EdbInfoCategoryType === 1">
+                    <span style="margin-right: 3px">预测值颜色:</span>
+                    <el-color-picker
+                      v-model="item.PredictChartColor"
+                      size="mini"
+											show-alpha
+                      :predefine="predefineColors"
+                    ></el-color-picker>
+                  </div>
+                  <div 
+										style="margin-top: 12px" 
+										v-if="chartInfo.ChartType === 1 
+										|| (chartInfo.ChartType === 6 &&item.ChartStyle==='spline')"
+									>
+                    线条粗细:
+                    <el-input
+                      style="width: 60px"
+                      size="mini"
+                      type="number"
+                      :min="1"
+                      v-model="item.ChartWidth"
+                    />
+                  </div>
+                </li>
+                <li v-if="chartInfo.ChartType === 6">
+                  <div style="display: flex">
+                    <span style="margin-right: 3px">生成样式:</span>
+                    <el-select
+											v-model="item.ChartStyle"
+											placeholder="请选择生成样式"
+											style="width: 50%"
+											class="edb-item-style"
+										>
+											<el-option
+												v-for="item in chartItemStyleArr"
+												:key="item.key"
+												:label="item.label"
+												:value="item.value"
+											>
+											</el-option>
+										</el-select>
+                  </div>
+                </li>
+              </ul>
+							<div style="margin: 10px;text-align: center;color: #999;" v-else>暂无配置</div>
+            </el-collapse-item>
+          </el-collapse>
+
+					<!-- 奇怪柱状图配置 -->
+					<bar-option
+						v-if="chartInfo.ChartType===7"
+						ref="BarOptRef"
+						:edblist="tableData"
+						:datedata="barDateList"
+						@getData="getBarPreviewData"
+					/>
+
+					<!-- 截面散点图 -->
+					<sectional-scatter-option
+						v-if="chartInfo.ChartType===10"
+						ref="SectionScatterOptRef"
+						@getData="getSectionScatterData"
+					/>
+        </div>
+			</div>
+      <span
+        class="move-btn resize"
+        v-drag
+        id="resize"
+        @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+      ></span>
+      <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+				<i class="el-icon-d-arrow-left"></i>
+			</span>
+    </div>
+    <div class="right-cont" id="right" :style="isSlideLeft ? 'width:100%' : `width:80%`">
+			<div class="chart-min-cont" v-if="tableData.length">
+				<div class="cont-top">
+					<div class="top-left">
+						<!-- 默认曲线图 -->
+						<template v-if="sameOptionType.includes(chartInfo.ChartType)">
+							<el-button
+								type="primary"
+								v-for="item in yearSelector"
+								:key="item.value"
+								size="medium"
+								:plain="item.value !== year_select"
+								class="year-btn"
+								@click.native="changeYear(item)"
+								>{{ item.name }}</el-button
+							>
+							<el-button type="text" class="btn-sty" @click="openDateDia">{{
+								dateTip
+							}}</el-button>
+						</template>
+						<!-- 季节性图选择年份区间 -->
+						<date-picker
+							v-else-if="chartInfo.ChartType === 2"
+							v-model="season_year"
+							type="month"
+							value-type="format"
+							range
+							placeholder="年份日期选择"
+							@change="seasonYearChange"
+						/>
+					</div>
+				</div>
+				<div class="cont-bottom">
+					<div class="chart-show-cont" v-show="options.series">
+						<div class="chartWrapper" id="chartWrapper">
+							<h2 class="chart-title" v-show="chartInfo.ChartName">{{ chartInfo.ChartName }}</h2>
+							<Chart :options="options" ref="chartRef" />
+							<div class="range-cont left" v-if="leftIndex != -1">
+								<el-input
+									style="width: 60px; display: block"
+									size="mini"
+									type="number"
+									placeholder="上限"
+									v-model="tableData[leftIndex].MaxData"
+								/>
+								<el-input
+									class="min-data-input"
+									size="mini"
+									type="number"
+									placeholder="下限"
+									v-model="tableData[leftIndex].MinData"
+								/>
+							</div>
+							<div class="range-cont right" v-if="rightIndex != -1">
+								<el-input
+									style="width: 60px; display: block"
+									size="mini"
+									type="number"
+									placeholder="上限"
+									v-model="tableData[rightIndex].MaxData"
+								/>
+								<el-input
+									class="min-data-input"
+									size="mini"
+									type="number"
+									placeholder="下限"
+									v-model="tableData[rightIndex].MinData"
+								/>
+							</div>
+							<!-- 右2上下限设置 -->
+							<div class="range-cont rightTwo" v-if="rightTwoIndex != -1">
+								<el-input
+									style="width: 60px; display: block"
+									size="mini"
+									type="number"
+									placeholder="上限"
+									v-model="tableData[rightTwoIndex].MaxData"
+								/>
+								<el-input
+									class="min-data-input"
+									size="mini"
+									type="number"
+									placeholder="下限"
+									v-model="tableData[rightTwoIndex].MinData"
+								/>
+							</div>
+
+							<!-- 后续新图专用上下限 和其他数据依赖不公用 柱形图 截面散点-->
+							<template v-if="[7,10].includes(chartInfo.ChartType)">	
+								<div class="range-cont left">
+									<el-input
+										style="width: 60px; display: block"
+										size="mini"
+										type="number"
+										placeholder="上限"
+										v-model="chartLimit.max"
+										@change="changeLimit"
+									/>
+									<el-input
+										class="min-data-input"
+										size="mini"
+										type="number"
+										placeholder="下限"
+										v-model="chartLimit.min"
+										@change="changeLimit"
+									/>
+								</div>
+								<!-- x轴上下限 -->
+								<div class="range-cont bottom" v-if="chartLimit.x_min||chartLimit.x_max">
+									<el-input
+										class="left"
+										size="mini"
+										type="number"
+										placeholder="下限"
+										v-model="chartLimit.x_min"
+										@change="changeLimit"
+									/>
+									<el-input
+										class="left"
+										size="mini"
+										type="number"
+										placeholder="上限"
+										v-model="chartLimit.x_max"
+										@change="changeLimit"
+									/>
+								</div>
+							</template>
+						</div>
+						<span class="chart-author"
+							>作者:{{ chartInfo.SysUserRealName || roleName }}</span
+						>
+
+						<!-- 公历农历切换 只用于季节性图 -->
+						<el-radio-group
+							v-model="calendar_type"
+							class="calendar-cont"
+							v-if="chartInfo.ChartType === 2"
+							@change="refreshChart"
+						>
+							<el-radio-button label="公历" />
+							<el-radio-button label="农历" />
+						</el-radio-group>
+					</div>
+					<el-table
+						:data="tableData"
+						ref="tableRef"
+						highlight-current-row
+						border
+					>
+						<el-table-column
+							v-for="item in tableColums"
+							:key="item.label"
+							:label="item.label"
+							:width="item.widthsty"
+							:min-width="item.minwidthsty"
+							align="center"
+						>
+							<template slot-scope="scope">
+								<div v-if="item.key === 'EdbName' && chartInfo.ChartType === 7">
+									<!-- 奇怪柱状图用别名 -->
+									<el-input 
+										v-model="scope.row.EdbAliasName"
+										placeholder="指标别名"
+										class="target-other-name"
+										clearable
+									/>
+								</div>
+								<span v-else>{{ scope.row[item.key] }}</span>
+							</template>
+						</el-table-column>
+						<el-table-column
+							label="操作"
+							key="Copy"
+							align="center"
+							width="140"
+						>
+							<template slot-scope="scope">
+								<span @click="delTarget(scope.row)" class="deletesty">删除&nbsp;</span>
+								<span class="editsty" @click="copyCode(scope.row)">
+									<i class="el-icon-document-copy" />&nbsp;复制数据</span
+								><br>
+								<span
+									class="editsty"
+									@click="viewTarget(scope.row)"
+								>查看数据</span>
+							</template>
+						</el-table-column>
+						<div slot="empty">
+							<img
+								src="~@/assets/img/data_m/table_no.png"
+								alt=""
+								style="
+									display: block;
+									width: 135px;
+									height: 90px;
+									margin: 20px auto 10px;
+								"
+							/>
+							<span>暂无指标</span>
+						</div>
+					</el-table>
+				</div>
+      </div>
+			<div class="nodata" v-else>
+				<img
+          src="~@/assets/img/data_m/table_no.png"
+          alt=""
+          style="
+            display: block;
+            width: 140px;
+            height: 148px;
+						margin: 0 auto;
+          "
+        />
+        暂无信息
+			</div>
+		</div>
+
+		<!-- 日期端选择弹窗 -->
+    <DateChooseDia
+      :isDateDia="isDateDia"
+      :dateForm="dateForm"
+      @cancel="isDateDia = false"
+      @dateBack="dataChangeBack"
+    />
+  </div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import { chartSetMixin } from './mixins/chartPublic';
+import addOrEditMixn from './mixins/addOreditMixin';
+import Chart from './components/chart';
+import DateChooseDia from './components/DateChooseDia';
+import barOption from './components/barOptionSection.vue';
+import sectionalScatterOption from './components/sectionalScatterOption.vue';
+export default {
+  components: { Chart,DateChooseDia,barOption,sectionalScatterOption },
+	directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 300 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    },
+  },
+	watch: {
+		tableData: {
+      handler(newval, oldval) {
+				if(newval.length) {
+					if([7,10].includes(this.chartInfo.ChartType)) {
+						// 奇怪柱形图
+						this.chartInfo.ChartType === 7 && this.barDateList.length && this.$refs.BarOptRef.getBarData();
+				
+					}else {
+						//拼接标题
+						this.chartInfo.ChartName =  this.sameOptionType.includes(this.chartInfo.ChartType) ? newval.map((item,index) => index === newval.length-1 ? item.EdbName : `${item.EdbName}和`).join('') : `${newval[0].EdbName}季节性`;
+	
+						this.setAddChartDefault();
+						this.setChartOptionHandle(newval);
+					}
+
+				}else {
+					this.chartInfo.ChartName = '';
+				}
+      },
+      deep: true,
+    }
+	},
+	computed: {
+		roleName() {
+			return localStorage.getItem('userName');
+		}
+	},
+	mixins: [chartSetMixin,addOrEditMixn],
+  data() {
+    return {
+			isSlideLeft: false,
+			search_txt: '',
+
+			calendar_type: '公历',//默认公历
+			season_year:'',//季节图时间段
+			activeNames:'',
+
+			needWatch: true
+
+    };
+  },
+  methods: {
+		/* 保存 */
+		saveHandle() {
+			if(!this.tableData.length) return this.$message.warning('暂未选择指标');
+			console.log(this.chartInfo)
+			this.$refs.diaForm.validate((valid) => {
+				if(valid) {
+					// 季节图只允许添加一个指标
+					if(this.chartInfo.ChartType === 2 && this.tableData.length > 1)  return this.$message.warning('您选择的图表样式为季节性图表,只支持单指标画图');
+
+					if(this.chartInfo.ChartType === 7 && !this.$refs.BarOptRef.dateList.length)  return this.$message.warning('请添加日期');
+
+					if(this.chartInfo.ChartType === 10 && !this.$refs.SectionScatterOptRef.seriesArr[0].edbs)  return this.$message.warning('请添加系列指标');
+
+					let db_arr = this.tableData.map(item => ({
+							ChartColor: item.ChartColor,
+							PredictChartColor: item.PredictChartColor,
+							ChartStyle: item.ChartStyle,
+							ChartWidth: Number(item.ChartWidth),
+							EdbInfoId: item.EdbInfoId,
+							EdbInfoType: item.EdbInfoType,
+							IsAxis: item.IsAxis,
+							IsOrder: item.IsOrder,
+							LeadUnit: item.EdbInfoType ? '' : item.LeadUnit,
+							LeadValue: item.EdbInfoType ? 0 : Number(item.LeadValue),
+							MaxData: Number(item.MaxData),
+							MinData: Number(item.MinData)
+						})
+					)
+
+					let public_param = {
+						ChartClassifyId: this.chartInfo.classify.length ? this.chartInfo.classify[this.chartInfo.classify.length - 1] : 0,
+						ChartName: this.chartInfo.ChartName,
+						ChartType: this.chartInfo.ChartType,
+						ChartEdbInfoList: db_arr,
+					}
+
+					//提交参数
+					const typePrams = this.getSaveParamsByChartType(public_param);
+
+					let params = this.sameOptionType.includes(this.chartInfo.ChartType) 
+						? {
+								...public_param,
+								DateType: this.year_select,
+								StartDate:
+										[5,6].includes(this.year_select)
+											? this.select_date[0]
+											: '',
+								EndDate: this.year_select === 5 ? this.select_date[1] : '',
+							} 
+						: typePrams
+
+					dataBaseInterface.chartAdd(params).then(res => {
+						if(res.Ret !== 200) return;
+							this.setChartImage(res.Data);
+					})
+				}
+			})
+		},
+
+		 /* 设置图表封面图片 */
+    setChartImage(data) {
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart: {
+          width: 340,
+          height: 230,
+        }
+      });
+      let form = new FormData();
+      form.append('Img', svg);
+      this.setImageHandle(form,data);
+    },
+    async setImageHandle(form,{ UniqueCode,ChartInfoId }) {
+      let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // let { Data } = await dataBaseInterface.uploadImg(form);
+      await dataBaseInterface.setChartImage({
+        ChartInfoId: ChartInfoId,
+        ImageUrl: Data.ResourceUrl,
+      });
+
+			this.$message.success('添加成功');
+			this.$router.replace({
+				path: '/chartsetting',
+				query: {
+					code: UniqueCode,
+					id: ChartInfoId
+				}
+			})
+
+    },
+	},
+  mounted() {
+		this.getMenu();
+		window.addEventListener('resize', this.reloadRightWid);
+	},
+	destroyed() {
+		window.removeEventListener('resize', this.reloadRightWid);
+	}
+};
+</script>
+<style lang="scss">
+.addchart-container {
+	$font-small: 12px; $font-normal: 14px;
+
+  display: flex;
+	*{ box-sizing: border-box; }
+	.el-form--label-top .el-form-item__label {
+		padding: 0;
+	}
+	.el-form-item {
+		margin-bottom: 8px;
+	}
+	.el-input-number .el-input__inner {
+		padding: 0 34px 0 4px;
+	}
+	.target-other-name .el-input__inner {
+		padding: 0 30px 0 5px !important;
+		height: 40px !important;
+		line-height: 40px !important;
+	}
+	.el-color-picker--mini .el-color-picker__trigger {
+		width: 60px;
+		height: 25px;
+		padding: 0;
+	}
+	.el-color-picker--mini .el-color-picker__mask {
+		width: 60px;
+		height: 25px;
+	}
+
+	.slide-icon {
+		padding: 20px 0;
+		/* display: block; */
+		box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+		border-radius: 5px;
+		cursor: pointer;
+		position: absolute;
+		top: 50%;
+		transform: translateY(-50%);
+		z-index: 99;
+		&:hover {
+			background-color: rgba(0, 0, 0, 0.05);
+		}
+		&.slide-left {
+			right: 0;
+		}
+		&.slide-right {
+			left: 0;
+		}
+	}
+  .left-cont {
+    width: 400px;
+    min-width: 300px;
+    background: #fff;
+    margin-right: 20px;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    height: calc(100vh - 113px);
+    overflow: hidden;
+    position: relative;
+    box-sizing: border-box;
+    .left-top {
+      padding: 15px 20px;
+      border: 1px solid #ececec;
+      box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+    }
+		.left-min {
+			padding: 30px 20px;
+			max-height: calc(100vh - 194px);
+			overflow-y: auto;
+			.search-cont {
+				color: #606266;
+				margin-top: 20px;
+			}
+			.targetset-cont {
+				padding: 30px 0 20px;
+				.el-input__inner {
+					height: 27px;
+					line-height: 27px;
+					padding: 0 4px;
+				}
+				.el-collapse-item.is-disabled .el-collapse-item__header {
+					color: #333;
+				}
+				.target-list {
+					border: 1px solid #DCDFE6;
+					.del-icon {
+						position: absolute;
+						right: 10px;
+						font-size: 16px;
+						color: #f00;
+						cursor: pointer;
+					}
+					.setting-cont {
+						padding: 20px 20px 0;
+						li {
+							padding-bottom: 20px;
+							margin-bottom: 20px;
+							border-bottom: 1px solid #DCDFE6;
+							&:last-child {
+								padding-bottom: 0;
+								margin-bottom: 0;
+								border-bottom: none;
+							}
+						}
+					}
+				}
+				.el-collapse-item__header {
+					background-color: #F0F2F5;
+					margin-bottom: 0;
+					border-bottom: 1px solid #DCDFE6;
+					padding: 0 30px;
+					.el-collapse-item__arrow {
+						position: absolute;
+						left: 8px;
+					}
+				}
+
+				.scatter-setting {
+					display: flex;
+					margin-bottom: 20px;
+				}
+			}
+		}
+		.move-btn {
+			height: 100%;
+			width: 4px;
+			position: absolute;
+			right: 0px;
+			top: 0;
+			&:hover {
+				cursor: col-resize;
+			}
+		}
+  }
+	.right-cont {
+		width: 80%;
+    .mx-datepicker {
+      width: 220px !important;
+    }
+		 /* =================== */
+		.chart-min-cont {
+			background: #fff;
+			border: 1px solid #ececec;
+			height: calc(100vh - 118px);
+			overflow: auto;
+			/* overflow: hidden; */
+			border-radius: 4px;
+			box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+			.cont-top {
+				padding: 12px 30px;
+				border-bottom: 1px solid #ececec;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+				.top-left {
+					.year-btn {
+						margin-right: 5px;
+						margin-bottom: 5px;
+					}
+					.btn-sty {
+						border: 1px solid #409eff;
+					}
+				}
+				.top-right {
+					font-size: 16px;
+					.join_txt {
+						color: #409eff;
+						cursor: pointer;
+						&:hover {
+							text-decoration: underline;
+						}
+					}
+					.collected {
+						color: #f00;
+						cursor: pointer;
+						&:hover {
+							text-decoration: underline;
+						}
+					}
+					.span-item {
+						color: #409eff;
+						cursor: pointer;
+						&:hover {
+							text-decoration: underline;
+						}
+						.el-icon-collection,
+						.el-icon-document-copy {
+							color: #409eff;
+						}
+					}
+				}
+			}
+			.cont-bottom {
+				padding: 20px 30px;
+				/* height: calc(100vh - 250px);
+				overflow: auto; */
+				.el-input__inner {
+					height: 27px;
+					line-height: 27px;
+					padding: 0 4px;
+				}
+				.el-input-number .el-input__inner {
+					padding: 0 34px 0 4px;
+				}
+				.highcharts-range-selector-group {
+					display: none;
+					.highcharts-input-group {
+						display: none;
+					}
+				}
+				.highcharts-axis-title {
+					display: block;
+				}
+				.calendar-cont {
+					display: block;
+					margin: 10px auto 0;
+					text-align: center;
+				}
+				/* =================== */
+				.chart-show-cont {
+					min-height: 300px;
+					padding: 0 150px 60px 120px;
+					position: relative;
+					.chart-title {
+						font-size: 16px;
+						font-weight: normal;
+						text-align: center;
+						margin-bottom: 10px;
+					}
+					.chart-author {
+						font-size: 14px;
+						color: #333;
+						position: absolute;
+						bottom: 20px;
+						right: 50px;
+					}
+					.chartWrapper {
+						position: relative;
+						.range-cont {
+							position: absolute;
+							top: 15%;
+							.min-data-input {
+								width: 60px;
+								display: block;
+							}
+							&.left {
+								left: -80px;
+							}
+							&.right {
+								right: -65px;
+							}
+							&.rightTwo {
+								right: -130px;
+							}
+							&.bottom {
+								width: 100%;
+								display: flex;
+								justify-content: space-between;
+								top: auto;
+								right: 0;
+								bottom: -3%;
+								.left {
+									width: 60px;
+									display: block;
+									flex-shrink: 0;
+								}
+							}
+						}
+					}
+				}
+				.options-cont {
+					display: flex;
+					flex-wrap: wrap;
+					justify-content: space-between;
+				}
+			}
+
+		}
+    .nodata {
+      height: calc(100vh - 120px);
+			background-color: #fff;
+      text-align: center;
+      font-size: 16px;
+      color: #666;
+			padding: 100px 0;
+    }
+		@media screen and (min-width: 1711px){
+			.min-data-input {
+				margin-top: 310px;
+			}
+			.btn-sty {
+				padding: 10px;
+			}
+			.year-btn,.btn-sty {
+				font-size: $font-normal;
+			}
+		}
+
+		@media screen and (max-width: 1710px){
+			.min-data-input {
+				margin-top: 230px;
+			}
+			.year-btn {
+				font-size: $font-small;
+				margin-left: 5px;
+				margin-right: 5px;
+				margin-bottom: 5px;
+				padding: 6px 12px;
+			}
+			.btn-sty {
+				font-size: $font-small;
+				margin-left: 5px;
+				padding: 6px;
+				border: 1px solid #409eff;
+			}
+		}
+	}
+}
+</style>
+<style lang="scss">
+.edb-item-style .el-input__icon {
+	line-height: 27px;
+}
+</style>

+ 593 - 0
src/views/dataEntry_manage/adjustdata/adjustData.vue

@@ -0,0 +1,593 @@
+<template>
+  <div class="adjust-data-container">
+    <div class="wrap-top">
+      <div>
+        <ul class="min-top" v-if="!edb_id">
+          <li>
+            <label style="margin-right:5px;">选择指标:</label>
+            <el-select
+              v-model="select_target"
+              v-loadMore="searchLoad"
+              :filterable="!select_target"
+              clearable
+              placeholder="请输入指标名称"
+              style="width: 200px"
+              remote
+              :remote-method="getTarget"
+              @click.native="inputFocusHandle"
+              @change="chooseTarget"
+              @blur="search_have_more = false"
+            >
+              <i slot="prefix" class="el-input__icon el-icon-search"></i>
+              <el-option
+                v-for="item in searchOptions"
+                :key="item.EdbInfoId"
+                :label="eta_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
+                :value="item.EdbInfoId"
+              >
+              </el-option>
+            </el-select>
+            <i class="el-icon-tickets" style="color:#409EFF;font-size:18px" @click="isLookHistory=true;lookEdbId=select_target" v-if="select_target"/>
+          </li>
+          <li v-show="old_edb_info.id">
+            <label style="margin-right:5px;"> 查询结果:( </label>
+            <span style="margin-right: 20px">指标ID:{{old_edb_info.id}}</span>
+            <span>指标名称:{{old_edb_info.name}})</span>
+          </li>
+        </ul>
+        <div v-if="edb_id" style="margin-bottom:20px">
+          <span style="display:inline-block;margin-right:30px">原指标ID:{{EDBInfoOfCalculateData.FromEdbCode}}</span>
+          <span>原指标名称:{{EDBInfoOfCalculateData.FromEdbName}}</span>
+        </div>
+        <el-form
+          ref="form"
+          label-position="right"
+          inline
+          label-width="80px"
+          :model="formData"
+          :rules="formRules"
+        >
+          <el-form-item label="指标名称" prop="targetName">
+            <el-input
+              v-model="formData.targetName"
+              style="width: 150px"
+              placeholder="请输入指标名称"
+            />
+          </el-form-item>
+          <el-form-item label="单位" prop="unit">
+            <selectUnit 
+							v-model="formData.unit" 
+							style="width: 150px"
+						/>
+          </el-form-item>
+          <el-form-item label="指标目录" prop="menu">
+            <el-cascader
+              v-model="formData.menu"
+              :options="classifyOptions"
+              :props="{
+                label: 'ClassifyName',
+                value: 'ClassifyId',
+                children: 'Children',
+                emitPath: false
+              }"
+              clearable
+              placeholder="请选择指标目录"
+            />
+          </el-form-item>
+          <el-form-item label="频度" prop="frequency">
+            <el-select
+              v-model="formData.frequency"
+              placeholder="请选择频度"
+              style="width: 150px"
+              clearable
+              :disabled="type === 14"
+            >
+              <el-option
+                v-for="item in frequencyArr"
+                :key="item"
+                :label="item"
+                :value="item"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+
+      </div>
+      <div class="right-handle">
+        <div>
+          <el-button type="primary" size="medium" @click="saveSheetHandle">保存</el-button>
+          <el-button type="primary" size="medium" plain @click="$router.go(-1)">取消</el-button>
+        </div>
+        <el-tooltip>
+          <div slot="content" v-html="tips"></div>
+          <div class="tips-cont">
+            <span>使用说明</span>
+            <i class="el-icon-question" style="color: #999;"></i>
+          </div>
+        </el-tooltip>
+      </div>
+    </div>
+    
+    <div class="main">
+      <div class="table-cont" v-if="!edb_id">
+        <el-table
+          :data="filterList"
+          border
+          height="650"
+          ref="table"
+        >
+            <el-table-column
+              v-for="item in tableColums"
+              :key="item.key"
+              :label="item.label"
+              :width="item.widthsty"
+              :min-width="item.minwidthsty"
+              align="center"
+            >
+              <template slot-scope="scope">
+                <span>{{ scope.row[item.key] }}</span>
+              </template>
+            </el-table-column>
+            <div slot="empty" style="padding: 50px 0;">
+              <img src="~@/assets/img/data_m/table_no.png" alt="" style="display:block;width:135px;height:90px;margin: 20px auto 10px;">
+              <span>暂无数据</span>
+            </div>
+        </el-table>
+      </div>
+      <div id="excel-container"></div>
+    </div>
+
+    <!-- 指标历史记录 -->
+    <edbHistoryDialog
+      :isOpenDialog.sync="isLookHistory"
+      :edbId="lookEdbId"
+    />
+  </div>
+</template>
+
+<script>
+import {dataBaseInterface} from '@/api/modules/chartApi'
+import { formRules } from '../databaseComponents/util';
+import { unitArr } from '@/utils/defaultOptions';
+import { mapState } from 'vuex';
+export default {
+  data() {
+    return {
+      edb_id: this.$route.query.edbid,
+      select_target: '',
+      formData: {
+        targetName: '',
+        menu: '',
+        frequency: '',
+        unit: ''
+      },
+      formRules,
+      unitArr,
+      frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
+      classifyOptions: [],
+
+      searchOptions: [],
+      search_have_more: false,
+			search_page: 1,
+			current_search: '',
+
+      old_edb_info: {
+        id: '',
+        name: ''
+      },
+      old_edb_data: [],
+      rowHeight: 48,
+      page_size: 20,
+      start_index: 0,
+      end_index: 49,
+      tableColums: [
+        { label: '日期',key:'DataTime' },
+        { label: '值',key:'Value' }
+      ],
+
+      tips: `数据调整:<br>1、将所选指标的历史数据经过调整后保存,该指标更新时将在调整数据的基础上更新最新数据;<br>
+      2、支持对所选指标添加未来的数据,指标更新到未来相同的日期时,进行数据更正;<br>
+      3、选中表格,使用“Ctrl+F”可调用快速查找功能,支持快速定位到表格中的数据;<br>
+      注:系统只取A、B列数据`,
+
+      excelData: [
+        {
+          r:0,
+          c:0,
+          v:{
+            m:"日期",
+            v:"日期",
+            bg:'#bbb'
+          },
+        },
+        {
+          r:0,
+          c:1,
+          v:{
+            m:"值",
+            v:"值",
+            bg:'#bbb'
+          },
+        },
+      ],
+
+      /* 查看历史弹窗 */
+			isLookHistory: false,
+			lookEdbId: 0,
+      EDBInfoOfCalculateData:{},
+    }
+  },
+  computed: {
+    excelOptions() {
+      return {
+        container: 'excel-container',
+        lang: 'zh', // 设定表格语言
+        showinfobar: false,//顶部info
+        showsheetbar:false,//底部sheet页 暂禁止添加多个表格
+        showtoolbarConfig:{
+          image: false,//图片
+          print: false,//打印
+          chart: false, // '图表'
+          postil:  false, //'批注'
+          pivotTable: false,  //'数据透视表'
+          function: false, // '公式'
+          frozenMode: false, // '冻结方式'
+          sortAndFilter: false, // '排序和筛选'
+          conditionalFormat: false, // '条件格式'
+          dataVerification: false, // '数据验证'
+          splitColumn: false, // '分列'
+          screenshot: false, // '截图'
+          findAndReplace: false, // '查找替换'
+        },
+        cellRightClickConfig: {
+          insertColumn: false,
+          matrix: false,
+          chart: false, // 图表生成
+          image: false, // 插入图片
+          link: false, // 插入链接
+          copyAs: false,
+        },
+        data: [{
+          column: 2,
+          scrollTop: 0,
+          scrollLeft: 0,
+          defaultColWidth: 200,
+          defaultRowHeight: 20,
+          frozen: [
+            {
+              type: 'row'
+            }
+          ],
+          celldata: this.excelData,
+        }],
+        hook:{
+          cellUpdateBefore(r,c,value){
+            // 禁止更新第一行
+            if(r===0) return false
+            
+            // if(c===0&&value) {
+            //   console.log(value)
+            //   console.log(isNaN(value)&&!isNaN(Date.parse(value)))
+            //   if(isNaN(value)&&!isNaN(Date.parse(value))) {
+            //     return true
+            //   }else {
+            //     bus.$message.warning('请输入正确的日期格式')
+            //     return false
+            //   }
+            // }
+          },
+          cellMousedownBefore(e,{r,c}){
+            if(r===0) return false
+          },
+
+          cellAllRenderBefore(a,b,c) {
+            // console.log(a,b,c)
+          },
+
+          rangePasteBefore(range,data) {
+            console.log(range,data)
+          }
+        },
+      }  
+    },
+
+    filterList() {
+      return this.old_edb_data.slice(this.start_index,this.end_index)
+    },
+
+    total_length() {
+      return this.old_edb_data.length;
+    },
+
+     ...mapState({
+			eta_lang: state => state.edb.eta_lang,	
+		})
+  },
+
+  mounted() {
+    this.getMenu();
+    if(this.$route.query.edbid) {
+      this.getEdaData(this.edb_id)
+      this.getEDBInfoOfCalculate()
+    }else {
+      this.$refs.table.bodyWrapper && this.$refs.table.bodyWrapper.addEventListener('scroll',this.loadMoreData)
+      this.initExcelOptions();
+    }
+    
+  },
+
+  beforeDestroy() {
+    luckysheet.destroy();
+    this.$refs.table && this.$refs.table.bodyWrapper && this.$refs.table.bodyWrapper.removeEventListener('scroll',this.loadMoreData)
+  },
+
+  methods: {
+    // 获取计算指标与基础指标关联信息
+    async getEDBInfoOfCalculate(){
+      const res=await dataBaseInterface.getEDBInfoCalculateMap({EdbInfoId:Number(this.edb_id)})
+      if(res.Ret===200){
+        this.EDBInfoOfCalculateData=res.Data
+      }
+    },
+
+    async getEdaData() {
+      const res = await dataBaseInterface.targetList({
+        PageSize: 100000,
+        CurrentIndex: this.page_no,
+        EdbInfoId: this.edb_id,
+      })
+      if (res.Ret!==200) return 
+      let arr = res.Data.Item.DataList ||[];
+      this.old_edb_data = arr;
+      this.formData = {
+        targetName: res.Data.Item.EdbName,
+        menu: res.Data.ClassifyList[0].ClassifyId,
+        frequency: res.Data.Item.Frequency,
+        unit: res.Data.Item.Unit
+      }
+      this.resetData()
+    },
+
+    /* 获取目录结构 */
+		getMenu() {
+			dataBaseInterface.menuList().then((res) => {
+				if (res.Ret === 200) {
+					this.filterNodes(res.Data.AllNodes)
+					this.classifyOptions = res.Data.AllNodes || [];
+				}
+			});
+		},
+		// 递归改变第三级目录结构
+		filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (item.Level === 2) {
+						delete item.Children;
+					}
+				});
+		},
+
+    /* 指标列表 */
+		getTarget(query) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search);
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+			this.searchApi(this.current_search);
+		},
+
+		searchApi(query,page=1) {
+			dataBaseInterface.targetSearchByPage({
+				KeyWord:query,
+				CurrentIndex: page,
+				FilterSource: this.type === 5 ? 2 : this.type === 14 ? 3 : 1
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				const { List,Paging } = res.Data;
+				this.search_have_more = page < Paging.Pages;
+				let arr = page === 1 ? List : this.searchOptions.concat(List);
+
+				this.searchOptions = this.$route.query.edbid ? arr.filter(item => item.EdbInfoId !== this.$route.query.edb_id) : arr;
+					
+			})
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page)
+		},
+
+    /* 选择指标 */
+    async chooseTarget(val) {
+      if(val) {
+        this.old_edb_info = {
+          id: this.searchOptions.find(_ => _.EdbInfoId === val) ? this.searchOptions.find(_ => _.EdbInfoId === val).EdbCode : '',
+          name: this.searchOptions.find(_ => _.EdbInfoId === val) ? this.searchOptions.find(_ => _.EdbInfoId === val).EdbName : ''
+        }
+        const res = await dataBaseInterface.targetList({
+          PageSize: 100000,
+          CurrentIndex: this.page_no,
+          EdbInfoId: val,
+        })
+        if (res.Ret!==200) return 
+        let arr = res.Data.Item.DataList ||[];
+        this.old_edb_data = arr;
+        this.resetData()
+      }else {
+        this.old_edb_info = {};
+        this.old_edb_data = [];
+        this.resetData()
+      }
+    },
+
+    /* 选择指标后重置数据 */
+    resetData() { 
+      this.excelData = [
+        {
+          r:0,
+          c:0,
+          v:{
+            m:"日期",
+            v:"日期",
+            bg:'#bbb'
+          },
+        },
+        {
+          r:0,
+          c:1,
+          v:{
+            m:"值",
+            v:"值",
+            bg:'#bbb'
+          },
+        },
+      ]
+
+      this.old_edb_data.forEach((item,index) => {
+        this.excelData.push({
+          r: index+1,
+          c:0,
+          v:{
+            m:item.DataTime,
+            v:item.DataTime
+          },
+        })
+        this.excelData.push({
+          r: index+1,
+          c:1,
+          v:{
+            m:item.Value,
+            v:item.Value
+          },
+        })
+      })
+      luckysheet.create(this.excelOptions)
+    },
+
+    /* 滚动加载当前数据 */
+    loadMoreData() {
+      const scrollTop = this.$refs.table.bodyWrapper.scrollTop;
+      this.start_index = Math.floor(scrollTop/this.rowHeight);
+      this.end_index = this.start_index + this.page_size;
+      $('.el-table__body')[0].style=`transform: translateY(${this.start_index*this.rowHeight}px)`
+    },
+
+    /* 保存 */
+    async saveSheetHandle() {
+      let data = luckysheet.getAllSheets()[0]
+      await this.$refs.form.validate();
+      // console.log(data.celldata)
+      if(data.celldata.length < 3) return this.$message.warning('请输入表格内容');
+
+      const { targetName,menu,frequency,unit} = this.formData;
+
+      //处理数据格式
+      let result_obj = {},DataList=[];
+      data.celldata.forEach(item => {
+        if(result_obj[item.r]&&item.c===1) {
+          result_obj[item.r] = {
+            Date: result_obj[item.r].v.m,
+            Value: Number(item.v.m)
+          }
+        } else {
+          result_obj[item.r] = item
+        }
+      })
+      for(let key in result_obj) {
+        if(result_obj[key].Date && !isNaN(result_obj[key].Value)) DataList.push(result_obj[key]);
+      }
+
+      const { Ret,Data } = await dataBaseInterface.adjustEdbEdit({
+        EdbName: targetName,
+        Frequency: frequency,
+        Unit: unit,
+        ClassifyId: menu,
+        EdbInfoId: Number(this.edb_id)|| 0,
+        FromEdbInfoId: this.select_target || 0,
+        DataList
+      })
+
+      if(Ret !== 200) return
+      this.$message.success('保存成功')
+
+      const { UniqueCode,EdbInfoId } = Data;
+
+      this.$router.replace({path:'/database', query: {
+        code: UniqueCode,
+        id: EdbInfoId
+      }});
+    },  
+
+    initExcelOptions() {
+      this.$nextTick(() => {
+        luckysheet.create(this.excelOptions)
+      })
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+*{ box-sizing: border-box; }
+.adjust-data-container {
+  .wrap-top {
+    display: flex;
+    justify-content: space-between;
+    /* align-items: center; */
+    margin-bottom: 20px;
+    padding: 20px;
+    background: #fff;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    z-index: 1;
+    .min-top {
+      margin-bottom: 10px;
+      display: flex;
+      align-items: center;
+      color: #606266;
+      li { margin-right: 35px; }
+    }
+    .right-handle {
+      min-width: 155px;
+    }
+    .tips-cont {
+      margin-top: 20px;
+    }
+  }
+  .main {
+    position: relative;
+    height: 650px;
+    display: flex;
+    .table-cont {
+      width: 260px;
+      flex-shrink: 0;
+      margin-right: 20px;
+      /* height: 600px;
+      overflow-y: scroll; */
+    }
+    #excel-container {
+      margin:0;padding:0;
+      width:100%;
+    }
+  }
+}
+</style>
+<style lang="scss">
+  .luckysheet .toolbar {
+    background: none;
+    margin: 0;
+    padding: 0;
+  }
+.luckysheet-input-box {
+  z-index: 99999;
+}
+</style>

+ 2832 - 0
src/views/dataEntry_manage/chartSetting.vue

@@ -0,0 +1,2832 @@
+<template>
+  <div class="chartSetting_container">
+    <div class="chartSetting_main box" id="box" v-if="showData">
+      <span
+        class="slide-icon slide-right"
+        @click="slideHandle"
+        v-show="isSlideLeft"
+      >
+        <i class="el-icon-d-arrow-right"></i>
+      </span>
+      <div class="chartSetting-label-list">
+          <edb-label-list 
+            :currentLang="currentLang"
+            :labelList="labelList"
+            :activeLabelId="select_node"
+            @clickLabel="changeCurrentLabel"
+            @deleteLabel="deleteLabel"
+            @moveLabel="({oldIndex,newIndex})=>{labelList[oldIndex] = labelList.splice(newIndex, 1, labelList[oldIndex])[0];}"
+          />
+      </div>
+      <div class="chartSetting-main">
+      <div class="main-left left" id="left" v-show="!isSlideLeft">
+        
+        <div class="add-chart-cont">
+          <el-button @click="$router.push({path: '/addchart'})" type="primary">添加图表</el-button>
+          <change-lang :lang="currentLang" @changeLang="changeLanguage" style="margin-left: 10px;"/>
+
+        </div>
+        
+        <ul class="left-tab">
+          <li :class="['tab',{'act': leftShowLabel===tab}]" v-for="tab in ['目录','坐标轴']" :key="tab" @click="leftShowLabel=tab">{{tab}}</li>
+          <li >
+            <el-checkbox v-model="isOnlyMe"  @change="onlyMeHandler">只看我的</el-checkbox>
+          </li>
+        </ul>
+
+        <!-- 目录 -->
+        <template v-if="leftShowLabel === '目录'">
+          <div class="chartSetting_main_top">
+            <el-select
+              v-model="search_txt"
+              v-loadMore="searchLoad"
+              :filterable="!search_txt"
+              remote
+              clearable
+              placeholder="请输入图表名称"
+              style="width: 100%; margin-top: 20px"
+              :remote-method="searchHandle"
+              @click.native="inputFocusHandle"
+            >
+              <i slot="prefix" class="el-input__icon el-icon-search"></i>
+              <el-option
+                v-for="item in searchOptions"
+                :key="item.ChartInfoId"
+                :label="currentLang==='en'?(item.ChartNameEn||item.ChartName):item.ChartName"
+                :value="item.ChartInfoId"
+              >
+              </el-option>
+            </el-select>
+          </div>
+          <div class="tree-cont">
+            <el-tree
+              ref="treeRef"
+              class="target_tree"
+              :data="treeData"
+              node-key="UniqueCode"
+              :props="defaultProp"
+              :allow-drag="canDragHandle"
+              :allow-drop="canDropHandle"
+              :current-node-key="select_node"
+              :default-expanded-keys="defaultShowNodes"
+              draggable
+              :expand-on-click-node="false"
+              check-strictly
+              empty-text="暂无分类"
+              lazy
+						  :load="handleTreeLoad"
+              @node-expand="handleNodeExpand"
+              @node-collapse="handleNodeCollapse"
+              @current-change="nodeChange"
+              @node-drop="dropOverHandle"
+              @node-drag-end="dropMouseLeave"
+              @node-drag-leave="dropMouseLeave"
+              @node-drag-enter="dropMouseOver"
+            >
+              <span class="custom-tree-node" slot-scope="{ node, data }">
+                <el-input
+                  ref="editVal"
+                  style="width: 90px"
+                  placeholder="请输入值"
+                  class="label-input"
+                  v-model="new_label"
+                  v-if="data.isEdit"
+                  @blur="changeValue(node, data)"
+                />
+                <span
+                  @dblclick.stop="editNodeLabel(node, data)"
+                  v-else
+                  class="text_oneLine node_label"
+                  :style="`width:${
+                    (select_node === data.UniqueCode && node.Nodewidth) || ''
+                  }`"
+                  :id="`node${data.UniqueCode}`"
+                >
+                  <span>{{ currentLang==='en' ? (data.ChartClassifyNameEn||data.ChartClassifyName) : data.ChartClassifyName }}</span>
+                </span>
+                <span
+                  style="display: flex; align-items: center"
+                  v-if="select_node === data.UniqueCode"
+                >
+                  <img
+                    src="~@/assets/img/data_m/move_ico.png"
+                    alt=""
+                    style="width: 14px; height: 14px; margin-right: 8px"
+                    v-if="data.SysUserId === roleId || role === 'admin'"
+                  />
+                  <img
+                    src="~@/assets/img/set_m/add.png"
+                    alt=""
+                    style="width: 14px; height: 14px; margin-right: 8px"
+                    @click.stop="addNode(node, data)"
+                    v-if="node.level === 1 && role === 'admin'"
+                  />
+                  <img
+                    src="~@/assets/img/set_m/edit.png"
+                    alt=""
+                    style="width: 15px; height: 14px; margin-right: 8px"
+                    @click.stop="editNode(node, data)"
+                    v-if="role === 'admin' && !data.ChartInfoId"
+                  />
+                  <img
+                    slot="reference"
+                    src="~@/assets/img/set_m/del.png"
+                    alt=""
+                    style="width: 14px; height: 14px"
+                    @click.stop="removeNode(node, data)"
+                    v-if="role === 'admin' && !data.ChartInfoId"
+                  />
+                </span>
+              </span>
+            </el-tree>
+            <div
+              class="noDepart"
+              @click="addLevelOneHandle"
+              v-if="role === 'admin'"
+            >
+              <img
+                src="~@/assets/img/set_m/add_ico.png"
+                alt=""
+                style="width: 16px; height: 16px; margin-right: 10px"
+              />
+              <span>添加图表分类</span>
+            </div>
+          </div>
+        </template>
+        <!-- 坐标轴 -->
+        <div class="targetset-cont" v-else>
+          <!-- 仅用于散点图配置提出 -->
+					<div class="scatter-setting" v-if="chartInfo.ChartType === 5 && tableData.length">
+						<div style="display: flex;margin-right: 15px;">
+							<span style="margin-right: 3px">线条颜色:</span>
+							<el-color-picker
+								v-model="tableData[0].ChartColor"
+								size="mini"
+								show-alpha
+								:predefine="predefineColors"
+							></el-color-picker>
+						</div>
+						<el-checkbox v-model="tableData[0].IsOrder">逆序</el-checkbox>
+					</div>
+
+          <el-collapse v-model="activeNames" class="target-list" v-if="tableData.length">
+            <el-collapse-item v-for="(item,index) in tableData" :key="item.EdbInfoId" :disabled="[2,5,7,10].includes(chartInfo.ChartType)">
+              <template slot="title">
+                <span class="text_oneLine">{{item.EdbName}}</span>
+              </template>
+              <ul class="setting-cont">
+                <!-- 堆叠图 或组合图中的堆叠类型 非第一项隐藏配置 -->
+								<template v-if="showYOptionsHandle(item,index)">
+                  <li>
+                    <el-checkbox v-model="item.IsOrder">逆序</el-checkbox>
+                  </li>
+                  <li>
+                    <el-radio-group v-model="item.IsAxis" size="mini">
+                      <el-radio-button :label="1">左轴</el-radio-button>
+                      <el-radio-button :label="0">右轴</el-radio-button>
+                      <!-- 指标有右轴时才可以选右2轴 不然没有右2这个概念的意义 -->
+											<el-radio-button 
+                        v-if="[1,6].includes(chartInfo.ChartType)"
+												:label="2" 
+												:disabled="(tableData.findIndex(_ => _.IsAxis===0) === -1) 
+												|| (tableData.findIndex(_ => _.IsAxis===0) === index 
+														&& tableData.filter(_ => _.IsAxis===0).length === 1)"
+											>右2轴</el-radio-button>
+                    </el-radio-group>
+                  </li>
+                </template>
+                <li style="min-width: 250px">
+                  <el-radio
+                    v-model="item.EdbInfoType"
+                    :label="1"
+                    @change="refreshTarget"
+                    >标准指标</el-radio
+                  >
+                  <div style="margin-top: 15px">
+                    <el-radio
+                      v-model="item.EdbInfoType"
+                      :label="0"
+                      style="margin-right: 10px"
+                      @change="refreshTarget"
+                      >领先指标</el-radio
+                    >
+                    <template v-if="item.EdbInfoType === 0">
+                      领先
+                      <el-input
+                        style="width: 60px"
+                        size="mini"
+                        type="number"
+                        min="0"
+                        v-model="item.LeadValue"
+                        @change="refreshTarget"
+                        @keyup.native="filterCode(item)"
+                      ></el-input>
+                      <el-select
+                        v-model="item.LeadUnit"
+                        placeholder=""
+                        style="width: 60px"
+                        size="mini"
+                        @change="refreshTarget"
+                      >
+                        <el-option
+                          v-for="item in fre_options"
+                          :key="item"
+                          :label="item"
+                          :value="item"
+                        >
+                        </el-option>
+                      </el-select>
+                    </template>
+                  </div>
+                </li>
+                <li>
+                  <div style="display: flex">
+                    <span style="margin-right: 3px">线条颜色:</span>
+                    <el-color-picker
+                      v-model="item.ChartColor"
+                      size="mini"
+                      show-alpha
+                      :predefine="predefineColors"
+                    ></el-color-picker>
+                  </div>
+                  <div style="display: flex;margin-top: 12px" v-if="item.EdbInfoCategoryType === 1">
+                    <span style="margin-right: 3px">预测值颜色:</span>
+                    <el-color-picker
+                      v-model="item.PredictChartColor"
+                      size="mini"
+											show-alpha
+                      :predefine="predefineColors"
+                    ></el-color-picker>
+                  </div>
+
+                  <div 
+                    style="margin-top: 12px"
+                    v-if="chartInfo.ChartType === 1 
+										|| (chartInfo.ChartType === 6 && item.ChartStyle==='spline')"
+                  >
+                    线条粗细:
+                    <el-input
+                      style="width: 60px"
+                      size="mini"
+                      type="number"
+                      :min="1"
+                      v-model="item.ChartWidth"
+											@keyup.native="filterWidth(item)"
+                    />
+                  </div>
+                </li>
+                <li v-if="chartInfo.ChartType === 6">
+                  <div style="display: flex">
+                    <span style="margin-right: 3px">生成样式:</span>
+                    <el-select
+											v-model="item.ChartStyle"
+											placeholder="请选择生成样式"
+											style="width: 50%"
+                      class="edb-item-style"
+										>
+											<el-option
+												v-for="item in chartItemStyleArr"
+												:key="item.key"
+												:label="item.label"
+												:value="item.value"
+											>
+											</el-option>
+										</el-select>
+                  </div>
+                </li>
+              </ul>
+            </el-collapse-item>
+          </el-collapse>
+          <div v-else class="nodata">
+            <img
+              src="~@/assets/img/data_m/table_no.png"
+              alt=""
+              style="
+                display: block;
+                width: 140px;
+                height: 148px;
+                margin: 5% auto 10px;
+              "
+            />
+            暂无信息
+          </div>
+        </div>
+        
+        <span
+          class="move-btn resize"
+          v-drag
+          id="resize"
+          @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+        ></span>
+        <span class="slide-icon slide-left" @click="slideHandle">
+          <i class="el-icon-d-arrow-left"></i>
+        </span>
+      </div>
+      <div
+        class="main-right right"
+        id="right"
+        :style="isSlideLeft ? 'width:100%' : `width:${dynamicWidth}`"
+      >
+        <!-- =============具体图表区域============== -->
+        <div class="chart-min-cont" v-if="tableData.length">
+          <div class="cont-top">
+            <div class="top-left">
+              <!-- 默认曲线图 -->
+              <template v-if="sameOptionType.includes(chartInfo.ChartType)">
+                <el-button
+                  type="primary"
+                  v-for="item in yearSelector"
+                  :key="item.value"
+                  size="medium"
+                  :plain="item.value !== year_select"
+                  class="year-btn"
+                  @click.native="changeYear(item)"
+                  >{{ item.name }}</el-button
+                >
+                <el-button type="text" class="btn-sty" @click="openDateDia">{{
+                  dateTip
+                }}</el-button>
+              </template>
+              <!-- 季节性图选择年份区间 -->
+              <date-picker
+                v-else-if="chartInfo.ChartType === 2"
+                v-model="season_year"
+                type="month"
+                value-type="format"
+                range
+                placeholder="年份日期选择"
+                @change="seasonYearChange"
+              />
+            </div>
+          </div>
+          <div class="cont-bottom">
+            <el-row class="bottom-min">
+              <el-col
+                :span="21"
+                style="padding-bottom: 30px;"
+              >
+               
+                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
+                <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
+                  <div class="chartWrapper" id="chartWrapper">
+                    <h2 class="chart-title">{{ currentLang==='en'?(chartInfo.ChartNameEn||chartInfo.ChartName):chartInfo.ChartName }}</h2>
+                    <Chart :options="options" ref="chartRef" />
+
+                    <div class="range-cont left" v-if="leftIndex != -1">
+                      <el-input
+                        style="width: 60px; display: block"
+                        size="mini"
+                        type="number"
+                        placeholder="上限"
+                        v-model="tableData[leftIndex].MaxData"
+                      />
+                      <el-input
+                        class="min-data-input"
+                        size="mini"
+                        type="number"
+                        placeholder="下限"
+                        v-model="tableData[leftIndex].MinData"
+                      />
+                    </div>
+                    <div 
+                      class="range-cont right" 
+                      v-if="rightIndex != -1"
+                    >
+                      <el-input
+                        style="width: 60px; display: block"
+                        size="mini"
+                        type="number"
+                        placeholder="上限"
+                        v-model="tableData[rightIndex].MaxData"
+                      />
+                      <el-input
+                        class="min-data-input"
+                        size="mini"
+                        type="number"
+                        placeholder="下限"
+                        v-model="tableData[rightIndex].MinData"
+                      />
+                    </div>
+
+                    <!-- 右2上下限设置 -->
+                    <div class="range-cont rightTwo" v-if="rightTwoIndex != -1">
+                      <el-input
+                        style="width: 60px; display: block"
+                        size="mini"
+                        type="number"
+                        placeholder="上限"
+                        v-model="tableData[rightTwoIndex].MaxData"
+                      />
+                      <el-input
+                        class="min-data-input"
+                        size="mini"
+                        type="number"
+                        placeholder="下限"
+                        v-model="tableData[rightTwoIndex].MinData"
+                      />
+                    </div>
+
+                    <!-- 后续新图专用上下限 和其他数据依赖不公用 柱形图 截面散点-->
+                    <template v-if="[7,10].includes(chartInfo.ChartType)">	
+                      <div class="range-cont left">
+                        <el-input
+                          style="width: 60px; display: block"
+                          size="mini"
+                          type="number"
+                          placeholder="上限"
+                          v-model="chartLimit.max"
+                          @change="changeLimit"
+                        />
+                        <el-input
+                          class="min-data-input"
+                          size="mini"
+                          type="number"
+                          placeholder="下限"
+                          v-model="chartLimit.min"
+                          @change="changeLimit"
+                        />
+                      </div>
+                      <!-- x轴上下限 -->
+                      <div class="range-cont bottom" v-if="chartLimit.x_min||chartLimit.x_max">
+                        <el-input
+                          class="left"
+                          size="mini"
+                          type="number"
+                          placeholder="下限"
+                          v-model="chartLimit.x_min"
+                          @change="changeLimit"
+                        />
+                        <el-input
+                          class="left"
+                          size="mini"
+                          type="number"
+                          placeholder="上限"
+                          v-model="chartLimit.x_max"
+                          @change="changeLimit"
+                        />
+                      </div>
+                    </template>
+                  </div>
+                  <span class="chart-author"
+                    >作者:{{ chartInfo.SysUserRealName || '' }}</span
+                  >
+
+                  <!-- 公历农历切换 只用于季节性图 -->
+                  <el-radio-group
+                    v-model="calendar_type"
+                    class="calendar-cont"
+                    v-if="chartInfo.ChartType === 2"
+                    @change="getChartInfo"
+                  >
+                    <el-radio-button label="公历" />
+                    <el-radio-button label="农历" />
+                  </el-radio-group>
+                </div>
+
+                <!-- 异常显示 -->
+                <p class="error-tip" style="min-height: 400px;" v-if="chartInfo.WarnMsg">{{chartInfo.WarnMsg}}</p>
+              </el-col>
+              <el-col :span="3" style="position: absolute;height: 100%;right: 0;">
+                <ul class="right-actions">
+                    <li>操作</li>
+                    <li
+                      class="span-item shareLink"
+                      @click="copyChartConfirm('url')"
+                      :data-clipboard-text="linkUrl"
+                      v-if="!chartInfo.Disabled"
+                    >
+                      <i class="el-icon-share"/>&nbsp;分享
+                    </li>
+                    <li
+                      class="span-item"
+                      @click="addMychartHandle(chartInfo)"
+                    >
+                      <img
+                        :src="$icons.chart_join_ico"
+                        alt=""
+                        style="width: 13px; height: 12px; vertical-align: middle"
+                      />加入我的图库
+                    </li>
+                    <li class="span-item" @click="refreshHandle">
+                      <span><i class="el-icon-refresh" style="margin-left:0"/>&nbsp;刷新 </span>
+                    </li>
+                    <li
+                      class="span-item"
+                    >
+                      <span @click="saveChartHandle('')">
+                        <i class="el-icon-collection" />&nbsp;保存
+                      </span>
+                    </li>
+                    <li
+                      class="span-item"
+                    >
+                      <span @click="saveChartOtherHandle">
+                        <i class="el-icon-document-add" />&nbsp;另存为
+                      </span>
+                    </li>
+                    <li
+                      class="span-item"
+                      v-if="chartInfo.IsEdit"
+                      @click="editChartHandle"
+                    >
+                      <img
+                        src="~@/assets/img/set_m/edit.png"
+                        alt=""
+                        style="width: 13px; height: 12px;"
+                      />&nbsp;编辑
+                    </li>
+                    <li
+                      class="span-item copy"
+                      @click="copyChartConfirm('office')"
+                      v-if="!chartInfo.Disabled"
+                    >
+                      <i class="el-icon-document-copy" />&nbsp;复制至office
+                    </li>
+                    <li
+                      class="span-item copy"
+                      @click="copyChartConfirm('微信')"
+                      v-if="!chartInfo.Disabled"
+                    >
+                      <img style="width: 13px; height: 12px;vertical-align: middle" src="~@/assets/img/chart_m/WeChat.jpg" />&nbsp;复制至微信
+                    </li>
+                    <li
+                      class="span-item copy"
+                      @click="openEnNameDia"
+                    >
+                      <img style="width: 16px;vertical-align: middle" :src="$icons.to_en" />&nbsp;设置英文名称
+                    </li>
+                    <li
+                      class="span-item"
+                      style="color: #ff4040"
+                      @click="delChartHandle"
+                      v-if="chartInfo.IsEdit"
+                    >
+                      <i class="el-icon-delete" style="color: #ff4040" />&nbsp;删除
+                    </li>
+                </ul>
+              </el-col>
+            </el-row>
+            <el-table
+              :data="tableData"
+              ref="tableRef"
+              highlight-current-row
+              border
+            >
+              <el-table-column
+                v-for="item in tableColums"
+                :key="item.label"
+                :label="item.label"
+                :width="item.widthsty"
+                :min-width="item.minwidthsty"
+                align="center"
+              >
+                <template slot-scope="scope">
+                  <span v-if="item.key==='SourceName'">
+                    {{scope.row[item.key]}}
+                    <i 
+                      class="el-icon-tickets" 
+                      style="color:#409EFF;font-size:18px" 
+                      @click="isLookHistory=true;lookEdbId=scope.row.EdbInfoId"
+                      v-if="scope.row.EdbType===2"
+                    />
+                  </span>
+                  <span v-else>{{ currentLang==='en' ? (scope.row[item.enKey]||scope.row[item.key]) : scope.row[item.key] }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="操作"
+                key="Copy"
+                align="center"
+                width="110"
+              >
+                <template slot-scope="scope">
+                  <span class="editsty" @click="copyCode(scope.row)">
+                    <i class="el-icon-document-copy" />&nbsp;复制数据</span
+                  >
+                  <span
+                    class="editsty"
+                    @click="viewTarget(scope.row)"
+                  >查看数据</span>
+                </template>
+              </el-table-column>
+              <div slot="empty">
+                <img
+                  src="~@/assets/img/data_m/table_no.png"
+                  alt=""
+                  style="
+                    display: block;
+                    width: 135px;
+                    height: 90px;
+                    margin: 20px auto 10px;
+                  "
+                />
+                <span>暂无指标</span>
+              </div>
+            </el-table>
+          </div>
+        </div>
+        <!-- ==============图表列表展示============= -->
+        <div class="chart-public-cont" v-else>
+          <span>共{{ public_total }}张图表</span>
+          <div
+            class="chart-public-list"
+            ref="listChartPage"
+            @scroll="loadMorePublicChart"
+          >
+            <el-col
+              :span="6"
+              style="margin-bottom: 20px; padding-right: 20px"
+              v-for="chart in chartPublicList"
+              :key="chart.ChartInfoId"
+            >
+              <el-card class="public-chart-item">
+                <div slot="header" class="item-top" style="position: relative;">
+                  <div class="chartEn-mark" v-show="chart.IsEnChart" style="top: -10px;left:-10px;">En</div>
+                  <span class="text_oneLine" :style="{'padding-left':chart.IsEnChart?'24px':''}">{{ currentLang === 'en' ? (chart.ChartNameEn||chart.ChartName) : chart.ChartName }}</span>
+                </div>
+                <img
+                  :src="chart.ChartImage"
+                  alt=""
+                  class="chart-img"
+                  @click="detailShowHandle(chart)"
+                />
+                <div class="item-bottom">
+                  <span>创建时间: {{ chart.CreateTime.slice(0,10) }}</span>
+                  <span
+                    class="join_txt"
+                    @click="addMychartHandle(chart)"
+                  >
+                    <img
+                      :src="$icons.chart_join_ico"
+                      alt=""
+                      style="width: 13px; height: 12px; vertical-align: middle"
+                    />
+                    加入我的图库
+                  </span>
+                </div>
+              </el-card>
+            </el-col>
+          </div>
+          <div v-if="!public_total" class="nodata">
+            <img
+              src="~@/assets/img/data_m/table_no.png"
+              alt=""
+              style="
+                display: block;
+                width: 140px;
+                height: 148px;
+                margin: 10% auto 0;
+              "
+            />
+            暂无图表
+          </div>
+        </div>
+      </div>
+      <img :src="drawImg" alt="" class="drawImg" />
+      </div>
+      </div>
+    <!-- 目录弹窗 -->
+    <chartDialog
+      :isOpenDialog="isOpenDialog"
+      :title="dialog_title"
+      :formData="dialogForm"
+      @closeDia="isOpenDialog = false"
+      @sucessCallback="sucessCallback"
+    />
+    <!-- 日期端选择弹窗 -->
+    <DateChooseDia
+      :isDateDia="isDateDia"
+      :dateForm="dateForm"
+      @cancel="isDateDia = false"
+      @dateBack="dataChangeBack"
+    />
+    <!-- 加入我的图库弹窗 -->
+    <addMyClassifyDia
+      :isAddMyDialog="isAddMyChart"
+      :add_id="add_chart_id"
+      :add_ids="add_ids"
+      @cancel="isAddMyChart = false"
+      @addSuccess="addMySuccess"
+    />
+
+    <!-- 图表另存 -->
+    <SaveChartOther 
+      :show.sync="isShowSaveOther" 
+      fromType="chartsetting"
+      :data="chartInfo"
+      @ensure="getTreeData"
+    />
+
+    <!-- 输入英文指标弹窗 -->
+		<set-en-name-dia 
+      :isOpenDialog="setEnName" 
+      @cancel="setEnName=false" 
+      @updateEnName="updateEnName" 
+      :formData="formItemArray"
+      :chartType="chartInfo.ChartType"
+      :datainfo="chartInfo.ChartType===10?JSON.parse(chartInfo.ExtraConfig):null"
+      :edblist="chartInfo.ChartType===10?tableData:[]"
+    />
+
+    <!-- 指标历史记录 -->
+    <edbHistoryDialog
+      :isOpenDialog.sync="isLookHistory"
+      :edbId="lookEdbId"
+    />
+  </div>
+</template>
+
+<script>
+import html2canvas from 'html2canvas';
+import { dataBaseInterface, mychartInterface } from '@/api/api.js';
+import {
+  copyOtherOptions
+} from '@/utils/defaultOptions';
+import { chartSetMixin } from './mixins/chartPublic'
+
+import mPage from '@/components/mPage';
+import Chart from './components/chart';
+import chartDialog from './components/chartDialog';
+import DateChooseDia from './components/DateChooseDia';
+import addMyClassifyDia from './components/addMyClassifyDia';
+import SaveChartOther from './components/SaveChartOther';
+import changeLang from "./components/changeLang.vue"
+import setEnNameDia from "./components/setEnNameDia.vue"
+import EdbLabelList from '../../components/edbLabelList.vue';
+export default {
+  name: '',
+  components: {
+    mPage,
+    chartDialog,
+    Chart,
+    DateChooseDia,
+    addMyClassifyDia,
+    SaveChartOther,
+    changeLang,
+    setEnNameDia,
+    EdbLabelList
+  },
+  directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 300 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    },
+  },
+  mixins: [chartSetMixin],
+  data() {
+    return {
+      showData: false,
+      treeData: [], //树数据
+      defaultShowNodes: [], //展开节点
+      defaultProp: {
+        label: 'ChartClassifyName',
+        children: 'Children',
+        isLeaf:'isLeaf'
+      }, //树结构配置项
+      loading: null,
+      selected_chartid: '', //当前选中的图表id
+      selected_chartClassify: '', //当前选中的图表所属分类
+      new_label: '', //新的节点label值
+      select_node: '', //当前选中的节点
+      /* 右侧 */
+      chartInfo: {}, //图表信息
+      search_txt: '', //搜索词
+      searchOptions: [], //搜索到的图表列表
+      
+      expandKey: [], //展开数组
+      /* 新增编辑目录弹窗 */
+      isOpenDialog: false,
+      dialog_title: '',
+      dialogForm: {
+        level: '',
+      },
+      drawImg: '',
+
+      /* 季节性图 */
+      season_year: '', //显示的年份
+      selected_chartType: '', //选择的图表类型 获取图表信息时用
+      calendar_type: '公历',
+      isSlideLeft: false,
+      dynamicNode: null, //当前选中的node对象 用于拖动宽度时动态改变label宽度
+      /* 公共图库列表展示 */
+      isShowPublicChart: false,
+      publicHaveMove: true, // 是否还有下一页
+      default_classify: '',
+      public_page_no: 1,
+      public_page_size: 12,
+      public_total: 0,
+      chartPublicList: [],
+      isAddMyChart: false, //加入图库弹窗
+      add_chart_id: '', //要加入的图表
+
+      /* 左侧更改目录和坐标轴切换 */
+      leftShowLabel: '目录',
+
+      add_ids:[],//加入时已有的分类
+      // 只看我的?
+      isOnlyMe:false,
+
+      search_page: 1,
+			search_have_more: false,
+			current_search:'',
+
+      /* 查看历史弹窗 */
+			isLookHistory: false,
+			lookEdbId: 0,
+        labelList:[],//标签列表
+    };
+  },
+  watch: {
+    /* 设置动态右侧区域宽度 */
+    isSlideLeft(newval) {
+      if (!newval) {
+        this.$nextTick(() => {
+          this.reloadRightWid();
+        });
+      }
+    },
+    // 公用图库关联分类
+    default_classify(newval) {
+      //重置滚动高度 防止触底加载
+      if(this.$refs.listChartPage) this.$refs.listChartPage.scrollTop = 0;
+      if (newval) {
+        this.public_page_no = 1;
+        this.getPublicChartList();
+      }
+    },
+    selected_chartid(newval) {
+      if (!newval) {
+        // this.year_select = 3;
+        this.year_select = this.yearSelector[0].value;
+        this.calendar_type = '公历';
+        this.season_year = '';
+        this.tableData = [];
+        this.chartInfo = {};
+      } else {
+        sessionStorage.removeItem('beforeOptions');
+        
+        newval && this.getChartInfo();
+        this.formItemArray=[]
+      }
+    },
+    /* 选中搜索图表 展开目录 选中图表 展示图表 */
+    search_txt(newval) {
+      if (newval) {
+        let [search_obj] = this.searchOptions.filter(
+          (item) => item.ChartInfoId === newval
+        );
+        // 查找图表的父级id
+        let arr = this.findParentNodeForClassifyId(search_obj.ChartClassifyId,search_obj.UniqueCode);
+        this.defaultShowNodes = arr;
+        this.select_node = search_obj.UniqueCode;
+      
+        this.selected_chartClassify = search_obj.ChartClassifyId; //图表所属分类
+        this.year_select = search_obj.DateType; //年份选择
+        this.calendar_type = search_obj.Calendar || '公历'; //公历/农历
+        this.season_year = [
+          search_obj.SeasonStartDate,
+          search_obj.SeasonEndDate,
+        ]; //季节年份区间
+        this.select_date = [search_obj.StartDate, search_obj.EndDate];
+        this.selected_chartType = search_obj.ChartType; //图表类型
+        this.selected_chartid = newval;
+
+         //滚动到高亮节点位置
+        setTimeout(() => {
+          this.$refs.treeRef.setCurrentKey(this.select_node);
+          let node = document.getElementById(`node${this.select_node}`);
+          let parent = document.getElementsByClassName('tree-cont')[0];
+
+          if(node.offsetTop > parent.offsetHeight) {
+            parent.scrollTop =  node.offsetTop - parent.offsetHeight/2
+          }
+        },400)
+      }
+    },
+
+		tableData: {
+      handler(newval, oldval) {
+        newval.length && !this.chartInfo.WarnMsg && this.setChartOptionHandle(newval);
+      },
+      deep: true,
+    },
+  },
+  computed: {
+    role() {
+      let role = localStorage.getItem('Role') || '';
+      if (['rai_researcher', 'ficc_researcher', 'researcher','ficc_seller','rai_seller','seller'].includes(role)) {
+        return 'researcher';
+      } else if (['rai_admin', 'ficc_admin'].includes(role)) {
+        return 'admin';
+      } else {
+        return role;
+      }
+    },
+    /* 登录角色id */
+    roleId() {
+      let id = parseInt(localStorage.getItem('AdminId'));
+      return id;
+    },
+    //登录角色姓名
+    roleName() {
+      let name = localStorage.getItem('userName') || '';
+      return name;
+    },
+    //禁用条件
+    isDisabled() {
+      if (
+        this.selected_chartid &&
+        this.role !== 'admin' &&
+        this.chartInfo.SysUserId !== this.roleId
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    /* 分享地址 */
+    linkUrl() {
+      const LINK_CHART_URL = process.env.CHART_LINK;
+      return `${LINK_CHART_URL}?code=${this.chartInfo.UniqueCode}&fromType=share&lang=${this.currentLang}`
+    }
+  },
+  methods: {
+    getTreeData(params) {
+      // dataBaseInterface.chartTree({IsShowMe:this.isOnlyMe}).then((res) => {
+      dataBaseInterface.chartClassify({IsShowMe:this.isOnlyMe}).then((res) => {
+        if (res.Ret === 200) {
+          this.showData = true;
+          this.currentLang = res.Data.Language === 'EN' ? 'en' : 'ch';
+					this.setLangIntoStore();
+
+          const arr=res.Data.AllNodes || [];
+          this.treeData = arr.map(item=>{
+						return {
+							...item,
+							isLeaf:item.Children.length?false:true
+						}
+					})
+          this.$nextTick(() => {
+            /* 新增完成后 处理树展开和选中图表 */
+            params && this.selectCurrentNode(params);
+          });
+        }
+      });
+    },
+    /* 节点变化时 */
+    nodeChange(data, node) {
+      this.search_txt = '';
+      this.dynamicNode = node;
+      sessionStorage.removeItem('beforeOptions');
+      //详情时判断是否是本人添加图表 若不是不用做保存校验 新增时要进入保存校验逻辑
+      if (
+        (this.selected_chartid &&
+          (this.role === 'admin' ||
+            this.chartInfo.SysUserId === this.roleId)) ||
+        !this.chartInfo.SysUserId
+      ) {
+        let arr = sessionStorage.getItem('defaultArr');
+        if (
+          arr &&
+          this.selected_chartid &&
+          arr !== JSON.stringify(this.tableData)
+        ) {
+          this.$confirm('您还未保存此图表,是否确认保存?', '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+            showClose: false,
+            closeOnClickModal: false,
+          })
+            .then(() => {
+              this.saveChartHandle('');
+            })
+            .catch(() => {
+              this.select_node = data.UniqueCode;
+              this.selected_chartid = data.ChartInfoId;
+              this.selected_chartType = data.ChartType;
+              this.selected_chartClassify = data.ChartInfoId
+                ? data.ChartClassifyId
+                : '';
+              this.calendar_type = data.ChartInfoId ? data.Calendar : '公历'; //公历/农历
+              this.season_year = data.ChartInfoId
+                ? [data.SeasonStartDate, data.SeasonEndDate]
+                : ''; //季节年份区间
+              this.year_select = data.ChartInfoId ? data.DateType : this.yearSelector[0].value; //图表年份选择
+              this.select_date =
+                this.year_select === 5 || this.year_select === 6
+                  ? [data.StartDate, data.EndDate]
+                  : '';
+              this.resetNodeStyle(node);
+              this.tableData =
+                !this.selected_chartClassify && this.tableData.length
+                  ? []
+                  : this.tableData;
+            });
+          return;
+        }
+      }
+      this.select_node = data.UniqueCode;
+      this.selected_chartid = data.ChartInfoId;
+      this.selected_chartType = data.ChartType;
+      this.selected_chartClassify = data.ChartInfoId
+        ? data.ChartClassifyId
+        : '';
+      this.calendar_type = data.ChartInfoId ? data.Calendar : '公历'; //公历/农历
+      this.season_year = data.ChartInfoId
+        ? [data.SeasonStartDate, data.SeasonEndDate]
+        : ''; //季节年份区间
+      this.year_select = data.ChartInfoId ? data.DateType : this.yearSelector[0].value; //图表年份选择
+      this.select_date =
+        this.year_select === 5 || this.year_select === 6
+          ? [data.StartDate, data.EndDate]
+          : '';
+      this.resetNodeStyle(node);
+      this.tableData =
+        !this.selected_chartClassify && this.tableData.length
+          ? []
+          : this.tableData;
+
+      //公用图库关联分类
+      this.default_classify = !data.ChartInfoId ? data.ChartClassifyId : '';
+    },
+    resetNodeStyle: _.debounce(function (node) {
+      const tree = $('.target_tree')[0];
+      let width = tree.offsetWidth;
+      let label_wid = width > 500 ? 'auto' : width <= 250 ? 80 : 0.58 * width;
+      this.$set(node, 'Nodewidth', label_wid + 'px');
+    }, 300),
+    /* 双击label出现input修改框 */
+    editNodeLabel(node, data) {
+      //目录名称可以双击修改 指标不能
+      if (!data.ChartInfoId && this.role === 'admin') {
+        this.$set(data, 'isEdit', true);
+        this.new_label = data.ChartClassifyName;
+        this.$nextTick(() => {
+          this.$refs.editVal.focus();
+        });
+      }
+    },
+    /* input失去焦点恢复node 修改最新的值*/
+    changeValue(node, data) {
+      if (this.new_label) {
+        this.$set(data, 'isEdit', false);
+        this.new_label !== data.ChartClassifyName &&
+          dataBaseInterface
+            .editChartClassify({
+              ChartClassifyId: data.ChartClassifyId,
+              ChartClassifyName: this.new_label,
+            })
+            .then((res) => {
+              if (res.Ret === 200) {
+                this.getTreeData();
+              }
+            });
+      } else {
+        this.$message.warning('名称不能为空');
+      }
+    },
+    // 只看我的 复选框改变事件
+    onlyMeHandler(){
+      this.getTreeData();
+      this.getPublicChartList()
+    },
+    /* 添加一级目录 */
+    addLevelOneHandle() {
+      this.dialog_title = '添加';
+      this.dialogForm = {
+        level_1: '',
+        parent_id: '',
+        level: 0,
+      };
+      this.isOpenDialog = true;
+    },
+    /* 添加节点 */
+    addNode(node, data) {
+      this.dialog_title = '添加';
+      /* 添加目录 */
+      this.dialogForm = {
+        level_1:
+          node.level === 1
+            ? data.ChartClassifyName
+            : node.level === 2
+            ? node.parent.data.ChartClassifyName
+            : node.parent.parent.data.ChartClassifyName,
+        level_2:
+          node.level === 1
+            ? ''
+            : node.level === 2
+            ? data.ChartClassifyName
+            : node.parent.data.ChartClassifyName,
+        // level_3: node.level === 3 ? data.ChartClassifyName : '',
+        parent_id: data.ChartClassifyId,
+        level: node.level,
+      };
+      this.isOpenDialog = true;
+      //存储当前要新增子级的目录code
+      sessionStorage.setItem('expandCode', data.UniqueCode);
+    },
+    /* 编辑节点 */
+    editNode(node, data) {
+
+      this.dialog_title = '编辑';
+      /* 编辑目录 */
+      this.dialogForm = {
+        level_1:
+          node.level === 1
+            ? data.ChartClassifyName
+            : node.level === 2
+            ? node.parent.data.ChartClassifyName
+            : node.parent.parent.data.ChartClassifyName,
+        level_2:
+          node.level === 1
+            ? ''
+            : node.level === 2
+            ? data.ChartClassifyName
+            : node.parent.data.ChartClassifyName,
+        // level_3: node.level === 3 ? data.ChartClassifyName : '',
+        classify_id: data.ChartClassifyId,
+        level: node.level,
+      };
+      this.isOpenDialog = true;
+    },
+    /* 删除节点校验 */
+    removeNode(node, data) {
+      dataBaseInterface
+        .delChartCheck({
+          ChartClassifyId: data.ChartClassifyId,
+          ChartInfoId: data.ChartInfoId,
+        })
+        .then((res) => {
+          if (res.Ret === 200) {
+            /**
+             * 0 可删除
+             * 1 关联图表一
+             * 2 有子目录无图表
+             */
+            if (res.Data.DeleteStatus === 1)
+              this.$confirm('该分类下关联图表不可删除', '删除失败', {
+                confirmButtonText: '知道了',
+                showCancelButton: false,
+                type: 'error',
+              });
+            else if (res.Data.DeleteStatus === 0 && !data.ChartInfoId)
+              this.$confirm('确定删除当前分类吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+              })
+                .then(() => {
+                  this.delHandle(data.ChartClassifyId, data.ChartInfoId);
+                })
+                .catch(() => {});
+            else if (res.Data.DeleteStatus === 0 && data.ChartInfoId)
+              this.$confirm('删除后该图表将不能再引用,确认删除吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+              })
+                .then(() => {
+                  this.delHandle(data.ChartClassifyId, data.ChartInfoId, 1);
+                })
+                .catch(() => {});
+            else if (res.Data.DeleteStatus === 2)
+              this.$confirm('确认删除当前分类及包含的子分类吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+              })
+                .then(() => {
+                  this.delHandle(data.ChartClassifyId, data.ChartInfoId);
+                })
+                .catch(() => {});
+          }
+        });
+    },
+    /* 删除方法 */
+    delHandle(ChartClassifyId, ChartInfoId, type) {
+      dataBaseInterface
+        .delChartClassify({
+          ChartClassifyId,
+          ChartInfoId,
+        })
+        .then((res) => {
+          if (res.Ret === 200) {
+            this.$message.success(res.Msg);
+            const label = this.labelList.find(i=>i.id===ChartInfoId)
+            if (!res.Data.ChartInfoId) this.selected_chartid = '';
+            if(type && res.Data.ChartInfoId){
+                this.getTreeData({
+                  code: res.Data.UniqueCode,
+                  id: res.Data.ChartInfoId,
+                  type: res.Data.ChartType,
+                })
+                label&&this.deleteLabel(label,'chart')
+            }else{
+                this.getTreeData();
+                label&&this.deleteLabel(label)
+            }
+            //如果router.query里的图表被删除,则清掉参数
+            if(Number(this.$route.query.id)===ChartInfoId){
+                this.$router.replace({path: '/chartsetting'})
+            }
+          }
+        });
+    },
+    /* 新增/编辑分类成功 */
+    sucessCallback(type) {
+      this.isOpenDialog = false;
+      this.getTreeData();
+      // type && this.getDataList();
+      this.selected_chartid && this.getChartInfo();
+      if (type === 'add') {
+        //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
+        let code = sessionStorage.getItem('expandCode');
+        let flag = this.defaultShowNodes.some((item) => {
+          return item === code;
+        });
+        // console.log(flag)
+        !flag && this.defaultShowNodes.push(code);
+        sessionStorage.removeItem('expandCode');
+      }
+    },
+    /* 判断节点是否能被拖拽 */
+    canDragHandle(node) {
+      let canMove = false;
+      if (node.data.SysUserId === this.roleId || this.role === 'admin') {
+        canMove = true;
+      }
+      return canMove;
+    },
+
+    /* 判断节点是否能被拖入 4*/
+    canDropHandle(draggingNode, dropNode, type) {
+      let canDrop = false;
+      // 移动的是一级目录
+			if(draggingNode.level===1&&dropNode.level===1) {
+				canDrop=true
+			} 
+
+			// 二级目录
+			if(draggingNode.level===2){
+				if((dropNode.level===1&&type==='inner')||(dropNode.level===2&&type!=='inner')){
+					canDrop=true
+				}
+			}
+
+			//三级指标层
+			if(draggingNode.level===3){
+				if((dropNode.level===2&&type==='inner')||(dropNode.level===3&&type!=='inner')){
+					canDrop=true
+				}
+			}
+
+      return canDrop;
+    },
+    /* 拖拽完成 */
+    dropOverHandle(b, a, i, e) {
+      // console.log(i, a);
+      // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
+      // 一/二级目录
+      if (b.level === 1 || b.level === 2) {
+        this.handleMoveCatalogue(b, a, i, e)
+      }
+
+      // 指标层
+      if (b.level === 3) {
+        this.handleMoveChart(b, a, i, e)
+      }
+    },
+
+    // 移动的为一、二级目录
+		handleMoveCatalogue(b,a,i,e){
+			let list=a.parent.childNodes,targetIndex=0,PrevClassifyId=0,NextClassifyId=0,ParentClassifyId=0;
+
+			list.forEach((item,index)=>{
+				if(item.data.ChartClassifyId===b.data.ChartClassifyId){
+					targetIndex=index
+					return
+				}
+			})
+
+			if(targetIndex===0){
+				PrevClassifyId=0
+				NextClassifyId=list[targetIndex+1].data.ChartClassifyId
+			}else if(targetIndex===list.length-1){
+				PrevClassifyId=list[targetIndex-1].data.ChartClassifyId
+				NextClassifyId=0
+			}else{
+				PrevClassifyId=list[targetIndex-1].data.ChartClassifyId
+				NextClassifyId=list[targetIndex+1].data.ChartClassifyId
+			}
+
+			if(b.level===2){
+				if(i==='inner'){
+					ParentClassifyId=a.data.ChartClassifyId
+					PrevClassifyId=0
+					NextClassifyId=a.data.Children.length>1?a.data.Children[1].ChartClassifyId:0
+				}else{
+					ParentClassifyId=a.data.ParentId
+				}
+			}
+
+      dataBaseInterface.chartClassifyMove({
+        ClassifyId: b.data.ChartClassifyId,
+        ParentClassifyId: ParentClassifyId,
+        PrevClassifyId: PrevClassifyId,
+        NextClassifyId:NextClassifyId
+      }).then((res) => {
+        if (res.Ret === 200) {
+          this.$message.success('移动成功!');
+          this.getTreeData();
+        }
+      });
+		},
+
+		// 移动的为指标层 三级
+		handleMoveChart(b,a,i,e){
+			let PrevChartInfoId=0,NextChartInfoId=0,targetIndex=0, list=a.parent.childNodes.map(_ => _.data)
+			if(i==='inner'){
+				PrevChartInfoId=0
+				NextChartInfoId=a.data.Children.length>1?a.data.Children[1].ChartInfoId:0
+			}else{
+				list.forEach((item,index)=>{
+					if(item.ChartInfoId===b.data.ChartInfoId){
+						targetIndex=index
+						return
+					}
+				})
+
+				if(targetIndex===0){
+					PrevChartInfoId=0
+					NextChartInfoId=list[targetIndex+1].ChartInfoId
+				}else if(targetIndex===list.length-1){
+					PrevChartInfoId=list[targetIndex-1].ChartInfoId
+					NextChartInfoId=0
+				}else{
+					PrevChartInfoId=list[targetIndex-1].ChartInfoId
+					NextChartInfoId=list[targetIndex+1].ChartInfoId
+				}
+			}	
+			
+      dataBaseInterface.chartMove({
+        ChartClassifyId: a.data.ChartClassifyId,
+        ChartInfoId: b.data.ChartInfoId,
+        PrevChartInfoId: PrevChartInfoId,
+        NextChartInfoId:NextChartInfoId
+      }).then((res) => {
+        if (res.Ret === 200) {
+          this.$message.success('移动成功!');
+        }
+        this.getTreeData();
+      });
+		},
+
+    /* 拖拽覆盖添加背景色 */
+    dropMouseOver(node1, node2, e) {
+      if (
+        ((node1.level === 2 && node2.level === 1) ||
+          (node1.level === 3 && node2.level === 2)) &&
+        (e.target.childNodes[0].className.includes('el-tree-node__content') ||
+          e.target.className.includes('el-tree-node__content'))
+      ) {
+        // console.log(e.target.childNodes[0])
+        e.target.childNodes[0].className.includes('el-tree-node__content')
+          ? (e.target.childNodes[0].style.backgroundColor = '#409eff')
+          : (e.target.style.backgroundColor = '#409eff');
+      }
+      // if (
+      // 	node2.level === 2 &&
+      // 	(e.target.childNodes[0].className.includes(
+      // 		'el-tree-node__content'
+      // 	) ||
+      // 		e.target.className.includes('el-tree-node__content'))
+      // ) {
+      // 	e.target.childNodes[0].className.includes('el-tree-node__content')
+      // 		? (e.target.childNodes[0].style.backgroundColor = '#409eff')
+      // 		: (e.target.style.backgroundColor = '#409eff');
+      // }
+    },
+    /* 拖拽离开/拖拽完成重置背景色 */
+    dropMouseLeave(node1, node2, e) {
+      let arrs = $('.el-tree-node__content');
+      for (let a of arrs) {
+        a.style.backgroundColor = 'transparent';
+      }
+    },
+    // 树节点展开
+    handleNodeExpand(data) {
+      // 保存当前展开的节点
+      let flag = false;
+      this.defaultShowNodes.some((item) => {
+        if (item === data.UniqueCode) {
+          // 判断当前节点是否存在, 存在不做处理
+          flag = true;
+          return true;
+        }
+      });
+      if (!flag) {
+        // 不存在则存到数组里
+        this.defaultShowNodes.push(data.UniqueCode);
+      }
+    },
+    // 树节点关闭
+    handleNodeCollapse(data) {
+      this.defaultShowNodes.forEach((item, index) => {
+        if (item === data.UniqueCode) {
+          // 删除关闭节点
+          this.defaultShowNodes.length = index;
+        }
+      });
+      // console.log(this.defaultShowNodes)
+    },
+
+    // 懒加载tree
+		handleTreeLoad(node,resolve){
+			if(node.level===0){
+				resolve(this.treeData)
+			}
+			if(node.level===1){
+				let arr=[]
+				this.treeData.forEach(item=>{
+					if(item.UniqueCode===node.data.UniqueCode){
+						arr=item.Children
+					}
+				})
+				resolve(arr)
+			}
+			if(node.level===2){
+				dataBaseInterface.getChartListForClassify({
+          ChartClassifyId:node.data.ChartClassifyId,
+          IsShowMe:this.isOnlyMe
+        }).then(res=>{
+					if(res.Ret===200){
+						let arr=res.Data.AllNodes||[]
+						arr=arr.map(item=>{
+							return {
+								...item,
+								isLeaf:true
+							}
+						})
+						resolve(arr)
+					}else{
+						resolve([])
+					}
+                    this.changeTreeNode()
+				})
+			}
+			if(node.level>2){
+				resolve([])
+			}
+		},
+
+    /* 获取图表详情信息  type为refresh刷新指标不存储时间 */
+    getChartInfo(type) {
+      // 判断图标类型 设置参数
+      let params =
+        this.sameOptionType.includes(this.selected_chartType)
+          ? {
+              ChartInfoId: this.selected_chartid,
+              DateType: this.year_select,
+              StartDate:
+                this.year_select === 5 || this.year_select === 6
+                  ? this.select_date[0]
+                  : '',
+              EndDate: this.year_select === 5 ? this.select_date[1] : '',
+            }
+          : {
+              ChartInfoId: this.selected_chartid,
+              Calendar: this.calendar_type,
+              SeasonStartDate: this.season_year ? this.season_year[0] : '',
+              SeasonEndDate: this.season_year ? this.season_year[1] : '',
+            };
+      dataBaseInterface.chartInfo(params).then((res) => {
+        if (res.Ret === 200) {
+          this.chartInfo = res.Data.ChartInfo;
+          let beforeOptions = sessionStorage.getItem('beforeOptions')
+            ? JSON.parse(sessionStorage.getItem('beforeOptions'))
+            : '';
+          //合并缓存配置和新的数据
+          let newarr = res.Data.EdbInfoList.map((item, index) => {
+            if (beforeOptions && type === 'refresh') {
+              const DataList = item.DataList;
+              return {
+                ...beforeOptions[index],
+                DataList,
+              };
+            } else {
+              return item;
+            }
+          });
+          this.tableData = newarr;
+          //  刷新最新的指标数据 防止领先配置已保存 指标数据确实原数据的情况 针对正常图
+          if (
+            type === 'refresh' &&
+            beforeOptions &&
+            (this.sameOptionType.includes(this.chartInfo.ChartType) && this.chartInfo.ChartType!==5)
+          )
+            this.refreshTarget();
+          sessionStorage.setItem(
+            'defaultArr',
+            JSON.stringify(res.Data.EdbInfoList)
+          );
+          if (!type) {
+            this.year_select = this.chartInfo.DateType;
+            this.select_date = [
+              this.chartInfo.StartDate,
+              this.chartInfo.EndDate,
+            ];
+            this.calendar_type = this.chartInfo.Calendar; //日历类型
+            // this.season_year = [ this.chartInfo.SeasonStartDate, this.chartInfo.SeasonEndDate ];
+            this.dateTip =
+              this.chartInfo.DateType === 5
+                ? `${this.chartInfo.StartDate}~${this.chartInfo.EndDate}`
+                : this.chartInfo.DateType === 6
+                ? `${this.chartInfo.StartDate}~至今`
+                : '请选择时间段';
+
+            //新图表类型 依赖数据不同单独init 数据
+            const typeInitMap = {
+              7: this.initBarData,
+              10: this.initSectionScatterData
+            }
+            typeInitMap[this.chartInfo.ChartType] && typeInitMap[this.chartInfo.ChartType](res.Data);
+            
+          }
+          //将指标添加进标签列表中
+            const {ChartNameEn,ChartName,ChartInfoId,UniqueCode,ChartClassifyId}=res.Data.ChartInfo
+            this.addLabel({code:UniqueCode,id:ChartInfoId,classifyId:ChartClassifyId,EdbName:ChartName,EdbNameEn:ChartNameEn,chartData:res.Data.ChartInfo})
+            this.defaultShowNodes=this.findParentNodeForClassifyId(ChartClassifyId,UniqueCode)
+            this.changeTreeNode()
+        }
+        
+      });
+    },
+
+    /* 搜索 */
+		searchHandle(query) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search)
+		},
+
+		searchApi(query,page=1) {
+      /* 查找列表 */
+      dataBaseInterface
+        .chartSearchByEs({
+          Keyword: query,
+          IsShowMe:this.isOnlyMe,
+          CurrentIndex: page
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return
+          const { List,Paging } = res.Data;
+          this.search_have_more = page < Paging.Pages;
+          this.searchOptions = page === 1 ? List : [...this.searchOptions,...List];
+        });
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+      if(this.current_search) {
+        this.searchApi(this.current_search)
+      }else {
+        this.searchOptions = [];
+      }
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page);
+		},
+
+    /* 保存当前图表配置 */
+    saveChartHandle: _.debounce(function () {
+      if (this.selected_chartid) {
+        //遍历每条线的指标配置
+        let arr = this.tableData.map((item) => {
+          return {
+            ChartColor: item.ChartColor,
+            PredictChartColor: item.PredictChartColor,
+            ChartStyle: item.ChartStyle,
+            ChartWidth: Number(item.ChartWidth),
+            EdbInfoId: item.EdbInfoId,
+            EdbInfoType: item.EdbInfoType,
+            IsAxis: item.IsAxis,
+            IsOrder: item.IsOrder,
+            LeadUnit: item.EdbInfoType ? '' : item.LeadUnit,
+            LeadValue: item.EdbInfoType ? 0 : Number(item.LeadValue),
+            MaxData: Number(item.MaxData),
+            MinData: Number(item.MinData),
+          };
+        });
+
+        let public_param = {
+          ChartClassifyId: this.selected_chartClassify,
+          ChartInfoId: this.selected_chartid || 0,
+          ChartEdbInfoList: arr,
+        }
+
+        let typeChartParam = {};
+        switch(this.chartInfo.ChartType) {
+          case 2:
+            typeChartParam = {
+              ...public_param,
+              Calendar: this.calendar_type,
+              SeasonStartDate: this.season_year ? this.season_year[0] : '',
+              SeasonEndDate: this.season_year ? this.season_year[1] : '',
+            }
+            break
+          case 7:
+            typeChartParam = {
+               ...public_param,
+              DateType: 6,
+              LeftMin: String(this.chartLimit.min),
+              LeftMax: String(this.chartLimit.max),
+            }
+          case 10: 
+            typeChartParam = {
+              ...public_param,
+              DateType: 6,
+              Calendar: "公历",
+              ExtraConfig: JSON.stringify({
+                ...JSON.parse(this.chartInfo.ExtraConfig),
+                XMinValue: String(this.chartLimit.x_min),
+                XMaxValue: String(this.chartLimit.x_max),
+                YMinValue: String(this.chartLimit.min),
+                YMaxValue: String(this.chartLimit.max),
+              })
+            } 
+        }
+
+        let params = this.sameOptionType.includes(this.selected_chartType)
+          ? {
+              ...public_param,
+              DateType: this.year_select,
+              StartDate:
+                this.year_select === 5 || this.year_select === 6
+                  ? this.select_date[0]
+                  : '',
+              EndDate: this.year_select === 5 ? this.select_date[1] : '',
+            }
+          : typeChartParam;
+
+        dataBaseInterface.chartSave(params).then((res) => {
+          if (res.Ret === 200) {
+            this.$message.success('保存成功');
+            sessionStorage.removeItem('beforeOptions');
+            sessionStorage.setItem(
+              'defaultArr',
+              JSON.stringify(this.tableData)
+            );
+            this.getTreeData();
+            //关联图表和图片
+            this.setChartImage();
+          }
+        });
+      }
+    }, 500),
+    // 英文面板时候的判断
+    copyChartConfirm(type){
+        if(this.currentLang=='en'){
+          // 是否所有数据都填写完
+          let flag=true
+          // 是否有英文表格名称
+          if(!this.chartInfo.ChartNameEn) flag = false
+          if(flag){
+            for (const data of this.tableData) {
+              // 单位中文名为空时 英文名不做判断
+              if(data.EdbNameEn=="" || (data.UnitEn=="" && data.Unit!="")){
+                flag = false
+                break
+              }
+            }
+          }
+          if(!flag){
+            this.$confirm('英文名称未输入完整,分享图表上可能出现空名称的情况,确定继续分享吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+            })
+            .then(() => {
+              if(type==='url'){
+                // this.shareUrl()
+                const input = document.createElement('input')
+                input.setAttribute('readonly','readonly')
+                input.value = this.linkUrl
+                document.body.appendChild(input)
+                input.select();
+                document.execCommand('copy');
+                document.body.removeChild(input);
+                this.$message.success('复制链接成功')
+              }else{
+                this.copyChartHandle(type)
+              }
+            })
+            .catch(() => {});
+          }else{
+            if(type=='url'){
+              this.shareUrl()
+            }else{
+              this.copyChartHandle(type)
+            }
+          }
+        }else{
+          if(type=='url'){
+            this.shareUrl()
+          }else{
+            this.copyChartHandle(type)
+          }
+        }
+    },
+    /* 点击复制先用canvas画出 转成图片在放到粘贴板中 */
+    copyChartHandle:_.debounce(function(type){{
+      let chartsName = this.currentLang=='ch'?this.chartInfo.ChartName:this.chartInfo.ChartNameEn
+      let { heightNum, widthNum , newTitle , dynamic_copyOptions} = this.dynamicWidthAndHeight(type,this.chartInfo.ChartType,chartsName,this.chartInfo.Source === 1?this.tableData.length:this.commodityChartData.length)
+      const chartType = this.sameOptionType.includes(this.chartInfo.ChartType)?'legend':'seasonLegend'
+      // 英文转SVG设置变动
+      if(this.currentLang == 'en'){
+        // 散点图 如果横轴单位为'英文单位',表示客户没填,转成svg时置为空
+        if(this.chartInfo.ChartType == 5){
+          this.$refs.chartRef.chart.options.xAxis.forEach(it => {
+            if(it.title.text == '英文单位') it.title.text='' 
+          });
+        }
+        // 如果竖轴坐标单位为'英文单位',表示客户没填,转成svg时置为空
+        this.$refs.chartRef.chart.options.yAxis.forEach(it => {
+          if(it.title.text == '英文单位') it.title.text='' 
+        });
+      }
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart:{
+          width:widthNum,
+          height:heightNum,
+          backgroundColor:"rgba(255, 255, 255, 0)",
+        },
+        title: {
+          text: newTitle,
+          margin: 10,
+          style: {
+            fontSize: '18px'
+          }
+        },
+        legend:{
+          ...copyOtherOptions[chartType],
+          ...dynamic_copyOptions[chartType]
+          }
+      });
+      this.copyBlobItem(widthNum,heightNum,svg,type);
+    }
+    },500) ,
+    // 选择
+    getSelect(targetNode) {
+      if (window.getSelection) {
+        //chrome等主流浏览器
+        var selection = window.getSelection();
+        var range = document.createRange();
+        range.selectNode(targetNode);
+        selection.removeAllRanges();
+        selection.addRange(range);
+      } else if (document.body.createTextRange) {
+        //ie
+        var range = document.body.createTextRange();
+        range.moveToElementText(targetNode);
+        range.select();
+      }
+    },
+    /* 点击删除图表 */
+    delChartHandle() {
+      this.$confirm('删除后该图表将不能再引用,确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          this.delHandle(
+            this.selected_chartClassify || 0,
+            this.selected_chartid,
+            1
+          );
+        })
+        .catch(() => {});
+    },
+    /* 图表未保存时更新图表数据 */
+    refreshTarget() {
+      for (let i in this.tableData) {
+        let params = {
+          EdbInfoId: this.tableData[i].EdbInfoId,
+          DateType: this.year_select,
+          StartDate:
+            this.year_select === 5 || this.year_select === 6
+              ? this.select_date[0]
+              : '',
+          EndDate: this.year_select === 5 ? this.select_date[1] : '',
+          EdbInfoType: this.tableData[i].EdbInfoType,
+          LeadValue: this.tableData[i].EdbInfoType
+            ? 0
+            : this.tableData[i].LeadValue,
+          LeadUnit: this.tableData[i].EdbInfoType
+            ? ''
+            : this.tableData[i].LeadUnit,
+        };
+        dataBaseInterface.edbinfoDetail(params).then((res) => {
+          if (res.Ret === 200) {
+            let newData = res.Data.EdbInfo;
+            this.tableData[i].DataList = newData.DataList;
+            if(newData.EdbInfoCategoryType===1) this.tableData[i].MoveLatestDate = newData.MoveLatestDate;
+          }
+        });
+      }
+    },
+    /* 年份改变 重新刷新图表接口  保存当前的图表配置和上下限 只改变图表 */
+    changeYear(item) {
+      this.year_select = item.value;
+      this.select_date = '';
+      this.dateTip = '请选择时间段';
+      //保存表格配置和上下限 曲线图需要保存表格配置 季节图就不用了
+      this.saveNowOptions();
+      // 图表已存在
+      this.selected_chartid && this.getChartInfo('refresh');
+    },
+    /* 打开时间段弹窗 */
+    openDateDia() {
+      // 自定义时间段回显
+      this.dateForm = {
+        date_type: this.year_select,
+        start_date:
+          this.year_select === 5 || this.year_select === 6
+            ? this.select_date[0]
+            : '',
+        end_date: this.year_select === 5 ? this.select_date[1] : '',
+      };
+      this.isDateDia = true;
+    },
+    /* 保存完自定义日期 刷新数据  保存当前的图表配置和上下限 只改变图表*/
+    dataChangeBack(data) {
+      this.year_select = data.dateType;
+      this.isDateDia = false;
+      this.select_date = [data.start_date, data.end_date];
+      if (data.dateType === 5) {
+        this.dateTip = `${data.start_date}~${data.end_date}`;
+      } else {
+        this.dateTip = `${data.start_date}~至今`;
+      }
+      this.saveNowOptions();
+      this.getChartInfo('refresh');
+    },
+
+    /* 编辑图表 跳转 */
+    editChartHandle() {
+      this.$router.push({
+        path: '/editchart',
+        query: {
+          code: this.chartInfo.UniqueCode
+        }
+      })
+    },
+    
+    /* 根据unicode展开树结构并选中当前图表 重置图表配置 日期区间 */
+    // 如果有chartData则说明是从图列表点击来的,如果没有 则说明是路由中带的参数此时要获取一下详情
+    async selectCurrentNode({ code, id, type,chartData }) {
+      let deep_arr = _.cloneDeep(this.treeData);
+      // 查找选中的节点信息
+      let select_obj = chartData?chartData:await this.findNode(deep_arr, id);
+      // 查找图表的分类父级id
+      let arr = this.findParentNodeForClassifyId(select_obj.ChartClassifyId, code); // 父的父的父-父的父-父
+      this.defaultShowNodes = arr;
+      this.select_node = code;
+      
+      // 重置筛选状态
+      this.selected_chartClassify = select_obj.ChartClassifyId; //图表所属分类
+      this.year_select = select_obj.DateType; //年份选择
+      this.calendar_type = select_obj.Calendar || '公历'; //公历/农历
+      this.season_year = [select_obj.SeasonStartDate, select_obj.SeasonEndDate]; //季节年份区间
+      this.select_date = [select_obj.StartDate, select_obj.EndDate]; //曲线日期选择
+      this.selected_chartType = select_obj.ChartType;
+      this.selected_chartid = id;
+
+      //滚动到高亮节点位置
+			setTimeout(() => {
+        this.$refs.treeRef.setCurrentKey(this.select_node);
+        let node = document.getElementById(`node${this.select_node}`);
+        let parent = document.getElementsByClassName('tree-cont')[0];
+
+        if(node.offsetTop > parent.offsetHeight) {
+          parent.scrollTop =  node.offsetTop - parent.offsetHeight/2
+        }
+      },400)
+    },
+    
+    /* 根据图表id 查找对象 */
+    findNode(arr, id) {
+      // 由于目录第三级图表改为懒加载 故从新增图跳转回来情况只能获取一下图详情了 不能直接去分类数据里面查了
+      return new Promise((resolve,reject)=>{
+        dataBaseInterface.chartInfo({
+          ChartInfoId: id,
+        }).then(res=>{
+          if(res.Ret==200){
+            resolve(res.Data.ChartInfo)
+          }
+        })
+      })
+      // 遍历取父级code push数组
+      // for (let i of arr) {
+      //   if (i.ChartInfoId === id) {
+      //     return i;
+      //   }
+      //   if (i.Children) {
+      //     let node = this.findNode(i.Children, id);
+      //     if (node) {
+      //       return node;
+      //     }
+      //   }
+      // }
+    },
+    /* 点击表格行展开配置项 */
+    rowClickHandle(row) {
+      this.expandKey =
+        this.expandKey.length && this.expandKey[0] === row.EdbCode
+          ? []
+          : [row.EdbCode];
+      //曲线图点击行 自动置底
+      // if (this.selected_chartType === 1) {
+      //   this.$nextTick(() => {
+      //     $('.chart-min-cont')[0].scrollTop = 10000;
+      //   });
+      // }
+    },
+    
+    /* 设置row-key */
+    getRowKey(row) {
+      return row.EdbCode;
+    },
+    /* 控制展开一行收起其他行并高亮 */
+    expandChangeHandle(row, expandedRows) {
+      this.expandKey =
+        this.expandKey.length && this.expandKey[0] === row.EdbCode
+          ? []
+          : [row.EdbCode];
+      //曲线图点击行 自动置底
+      // if (this.selected_chartType === 1) {
+      //   this.$nextTick(() => {
+      //     $('.chart-min-cont')[0].scrollTop = 10000;
+      //   });
+      // }
+      this.$refs.tableRef.setCurrentRow(row);
+    },
+    // 查找树节点所有父节点
+    findParentNodeHandle(arr, id) {
+      // 遍历取父级code push数组
+      for (let i of arr) {
+        if (i.UniqueCode === id) {
+          return [i.UniqueCode];
+        }
+        if (i.Children) {
+          let node = this.findParentNodeHandle(i.Children, id);
+          if (node) {
+            return node.concat(i.UniqueCode);
+          }
+        }
+      }
+    },
+    // 通过分类id找到指标所属的分类
+    findParentNodeForClassifyId(id,code){
+      let arr=[]
+			this.treeData.forEach(item=>{
+				if(item.Children){
+					item.Children.forEach(_item=>{
+						if(_item.ChartClassifyId==id){
+							arr=[item.UniqueCode,_item.UniqueCode]
+						}
+					})
+				}
+			})
+			return [...arr]
+    },
+
+    /* 向左收起 展开 */
+    slideHandle() {
+      this.isSlideLeft = !this.isSlideLeft;
+    },
+    /* 保存图表当前配置项 上下限 */
+    saveNowOptions() {
+      const dataArr = _.cloneDeep(this.tableData);
+      dataArr.forEach((item) => {
+        item.MaxData = Number(item.MaxData);
+        item.MinData = Number(item.MinData);
+        delete item.DataList;
+      });
+      sessionStorage.setItem('beforeOptions', JSON.stringify(dataArr));
+    },
+    /* 季节图切换年份  保持当前配置 */
+    seasonYearChange() {
+      this.saveNowOptions();
+      this.getChartInfo('refresh');
+    },
+    /* 一键刷新 超长等待..*/
+    refreshHandle() {
+      this.refreshLoading = this.$loading({
+        lock: true,
+        target: '.main-right',
+        text: '刷新图表中...',
+        spinner: 'el-icon-loading',
+        background: 'rgba(255, 255, 255, 0.8)',
+      });
+      dataBaseInterface
+        .chartRefresh({
+          ChartInfoId: this.selected_chartid,
+        })
+        .then((res) => {
+          this.refreshLoading.close();
+          if (res.Ret === 200) {
+            this.getChartInfo('refresh');
+            this.$message.success(res.Msg);
+          }
+        });
+    },
+    /* 重绘右侧区域宽度 */
+    reloadRightWid() {
+      let total_wid = $('#box')[0].offsetWidth;
+      let left = $('#left')[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + 'px';
+      $('#right')[0].style.width = rigtWid;
+    },
+
+    /* 转base64 */
+    svgToBase64(svg) {
+      const base64img = `data:image/svg+xml;base64,${window.btoa(
+        unescape(encodeURI(svg))
+      )}`;
+      // console.log(base64img)
+      return base64img;
+    },
+
+    /* 点击保存时关联图表和截取的图片 */
+    setChartImage() {
+      let svg = this.$refs.chartRef.chart.getSVG({
+          chart:{
+          width: 340,
+          height: 230,
+          }
+        });
+        let form = new FormData();
+        form.append('Img', svg);
+        this.setImageHandle(form);
+    },
+    async setImageHandle(form) {
+      let { Data } = await dataBaseInterface.uploadImgSvg(form);
+
+      // let { Data } = await dataBaseInterface.uploadImg(form);
+      await dataBaseInterface.setChartImage({
+        ChartInfoId: this.selected_chartid,
+        ImageUrl: Data.ResourceUrl,
+      });
+    },
+
+    /* 分享图表 */
+    shareUrl() {
+      var clipboard = new this.Clipboard('.shareLink')
+      clipboard.on('success', e => {
+        console.log(e);
+        this.$message.success('复制链接成功')
+        e.clearSelection() // 释放内存
+        clipboard.destroy()
+      })
+      // // 浏览器不支持
+      clipboard.on('error', e => {
+        this.$message.warning('浏览器暂不支持')
+        // 释放内存
+        clipboard.destroy()
+      })
+    },
+
+    /* ----------------公用图库part-------------------- */
+    getPublicChartList() {
+      mychartInterface
+        .publicList({
+          PageSize: this.public_page_size,
+          CurrentIndex: this.public_page_no,
+          ChartClassifyId: this.default_classify || 0,
+          IsShowMe:this.isOnlyMe || false
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          // this.isShowPublicChart = res.Data ? true : false;
+          this.publicHaveMove = res.Data
+            ? this.public_page_no < res.Data.Paging.Pages
+            : false;
+          this.chartPublicList = res.Data
+            ? this.public_page_no === 1
+              ? res.Data.List
+              : [...this.chartPublicList, ...res.Data.List]
+            : [];
+          this.public_total = res.Data ? res.Data.Paging.Totals : 0;
+        });
+    },
+
+    /* 加载更多 */
+    loadMorePublicChart:_.throttle(function(e) {
+      let scrollTop = this.$refs.listChartPage.scrollTop;
+      let clientHeight = this.$refs.listChartPage.clientHeight;
+      let scrollHeight = this.$refs.listChartPage.scrollHeight;
+      console.log('scrollTop:',scrollTop)
+      console.log('clientHeight:',clientHeight)
+      console.log('scrollHeight:',scrollHeight)
+			if(scrollTop + clientHeight >= scrollHeight-10 && this.publicHaveMove){
+				this.public_page_no++;
+				this.getPublicChartList();
+			}
+    },300),
+
+    /* 点击图表区域跳转详情 选中左侧图表菜单 */
+    detailShowHandle(item) {
+
+      this.leftShowLabel = '目录';
+      this.$nextTick(() => {
+        let params = {
+          code: item.UniqueCode,
+          id: item.ChartInfoId,
+          type: item.ChartType,
+          chartData:item
+        };
+        this.selectCurrentNode(params);
+        this.default_classify = '';
+        this.reloadRightWid();
+      })
+    },
+
+    /* 加入我的图库 */
+    addMychartHandle(item) {
+      this.add_chart_id = item.ChartInfoId;
+      //已有的分类ids
+      this.add_ids = item.MyChartClassifyId ? item.MyChartClassifyId.split(',').map(item => Number(item)) : [];
+      this.isAddMyChart = true;
+    },
+
+    /* 加入我的图库成功 */
+    addMySuccess(params) {
+      this.isAddMyChart = false;
+
+      /* 判断是详情还是图库列表 */
+      if (this.selected_chartid) {
+        this.chartInfo.IsAdd = true;
+        this.chartInfo.MyChartId = params.MyChartInfoId;
+        this.chartInfo.MyChartClassifyId = params.MyChartClassifyId;
+      } else {
+        this.chartPublicList.forEach((item) => {
+          if (item.ChartInfoId === this.add_chart_id) {
+            item.IsAdd = true;
+            item.MyChartId = params.MyChartInfoId;
+            item.MyChartClassifyId = params.MyChartClassifyId
+          }
+        });
+      }
+    },
+
+    /* 存储中英文状态 */
+		setLangIntoStore() {
+			this.$store.commit('edb/SET_CAHRT_LANG',this.currentLang)
+		},
+    /* 获取标签列表 */
+    getlabelList(){
+        const List = JSON.parse(sessionStorage.getItem('etachart'))||[]
+        this.labelList = List
+    },
+    /* 添加标签  params 基本属性{code,id,classifyId,EdbName,EdbNameEn}*/
+    addLabel(params){
+        const index = this.labelList.findIndex(i=>i.code===params.code)
+        //标签已存在列表中,更新标签的值
+        if(index!==-1){
+            this.labelList.splice(index,1,params)
+            return
+        }
+        //根据页面宽度 判断标签数量是否达到上限
+        const listWidth = document.querySelector('.chartSetting-label-list').offsetWidth
+        const minWidth=170+20
+        const maxNum = Math.floor(listWidth/minWidth)
+        if(this.labelList.length>=maxNum){
+            //达到上限则挤出第一个,再添加
+            this.labelList.shift()
+        }
+        this.labelList.push(params)
+    },
+    //改变选中标签,
+    changeCurrentLabel(params){
+        if(params.code!==this.select_node){
+            this.selectCurrentNode(params)
+        }
+    },
+    //删除标签
+    deleteLabel(params,type="label"){
+        const index = this.labelList.findIndex(i=>i.code===params.code)
+        //如果删除的标签是选中状态
+        if(this.select_node===params.code){
+            //删除的是唯一一个标签
+            if(this.labelList.length===1){
+                this.selected_chartid=''
+                this.select_node = ''
+                this.$refs.treeRef.setCurrentKey(null)
+                this.getPublicChartList()
+            //不是唯一的标签,则默认选中上一个/下一个
+            }else{
+                type==='label'&&index===0&&this.changeCurrentLabel(this.labelList[1])
+                type==='label'&&index!==0&&index!==-1&&this.changeCurrentLabel(this.labelList[index-1])
+            }
+        }
+        index!==-1&&this.labelList.splice(index,1)
+    },
+    changeTreeNode(){
+        this.$refs.treeRef.setCurrentKey(this.select_node);
+        this.$nextTick(()=>{
+            const _node = this.$refs.treeRef.getNode(this.select_node)
+            this.dynamicNode = _node;
+            this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
+        })
+    }
+
+  },
+    //离开页面时保存标签
+    beforeRouteLeave(to,from,next){
+        sessionStorage.setItem('etachart',JSON.stringify(this.labelList))
+        next()
+    },
+  mounted() {
+    this.getlabelList()
+
+    if(this.$route.query.code) {
+      this.getTreeData({code: this.$route.query.code,id: Number(this.$route.query.id)})
+    } else {
+      this.getTreeData();
+      this.getPublicChartList();
+    }
+    window.addEventListener('resize', this.reloadRightWid);
+
+    //离开页面时保存标签
+    window.onbeforeunload = ()=>{
+        sessionStorage.setItem('etachart',JSON.stringify(this.labelList))
+    }
+  },
+  destroyed() {
+    window.removeEventListener('resize', this.reloadRightWid);
+    window.onbeforeunload = null
+  },
+};
+</script>
+<style lang="scss">
+@import './css/chartfit.scss';
+.chartSetting_container {
+  * {box-sizing: border-box;}
+  .flip-list-move {
+    transition: transform 0.4s;
+  }
+  .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
+    background-color: #409eff !important;
+    border-color: #409eff;
+  }
+  .el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner {
+    background-color: #409eff !important;
+    border-color: #409eff;
+  }
+  .el-card .el-card__header {
+    padding: 14px 20px;
+  }
+
+  .main-left {
+    .add-chart-cont {
+      padding: 15px 20px;
+      border: 1px solid #ECECEC;
+      display: flex;
+      box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+    }
+    .left-tab {
+      display: flex;
+      align-items: center;
+      padding: 20px 20px 0;
+      .tab {
+        cursor: pointer;
+        font-size: 16px;
+        border-bottom: 2px solid transparent;
+        margin-right: 40px;
+        padding-bottom: 5px;
+        &.act{
+          color: #409eff;
+          border-color: #409eff;
+        }
+        &:hover {
+          color: #409eff;
+        }
+      }
+    }
+    .targetset-cont {
+      padding: 30px 20px 20px;
+      height: calc(100vh - 290px);
+      overflow-y: auto;
+      .target-list {
+        border: 1px solid #DCDFE6;
+        .setting-cont {
+          padding: 20px 20px 0;
+          li {
+            padding-bottom: 20px;
+            margin-bottom: 20px;
+            border-bottom: 1px solid #DCDFE6;
+            &:last-child {
+              padding-bottom: 0;
+              margin-bottom: 0;
+              border-bottom: none;
+            }
+          }
+        }
+      }
+      .scatter-setting {
+        display: flex;
+        margin-bottom: 20px;
+      }
+      .el-input__inner {
+        height: 27px;
+        line-height: 27px;
+        padding: 0 4px;
+      }
+      .el-input-number .el-input__inner {
+        padding: 0 34px 0 4px;
+      }
+      .el-color-picker--mini .el-color-picker__trigger {
+        width: 60px;
+        height: 25px;
+        padding: 0;
+      }
+      .el-color-picker--mini .el-color-picker__mask {
+        width: 60px;
+        height: 25px;
+      }
+      .el-collapse-item__header {
+        background-color: #F0F2F5;
+        margin-bottom: 0;
+        border-bottom: 1px solid #DCDFE6;
+        padding: 0 20px 0 30px;
+        .el-collapse-item__arrow {
+          position: absolute;
+          left: 8px;
+        }
+      }
+    }
+  }
+  .cont-bottom {
+    .error-tip{ color: #D03F28; font-size: 16px;padding: 25px 0 0 25px; }
+    .bottom-min {
+      border: 1px solid #DCDFE6;
+      margin-bottom: 20px;
+      .right-actions {
+        /* max-width: 160px; */
+        height: 100%;
+        padding: 20px 10px;
+        border-left: 1px solid #DCDFE6;
+        li {
+          margin-bottom: 15px;
+        }
+        @media screen and (max-width: 1710px) {
+          font-size: 12px;
+        }
+        .span-item {
+          color: #409eff;
+          cursor: pointer;
+          &:hover {
+            text-decoration: underline;
+          }
+          .el-icon-collection,
+          .el-icon-document-copy {
+            color: #409eff;
+          }
+        }
+      }
+      .calendar-cont {
+        .el-radio-button__inner {
+          padding: 8px 16px;
+        }
+      }
+    }
+  }
+
+   /* ===================== */
+  .chart-public-cont {
+    color: #333;
+    .el-card .el-card__header,
+    .el-card__body {
+      padding: 10px;
+    }
+
+    .chart-public-list {
+      margin-top: 10px;
+      display: flex;
+      flex-wrap: wrap;
+      max-height: calc(100vh - 143px);
+      overflow: hidden;
+      overflow-y: auto;
+      .drag-cont {
+        width: 100%;
+        display: flex;
+        flex-wrap: wrap;
+      }
+      .dragShdow {
+        box-shadow: 0 1px 8px rgba(64, 158, 255, 0.8);
+        opacity: 0.5;
+      }
+      .public-chart-item {
+        .item-top {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          font-size: 16px;
+          font-weight: 600;
+        }
+        .chart-img {
+          width: 100%;
+          height: 230px;
+          object-fit: fill !important;
+          cursor: pointer;
+        }
+        .item-bottom {
+          margin-top: 10px;
+          display: flex;
+          justify-content: space-between;
+          font-size: 12px;
+          color: #666;
+          .collected {
+            color: #f00;
+            cursor: pointer;
+          }
+          .join_txt {
+            color: #409eff;
+            cursor: pointer;
+          }
+        }
+      }
+    }
+  }
+  .nodata {
+    /* height: calc(100vh - 240px); */
+    text-align: center;
+    font-size: 16px;
+    color: #666;
+  }
+  .copy-excel {
+    color: #409eff;
+    font-size: 14px;
+    padding-left: 50px;
+    padding-right: 10px;
+  }
+
+  @media screen and (min-width: 1711px) {
+    .el-icon-refresh {
+      font-size: 17px;
+      margin-left: 5px;
+      cursor: pointer;
+    }
+    .chartSetting_top {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20px;
+      padding: 20px 30px;
+      background: #fff;
+      border: 1px solid #ececec;
+      border-radius: 4px;
+      box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+      .el-select__input {
+        margin-left: 30px;
+      }
+    }
+    .chartSetting_main {
+      /* display: flex; */
+      div::-webkit-scrollbar {
+        width: 5px !important;
+      }
+      .slide-icon {
+        padding: 20px 0;
+        /* display: block; */
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+        border-radius: 5px;
+        cursor: pointer;
+        position: absolute;
+        top: 50%;
+        transform: translateY(-50%);
+        z-index: 99;
+        &:hover {
+          background-color: rgba(0, 0, 0, 0.05);
+        }
+        &.slide-left {
+          right: 0;
+        }
+        &.slide-right {
+          left: 0;
+        }
+      }
+      .main-left {
+        width: 400px;
+        min-width: 300px;
+        background: #fff;
+        margin-right: 20px;
+        border: 1px solid #ececec;
+        border-radius: 4px;
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+        height: calc(100vh - 113px);
+        overflow: hidden;
+        position: relative;
+        box-sizing: border-box;
+        .chartSetting_main_top {
+          padding: 10px 20px 15px;
+          .add-cont {
+            cursor: pointer;
+            font-size: 15px;
+            color: #409eff;
+          }
+        }
+        .tree-cont {
+          padding: 15px 20px 30px;
+          overflow: auto;
+          max-height: calc(100vh - 330px);
+        }
+        .target_tree {
+          font-size: 14px;
+          color: #333;
+          .label-input .el-input__inner {
+            height: 25px;
+            line-height: 25px;
+          }
+          .custom-tree-node {
+            display: flex !important;
+            justify-content: space-between;
+            align-items: center;
+            display: block;
+            flex: 1;
+            .node_label {
+              margin-right: 2px;
+            }
+          }
+          .el-tree__drop-indicator {
+            /* position:absolute; */
+            /* left:0;
+						right:0; */
+            height: 3px;
+            // margin-top: 8px;
+            background-color: #409eff;
+          }
+          .el-tree-node__content {
+            margin-bottom: 14px !important;
+          }
+          .el-tree-node__children {
+            .el-tree-node {
+              /* margin-bottom: 8px !important; */
+              margin-bottom: 0px !important;
+              padding-left: 18px;
+            }
+            .el-tree-node__content {
+              margin-bottom: 5px !important;
+              padding-left: 0 !important;
+            }
+          }
+          .expanded.el-icon-caret-right:before {
+            content: url('../../assets/img/set_m/down.png') !important;
+          }
+          .el-icon-caret-right:before {
+            content: url('../../assets/img/set_m/slide.png') !important;
+          }
+          .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+            content: '' !important;
+          }
+          .el-tree-node__expand-icon.expanded {
+            -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+          }
+          .el-tree-node.is-current > .el-tree-node__content {
+            background-color: #f0f4ff !important;
+          }
+          .el-tree-node__content {
+            padding-right: 10px !important;
+          }
+        }
+        .noDepart {
+          margin: 60px 0;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          color: #409eff;
+          font-size: 16px;
+          cursor: pointer;
+        }
+        .move-btn {
+          height: 100%;
+          width: 4px;
+          /* opacity: 0; */
+          position: absolute;
+          right: 0px;
+          top: 0;
+          &:hover {
+            cursor: col-resize;
+            /* background-color: orange */
+          }
+        }
+      }
+      .main-right {
+        width: 80%;
+        .mx-datepicker {
+          width: 220px !important;
+        }
+        /* =================== */
+        .chart-min-cont {
+          background: #fff;
+          border: 1px solid #ececec;
+          height: calc(100vh - 114px);
+          overflow: auto;
+          /* overflow: hidden; */
+          border-radius: 4px;
+          box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+          .cont-top {
+            padding: 12px 30px;
+            border-bottom: 1px solid #ececec;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+            .top-left {
+              .year-btn {
+                font-size: 14px;
+                margin-right: 5px;
+                margin-bottom: 5px;
+              }
+              .btn-sty {
+                font-size: 16px;
+                padding: 10px;
+                border: 1px solid #409eff;
+              }
+            }
+            .top-right {
+              font-size: 16px;
+              .join_txt {
+                color: #409eff;
+                cursor: pointer;
+                &:hover {
+                  text-decoration: underline;
+                }
+              }
+              .collected {
+                color: #f00;
+                cursor: pointer;
+                &:hover {
+                  text-decoration: underline;
+                }
+              }
+              .span-item {
+                color: #409eff;
+                cursor: pointer;
+                &:hover {
+                  text-decoration: underline;
+                }
+                .el-icon-collection,
+                .el-icon-document-copy {
+                  color: #409eff;
+                }
+              }
+            }
+          }
+          .cont-bottom {
+            padding: 20px 30px;
+            /* height: calc(100vh - 250px);
+						overflow: auto; */
+            .el-input__inner {
+              height: 27px;
+              line-height: 27px;
+              padding: 0 4px;
+            }
+            .el-input-number .el-input__inner {
+              padding: 0 34px 0 4px;
+            }
+            .el-color-picker--mini .el-color-picker__trigger {
+              width: 60px;
+              height: 25px;
+              padding: 0;
+            }
+            .el-color-picker--mini .el-color-picker__mask {
+              width: 60px;
+              height: 25px;
+            }
+            .el-table__expanded-cell {
+              padding: 20px 26px;
+            }
+            .highcharts-range-selector-group {
+              display: none;
+              .highcharts-input-group {
+                display: none;
+              }
+            }
+            .highcharts-axis-title {
+              display: block;
+            }
+            .calendar-cont {
+              display: block;
+              margin: 10px auto 0;
+              text-align: center;
+            }
+            /* =================== */
+            .chart-show-cont {
+              padding: 0 160px 0 120px;
+              position: relative;
+              .chart-title {
+                font-size: 16px;
+                font-weight: normal;
+                text-align: center;
+                margin-bottom: 10px;
+              }
+              .chart-author {
+                font-size: 14px;
+                color: #333;
+                position: absolute;
+                bottom: -20px;
+                right: 50px;
+              }
+              .chartWrapper {
+                position: relative;
+                .range-cont {
+                  position: absolute;
+                  top: 13%;
+                  .min-data-input {
+                    width: 60px;
+                    display: block;
+                    margin-top: 320px;
+                  }
+                  &.left {
+                    left: -80px;
+                  }
+                  &.right {
+                    right: -65px;
+                  }
+                  &.rightTwo {
+                    right: -130px;
+                  }
+                  &.bottom {
+                    width: 100%;
+                    display: flex;
+                    justify-content: space-between;
+                    top: auto;
+                    right: 0;
+                    bottom: -3%;
+                    .left {
+                      width: 60px;
+                      display: block;
+                      flex-shrink: 0;
+                    }
+                  }
+                }
+              }
+            }
+            .options-cont {
+              display: flex;
+              flex-wrap: wrap;
+              justify-content: space-between;
+            }
+          }
+        }
+      }
+      .chartSetting-main{
+          display: flex;
+      }
+      .chartSetting-label-list{
+          margin-bottom: 22px;
+      }
+    }
+
+    .drawImg {
+      position: absolute;
+      top: -999px;
+      z-index: -100;
+    }
+  }
+
+}
+</style>
+<style lang="scss">
+.edb-item-style .el-input__icon {
+	line-height: 27px;
+}
+</style>

+ 578 - 0
src/views/dataEntry_manage/coal/index.vue

@@ -0,0 +1,578 @@
+<template>
+	<div class="lzTarget-container">
+		<div class="left-cont minHeight">
+			<div class="left-top">
+				<!-- <el-button type="primary" plain size="medium" @click="exportClick" :loading="btnload">导出Excel</el-button> -->
+				<el-button style="width:100%;" type="primary" plain size="medium" @click="exportClick" :loading="btnload">导出Excel</el-button>
+				<el-autocomplete
+				style="margin: 20px 0;width:100%;"
+				prefix-icon="el-icon-search"
+      			v-model="leftSearchVal"
+      			:fetch-suggestions="handleLeftSearch"
+				:trigger-on-focus="false"
+      			placeholder="指标名称/指标ID"
+      			@select="handleSelectLeftSearchval"
+				popper-class="el-autocomplete-suggestion-data-entry"
+				clearable>
+				  <template slot-scope="scope">
+              		<div v-if="scope.item.nodata" style="text-align:center">暂无数据</div>
+              		<div v-else>
+                		{{scope.item.IndexName}}
+              		</div>
+            		</template>
+				</el-autocomplete>
+			</div>
+			<!-- <ul class="classify-list">
+				<li
+					:class="[
+						'classify-item',
+						{ act: select_classify === item.BreedShortName },
+					]"
+					v-for="item in classifyList"
+					:key="item.BreedShortName"
+					@click="changeClassify(item.BreedShortName)"
+				>
+					{{ item.BreedShortName }}
+				</li>
+			</ul> -->
+			<div>
+				<el-tree
+				class="filter-tree"
+				:data="classifyList"
+				node-key="ClassifyId"
+				:current-node-key="select_node"
+				:props="defaultProps"
+				default-expand-all
+				:default-checked-keys="[select_classify]"
+				:filter-node-method="filterNode"
+				ref="coalTree"
+				highlight-current
+				@node-click="clickClassify"
+				>
+				</el-tree>
+			</div>
+		</div>
+		<div class="right-cont minHeight" 
+		v-loading="dataloading"
+		element-loading-text="获取数据中...">
+			<div 
+				class="right-box"
+				v-infinite-scroll="loadNext" 
+				:infinite-scroll-disabled="!haveMore"
+				:infinite-scroll-immediate="false"
+				v-if="rightShow"
+			>
+				<div class="data-header">
+					<lz-table :tableOption="tableOption" tableType="header" ref="table" source="coal"/>
+				</div>
+				<div class="data-cont" v-if="dateArr.length">
+					<lz-table
+						:tableOption="tableOption"
+						tableType="data"
+						:dateArr="dateArr"
+						source="coal"
+					/>
+				</div>
+				<div v-else class="nodata"></div>
+			</div>
+			<div class="frequency-list" v-if="rightShow">
+				<el-button
+					type="primary"
+					class="frequency-btn"
+					:plain="select_frequency !== item.key"
+					v-for="item in frequencyList"
+					:key="item.key"
+					@click="changeFrequency(item.key)"
+					>{{ item.label }}</el-button
+				>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+import lzTable from '@/components/lzTable.vue';
+import { coalDataInterface } from '@/api/api.js';
+export default {
+	name: '',
+	components: { lzTable },
+	watch: {
+		select_classify_name(newval) {
+			console.info("watch");
+			console.info(newval)
+			console.info(this.isAuto)
+			if(!this.isAuto) return
+			this.select_frequency = '';
+			this.page_no = 1;
+			newval && this.getFrequency();
+		},
+		select_frequency(newval) {
+			console.info("watch");
+			console.info(newval)
+			console.info(this.isAuto)
+			if(!this.isAuto) return
+			this.page_no = 1;
+			newval && this.getDataList();
+		},
+	},
+	data() {
+		return {
+			dataloading: false,
+			rightShow: false,
+			exportBase:process.env.API_ROOT+'/entry/export/coalList',//中国煤炭网数据导出接口
+			defaultProps:{
+				label: 'ClassifyName',
+				children: 'Child',
+			},
+			classifyList: [],
+			select_frequency: '',
+			frequencyType: new Map([
+				[1, '日度'],
+				[2, '周度'],
+				[3, '旬度'],
+				[4, '月度'],
+				[5, '季度'],
+				[6, '年度'],
+				[99, '无固定频率'],
+			]),
+			frequencyList: [],
+			tableOption: [],
+			dateArr: [],//最长的日期数组
+			btnload: false,
+			page_size: 20,
+			page_no: 1,
+			haveMore: false,
+
+			leftSearchVal:'',//左侧搜索值
+			leftSearchTradeCode:'', //如果是搜索选择的 则有此code
+			select_quota:'',	// 选择的指标名
+			select_Unit:'',	// 选择的单位
+			select_UpdateTime:'',	// 更新时间
+			select_classify: '',//选择的分类id
+			select_classify_name: '',//选择的分类名称
+			select_node:0,
+			isAuto:true,	// 改变分类时是否自动获取数据
+		};
+	},
+	methods: {
+		/* 获取分类 */
+		getClassify() {
+			coalDataInterface.classifyList().then((res) => {
+				if (res.Ret !== 200) return;
+				this.classifyList = res.Data || [];
+				this.select_classify =
+					this.select_classify || this.classifyList[0].ClassifyId;
+				this.select_classify_name=this.classifyList[0].Child[0].ClassifyName
+				this.$nextTick(()=>{
+					this.select_node = this.classifyList[0].Child[0].ClassifyId;
+        			this.$refs.coalTree.setCurrentKey(this.select_node);
+                    console.info("select_node")
+					console.info(this.select_node)
+				})
+			});
+		},
+		/* 获取频度 */
+		getFrequency(defaultSelect) {
+			coalDataInterface
+				.frequencyList({
+					ClassifyId: Number(this.select_classify),
+				})
+				.then((res) => {
+					if (res.Ret !== 200) return;
+					this.frequencyList = 
+						res.Data ?
+						res.Data.map((item) => {
+							console.info(this.frequencyType.get(item.Frequency))
+							return {
+								label: this.frequencyType.get(item.Frequency),
+								key: item.Frequency,
+							};
+						}) : [];
+					console.info(this.frequencyList)
+					//设置当前选中的频度,若传入有默认选项则选中默认频度,否则选中列表第一个
+					this.select_frequency =  defaultSelect||this.frequencyList.length ? this.frequencyList[0].key : '';
+					!this.frequencyList.length && this.nodataDeal();
+					//如果有默认频度,结束后恢复watcher
+					this.$nextTick(()=>{
+						if(defaultSelect) this.isAuto=true
+					})
+				});
+		},
+		/* 获取数据 */
+		getDataList() {
+			this.dataloading = true;
+			coalDataInterface
+				.dataList({
+					PageSize: this.page_size,
+					CurrentIndex: this.page_no,
+					ClassifyId: Number(this.select_classify),
+					GroupName:this.select_classify_name,
+					Frequency: this.frequencyType.get(this.select_frequency),
+				})
+				.then((res) => {
+					this.rightShow = true;
+					if (res.Ret !== 200) return;
+
+					// 找出最多的页码 判断是否还有数据
+					let page_arrs = res.Data.map(item => item.Paging.Pages);
+					let totalPage = Math.max.apply(Math,page_arrs);
+					this.haveMore =  this.page_no < totalPage ? true : false;
+
+					// 合并数据
+					if(this.page_no === 1) {
+						this.tableOption = res.Data;
+					}else {
+						this.tableOption.forEach(item => {
+							res.Data.forEach(_item => {
+								if(item.IndexCode === _item.IndexCode) {
+									item.DataList = [...item.DataList,..._item.DataList];
+								}
+							})
+						})
+					}
+
+					// 找出所有指标中数据的日期做多的那个 拆出日期数组 用来遍历表格行 ---错误逻辑
+					// 合并所有指标中的日期 作为日期数组
+					let arr = res.Data.map((item) => {
+						return item.DataList;
+					});
+
+					let obj = [];
+					for(let i of arr) {
+						for(let j of i) {
+							obj.push(j.DataTime)
+						}
+					}
+					let arr2 = [...new Set(obj)].sort().reverse();
+
+					let concatArr = [...new Set([...this.dateArr,...arr2])].sort().reverse();
+					this.dateArr = this.page_no === 1 ?  arr2 : concatArr;
+
+					/* 不满6个追加6个空的显示一排 别问 问就是为了美观  */
+					if(res.Data.length < 7) for( let i = 0; i < 7;i++ ) {
+						this.tableOption.push({
+							DataList:[]
+						})
+						if(this.tableOption.length >= 7) break;
+					}
+
+					//数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
+					if(this.dateArr.length < 12) for( let i = 0; i < 12;i++ ) {
+						this.dateArr.push('')
+						if(this.dateArr.length >= 12) break;
+					}
+
+					this.dataloading = false;
+					this.page_no ===1 && this.$nextTick(() => {
+						this.initWidth()
+					})
+				});
+		},
+		// 获取单个指标数据
+		async getTargetDataList(e) {
+			this.dataloading = true;
+			try{
+				const res = await coalDataInterface.getTargetDataList({
+					IndexCode:this.leftSearchTradeCode
+				})
+				this.rightShow = true;
+				if(res.Ret!==200) return
+				// 设置为没有更多数据
+				this.haveMore = false
+			    this.select_Unit=res.Data[0].Unit
+				this.select_classify=res.Data[0].ClassifyId
+				this.select_UpdateTime=res.Data[0].ModifyTime
+				// 合并数据
+				// this.tableOption = [{
+				// 	DataList:res.Data.DataList,
+				// 	...e
+				// }];
+				this.tableOption=res.Data
+				// 这里是单个指标所以不用合并日期
+				// const arr=res.Data.map(item=>item.DataTime)
+				let arr=[]
+				res.Data.forEach(item=>{
+					item.DataList.forEach(_item=>{
+						arr.push(_item.DataTime)
+					})
+				})
+				this.dateArr=[...new Set(arr)].sort().reverse()
+				/* 不满6个追加6个空的显示一排 别问 问就是为了美观  */
+				for( let i = 0; i < 7;i++ ) {
+					this.tableOption.push({
+						DataList:[]
+					})
+					if(this.tableOption.length >= 7) break;
+				}
+				//数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
+				if(this.dateArr.length < 12) for( let i = 0; i < 12;i++ ) {
+					this.dateArr.push('')
+					if(this.dateArr.length >= 12) break;
+				}
+
+				this.dataloading = false;
+				this.initWidth()
+			}catch(err){
+				console.log(err);
+			}
+		},
+		loadNext() {
+			this.page_no ++;
+			this.getDataList();
+		},
+
+		/* 改变品种 */
+		clickClassify(node,parentNode) {
+			// console.info("node")
+			// console.info(node)
+			// console.info(parentNode)
+			if(parentNode.level==1) return
+			this.isAuto=true
+
+			this.select_classify = parentNode.parent.data.ClassifyId;
+			this.select_classify_name = parentNode.data.ClassifyName;
+			this.leftSearchVal=''
+			this.leftSearchTradeCode=''
+			this.select_quota=''
+			this.select_Unit=''
+			this.select_UpdateTime=''
+		},
+		/* 改变频度 */
+		changeFrequency(key) {
+			this.select_frequency = key;
+			this.leftSearchVal=''
+		},
+		initWidth() {
+			$('.right-box')[0].style.width = this.$refs.table.$el.clientWidth + 5 + 'px';
+			$('.right-box')[0].scrollTop = 0;
+			$('.right-box')[0].scrollLeft = 0;
+		},
+		/* 无频度的异常显示处理 7*12*/
+		nodataDeal() {
+			this.tableOption = [];this.dateArr=[];
+			for( let i = 0; i < 7;i++ ) {
+				this.tableOption.push({
+					DataList:[]
+				})
+				if(this.tableOption.length >= 7) break;
+			}
+			for( let i = 0; i < 12;i++ ) {
+				this.dateArr.push('')
+				if(this.dateArr.length >= 12) break;
+			}
+		},
+		/* 钢联数据导出 */
+		exportClick() {
+			this.btnload = true;
+			// var iframe = document.createElement("iframe")
+			// iframe.style.display = "none";
+			// iframe.src = this.exportLzapi;
+			// document.body.appendChild(iframe);
+
+			const link = document.createElement("a")
+			link.href=this.exportCoalApi
+			link.download=''
+			link.click()
+			console.log({
+				QuotaName:this.select_quota,
+				IndexCode:this.leftSearchTradeCode,
+				TypeName:this.select_classify_name,
+				sendBreedName: this.escapeStr(this.select_classify_name),
+				Frequency:this.select_frequency,
+				UnitName:this.select_Unit,
+				ModifyTime:this.select_UpdateTime,
+				url:this.exportGlapi
+			});
+			setTimeout(()=> {
+				this.btnload = false;
+			},5000)
+		},
+
+		//左侧搜索
+    	async handleLeftSearch(query,cb){
+      		cb([])
+      		if(!query) return
+      		const res=await coalDataInterface.getTargetListByName({
+        		Keyword:query,
+      		})
+      		if(res.Ret===200){
+        		let arr=res.Data||[]
+        		if(!arr.length){
+          			cb([{nodata:true}])
+        		}else{
+          			cb(arr)
+        		}
+      		}
+    	},
+		// 选中左侧搜索值
+    	handleSelectLeftSearchval(e){
+			console.info("handleSelectLeftSearchval")
+			console.info(e)
+      		if(!e.IndexCode) return
+      		this.rightShow=false
+      		this.select_frequency=e.FrequencyName
+      		this.select_classify=e.BreedShortName
+      		this.leftSearchTradeCode=e.IndexCode
+      		this.leftSearchVal=e.IndexName
+			this.select_quota=e.IndexName
+			this.select_Unit=e.UnitName
+			this.select_UpdateTime=e.UpdateTime
+      		this.select_classify_name=''
+			// 关闭watcher
+			this.isAuto=false
+			//this.getFrequency(e.FrequencyName)
+			// 获取单独指标数据
+			this.getTargetDataList(e)
+      		// this.getDataList()
+      		this.$nextTick(()=>{
+				this.rightShow=true
+        		this.handleScrollLeftWrap()
+      		})
+    	},
+		// 左侧滚动
+    	handleScrollLeftWrap(){
+      		// let top=$('.act')[0].offsetTop
+      		// $('.classify-list').animate({
+        	// 	"scrollTop": top-200
+      		// })
+    	},
+		// 对[# ;]转义
+		escapeStr(str){
+			return str.replace(/#/g,escape('#')).replace(/;/g,escape(';'))
+		},
+	},
+	computed: {
+		exportCoalApi() {
+			// 钢联数据导出接口
+			let urlStr=this.exportBase
+			// token
+			urlStr+=`?${localStorage.getItem('auth')||''}`
+			// 指标名称参数
+			urlStr+=`&IndexName=${this.select_quota}`
+			// 指标id
+			urlStr+=`&IndexCode=${this.leftSearchTradeCode}`
+			// 分类id
+			urlStr+=`&ClassifyId=${this.select_classify}`
+			// 分类名称
+			urlStr+=`&TypeName=${this.select_classify_name}`
+			// 频度
+			urlStr+=`&Frequency=${this.select_frequency}`
+			// 单位
+			urlStr+=`&UnitName=${this.select_Unit}`
+			// 修改时间
+			urlStr+=`&ModifyTime=${this.select_UpdateTime}`
+			return this.escapeStr(urlStr)
+		}
+	},
+	created() {},
+	mounted() {
+		this.getClassify();
+	},
+};
+</script>
+
+<style lang="scss">
+.lzTarget-container{
+
+	// .is-checked{
+	// 	.is-current{
+	// 		background-color: #f0f2f5;
+	// 	}
+	// }
+.el-tree-node{
+	
+	.el-tree-node__children{
+		.el-tree-node__content{
+			white-space: normal;
+			min-height: 26px;
+			height: auto;
+			margin-bottom: 5px;
+		}
+	}
+}
+.el-tree-node__content{
+	// min-height: 26px;
+	// white-space: normal;
+}
+}
+
+</style>
+<style lang="scss" scoped>
+.lzTarget-container {
+	display: flex;
+	* {
+		box-sizing: border-box;
+	}
+	.minHeight {
+		height: calc(100vh - 120px);
+		background-color: #fff;
+		box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+		border-radius: 4px;
+	}
+	div::-webkit-scrollbar {
+		width: 5px !important;
+	}
+	.left-cont {
+		min-width: 250px;
+		margin-right: 20px;
+		padding: 30px 0;
+		// overflow: hidden;
+		.left-top {
+			padding: 0 20px;
+		}
+		.filter-tree {
+			padding: 0 20px;
+			/* margin-top: 20px; */
+			height: calc(100vh - 280px);
+			overflow-y: auto;
+			.classify-item {
+				font-size: 14px;
+				color: #666;
+				margin-bottom: 20px;
+				&:hover {
+					cursor: pointer;
+					color: #409eff;
+				}
+				&.act {
+					color: #409eff;
+				}
+			}
+		}
+	}
+	.right-cont {
+		width: 80%;
+		padding: 30px;
+		.right-box {
+			max-width: 100%;
+			max-height: calc(100vh - 230px);
+			border-left: 1px solid #dcdfe6;
+			border-right: 1px solid #dcdfe6;
+			overflow: auto;
+			.data-header {
+				width: 100%;
+				position: sticky;
+				top: 0;
+				z-index: 2;
+			}
+			.data-cont {
+				height: calc(100vh - 444px);
+			}
+			.nodata {
+				height: calc(100vh - 460px);
+				border: 1px solid #dcdfe6;
+				font-size: 16px;
+				color: #999;
+			}
+		}
+		.frequency-list {
+			margin-top: 20px;
+			display: flex;
+			flex-wrap: wrap;
+			.frequency-btn {
+				width: 112px;
+				margin: 0 30px 10px 0;
+			}
+		}
+	}
+}
+</style>

+ 72 - 0
src/views/dataEntry_manage/codecount/compoments/codeMirror.vue

@@ -0,0 +1,72 @@
+<template>
+	<codemirror
+		v-model="codeContent"
+		:options="codeOptions"
+		placeholder="请输入python代码"
+	/>
+</template>
+
+<script>
+import { codemirror } from 'vue-codemirror';
+import 'codemirror/lib/codemirror.css'
+//python语法高亮
+import 'codemirror/mode/python/python.js'
+// 光标行高亮
+import 'codemirror/addon/selection/active-line';
+//代码折叠
+import 'codemirror/addon/fold/foldgutter.css'
+import 'codemirror/addon/fold/foldcode.js'
+import 'codemirror/addon/fold/foldgutter.js'
+import 'codemirror/addon/fold/brace-fold.js'
+import 'codemirror/addon/fold/comment-fold.js'
+import 'codemirror/addon/fold/indent-fold'
+
+
+export default {
+	name:'',
+	components: { codemirror },
+	props: {
+		code: {
+			type: String,
+		}
+	},
+	watch: {
+		code(newval) {
+			this.codeContent = _.cloneDeep(newval);
+		},
+		codeContent(newval) {
+			if(newval !== this.code) {
+				console.log('code change')
+				this.$emit('initResult')
+			}
+		}
+	},
+	data () {
+		return {
+			codeContent: '',
+			codeOptions: {
+				tabSize: 4,
+        mode: 'text/x-python',
+				styleActiveLine: true,
+        theme: 'default',
+        lineNumbers: true,
+        line: true,
+				indentWithTab: true,
+				//代码折叠
+				foldGutter: true,
+				gutters:["CodeMirror-linenumbers", "CodeMirror-foldgutter",'CodeMirror-lint-markers'],
+        height: 'auto',
+			}
+		};
+	},
+	methods: {
+		
+	},
+	mounted() {},
+}
+</script>
+<style lang='scss' scoped>
+.CodeMirror {
+	height: 300px !important;
+}
+</style>

+ 64 - 0
src/views/dataEntry_manage/codecount/compoments/dataTable.vue

@@ -0,0 +1,64 @@
+<template>
+  <table id="dataTable" ref="datatable"></table>
+</template>
+
+<script>
+const tableOptions = {
+  scrollY: "250px",
+  searching: false,
+  scrollCollapse: true,
+  paging: false,
+  fixedHeader: true,
+  autoWidth: true,
+  ordering: false,
+  stripeClasses: [ 'strip1', 'strip2' ]
+}
+export default {
+  name: '',
+  props: {
+    // show: {
+    //   type: Boolean,
+    //   required: true
+    // },
+    columns: {
+      type: Array,
+      default: [
+        { title: '日期' },
+        { title: '值'  },
+      ],
+    },
+    data: {
+      type: Array,
+      default: [],
+    }
+  },
+  methods: {
+    initData() {
+      this.DataTable = $('#dataTable').DataTable({
+        ...tableOptions,
+        data: this.data,
+        columns: this.columns,
+      });
+    },
+  },
+  mounted() {
+    this.initData();
+  }
+};
+</script>
+<style lang="scss" >
+.dataTables_wrapper {
+  .dataTable td {
+    text-align: center !important;
+  }
+  .dataTables_scrollHeadInner,.dataTables_scrollHeadInner .dataTable  {
+    width: 100% !important;
+  }
+  .dataTables_info {
+    display: none;
+  }
+  .strip1  td{
+    background-color: #f9f9f9
+  }
+}
+</style>

+ 473 - 0
src/views/dataEntry_manage/codecount/index.vue

@@ -0,0 +1,473 @@
+<template>
+	<el-card class="codecount-container">
+		<div slot="header" class="header">
+			<span>代码运算</span>
+			<div>
+				<el-button type="primary" @click="runCodeHandle">运行</el-button>
+				<el-button type="primary" plain @click="saveHandle" v-if="!isView">保存</el-button>
+			</div>
+		</div>
+		<div class="bottom">
+			<el-col :span="15" class="bottom-wrapper left-wrapper">
+				<div class="code-editor">
+					<code-mirror ref="codeRef" :code="runCode" @initResult="initResult"/>
+				</div>
+				<div class="code-result">
+					<span>结果展示</span>
+					<div class="code-result-wrapper" v-if="isShowResult">
+						<data-table
+							:data="runResultData"
+						/>
+					</div>
+				</div>
+			</el-col>
+			<el-col :span="8" class="bottom-wrapper">
+				<el-tabs>
+					<el-tab-pane label="基础信息">
+						<el-form
+							ref="diaForm"
+							label-position="left"
+							inline
+							label-width="80px"
+							:model="formData"
+							:disabled="isView"
+						>
+							<el-form-item label="指标名称" prop="edb_name">
+								<el-input
+									v-model="formData.edb_name"
+									placeholder="指标名称"
+									style="width:220px"
+								/>
+							</el-form-item>
+							<el-form-item label="单位" prop="unit">
+								<selectUnit 
+									v-model="formData.unit" 
+									style="width:220px"
+								/>
+							</el-form-item>
+							<el-form-item label="频度" prop="frequency">
+								<el-select 
+								v-model="formData.frequency" 
+								placeholder="请选择频度" 
+								clearable 
+								@change="changeTrade"
+								style="width:220px">
+									<el-option
+										v-for="item in frequencyArr"
+										:key="item"
+										:label="item"
+										:value="item">
+									</el-option>
+								</el-select>
+							</el-form-item>
+							<el-form-item label="指标目录" prop="menu">
+								<el-cascader
+								v-model="formData.menu"
+								:options="menuOptions"
+								:props="{
+									label: 'ClassifyName',
+									value: 'ClassifyId',
+									children: 'Children',
+								}"
+								@change="menuChange"
+								clearable
+								style="width:220px"
+								placeholder="请选择指标目录"/>
+							</el-form-item>
+						</el-form>
+					</el-tab-pane>
+					<el-tab-pane label="指标信息" v-if="!isView">
+						<el-form
+							label-position="left"
+							inline
+							label-width="100px"
+						>
+							<el-form-item label="数据来源">
+								<el-select 
+								v-model="fromType" 
+								placeholder="请选择来源"
+								style="width:220px"
+								@change="changeTrade">
+									<el-option
+										v-for="item in allFromArr"
+										:key="item.key"
+										:label="item.name"
+										:value="item.key">
+									</el-option>
+								</el-select>
+							</el-form-item>
+							<el-form-item label="指标名称/ID">
+								<el-select
+									v-model="search_txt"
+									v-loadMore="searchLoad"
+									ref="searchRef"
+									:filterable="!search_txt"
+									remote
+									clearable
+									placeholder="指标ID/指标名称"
+									:remote-method="searchHandle"
+									@click.native="inputFocusHandle"
+									style="width:220px"
+								>
+									<i slot="prefix" class="el-input__icon el-icon-search"></i>
+									<el-option
+										v-for="item in searchOptions"
+										:key="item.EdbInfoId"
+										:label="eta_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
+										:value="item.EdbInfoId"
+									>
+									</el-option>
+								</el-select>
+
+							</el-form-item>
+						</el-form>
+						<div class="search-result">
+							<p>查询结果 <span style="color: #999;">(展示指标所在表结构及调取指标代码)</span></p>
+							<template v-if="resultInfo.sheet_name">
+								<table border>
+									<thead>
+										<tr>
+											<td v-for="item in resultInfo.headers" :key="item">{{item}}</td>
+										</tr>
+									</thead>
+									<tbody>
+										<tr v-for="(item,index) in resultInfo.sheetArr" :key="item.key">
+											<td :rowspan="resultInfo.sheetArr.length" v-if="index === 0">{{resultInfo.sheet_name}}</td>
+											<td>{{item.key}}</td>
+											<td>{{item.label}}</td>
+										</tr>
+									</tbody>
+								</table>
+								<div class="sql-code" v-html="resultInfo.sql_code"></div>
+								<el-button type="primary" class="copy-btn" @click="copyCode" :data-clipboard-text="resultInfo.sql_code">复制代码</el-button>
+
+							</template>
+						</div>
+					</el-tab-pane>
+				</el-tabs>
+			</el-col>
+		</div>
+	</el-card>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import { unitArr } from '@/utils/defaultOptions';
+import storage from '@/utils/storage.js';
+import { allFromArr } from '../databaseComponents/util';
+import codeMirror from './compoments/codeMirror';
+import dataTable from './compoments/dataTable';
+import { mapState } from 'vuex';
+export default {
+	name:'',
+	components: { codeMirror,dataTable },
+	computed: {
+		...mapState({
+			eta_lang: state => state.edb.eta_lang,	
+		})
+	},
+	data () {
+		return {
+			isView: this.$route.query.isView ? true : false,
+			formData: {},
+			fromType:"",
+			unitArr,
+			allFromArr,//所有指标来源
+			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
+			menuOptions:[],//目录数组
+
+			search_txt: '',
+			search_have_more: false,
+			searchOptions:[],
+			search_page: 1,
+			current_search: '',
+
+			isShowResult: false,
+			runCode: '',
+			runResultData:[],//运行结果
+
+			resultInfo: {
+				headers: ['表名','字段名','*字段说明'],
+				sheetArr:[],
+				sheet_name: '',
+				sql_code: ''
+			}
+		};
+	},
+	watch: {
+		//每搜索一次记录一次
+		search_txt(newval) {
+			if(!newval) return;
+
+			let historySearch = storage.get('pycode_seachlist') || [];
+			let obj = {
+				EdbInfoId: newval,
+				EdbName: this.searchOptions.find(_ => _.EdbInfoId===newval).EdbName
+			}
+			//有搜索记录删除上条
+			let index = historySearch.findIndex(_ => _.EdbInfoId === newval)
+			if(index !== -1) historySearch.splice(index, 1);
+			historySearch.unshift(obj)
+
+			storage.set('pycode_seachlist',historySearch,1)
+
+			this.getEdbSheeetInfo(newval);
+
+		}
+	},
+	methods: {
+
+		/* 运行代码 */
+		runCodeHandle: _.debounce(function() {
+			if(!this.$refs.codeRef.codeContent) return this.$message.warning('请输入代码');
+
+			this.isShowResult = false;
+
+			const loading = this.$loading({
+				lock: true,
+				text: '运行中...',
+				target:'.left-wrapper',
+				spinner: 'el-icon-loading'
+			});
+
+			dataBaseInterface.runCode({
+				PythonCode: encodeURIComponent(this.$refs.codeRef.codeContent)
+			}).then(res => {
+				
+				loading.close();
+				if(res.Ret !== 200) return
+				this.$message.success('运行成功')
+
+				const { date,value } = res.Data;
+				const data_arr = []
+				for(let i in date) {
+					data_arr.push([date[i],value[i]])
+				}
+				this.runResultData = data_arr;
+				this.isShowResult = true;
+			})
+		},200),
+
+		/* 获取指标详情 */
+		getEdbInfo() {
+			if(!this.$route.query.edbid) return;
+			dataBaseInterface.countCodeDetail({
+				EdbInfoId: Number(this.$route.query.edbid)
+			}).then(res => {
+				if(res.Ret !== 200) return
+				
+				const { EdbInfoDetail,PythonCode } = res.Data;
+				const { EdbName,ClassifyId,Frequency,Unit } = EdbInfoDetail;
+
+				this.formData = {
+					edb_name: EdbName,
+					menu: ClassifyId,
+					frequency: Frequency,
+					unit: Unit
+				}
+				this.runCode = PythonCode
+				
+			})
+		},
+
+		/* 获取表结构 */
+		getEdbSheeetInfo(EdbInfoId) {
+			dataBaseInterface.edbSheetDetail({
+				EdbInfoId
+			}).then(res => {
+				if(res.Ret !== 200) return
+				
+				const { ColumnList,TableName,TemplateStr } = res.Data;
+				this.resultInfo.sheet_name = TableName;
+				this.resultInfo.sql_code = decodeURIComponent(TemplateStr);
+				this.resultInfo.sheetArr = ColumnList.map(_ => {
+					let key = Object.keys(_)[0];
+					return {
+						key,
+						label: _[key]
+					}
+				})
+
+			})
+		},
+
+		/* code变化时重置结果展示 */
+		initResult() {
+			this.isShowResult = false
+		},
+
+		/* 复制代码 */
+		copyCode() {
+			var clipboard = new this.Clipboard('.copy-btn')
+				clipboard.on('success', e => {
+					this.$message.success('复制成功')
+					e.clearSelection() // 释放内存
+					clipboard.destroy()
+				})
+				// // 浏览器不支持
+				clipboard.on('error', e => {
+					this.$message.warning('浏览器暂不支持')
+					// 释放内存
+					clipboard.destroy()
+				})
+		},
+		
+		/* 保存代码 */
+		async saveHandle() {
+			if(!this.formData.edb_name || !this.formData.menu || !this.formData.frequency || !this.formData.unit) return this.$message.warning('请填写完整基础信息')
+			if(!this.isShowResult) return this.$message.warning('请先运行代码')
+
+			const loading = this.$loading({
+				lock: true,
+				text: '保存中...',
+				target:'.codecount-container',
+				spinner: 'el-icon-loading'
+			});
+			
+			const { edb_name,menu,frequency,unit } = this.formData
+			let params = {
+				PythonCode: encodeURIComponent(this.$refs.codeRef.codeContent),
+				EdbName: edb_name,
+				Frequency: frequency,
+				Unit: unit,
+				ClassifyId: menu
+			}
+			
+			const { Ret,Data } = this.$route.query.edbid ? await dataBaseInterface.editCountCode({ ...params,EdbInfoId: Number(this.$route.query.edbid) }) : await dataBaseInterface.addCountCode(params);
+			
+			loading.close();
+			if( Ret !== 200 ) return 
+			this.$message.success('保存成功')
+			const { UniqueCode,EdbInfoId } = Data;
+
+      this.$router.replace({path:'/database', query: {
+        code: UniqueCode,
+        id: EdbInfoId
+      }});
+
+		},
+
+		/* 获取目录结构 */
+		getMenu() {
+			dataBaseInterface.menuList().then((res) => {
+				if (res.Ret !== 200) return
+					this.filterNodes(res.Data.AllNodes);
+					this.menuOptions = res.Data.AllNodes || [];
+			});
+		},
+		// 递归改变第三级目录结构
+		filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (item.Level === 2) {
+						delete item.Children;
+					}
+				});
+		},
+
+		/* 选择目录 */
+		menuChange(val) {
+			this.formData.menu = val.length ? val[val.length - 1] : '';
+		},
+
+		/* 搜索 */
+		searchHandle(query) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search)
+		},
+
+		searchApi(query,page=1) {
+			if(!query){ this.searchOptions = []; return }   
+			dataBaseInterface.targetSearchByPage({
+				KeyWord:query,
+				CurrentIndex: page,
+				Source: this.fromType || 0,
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				const { List,Paging } = res.Data;
+				this.search_have_more = page < Paging.Pages;
+				this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
+
+			})
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+			this.searchOptions = this.fromType ? [] : storage.get('pycode_seachlist');
+			// this.searchApi(this.current_search);
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page);
+		},
+	},
+	mounted() {
+		this.getEdbInfo();
+		this.getMenu();
+	},
+}
+</script>
+<style lang='scss' scoped>
+*{ box-sizing: border-box;}
+.codecount-container {
+	.header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		font-size: 16px;
+	}
+	.bottom {
+		height: calc(100vh - 240px);
+		.bottom-wrapper {
+			padding: 20px;
+			height: 100%;
+			border: 1px solid #ECECEC;
+			border-radius: 4px;
+			&:first-child {
+				margin-right: 20px;
+				padding: 20px 0;
+			}
+			.code-editor {
+				padding: 0 20px;
+			}
+			.code-result {
+				border-top: 1px solid #ECECEC;
+				margin-top: 20px;
+				padding: 20px;
+			}
+
+			.search-result {
+				border-top: 1px solid #ECECEC;
+				padding: 20px 0;
+				table {
+					width: 100%;
+					margin-top: 22px;
+					td{ border-color: #DCDFE6; width: 33%; height: 36px;text-align: center;}
+				}
+				.sql-code {
+					min-height: 100px;
+					border: 1px solid #DCDFE6;
+					border-top: none;
+				}
+				.copy-btn {
+					display: block;
+					margin: 20px auto;
+				}
+			}
+		}
+	}
+}
+</style>
+<style lang="scss">
+.codecount-container {
+	.el-tabs__nav-wrap::after {
+		background-color: #fff;
+	}
+}
+</style>

部分文件因文件數量過多而無法顯示