diff --git a/report-ui/.babelrc b/report-ui/.babelrc
new file mode 100644
index 00000000..a2a380fe
--- /dev/null
+++ b/report-ui/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ ["env", {
+ "modules": false,
+ "targets": {
+ "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
+ }
+ }],
+ "stage-2"
+ ],
+ "plugins":["transform-vue-jsx", "transform-runtime"]
+}
diff --git a/report-ui/.editorconfig b/report-ui/.editorconfig
new file mode 100644
index 00000000..ea6e20f5
--- /dev/null
+++ b/report-ui/.editorconfig
@@ -0,0 +1,14 @@
+# http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/report-ui/.gitignore b/report-ui/.gitignore
new file mode 100644
index 00000000..78a0eada
--- /dev/null
+++ b/report-ui/.gitignore
@@ -0,0 +1,15 @@
+.DS_Store
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
diff --git a/report-ui/.postcssrc.js b/report-ui/.postcssrc.js
new file mode 100644
index 00000000..eee3e92d
--- /dev/null
+++ b/report-ui/.postcssrc.js
@@ -0,0 +1,10 @@
+// https://github.com/michael-ciniawsky/postcss-load-config
+
+module.exports = {
+ "plugins": {
+ "postcss-import": {},
+ "postcss-url": {},
+ // to edit target browsers: use "browserslist" field in package.json
+ "autoprefixer": {}
+ }
+}
diff --git a/report-ui/Dockerfile b/report-ui/Dockerfile
new file mode 100644
index 00000000..b3f73aae
--- /dev/null
+++ b/report-ui/Dockerfile
@@ -0,0 +1,4 @@
+# Dockerfile
+FROM nginx:alpine
+COPY dist/ /usr/share/nginx/html/
+EXPOSE 80
\ No newline at end of file
diff --git a/report-ui/build/build.js b/report-ui/build/build.js
new file mode 100644
index 00000000..766c3add
--- /dev/null
+++ b/report-ui/build/build.js
@@ -0,0 +1,45 @@
+'use strict'
+require('./check-versions')()
+
+//process.env.NODE_ENV = 'production'
+
+const ora = require('ora')
+const rm = require('rimraf')
+const path = require('path')
+const chalk = require('chalk')
+const webpack = require('webpack')
+const config = require('../config')
+const webpackConfig = require('./webpack.prod.conf')
+
+const spinner = ora('building for ' + process.env.NODE_ENV + '...')
+spinner.start()
+
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
+ if (err) throw err
+ webpack(webpackConfig, (err, stats) => {
+ spinner.stop()
+ if (err) throw err
+ process.stdout.write(
+ stats.toString({
+ colors: true,
+ modules: false,
+ children: false,
+ chunks: false,
+ chunkModules: false
+ }) + '\n\n'
+ )
+
+ if (stats.hasErrors()) {
+ console.log(chalk.red(' Build failed with errors.\n'))
+ process.exit(1)
+ }
+
+ console.log(chalk.cyan(' Build complete.\n'))
+ console.log(
+ chalk.yellow(
+ ' Tip: built files are meant to be served over an HTTP server.\n' +
+ " Opening index.html over file:// won't work.\n"
+ )
+ )
+ })
+})
diff --git a/report-ui/build/check-versions.js b/report-ui/build/check-versions.js
new file mode 100644
index 00000000..c5c29e90
--- /dev/null
+++ b/report-ui/build/check-versions.js
@@ -0,0 +1,64 @@
+'use strict'
+const chalk = require('chalk')
+const semver = require('semver')
+const packageConfig = require('../package.json')
+const shell = require('shelljs')
+
+function exec(cmd) {
+ return require('child_process')
+ .execSync(cmd)
+ .toString()
+ .trim()
+}
+
+const versionRequirements = [
+ {
+ name: 'node',
+ currentVersion: semver.clean(process.version),
+ versionRequirement: packageConfig.engines.node
+ }
+]
+
+if (shell.which('npm')) {
+ versionRequirements.push({
+ name: 'npm',
+ currentVersion: exec('npm --version'),
+ versionRequirement: packageConfig.engines.npm
+ })
+}
+
+module.exports = function() {
+ const warnings = []
+
+ for (let i = 0; i < versionRequirements.length; i++) {
+ const mod = versionRequirements[i]
+
+ if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
+ warnings.push(
+ mod.name +
+ ': ' +
+ chalk.red(mod.currentVersion) +
+ ' should be ' +
+ chalk.green(mod.versionRequirement)
+ )
+ }
+ }
+
+ if (warnings.length) {
+ console.log('')
+ console.log(
+ chalk.yellow(
+ 'To use this template, you must update following to modules:'
+ )
+ )
+ console.log()
+
+ for (let i = 0; i < warnings.length; i++) {
+ const warning = warnings[i]
+ console.log(' ' + warning)
+ }
+
+ console.log()
+ process.exit(1)
+ }
+}
diff --git a/report-ui/build/logo.png b/report-ui/build/logo.png
new file mode 100644
index 00000000..f3d2503f
Binary files /dev/null and b/report-ui/build/logo.png differ
diff --git a/report-ui/build/utils.js b/report-ui/build/utils.js
new file mode 100644
index 00000000..c96d0936
--- /dev/null
+++ b/report-ui/build/utils.js
@@ -0,0 +1,108 @@
+'use strict'
+const path = require('path')
+const config = require('../config')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const packageConfig = require('../package.json')
+
+exports.assetsPath = function(_path) {
+ const assetsSubDirectory =
+ process.env.NODE_ENV === 'production'
+ ? config.build.assetsSubDirectory
+ : config.dev.assetsSubDirectory
+
+ return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function(options) {
+ options = options || {}
+
+ const cssLoader = {
+ loader: 'css-loader',
+ options: {
+ sourceMap: options.sourceMap
+ }
+ }
+
+ const postcssLoader = {
+ loader: 'postcss-loader',
+ options: {
+ sourceMap: options.sourceMap
+ }
+ }
+
+ // generate loader string to be used with extract text plugin
+ function generateLoaders(loader, loaderOptions) {
+ const loaders = []
+
+ // Extract CSS when that option is specified
+ // (which is the case during production build)
+ if (options.extract) {
+ loaders.push(MiniCssExtractPlugin.loader)
+ } else {
+ loaders.push('vue-style-loader')
+ }
+
+ loaders.push(cssLoader)
+
+ if (options.usePostCSS) {
+ loaders.push(postcssLoader)
+ }
+
+ if (loader) {
+ loaders.push({
+ loader: loader + '-loader',
+ options: Object.assign({}, loaderOptions, {
+ sourceMap: options.sourceMap
+ })
+ })
+ }
+
+ return loaders
+ }
+ // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+ return {
+ css: generateLoaders(),
+ postcss: generateLoaders(),
+ less: generateLoaders('less'),
+ sass: generateLoaders('sass', {
+ indentedSyntax: true
+ }),
+ scss: generateLoaders('sass'),
+ stylus: generateLoaders('stylus'),
+ styl: generateLoaders('stylus')
+ }
+}
+
+// Generate loaders for standalone style files (outside of .vue)
+exports.styleLoaders = function(options) {
+ const output = []
+ const loaders = exports.cssLoaders(options)
+
+ for (const extension in loaders) {
+ const loader = loaders[extension]
+ output.push({
+ test: new RegExp('\\.' + extension + '$'),
+ use: loader
+ })
+ }
+
+ return output
+}
+
+exports.createNotifierCallback = () => {
+ const notifier = require('node-notifier')
+
+ return (severity, errors) => {
+ if (severity !== 'error') return
+
+ const error = errors[0]
+ const filename = error.file && error.file.split('!').pop()
+
+ notifier.notify({
+ title: packageConfig.name,
+ message: severity + ': ' + error.name,
+ subtitle: filename || '',
+ icon: path.join(__dirname, 'logo.png')
+ })
+ }
+}
diff --git a/report-ui/build/vue-loader.conf.js b/report-ui/build/vue-loader.conf.js
new file mode 100644
index 00000000..5496c931
--- /dev/null
+++ b/report-ui/build/vue-loader.conf.js
@@ -0,0 +1,5 @@
+'use strict'
+
+module.exports = {
+ //You can set the vue-loader configuration by yourself.
+}
diff --git a/report-ui/build/webpack.base.conf.js b/report-ui/build/webpack.base.conf.js
new file mode 100644
index 00000000..9138da30
--- /dev/null
+++ b/report-ui/build/webpack.base.conf.js
@@ -0,0 +1,93 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const config = require('../config')
+const {
+ VueLoaderPlugin
+} = require('vue-loader')
+const vueLoaderConfig = require('./vue-loader.conf')
+
+function resolve(dir) {
+ return path.join(__dirname, '..', dir)
+}
+
+module.exports = {
+ context: path.resolve(__dirname, '../'),
+ entry: {
+ app: './src/main.js'
+ },
+ output: {
+ path: config.build.assetsRoot,
+ filename: '[name].js',
+ publicPath: config.build.assetsPublicPath //process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
+ },
+ resolve: {
+ extensions: ['.js', '.vue', '.json'],
+ alias: {
+ '@': resolve('src')
+ }
+ },
+ module: {
+ rules: [{
+ test: /\.vue$/,
+ loader: 'vue-loader',
+ options: vueLoaderConfig
+ },
+ {
+ test: /\.js$/,
+ loader: 'babel-loader',
+ include: [
+ resolve('src'),
+ resolve('test'),
+ resolve('node_modules/webpack-dev-server/client')
+ ]
+ },
+ {
+ test: /\.svg$/,
+ loader: 'svg-sprite-loader',
+ include: [resolve('src/icons')],
+ options: {
+ symbolId: 'icon-[name]'
+ }
+ },
+ {
+ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+ loader: 'url-loader',
+ exclude: [resolve('src/icons')],
+ options: {
+ limit: 10000,
+ name: utils.assetsPath('img/[name].[hash:7].[ext]')
+ }
+ },
+ {
+ test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: utils.assetsPath('media/[name].[hash:7].[ext]')
+ }
+ },
+ {
+ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+ }
+ }
+ ]
+ },
+ plugins: [new VueLoaderPlugin()],
+ node: {
+ // prevent webpack from injecting useless setImmediate polyfill because Vue
+ // source contains it (although only uses it if it's native).
+ setImmediate: false,
+ // prevent webpack from injecting mocks to Node native modules
+ // that does not make sense for the client
+ dgram: 'empty',
+ fs: 'empty',
+ net: 'empty',
+ tls: 'empty',
+ child_process: 'empty'
+ }
+}
diff --git a/report-ui/build/webpack.dev.conf.js b/report-ui/build/webpack.dev.conf.js
new file mode 100644
index 00000000..cfc157ab
--- /dev/null
+++ b/report-ui/build/webpack.dev.conf.js
@@ -0,0 +1,100 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+const portfinder = require('portfinder')
+
+function resolve(dir) {
+ return path.join(__dirname, '..', dir)
+}
+
+const HOST = process.env.HOST
+const PORT = process.env.PORT && Number(process.env.PORT)
+
+const devWebpackConfig = merge(baseWebpackConfig, {
+ mode: 'development',
+ output: {
+ path: config.build.assetsRoot,
+ filename: '[name].js',
+ publicPath: config.dev.assetsPublicPath
+ },
+ module: {
+ rules: utils.styleLoaders({
+ sourceMap: config.dev.cssSourceMap,
+ usePostCSS: true
+ })
+ },
+ // cheap-module-eval-source-map is faster for development
+ devtool: config.dev.devtool,
+
+ // these devServer options should be customized in /config/index.js
+ devServer: {
+ clientLogLevel: 'warning',
+ historyApiFallback: true,
+ hot: true,
+ compress: true,
+ host: HOST || config.dev.host,
+ port: PORT || config.dev.port,
+ open: config.dev.autoOpenBrowser,
+ overlay: config.dev.errorOverlay
+ ? { warnings: false, errors: true }
+ : false,
+ publicPath: config.dev.assetsPublicPath,
+ proxy: config.dev.proxyTable,
+ quiet: true, // necessary for FriendlyErrorsPlugin
+ watchOptions: {
+ poll: config.dev.poll
+ }
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env': require('../config/dev.env')
+ }),
+ new webpack.HotModuleReplacementPlugin(),
+ // https://github.com/ampedandwired/html-webpack-plugin
+ new HtmlWebpackPlugin({
+ filename: 'index.html',
+ template: 'index.html',
+ inject: true,
+ favicon: resolve('favicon.ico'),
+ title: 'vue-admin-template'
+ })
+ ]
+})
+
+module.exports = new Promise((resolve, reject) => {
+ portfinder.basePort = process.env.PORT || config.dev.port
+ portfinder.getPort((err, port) => {
+ if (err) {
+ reject(err)
+ } else {
+ // publish the new Port, necessary for e2e tests
+ process.env.PORT = port
+ // add port to devServer config
+ devWebpackConfig.devServer.port = port
+
+ // Add FriendlyErrorsPlugin
+ devWebpackConfig.plugins.push(
+ new FriendlyErrorsPlugin({
+ compilationSuccessInfo: {
+ messages: [
+ `Your application is running here: http://${
+ devWebpackConfig.devServer.host
+ }:${port}`
+ ]
+ },
+ onErrors: config.dev.notifyOnErrors
+ ? utils.createNotifierCallback()
+ : undefined
+ })
+ )
+
+ resolve(devWebpackConfig)
+ }
+ })
+})
diff --git a/report-ui/build/webpack.prod.conf.js b/report-ui/build/webpack.prod.conf.js
new file mode 100644
index 00000000..920a7f26
--- /dev/null
+++ b/report-ui/build/webpack.prod.conf.js
@@ -0,0 +1,182 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+
+function resolve(dir) {
+ return path.join(__dirname, '..', dir)
+}
+
+var env = require('../config/dev.env')
+if (process.env.NODE_ENV === 'testing') {
+ env = require('../config/test.env')
+}
+if (process.env.NODE_ENV === 'production') {
+ env = require('../config/prod.env')
+}
+
+// For NamedChunksPlugin
+const seen = new Set()
+const nameLength = 4
+
+const webpackConfig = merge(baseWebpackConfig, {
+ mode: 'production',
+ module: {
+ rules: utils.styleLoaders({
+ sourceMap: config.build.productionSourceMap,
+ extract: true,
+ usePostCSS: true
+ })
+ },
+ devtool: config.build.productionSourceMap ? config.build.devtool : false,
+ output: {
+ path: config.build.assetsRoot,
+ filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
+ chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
+ },
+ plugins: [
+ // http://vuejs.github.io/vue-loader/en/workflow/production.html
+ new webpack.DefinePlugin({
+ 'process.env': env
+ }),
+ // extract css into its own file
+ new MiniCssExtractPlugin({
+ filename: utils.assetsPath('css/[name].[contenthash:8].css'),
+ chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
+ }),
+ // generate dist index.html with correct asset hash for caching.
+ // you can customize output by editing /index.html
+ // see https://github.com/ampedandwired/html-webpack-plugin
+ new HtmlWebpackPlugin({
+ filename: config.build.index,
+ template: 'index.html',
+ inject: true,
+ favicon: resolve('favicon.ico'),
+ title: 'vue-admin-template',
+ minify: {
+ removeComments: true,
+ collapseWhitespace: true,
+ removeAttributeQuotes: true
+ // more options:
+ // https://github.com/kangax/html-minifier#options-quick-reference
+ }
+ // default sort mode uses toposort which cannot handle cyclic deps
+ // in certain cases, and in webpack 4, chunk order in HTML doesn't
+ // matter anyway
+ }),
+ new ScriptExtHtmlWebpackPlugin({
+ //`runtime` must same as runtimeChunk name. default is `runtime`
+ inline: /runtime\..*\.js$/
+ }),
+ // keep chunk.id stable when chunk has no name
+ new webpack.NamedChunksPlugin(chunk => {
+ if (chunk.name) {
+ return chunk.name
+ }
+ const modules = Array.from(chunk.modulesIterable)
+ if (modules.length > 1) {
+ const hash = require('hash-sum')
+ const joinedHash = hash(modules.map(m => m.id).join('_'))
+ let len = nameLength
+ while (seen.has(joinedHash.substr(0, len))) len++
+ seen.add(joinedHash.substr(0, len))
+ return `chunk-${joinedHash.substr(0, len)}`
+ } else {
+ return modules[0].id
+ }
+ }),
+ // keep module.id stable when vender modules does not change
+ new webpack.HashedModuleIdsPlugin(),
+ // copy custom static assets
+ new CopyWebpackPlugin([{
+ from: path.resolve(__dirname, '../static'),
+ to: config.build.assetsSubDirectory,
+ ignore: ['.*']
+ }])
+ ],
+ optimization: {
+ splitChunks: {
+ chunks: 'all',
+ cacheGroups: {
+ libs: {
+ name: 'chunk-libs',
+ test: /[\\/]node_modules[\\/]/,
+ priority: 10,
+ chunks: 'initial' // 只打包初始时依赖的第三方
+ },
+ elementUI: {
+ name: 'chunk-elementUI', // 单独将 elementUI 拆包
+ priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
+ test: /[\\/]node_modules[\\/]element-ui[\\/]/
+ }
+ }
+ },
+ runtimeChunk: 'single',
+ minimizer: [
+ new UglifyJsPlugin({
+ uglifyOptions: {
+ mangle: {
+ safari10: true
+ }
+ },
+ sourceMap: config.build.productionSourceMap,
+ cache: true,
+ parallel: true
+ }),
+ // Compress extracted CSS. We are using this plugin so that possible
+ // duplicated CSS from different components can be deduped.
+ new OptimizeCSSAssetsPlugin()
+ ]
+ }
+})
+
+if (config.build.productionGzip) {
+ const CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+ webpackConfig.plugins.push(
+ new CompressionWebpackPlugin({
+ asset: '[path].gz[query]',
+ algorithm: 'gzip',
+ test: new RegExp(
+ '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
+ ),
+ threshold: 10240,
+ minRatio: 0.8
+ })
+ )
+}
+
+if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) {
+ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
+ .BundleAnalyzerPlugin
+
+ if (config.build.bundleAnalyzerReport) {
+ webpackConfig.plugins.push(
+ new BundleAnalyzerPlugin({
+ analyzerPort: 8080,
+ generateStatsFile: false
+ })
+ )
+ }
+
+ if (config.build.generateAnalyzerReport) {
+ webpackConfig.plugins.push(
+ new BundleAnalyzerPlugin({
+ analyzerMode: 'static',
+ reportFilename: 'bundle-report.html',
+ openAnalyzer: false
+ })
+ )
+ }
+}
+
+module.exports = webpackConfig
diff --git a/report-ui/config/dev.env.js b/report-ui/config/dev.env.js
new file mode 100644
index 00000000..5c6289bb
--- /dev/null
+++ b/report-ui/config/dev.env.js
@@ -0,0 +1,9 @@
+'use strict'
+const merge = require('webpack-merge')
+const prodEnv = require('./prod.env')
+
+module.exports = merge(prodEnv, {
+ NODE_ENV: '"development"',
+ // BASE_API: '"http://10.108.26.163:8080"'
+ BASE_API: '"http://10.108.26.197"'
+})
diff --git a/report-ui/config/index.js b/report-ui/config/index.js
new file mode 100644
index 00000000..a42218c0
--- /dev/null
+++ b/report-ui/config/index.js
@@ -0,0 +1,86 @@
+'use strict'
+// Template version: 1.2.6
+// see http://vuejs-templates.github.io/webpack for documentation.
+
+const path = require('path')
+
+module.exports = {
+ dev: {
+ // Paths
+ assetsSubDirectory: 'static',
+ assetsPublicPath: '/',
+ proxyTable: {},
+
+ // Various Dev Server settings
+ host: 'localhost', // can be overwritten by process.env.HOST
+ port: 9528, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
+ autoOpenBrowser: true,
+ errorOverlay: true,
+ notifyOnErrors: false,
+ poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
+
+ // Use Eslint Loader?
+ // If true, your code will be linted during bundling and
+ // linting errors and warnings will be shown in the console.
+ useEslint: true,
+ // If true, eslint errors and warnings will also be shown in the error overlay
+ // in the browser.
+ showEslintErrorsInOverlay: false,
+
+ /**
+ * Source Maps
+ */
+
+ // https://webpack.js.org/configuration/devtool/#development
+ devtool: 'cheap-source-map',
+
+ // CSS Sourcemaps off by default because relative paths are "buggy"
+ // with this option, according to the CSS-Loader README
+ // (https://github.com/webpack/css-loader#sourcemaps)
+ // In our experience, they generally work as expected,
+ // just be aware of this issue when enabling this option.
+ cssSourceMap: false
+ },
+
+ build: {
+ // Template for index.html
+ index: path.resolve(__dirname, '../dist/index.html'),
+
+ // Paths
+ assetsRoot: path.resolve(__dirname, '../dist'),
+ assetsSubDirectory: 'static',
+
+ /**
+ * You can set by youself according to actual condition
+ * You will need to set this if you plan to deploy your site under a sub path,
+ * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
+ * then assetsPublicPath should be set to "/bar/".
+ * In most cases please use '/' !!!
+ */
+ assetsPublicPath: '/',
+
+ /**
+ * Source Maps
+ */
+
+ productionSourceMap: false,
+ // https://webpack.js.org/configuration/devtool/#production
+ devtool: 'source-map',
+
+ // Gzip off by default as many popular static hosts such as
+ // Surge or Netlify already gzip all static assets for you.
+ // Before setting to `true`, make sure to:
+ // npm install --save-dev compression-webpack-plugin
+ productionGzip: false,
+ productionGzipExtensions: ['js', 'css'],
+
+ // Run the build command with an extra argument to
+ // View the bundle analyzer report after build finishes:
+ // `npm run build --report`
+ // Set to `true` or `false` to always turn it on or off
+ bundleAnalyzerReport: process.env.npm_config_report || false,
+
+ // `npm run build:prod --generate_report`
+ generateAnalyzerReport: process.env.npm_config_generate_report || false
+ }
+}
diff --git a/report-ui/config/prod.env.js b/report-ui/config/prod.env.js
new file mode 100644
index 00000000..40dc4ad3
--- /dev/null
+++ b/report-ui/config/prod.env.js
@@ -0,0 +1,5 @@
+'use strict'
+module.exports = {
+ NODE_ENV: '"production"',
+ BASE_API: '"https://log.haitongauto.com"'
+}
diff --git a/report-ui/config/test.env.js b/report-ui/config/test.env.js
new file mode 100644
index 00000000..b7cf0c6b
--- /dev/null
+++ b/report-ui/config/test.env.js
@@ -0,0 +1,8 @@
+'use strict'
+const merge = require('webpack-merge')
+const prodEnv = require('./prod.env')
+
+module.exports = merge(prodEnv, {
+ NODE_ENV: '"testing"',
+ BASE_API: '"http://haitongnla.test.anji-plus.com"'
+})
diff --git a/report-ui/favicon.ico b/report-ui/favicon.ico
new file mode 100644
index 00000000..1f80c113
Binary files /dev/null and b/report-ui/favicon.ico differ
diff --git a/report-ui/index.html b/report-ui/index.html
new file mode 100644
index 00000000..db342f75
--- /dev/null
+++ b/report-ui/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ 海通物流
+
+
+
+
+
+
+
+
diff --git a/report-ui/package.json b/report-ui/package.json
new file mode 100644
index 00000000..3384eee1
--- /dev/null
+++ b/report-ui/package.json
@@ -0,0 +1,92 @@
+{
+ "name": "mirror-manager",
+ "version": "3.8.0",
+ "description": "mirror-manager",
+ "author": "mirror-team@anji-plus.com",
+ "scripts": {
+ "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+ "start": "npm run dev",
+ "build": "cross-env NODE_ENV=production node build/build.js",
+ "build:dev": "cross-env NODE_ENV=development node build/build.js",
+ "build:test": "cross-env NODE_ENV=testing node build/build.js",
+ "build:prod": "cross-env NODE_ENV=production node build/build.js"
+ },
+ "dependencies": {
+ "@ckeditor/ckeditor5-build-decoupled-document": "^23.1.0",
+ "axios": "0.18.0",
+ "chokidar": "^3.5.2",
+ "codemirror": "^5.58.1",
+ "crypto-js": "^3.1.9-1",
+ "echarts": "^4.9.0",
+ "echarts-gl": "^1.1.1",
+ "element-ui": "^2.9.2",
+ "js-cookie": "2.2.0",
+ "miment": "^0.0.9",
+ "moment": "^2.29.1",
+ "normalize.css": "7.0.0",
+ "nprogress": "0.2.0",
+ "sortablejs": "^1.10.2",
+ "uninstall": "0.0.0",
+ "vue": "2.6.11",
+ "vue-codemirror": "^4.0.6",
+ "vue-router": "3.0.1",
+ "vuedraggable": "^2.24.1",
+ "vuex": "3.0.1"
+ },
+ "devDependencies": {
+ "autoprefixer": "8.5.0",
+ "babel-core": "6.26.0",
+ "babel-helper-vue-jsx-merge-props": "2.0.3",
+ "babel-loader": "7.1.5",
+ "babel-plugin-syntax-jsx": "6.18.0",
+ "babel-plugin-transform-runtime": "6.23.0",
+ "babel-plugin-transform-vue-jsx": "3.7.0",
+ "babel-preset-env": "1.7.0",
+ "babel-preset-stage-2": "6.24.1",
+ "chalk": "2.4.1",
+ "copy-webpack-plugin": "4.5.2",
+ "cross-env": "^5.2.0",
+ "css-loader": "1.0.0",
+ "eventsource-polyfill": "0.9.6",
+ "file-loader": "1.1.11",
+ "friendly-errors-webpack-plugin": "1.7.0",
+ "html-webpack-plugin": "4.0.0-alpha",
+ "js-md5": "^0.7.3",
+ "mini-css-extract-plugin": "0.4.1",
+ "node-notifier": "5.2.1",
+ "node-sass": "^4.7.2",
+ "optimize-css-assets-webpack-plugin": "5.0.0",
+ "ora": "3.0.0",
+ "path-to-regexp": "2.4.0",
+ "portfinder": "1.0.16",
+ "postcss-import": "12.0.0",
+ "postcss-loader": "2.1.6",
+ "postcss-url": "7.3.2",
+ "rimraf": "2.6.2",
+ "sass-loader": "7.0.3",
+ "script-ext-html-webpack-plugin": "2.0.1",
+ "semver": "5.5.0",
+ "shelljs": "0.8.2",
+ "svg-sprite-loader": "3.8.0",
+ "svgo": "1.0.5",
+ "uglifyjs-webpack-plugin": "1.2.7",
+ "url-loader": "1.0.1",
+ "vue-loader": "15.3.0",
+ "vue-style-loader": "4.1.2",
+ "vue-template-compiler": "2.6.11",
+ "webpack": "4.16.5",
+ "webpack-bundle-analyzer": "2.13.1",
+ "webpack-cli": "3.1.0",
+ "webpack-dev-server": "3.1.5",
+ "webpack-merge": "4.1.4"
+ },
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not ie <= 8"
+ ]
+}
diff --git a/report-ui/src/App.vue b/report-ui/src/App.vue
new file mode 100644
index 00000000..34fcad4e
--- /dev/null
+++ b/report-ui/src/App.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/api/GaeaReport.js b/report-ui/src/api/GaeaReport.js
new file mode 100644
index 00000000..a90c5500
--- /dev/null
+++ b/report-ui/src/api/GaeaReport.js
@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 设计报表
+export function design(data) {
+ return request({
+ url: 'business/report/design',
+ method: 'post',
+ data,
+ })
+}
+
+// 预览报表,渲染数据
+export function preview(data) {
+ return request({
+ url: 'business/reportExcel/preview',
+ method: 'post',
+ data,
+ })
+}
+
+// 导出报表
+export function exportExcel(data) {
+ return request({
+ url: 'business/reportExcel/exportExcel',
+ method: 'post',
+ data,
+ })
+}
+
+// 导出报表
+export function exportPdf(data) {
+ return request({
+ url: 'business/reportExcel/exportPdf',
+ method: 'post',
+ data,
+ })
+}
+
+// 获取所有数据集
+export function queryAllDataSet() {
+ return request({
+ url: 'business/dataSet/queryAllDataSet',
+ method: 'get',
+ })
+}
+
+// 获取对应数据集的列集合
+export function detail(data) {
+ return request({
+ url: 'business/dataSet/detailBysetId/' + data,
+ method: 'get',
+ })
+}
+
+// 获取对应数据集的列集合
+export function detailBysetCode(data) {
+ return request({
+ url: 'business/dataSet/detailBysetCode/' + data,
+ method: 'get',
+ })
+}
+
+// 根据reportCode获取报表表格详情
+export function detailByReportCode(data) {
+ return request({
+ url: 'business/reportExcel/detailByReportCode/' + data,
+ method: 'get',
+ })
+}
diff --git a/report-ui/src/api/axios.js b/report-ui/src/api/axios.js
new file mode 100644
index 00000000..4911708b
--- /dev/null
+++ b/report-ui/src/api/axios.js
@@ -0,0 +1,84 @@
+import axios from 'axios';
+import { Message, MessageBox } from 'element-ui';
+import { setItem, getItem, delItem } from '@/utils/storage';
+import signUtil from '@/utils/signUtil';
+import { deepClone } from "@/utils"
+
+axios.defaults.baseURL = process.env.BASE_API
+const service = axios.create({
+ withCredentials: false,
+ timeout: 60000,
+ headers: {
+ 'Content-Type': 'application/json',
+ }
+})
+
+service.interceptors.request.use(
+ config => {
+ // 在发送请求之前做些什么
+ var token = getItem('token');
+ config.data = signUtil.sign(token, deepClone(config.data));
+ // console.log(config, 'config')
+ return config
+ },
+ error => {
+ // Do something with request error
+ console.log(error) // for debug
+ Promise.reject(error)
+ }
+)
+
+// response interceptor
+service.interceptors.response.use(
+ response => {
+ const res = response.data;
+ if (res.repCode == '0000') {
+ return res
+ }
+ else if (res.repCode == '0024') {
+
+ //登录超时或被登出,弹确认框,用户确认后,跳转到登录页面
+ MessageBox({
+ message: "当前登录已失效或异地登录,请重新登录",
+ type: 'error',
+ duration: 3 * 1000,
+ }).then(() => {
+ console.log(1)
+ sessionStorage.clear();
+ localStorage.clear();
+ delItem('token')
+ // location.reload();
+ window.location.href = "/";
+ }).catch(err => {
+ console.log(2)
+ })
+ } else if (res.repCode == "3100" || res.repCode == "3101") {
+ return res;
+ }
+ else {
+ Message({
+ message: res.repMsg,
+ type: 'error',
+ duration: 3 * 1000
+ })
+ return res;
+ }
+ },
+ error => {
+ var errorStatus = error.response.status;
+ var errorData = error.response.data;
+ var messageTxt = "";
+ if (errorStatus != 200) {
+ messageTxt = "服务器内部错误,请联系管理员";
+ } else {
+ messageTxt = '失败原因:' + errorData.repCode + '--' + errorData.repMsg;
+ }
+ Message({
+ message: messageTxt,
+ type: 'error',
+ duration: 5 * 1000
+ })
+ }
+)
+
+export default service
\ No newline at end of file
diff --git a/report-ui/src/api/bigscreen.js b/report-ui/src/api/bigscreen.js
new file mode 100644
index 00000000..95f3adad
--- /dev/null
+++ b/report-ui/src/api/bigscreen.js
@@ -0,0 +1,43 @@
+import request from '@/utils/request'
+
+// 保存大屏设计
+export function insertDashboard(data) {
+ return request({
+ url: 'business/reportDashboard',
+ method: 'post',
+ data,
+ })
+}
+
+// 预览、查询大屏详情
+export function detailDashboard(data) {
+ return request({
+ url: 'business/reportDashboard/' + data,
+ method: 'get',
+ })
+}
+
+// 数据集查询
+export function queryAllDataSet(data) {
+ return request({
+ url: 'business/dataSet/queryAllDataSet',
+ method: 'get',
+ })
+}
+
+// 获取数据集信息
+export function detailBysetId(data) {
+ return request({
+ url: 'business/dataSet/detailBysetId/' + data,
+ method: 'get',
+ })
+}
+
+// 获取动态数据
+export function getData(data) {
+ return request({
+ url: 'business/reportDashboard/getData',
+ method: 'post',
+ data,
+ })
+}
diff --git a/report-ui/src/api/calculation/calculation.js b/report-ui/src/api/calculation/calculation.js
new file mode 100644
index 00000000..39d88388
--- /dev/null
+++ b/report-ui/src/api/calculation/calculation.js
@@ -0,0 +1,64 @@
+import request from '@/api/axios'
+
+// 分页查询
+export const reqPageList = data => {
+ return request({
+ url: '/analysis-service/calculate/queryByPage',
+ method: 'post',
+ data
+ })
+}
+
+// 新增
+export const reqAddDeviceType = data => {
+ return request({
+ url: '/analysis-service/calculate/create',
+ method: 'post',
+ data
+ })
+}
+
+// 编辑
+export const reqEditDeviceType = data => {
+ return request({
+ url: '/analysis-service/calculate/updateById',
+ method: 'post',
+ data
+ })
+}
+
+// 删除
+export const reqDeleteDeviceType = data => {
+ return request({
+ url: '/analysis-service/calculate/deleteByIds',
+ method: 'post',
+ data
+ })
+}
+
+// 根据id查明细
+export const reqDetail = data => {
+ return request({
+ url: '/analysis-service/calculate/queryById',
+ method: 'post',
+ data
+ })
+}
+
+// 根据监控项id 拉取监控项树结构
+export const reqItemTree = data => {
+ return request({
+ url: '/analysis-service/item/tree',
+ method: 'post',
+ data
+ })
+}
+
+// 计算执行sql 语句
+export const reqExecuteSql = data => {
+ return request({
+ url: '/analysis-service/calculate/executeSql',
+ method: 'post',
+ data
+ })
+}
diff --git a/report-ui/src/api/common.js b/report-ui/src/api/common.js
new file mode 100644
index 00000000..1db32a1a
--- /dev/null
+++ b/report-ui/src/api/common.js
@@ -0,0 +1,25 @@
+/*
+ * @Author: zyk
+ * @Date: 2020-07-13 15:13:34
+ * @Last Modified by: zyk
+ * @Last Modified time: 2021-03-15 13:28:28
+ */
+
+import request from '@/utils/request'
+
+// 数据字典接口
+export function dataDictionary(dictName) {
+ return request({
+ url: `/business/gaeaDict/select/${dictName}`,
+ method: 'GET',
+ })
+}
+
+// 图片上传接口
+export function uploadImg(data) {
+ return request({
+ url: '/business/file/upload',
+ method: 'POST',
+ data,
+ })
+}
diff --git a/report-ui/src/api/deviceInfo.js b/report-ui/src/api/deviceInfo.js
new file mode 100644
index 00000000..707b1113
--- /dev/null
+++ b/report-ui/src/api/deviceInfo.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+/** i18n版本*/
+export function add (data) {
+ return request({
+ url: 'business/deviceInfo',
+ method: 'post',
+ data,
+ })
+}
+
+export function del (ids) {
+ return request({
+ url: 'business/deviceInfo/' + ids,
+ method: 'delete',
+ data: ids,
+ })
+}
+
+export function edit (data) {
+ return request({
+ url: 'business/deviceInfo',
+ method: 'put',
+ data,
+ })
+}
+
+export function preview (data) {
+ return request({
+ url: 'business/deviceInfo/' + data.id,
+ method: 'get',
+ params: data,
+ })
+}
+
+export default { add, edit, del, preview }
diff --git a/report-ui/src/api/dict-data.js b/report-ui/src/api/dict-data.js
new file mode 100644
index 00000000..28f06385
--- /dev/null
+++ b/report-ui/src/api/dict-data.js
@@ -0,0 +1,54 @@
+/*
+ * @Author: zyk
+ * @Date: 2020-07-13 15:13:17
+ * @Last Modified by: zyk
+ * @Last Modified time: 2020-12-15 15:34:34
+ */
+import request from '@/utils/request'
+// 数据字典和基础数据查询的相关接口
+
+/**
+ * 数据字典多类型编码查询接口
+ * type参数 类型 String
+ * type参数 格式 'type'
+ */
+export function getDictList(type) {
+ return request({
+ url: `/business/gaeaDict/select/${type}`,
+ method: 'get',
+ })
+}
+export function getDictCodes(project) {
+ return request({
+ url: `/business/gaeaDict/selectAll/${project}`,
+ method: 'get',
+ })
+}
+
+/**
+ * 数据字典多类型编码查询接口
+ * typeList参数 类型 Array
+ * typeList参数 格式 ['type1','type2',...]
+ */
+export function getMultipleDictList(typeList) {
+ const types = typeList + ''
+ return request({
+ url: `/v1/dict/types`,
+ method: 'get',
+ params: { types },
+ })
+}
+
+/**
+ * 主数据编码查询接口
+ * typeList参数 类型 Array
+ * typeList参数 格式 ['type1','type2',...]
+ */
+export function getBaseDataList(typeList) {
+ const types = typeList + ''
+ return request({
+ url: `/v1/master/types`,
+ method: 'get',
+ params: { types },
+ })
+}
diff --git a/report-ui/src/api/helpCenter/helpCenter.js b/report-ui/src/api/helpCenter/helpCenter.js
new file mode 100644
index 00000000..31c0f14a
--- /dev/null
+++ b/report-ui/src/api/helpCenter/helpCenter.js
@@ -0,0 +1,36 @@
+import request from '@/api/axios'
+
+// 查询字典
+export function queryForCodeSelect(params={}) {
+ return request({
+ url: '/auth-service/dict/queryForCodeSelect',
+ method: 'post',
+ data: params
+ })
+}
+
+// 查询标题
+export function querytitleByCategory(params) {
+ return request({
+ url: '/auth-service/help/querytitleByCategory',
+ method: 'post',
+ data: params
+ })
+}
+
+// 关键词查询
+export function searchKeyWord(params = {}) {
+ return request({
+ url: '/auth-service/help/searchKeyWord',
+ method: 'post',
+ data: params
+ })
+}
+
+export function queryById(data) {
+ return request({
+ url: '/auth-service/help/queryById',
+ method: 'post',
+ data
+ })
+}
diff --git a/report-ui/src/api/login.js b/report-ui/src/api/login.js
new file mode 100644
index 00000000..52c354ca
--- /dev/null
+++ b/report-ui/src/api/login.js
@@ -0,0 +1,31 @@
+import request from './axios'
+
+export function login (data) {
+ return request({
+ url: '/login',
+ method: 'post',
+ data
+ })
+}
+
+export function logout () {
+ return request({
+ url: '/accessUser/logout',
+ method: 'post'
+ })
+}
+
+// 登录之后 根据旧修改密码
+export const reqUpdatePassword = data => request({
+ url: '/auth-service/user/updatePassword',
+ method: 'post',
+ data: data
+})
+
+export function queryForCodeSelect (params = {}) {
+ return request({
+ url: '/auth-service/dict/queryForCodeSelect',
+ method: 'post',
+ data: params
+ })
+}
\ No newline at end of file
diff --git a/report-ui/src/api/report.js b/report-ui/src/api/report.js
new file mode 100644
index 00000000..f96700e8
--- /dev/null
+++ b/report-ui/src/api/report.js
@@ -0,0 +1,170 @@
+/*
+ * @Author: zyk
+ * @Date: 2020-07-13 15:13:37
+ * @Last Modified by: zyk
+ * @Last Modified time: 2021-03-04 10:46:26
+ */
+import request from '@/utils/request'
+import { add, del, edit, preview } from '@/api/deviceInfo'
+// datasource
+export function pageList(params) {
+ return request({
+ url: '/business/dataSource/pageList',
+ method: 'get',
+ params,
+ })
+}
+export function dataSource(data) {
+ return request({
+ url: '/business/dataSource/' + data.id,
+ method: 'get',
+ data,
+ })
+}
+// delete datasource
+export function deleteDataSource(data) {
+ return request({
+ url: '/business/dataSource/' + data.id,
+ method: 'delete',
+ data,
+ })
+}
+export function testConnection(data) {
+ return request({
+ url: '/business/dataSource/testConnection',
+ method: 'post',
+ data,
+ })
+}
+export function addDataSource(data) {
+ return request({
+ url: '/business/dataSource',
+ method: 'post',
+ data,
+ })
+}
+export function editDataSource(data) {
+ return request({
+ url: '/business/dataSource',
+ method: 'put',
+ data,
+ })
+}
+// resultset
+export function dataSetPreview(data) {
+ return request({
+ url: `/business/dataSet/detailBysetId/${data.id}`,
+ method: 'get',
+ })
+}
+
+export function addDataSet(data) {
+ return request({
+ url: '/business/dataSet',
+ method: 'post',
+ data,
+ })
+}
+export function editDataSet(data) {
+ return request({
+ url: '/business/dataSet',
+ method: 'put',
+ data,
+ })
+}
+// delete dataset
+export function deleteDataSet(data) {
+ return request({
+ url: '/business/dataSet/' + data.id,
+ method: 'delete',
+ data,
+ })
+}
+// 下拉数据源
+export function queryAllDataSourceSet(data) {
+ return request({
+ url: '/business/dataSource/queryAllDataSource',
+ method: 'get',
+ data,
+ })
+}
+// 数据集高级规则js验证
+export function verificationSet(data) {
+ return request({
+ url: '/business/dataSetParam/verification',
+ method: 'post',
+ data,
+ })
+}
+// 测试数据转换,以及返回数据table列表
+export function testTransformSet(data) {
+ return request({
+ url: '/business/dataSet/testTransform',
+ method: 'post',
+ data,
+ })
+}
+
+// report
+export function reportPageList(params) {
+ return request({
+ url: '/business/report/pageList',
+ method: 'get',
+ params,
+ })
+}
+// report
+export function addReport(data) {
+ return request({
+ url: '/business/report',
+ method: 'post',
+ data,
+ })
+}
+
+// report
+export function editReport(data) {
+ return request({
+ url: '/business/report',
+ method: 'put',
+ data,
+ })
+}
+
+// report
+export function delReport(data) {
+ return request({
+ url: '/business/report/delReport',
+ method: 'delete',
+ data,
+ })
+}
+
+// report
+export function detailReport(id, accessKey) {
+ return request({
+ url: `/business/report/${id}?accessKey=${accessKey}`,
+ method: 'get',
+ })
+}
+
+// reportExcel
+export function addReportExcel(data) {
+ return request({
+ url: '/business/reportExcel',
+ method: 'post',
+ data,
+ })
+}
+
+// reportExcel
+export function editReportExcel(data) {
+ return request({
+ url: '/business/reportExcel',
+ method: 'put',
+ data,
+ })
+}
+
+
+export default { add, edit, del, preview }
diff --git a/report-ui/src/api/upload.js b/report-ui/src/api/upload.js
new file mode 100644
index 00000000..192e7e2f
--- /dev/null
+++ b/report-ui/src/api/upload.js
@@ -0,0 +1,71 @@
+import axios from 'axios';
+import { Message, MessageBox } from 'element-ui';
+import { setItem, getItem, delItem } from '@/utils/storage';
+
+axios.defaults.baseURL = process.env.BASE_API
+// axios.defaults.baseURL = 'http://10.108.12.23:8080' // 德明本地
+// axios.defaults.baseURL = "http://haitongnla.test.anji-plus.com"
+// axios.defaults.baseURL = "http://10.108.26.163:8080"
+
+const service = axios.create({
+ withCredentials: true,
+ timeout: 60000,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+})
+
+// response interceptor
+service.interceptors.response.use(
+ response => {
+ const res = response.data;
+ if (res.repCode == '0000') {
+ return res
+ }
+ else if (res.repCode == '0024') {
+
+ //登录超时或被登出,弹确认框,用户确认后,跳转到登录页面
+ MessageBox({
+ message: "当前登录已失效或异地登录,请重新登录",
+ type: 'error',
+ duration: 3 * 1000,
+ }).then(() => {
+ console.log(1)
+ sessionStorage.clear();
+ localStorage.clear();
+ delItem('token')
+ // location.reload();
+ window.location.href = "/";
+ }).catch(err => {
+ console.log(2)
+ })
+ }else if(res.repCode == "3100" || res.repCode == "3101"){
+ return res;
+ }
+ else {
+ Message({
+ message: res.repMsg,
+ type: 'error',
+ duration: 3 * 1000
+ })
+ return res;
+ }
+ },
+ error => {
+ var errorStatus = error.response.status;
+ var errorData = error.response.data;
+ var messageTxt = "";
+ if (errorStatus != 200) {
+ messageTxt = "服务器内部错误,请联系管理员";
+ } else {
+ messageTxt = '失败原因:' + errorData.repCode + '--' + errorData.repMsg;
+ }
+ Message({
+ message: messageTxt,
+ type: 'error',
+ duration: 5 * 1000
+ })
+ }
+)
+
+export default service
\ No newline at end of file
diff --git a/report-ui/src/assets/iconfont/demo.css b/report-ui/src/assets/iconfont/demo.css
new file mode 100644
index 00000000..a67054a0
--- /dev/null
+++ b/report-ui/src/assets/iconfont/demo.css
@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+ font-family: "iconfont logo";
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+ font-family: "iconfont logo";
+ font-size: 160px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+ position: relative;
+}
+
+.nav-tabs .nav-more {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ height: 42px;
+ line-height: 42px;
+ color: #666;
+}
+
+#tabs {
+ border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+ cursor: pointer;
+ width: 100px;
+ height: 40px;
+ line-height: 40px;
+ text-align: center;
+ font-size: 16px;
+ border-bottom: 2px solid transparent;
+ position: relative;
+ z-index: 1;
+ margin-bottom: -1px;
+ color: #666;
+}
+
+
+#tabs .active {
+ border-bottom-color: #f00;
+ color: #222;
+}
+
+.tab-container .content {
+ display: none;
+}
+
+/* 页面布局 */
+.main {
+ padding: 30px 100px;
+ width: 960px;
+ margin: 0 auto;
+}
+
+.main .logo {
+ color: #333;
+ text-align: left;
+ margin-bottom: 30px;
+ line-height: 1;
+ height: 110px;
+ margin-top: -50px;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.main .logo a {
+ font-size: 160px;
+ color: #333;
+}
+
+.helps {
+ margin-top: 40px;
+}
+
+.helps pre {
+ padding: 20px;
+ margin: 10px 0;
+ border: solid 1px #e7e1cd;
+ background-color: #fffdef;
+ overflow: auto;
+}
+
+.icon_lists {
+ width: 100% !important;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.icon_lists li {
+ width: 100px;
+ margin-bottom: 10px;
+ margin-right: 20px;
+ text-align: center;
+ list-style: none !important;
+ cursor: default;
+}
+
+.icon_lists li .code-name {
+ line-height: 1.2;
+}
+
+.icon_lists .icon {
+ display: block;
+ height: 100px;
+ line-height: 100px;
+ font-size: 42px;
+ margin: 10px auto;
+ color: #333;
+ -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+ -moz-transition: font-size 0.25s linear, width 0.25s linear;
+ transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+ font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+ /* 通过设置 font-size 来改变图标大小 */
+ width: 1em;
+ /* 图标和文字相邻时,垂直对齐 */
+ vertical-align: -0.15em;
+ /* 通过设置 color 来改变 SVG 的颜色/fill */
+ fill: currentColor;
+ /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+ normalize.css 中也包含这行 */
+ overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+ color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+ color: #666;
+ font-size: 14px;
+ line-height: 1.8;
+}
+
+.highlight {
+ line-height: 1.5;
+}
+
+.markdown img {
+ vertical-align: middle;
+ max-width: 100%;
+}
+
+.markdown h1 {
+ color: #404040;
+ font-weight: 500;
+ line-height: 40px;
+ margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+ color: #404040;
+ margin: 1.6em 0 0.6em 0;
+ font-weight: 500;
+ clear: both;
+}
+
+.markdown h1 {
+ font-size: 28px;
+}
+
+.markdown h2 {
+ font-size: 22px;
+}
+
+.markdown h3 {
+ font-size: 16px;
+}
+
+.markdown h4 {
+ font-size: 14px;
+}
+
+.markdown h5 {
+ font-size: 12px;
+}
+
+.markdown h6 {
+ font-size: 12px;
+}
+
+.markdown hr {
+ height: 1px;
+ border: 0;
+ background: #e9e9e9;
+ margin: 16px 0;
+ clear: both;
+}
+
+.markdown p {
+ margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+ width: 80%;
+}
+
+.markdown ul>li {
+ list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+ margin: 0.6em 0;
+}
+
+.markdown ol>li {
+ list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown code {
+ margin: 0 3px;
+ padding: 0 5px;
+ background: #eee;
+ border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+ font-weight: 600;
+}
+
+.markdown>table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ empty-cells: show;
+ border: 1px solid #e9e9e9;
+ width: 95%;
+ margin-bottom: 24px;
+}
+
+.markdown>table th {
+ white-space: nowrap;
+ color: #333;
+ font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+ border: 1px solid #e9e9e9;
+ padding: 8px 16px;
+ text-align: left;
+}
+
+.markdown>table th {
+ background: #F7F7F7;
+}
+
+.markdown blockquote {
+ font-size: 90%;
+ color: #999;
+ border-left: 4px solid #e9e9e9;
+ padding-left: 0.8em;
+ margin: 1em 0;
+}
+
+.markdown blockquote p {
+ margin: 0;
+}
+
+.markdown .anchor {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ margin-left: 8px;
+}
+
+.markdown .waiting {
+ color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+ opacity: 1;
+ display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+ clear: both;
+}
+
+
+.hljs {
+ display: block;
+ background: white;
+ padding: 0.5em;
+ color: #333333;
+ overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+ color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+ color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+ color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+ color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+ color: #63a35c;
+}
+
+.hljs-tag {
+ color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+ color: #795da3;
+}
+
+.hljs-addition {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.hljs-deletion {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.hljs-link {
+ text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ background: none;
+ text-shadow: 0 1px white;
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+@media print {
+
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+ white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #9a6e3a;
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+
+.token.function,
+.token.class-name {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/report-ui/src/assets/iconfont/demo_index.html b/report-ui/src/assets/iconfont/demo_index.html
new file mode 100644
index 00000000..7d323ed1
--- /dev/null
+++ b/report-ui/src/assets/iconfont/demo_index.html
@@ -0,0 +1,1918 @@
+
+
+
+
+ IconFont Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Unicode
+ Font class
+ Symbol
+
+
+
查看项目
+
+
+
+
+
+
+
Unicode 引用
+
+
+
Unicode 是字体在网页端最原始的应用方式,特点是:
+
+ 兼容性最好,支持 IE6+,及所有现代浏览器。
+ 支持按字体的方式去动态调整图标大小,颜色等等。
+ 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
+
+
+ 注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式
+
+
Unicode 使用步骤如下:
+
第一步:拷贝项目下面生成的 @font-face
+
@font-face {
+ font-family: 'iconfont';
+ src: url('iconfont.eot');
+ src: url('iconfont.eot?#iefix') format('embedded-opentype'),
+ url('iconfont.woff2') format('woff2'),
+ url('iconfont.woff') format('woff'),
+ url('iconfont.ttf') format('truetype'),
+ url('iconfont.svg#iconfont') format('svg');
+}
+
+
第二步:定义使用 iconfont 的样式
+
.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+
第三步:挑选相应图标并获取字体编码,应用于页面
+
+<span class="iconfont">3</span>
+
+
+ "iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
+
+
+
+
+
+
+
+
+
+ 返回
+
+ .icon1
+
+
+
+
+
+
+ 下载
+
+ .iconxiazai
+
+
+
+
+
+
+ 下载
+
+ .icon11-04
+
+
+
+
+
+
+ 邮箱
+
+ .iconyouxiang
+
+
+
+
+
+
+ 绑定手机
+
+ .iconbangdingshouji
+
+
+
+
+
+
+ 手机
+
+ .iconshouji
+
+
+
+
+
+
+ 52-手机
+
+ .icon52-shouji
+
+
+
+
+
+
+ home
+
+ .iconhome
+
+
+
+
+
+
+ home
+
+ .iconhome2
+
+
+
+
+
+
+ Kafka
+
+ .iconKafka
+
+
+
+
+
+
+ 数据接入—Kafka集群
+
+ .iconshujujieruKafkajiqun
+
+
+
+
+
+
+ kafka
+
+ .iconkafka
+
+
+
+
+
+
+ elasticsearch-Elasticsearch
+
+ .iconelasticsearch-Elasticsearch
+
+
+
+
+
+
+ apachekafka
+
+ .iconapachekafka
+
+
+
+
+
+
+ elasticsearch
+
+ .iconelasticsearch
+
+
+
+
+
+
+ 问题反馈
+
+ .iconwentifankui
+
+
+
+
+
+
+ 问题反馈
+
+ .iconwentifankui1
+
+
+
+
+
+
+ 问题反馈
+
+ .iconwentifankui2
+
+
+
+
+
+
+ alikafka 消息队列Kafka
+
+ .iconalikafkaxiaoxiduilieKafka
+
+
+
+
+
+
+ 项目查询-查看设备
+
+ .iconxiangmuchaxun-chakanshebei
+
+
+
+
+
+
+ elasticsearch Elasticsearch
+
+ .iconelasticsearchElasticsearch
+
+
+
+
+
+
+ 511统计_树图
+
+ .icon511tongji_shutu
+
+
+
+
+
+
+ 分享
+
+ .iconfenxiang1
+
+
+
+
+
+
+ 分享
+
+ .iconfenxiang2
+
+
+
+
+
+
+ 分享
+
+ .iconfenxiang_2
+
+
+
+
+
+
+ 告警-紧急
+
+ .iconNMStubiao-
+
+
+
+
+
+
+ 完成安全事件
+
+ .iconwanchenganquanshijian
+
+
+
+
+
+
+ eventbridge 消息事件总线
+
+ .iconeventbridgexiaoxishijianzongxian
+
+
+
+
+
+
+ 树
+
+ .iconshu
+
+
+
+
+
+
+ 设备关机
+
+ .iconshebeiguanji
+
+
+
+
+
+
+ 好房拓 4.0.0 iconfont_短信
+
+ .iconhaofangtuo400iconfontduanxin
+
+
+
+
+
+
+ 业务参数
+
+ .iconnavicon-ywcs
+
+
+
+
+
+
+ 列表
+
+ .iconliebiao
+
+
+
+
+
+
+ 编辑
+
+ .iconbianji
+
+
+
+
+
+
+ 邮件
+
+ .iconyoujian
+
+
+
+
+
+
+ 社交钉钉
+
+ .iconshejiaodingding
+
+
+
+
+
+
+ 字典管理
+
+ .iconzidianguanli
+
+
+
+
+
+
+ 图表
+
+ .icontubiao
+
+
+
+
+
+
+ 钉钉
+
+ .icondingding
+
+
+
+
+
+
+ 短信
+
+ .iconduanxin
+
+
+
+
+
+
+ directmail 邮件推送
+
+ .icondirectmailyoujiantuisong
+
+
+
+
+
+
+ 设备设施
+
+ .iconshebeisheshi
+
+
+
+
+
+
+ 通知
+
+ .icontongzhi
+
+
+
+
+
+
+ 日志
+
+ .iconrizhi
+
+
+
+
+
+
+ 触发器配置-灰
+
+ .iconchufaqipeizhi-hui
+
+
+
+
+
+
+ vcs 视觉计算服务
+
+ .iconvcsshijuejisuanfuwu
+
+
+
+
+
+
+ 设备
+
+ .iconbar_icon_shebei
+
+
+
+
+
+
+ user-before
+
+ .iconuser-before
+
+
+
+
+
+
+ 科目维护图标
+
+ .iconkemuweihutubiao
+
+
+
+
+
+
+ 会计科目维护
+
+ .iconaccounting-subjects
+
+
+
+
+
+
+ 成本查询
+
+ .iconRectangleCopy
+
+
+
+
+
+
+ 成本数据管理
+
+ .iconchengbenshujuguanli
+
+
+
+
+
+
+ 基本数据
+
+ .iconjibenshuju
+
+
+
+
+
+
+ B-省市区
+
+ .iconB-shengshiqu
+
+
+
+
+
+
+ 组织机构
+
+ .iconzuzhijigou
+
+
+
+
+
+
+ 按钮
+
+ .iconanniu
+
+
+
+
+
+
+ 菜单
+
+ .iconcaidan2
+
+
+
+
+
+
+ 问号
+
+ .iconwenhao
+
+
+
+
+
+
+ 垃圾桶
+
+ .iconlajitong
+
+
+
+
+
+
+ 重置密码
+
+ .iconzhongzhimima
+
+
+
+
+
+
+ 设置
+
+ .iconshezhi
+
+
+
+
+
+
+ 中转
+
+ .iconzhongzhuan
+
+
+
+
+
+
+ add
+
+ .iconadd
+
+
+
+
+
+
+ minus
+
+ .iconminus
+
+
+
+
+
+
+ password
+
+ .iconpassword
+
+
+
+
+
+
+ 用户
+
+ .iconyonghu
+
+
+
+
+
+
+ 权限
+
+ .iconquanxian
+
+
+
+
+
+
+ 角色
+
+ .iconjiaose1
+
+
+
+
+
+
+ 字典
+
+ .iconzidian
+
+
+
+
+
+
+ 参数设置
+
+ .iconcssz
+
+
+
+
+
+
+ 编辑
+
+ .iconbianji1
+
+
+
+
+
+
+ 用户权限
+
+ .icondfzq-
+
+
+
+
+
+
+ 分享
+
+ .iconfenxiang
+
+
+
+
+
+
+ 授权
+
+ .iconshouquan1
+
+
+
+
+
+
+ 左箭头
+
+ .iconjiantou
+
+
+
+
+
+
+ 左箭头
+
+ .iconjiantou-copy-copy
+
+
+
+
+
+
font-class 引用
+
+
+
font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。
+
与 Unicode 使用方式相比,具有如下特点:
+
+ 兼容性良好,支持 IE8+,及所有现代浏览器。
+ 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
+ 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
+ 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
+
+
使用步骤如下:
+
第一步:引入项目下面生成的 fontclass 代码:
+
<link rel="stylesheet" href="./iconfont.css">
+
+
第二步:挑选相应图标并获取类名,应用于页面:
+
<span class="iconfont iconxxx"></span>
+
+
+ "
+ iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
+
+
+
+
+
+
+
+
+
+
+ 返回
+ #icon1
+
+
+
+
+
+
+ 下载
+ #iconxiazai
+
+
+
+
+
+
+ 下载
+ #icon11-04
+
+
+
+
+
+
+ 邮箱
+ #iconyouxiang
+
+
+
+
+
+
+ 绑定手机
+ #iconbangdingshouji
+
+
+
+
+
+
+ 手机
+ #iconshouji
+
+
+
+
+
+
+ 52-手机
+ #icon52-shouji
+
+
+
+
+
+
+ home
+ #iconhome
+
+
+
+
+
+
+ home
+ #iconhome2
+
+
+
+
+
+
+ Kafka
+ #iconKafka
+
+
+
+
+
+
+ 数据接入—Kafka集群
+ #iconshujujieruKafkajiqun
+
+
+
+
+
+
+ kafka
+ #iconkafka
+
+
+
+
+
+
+ elasticsearch-Elasticsearch
+ #iconelasticsearch-Elasticsearch
+
+
+
+
+
+
+ apachekafka
+ #iconapachekafka
+
+
+
+
+
+
+ elasticsearch
+ #iconelasticsearch
+
+
+
+
+
+
+ 问题反馈
+ #iconwentifankui
+
+
+
+
+
+
+ 问题反馈
+ #iconwentifankui1
+
+
+
+
+
+
+ 问题反馈
+ #iconwentifankui2
+
+
+
+
+
+
+ alikafka 消息队列Kafka
+ #iconalikafkaxiaoxiduilieKafka
+
+
+
+
+
+
+ 项目查询-查看设备
+ #iconxiangmuchaxun-chakanshebei
+
+
+
+
+
+
+ elasticsearch Elasticsearch
+ #iconelasticsearchElasticsearch
+
+
+
+
+
+
+ 511统计_树图
+ #icon511tongji_shutu
+
+
+
+
+
+
+ 分享
+ #iconfenxiang1
+
+
+
+
+
+
+ 分享
+ #iconfenxiang2
+
+
+
+
+
+
+ 分享
+ #iconfenxiang_2
+
+
+
+
+
+
+ 告警-紧急
+ #iconNMStubiao-
+
+
+
+
+
+
+ 完成安全事件
+ #iconwanchenganquanshijian
+
+
+
+
+
+
+ eventbridge 消息事件总线
+ #iconeventbridgexiaoxishijianzongxian
+
+
+
+
+
+
+ 树
+ #iconshu
+
+
+
+
+
+
+ 设备关机
+ #iconshebeiguanji
+
+
+
+
+
+
+ 好房拓 4.0.0 iconfont_短信
+ #iconhaofangtuo400iconfontduanxin
+
+
+
+
+
+
+ 业务参数
+ #iconnavicon-ywcs
+
+
+
+
+
+
+ 列表
+ #iconliebiao
+
+
+
+
+
+
+ 编辑
+ #iconbianji
+
+
+
+
+
+
+ 邮件
+ #iconyoujian
+
+
+
+
+
+
+ 社交钉钉
+ #iconshejiaodingding
+
+
+
+
+
+
+ 字典管理
+ #iconzidianguanli
+
+
+
+
+
+
+ 图表
+ #icontubiao
+
+
+
+
+
+
+ 钉钉
+ #icondingding
+
+
+
+
+
+
+ 短信
+ #iconduanxin
+
+
+
+
+
+
+ directmail 邮件推送
+ #icondirectmailyoujiantuisong
+
+
+
+
+
+
+ 设备设施
+ #iconshebeisheshi
+
+
+
+
+
+
+ 通知
+ #icontongzhi
+
+
+
+
+
+
+ 日志
+ #iconrizhi
+
+
+
+
+
+
+ 触发器配置-灰
+ #iconchufaqipeizhi-hui
+
+
+
+
+
+
+ vcs 视觉计算服务
+ #iconvcsshijuejisuanfuwu
+
+
+
+
+
+
+ 设备
+ #iconbar_icon_shebei
+
+
+
+
+
+
+ user-before
+ #iconuser-before
+
+
+
+
+
+
+ 科目维护图标
+ #iconkemuweihutubiao
+
+
+
+
+
+
+ 会计科目维护
+ #iconaccounting-subjects
+
+
+
+
+
+
+ 成本查询
+ #iconRectangleCopy
+
+
+
+
+
+
+ 成本数据管理
+ #iconchengbenshujuguanli
+
+
+
+
+
+
+ 基本数据
+ #iconjibenshuju
+
+
+
+
+
+
+ B-省市区
+ #iconB-shengshiqu
+
+
+
+
+
+
+ 组织机构
+ #iconzuzhijigou
+
+
+
+
+
+
+ 按钮
+ #iconanniu
+
+
+
+
+
+
+ 菜单
+ #iconcaidan2
+
+
+
+
+
+
+ 问号
+ #iconwenhao
+
+
+
+
+
+
+ 垃圾桶
+ #iconlajitong
+
+
+
+
+
+
+ 重置密码
+ #iconzhongzhimima
+
+
+
+
+
+
+ 设置
+ #iconshezhi
+
+
+
+
+
+
+ 中转
+ #iconzhongzhuan
+
+
+
+
+
+
+ add
+ #iconadd
+
+
+
+
+
+
+ minus
+ #iconminus
+
+
+
+
+
+
+ password
+ #iconpassword
+
+
+
+
+
+
+ 用户
+ #iconyonghu
+
+
+
+
+
+
+ 权限
+ #iconquanxian
+
+
+
+
+
+
+ 角色
+ #iconjiaose1
+
+
+
+
+
+
+ 字典
+ #iconzidian
+
+
+
+
+
+
+ 参数设置
+ #iconcssz
+
+
+
+
+
+
+ 编辑
+ #iconbianji1
+
+
+
+
+
+
+ 用户权限
+ #icondfzq-
+
+
+
+
+
+
+ 分享
+ #iconfenxiang
+
+
+
+
+
+
+ 授权
+ #iconshouquan1
+
+
+
+
+
+
+ 左箭头
+ #iconjiantou
+
+
+
+
+
+
+ 左箭头
+ #iconjiantou-copy-copy
+
+
+
+
+
Symbol 引用
+
+
+
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
+ 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:
+
+ 支持多色图标了,不再受单色限制。
+ 通过一些技巧,支持像字体那样,通过 font-size
, color
来调整样式。
+ 兼容性较差,支持 IE9+,及现代浏览器。
+ 浏览器渲染 SVG 的性能一般,还不如 png。
+
+
使用步骤如下:
+
第一步:引入项目下面生成的 symbol 代码:
+
<script src="./iconfont.js"></script>
+
+
第二步:加入通用 CSS 代码(引入一次就行):
+
<style>
+.icon {
+ width: 1em;
+ height: 1em;
+ vertical-align: -0.15em;
+ fill: currentColor;
+ overflow: hidden;
+}
+</style>
+
+
第三步:挑选相应图标并获取类名,应用于页面:
+
<svg class="icon" aria-hidden="true">
+ <use xlink:href="#icon-xxx"></use>
+</svg>
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/assets/iconfont/iconfont.css b/report-ui/src/assets/iconfont/iconfont.css
new file mode 100644
index 00000000..49b9902a
--- /dev/null
+++ b/report-ui/src/assets/iconfont/iconfont.css
@@ -0,0 +1,321 @@
+@font-face {font-family: "iconfont";
+ src: url('iconfont.eot?t=1607672860281'); /* IE9 */
+ src: url('iconfont.eot?t=1607672860281#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
+ url('iconfont.woff?t=1607672860281') format('woff'),
+ url('iconfont.ttf?t=1607672860281') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
+ url('iconfont.svg?t=1607672860281#iconfont') format('svg'); /* iOS 4.1- */
+}
+
+.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon1:before {
+ content: "\e63b";
+}
+
+.iconxiazai:before {
+ content: "\e639";
+}
+
+.icon11-04:before {
+ content: "\e784";
+}
+
+.iconyouxiang:before {
+ content: "\e769";
+}
+
+.iconbangdingshouji:before {
+ content: "\e64d";
+}
+
+.iconshouji:before {
+ content: "\e854";
+}
+
+.icon52-shouji:before {
+ content: "\e871";
+}
+
+.iconhome:before {
+ content: "\e610";
+}
+
+.iconhome2:before {
+ content: "\e61a";
+}
+
+.iconKafka:before {
+ content: "\e65a";
+}
+
+.iconshujujieruKafkajiqun:before {
+ content: "\e64f";
+}
+
+.iconkafka:before {
+ content: "\e6f2";
+}
+
+.iconelasticsearch-Elasticsearch:before {
+ content: "\e853";
+}
+
+.iconapachekafka:before {
+ content: "\eb3f";
+}
+
+.iconelasticsearch:before {
+ content: "\eb85";
+}
+
+.iconwentifankui:before {
+ content: "\e8d1";
+}
+
+.iconwentifankui1:before {
+ content: "\e70e";
+}
+
+.iconwentifankui2:before {
+ content: "\e643";
+}
+
+.iconalikafkaxiaoxiduilieKafka:before {
+ content: "\e8a4";
+}
+
+.iconxiangmuchaxun-chakanshebei:before {
+ content: "\e682";
+}
+
+.iconelasticsearchElasticsearch:before {
+ content: "\e6a1";
+}
+
+.icon511tongji_shutu:before {
+ content: "\e64a";
+}
+
+.iconfenxiang1:before {
+ content: "\e615";
+}
+
+.iconfenxiang2:before {
+ content: "\e60f";
+}
+
+.iconfenxiang_2:before {
+ content: "\e600";
+}
+
+.iconNMStubiao-:before {
+ content: "\e628";
+}
+
+.iconwanchenganquanshijian:before {
+ content: "\e68a";
+}
+
+.iconeventbridgexiaoxishijianzongxian:before {
+ content: "\e74d";
+}
+
+.iconshu:before {
+ content: "\e629";
+}
+
+.iconshebeiguanji:before {
+ content: "\e61d";
+}
+
+.iconhaofangtuo400iconfontduanxin:before {
+ content: "\e6d8";
+}
+
+.iconnavicon-ywcs:before {
+ content: "\e661";
+}
+
+.iconliebiao:before {
+ content: "\e660";
+}
+
+.iconbianji:before {
+ content: "\e60c";
+}
+
+.iconyoujian:before {
+ content: "\e63a";
+}
+
+.iconshejiaodingding:before {
+ content: "\e678";
+}
+
+.iconzidianguanli:before {
+ content: "\e624";
+}
+
+.icontubiao:before {
+ content: "\e73f";
+}
+
+.icondingding:before {
+ content: "\e690";
+}
+
+.iconduanxin:before {
+ content: "\e603";
+}
+
+.icondirectmailyoujiantuisong:before {
+ content: "\e714";
+}
+
+.iconshebeisheshi:before {
+ content: "\e61c";
+}
+
+.icontongzhi:before {
+ content: "\e606";
+}
+
+.iconrizhi:before {
+ content: "\e663";
+}
+
+.iconchufaqipeizhi-hui:before {
+ content: "\e689";
+}
+
+.iconvcsshijuejisuanfuwu:before {
+ content: "\e759";
+}
+
+.iconbar_icon_shebei:before {
+ content: "\e60a";
+}
+
+.iconuser-before:before {
+ content: "\e617";
+}
+
+.iconkemuweihutubiao:before {
+ content: "\e60b";
+}
+
+.iconaccounting-subjects:before {
+ content: "\e677";
+}
+
+.iconRectangleCopy:before {
+ content: "\e6dd";
+}
+
+.iconchengbenshujuguanli:before {
+ content: "\e6c7";
+}
+
+.iconjibenshuju:before {
+ content: "\e71d";
+}
+
+.iconB-shengshiqu:before {
+ content: "\e72d";
+}
+
+.iconzuzhijigou:before {
+ content: "\e66e";
+}
+
+.iconanniu:before {
+ content: "\e8c5";
+}
+
+.iconcaidan2:before {
+ content: "\e61b";
+}
+
+.iconwenhao:before {
+ content: "\e67f";
+}
+
+.iconlajitong:before {
+ content: "\e636";
+}
+
+.iconzhongzhimima:before {
+ content: "\e620";
+}
+
+.iconshezhi:before {
+ content: "\e68f";
+}
+
+.iconzhongzhuan:before {
+ content: "\e69b";
+}
+
+.iconadd:before {
+ content: "\e6b9";
+}
+
+.iconminus:before {
+ content: "\e6ba";
+}
+
+.iconpassword:before {
+ content: "\e622";
+}
+
+.iconyonghu:before {
+ content: "\e604";
+}
+
+.iconquanxian:before {
+ content: "\e633";
+}
+
+.iconjiaose1:before {
+ content: "\e64c";
+}
+
+.iconzidian:before {
+ content: "\e716";
+}
+
+.iconcssz:before {
+ content: "\e672";
+}
+
+.iconbianji1:before {
+ content: "\e642";
+}
+
+.icondfzq-:before {
+ content: "\e609";
+}
+
+.iconfenxiang:before {
+ content: "\e641";
+}
+
+.iconshouquan1:before {
+ content: "\e634";
+}
+
+.iconjiantou:before {
+ content: "\e653";
+}
+
+.iconjiantou-copy-copy:before {
+ content: "\e654";
+}
+
diff --git a/report-ui/src/assets/iconfont/iconfont.eot b/report-ui/src/assets/iconfont/iconfont.eot
new file mode 100644
index 00000000..b062714b
Binary files /dev/null and b/report-ui/src/assets/iconfont/iconfont.eot differ
diff --git a/report-ui/src/assets/iconfont/iconfont.js b/report-ui/src/assets/iconfont/iconfont.js
new file mode 100644
index 00000000..4bb7a672
--- /dev/null
+++ b/report-ui/src/assets/iconfont/iconfont.js
@@ -0,0 +1 @@
+!function(c){var l,h,a,i,z,o,m=' ',t=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(t&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function s(){z||(z=!0,a())}l=function(){var c,l,h,a;(a=document.createElement("div")).innerHTML=m,m=null,(h=a.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",c=h,(l=document.body).firstChild?(a=c,(h=l.firstChild).parentNode.insertBefore(a,h)):l.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(h=function(){document.removeEventListener("DOMContentLoaded",h,!1),l()},document.addEventListener("DOMContentLoaded",h,!1)):document.attachEvent&&(a=l,i=c.document,z=!1,(o=function(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(o,50)}s()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,s())})}(window);
\ No newline at end of file
diff --git a/report-ui/src/assets/iconfont/iconfont.json b/report-ui/src/assets/iconfont/iconfont.json
new file mode 100644
index 00000000..a2651d7f
--- /dev/null
+++ b/report-ui/src/assets/iconfont/iconfont.json
@@ -0,0 +1,541 @@
+{
+ "id": "1513211",
+ "name": "基础权限",
+ "font_family": "iconfont",
+ "css_prefix_text": "icon",
+ "description": "",
+ "glyphs": [
+ {
+ "icon_id": "18774317",
+ "name": "返回",
+ "font_class": "1",
+ "unicode": "e63b",
+ "unicode_decimal": 58939
+ },
+ {
+ "icon_id": "5388367",
+ "name": "下载",
+ "font_class": "xiazai",
+ "unicode": "e639",
+ "unicode_decimal": 58937
+ },
+ {
+ "icon_id": "14245657",
+ "name": "下载",
+ "font_class": "11-04",
+ "unicode": "e784",
+ "unicode_decimal": 59268
+ },
+ {
+ "icon_id": "4933441",
+ "name": "邮箱",
+ "font_class": "youxiang",
+ "unicode": "e769",
+ "unicode_decimal": 59241
+ },
+ {
+ "icon_id": "7140630",
+ "name": "绑定手机",
+ "font_class": "bangdingshouji",
+ "unicode": "e64d",
+ "unicode_decimal": 58957
+ },
+ {
+ "icon_id": "8288872",
+ "name": "手机",
+ "font_class": "shouji",
+ "unicode": "e854",
+ "unicode_decimal": 59476
+ },
+ {
+ "icon_id": "16218102",
+ "name": "52-手机",
+ "font_class": "52-shouji",
+ "unicode": "e871",
+ "unicode_decimal": 59505
+ },
+ {
+ "icon_id": "684484",
+ "name": "home",
+ "font_class": "home",
+ "unicode": "e610",
+ "unicode_decimal": 58896
+ },
+ {
+ "icon_id": "7165766",
+ "name": "home",
+ "font_class": "home2",
+ "unicode": "e61a",
+ "unicode_decimal": 58906
+ },
+ {
+ "icon_id": "981325",
+ "name": "Kafka",
+ "font_class": "Kafka",
+ "unicode": "e65a",
+ "unicode_decimal": 58970
+ },
+ {
+ "icon_id": "4772840",
+ "name": "数据接入—Kafka集群",
+ "font_class": "shujujieruKafkajiqun",
+ "unicode": "e64f",
+ "unicode_decimal": 58959
+ },
+ {
+ "icon_id": "8691927",
+ "name": "kafka",
+ "font_class": "kafka",
+ "unicode": "e6f2",
+ "unicode_decimal": 59122
+ },
+ {
+ "icon_id": "13140799",
+ "name": "elasticsearch-Elasticsearch",
+ "font_class": "elasticsearch-Elasticsearch",
+ "unicode": "e853",
+ "unicode_decimal": 59475
+ },
+ {
+ "icon_id": "15378137",
+ "name": "apachekafka",
+ "font_class": "apachekafka",
+ "unicode": "eb3f",
+ "unicode_decimal": 60223
+ },
+ {
+ "icon_id": "15378319",
+ "name": "elasticsearch",
+ "font_class": "elasticsearch",
+ "unicode": "eb85",
+ "unicode_decimal": 60293
+ },
+ {
+ "icon_id": "3253279",
+ "name": "问题反馈",
+ "font_class": "wentifankui",
+ "unicode": "e8d1",
+ "unicode_decimal": 59601
+ },
+ {
+ "icon_id": "3922909",
+ "name": "问题反馈",
+ "font_class": "wentifankui1",
+ "unicode": "e70e",
+ "unicode_decimal": 59150
+ },
+ {
+ "icon_id": "13177275",
+ "name": "问题反馈",
+ "font_class": "wentifankui2",
+ "unicode": "e643",
+ "unicode_decimal": 58947
+ },
+ {
+ "icon_id": "5583350",
+ "name": "alikafka 消息队列Kafka",
+ "font_class": "alikafkaxiaoxiduilieKafka",
+ "unicode": "e8a4",
+ "unicode_decimal": 59556
+ },
+ {
+ "icon_id": "11033199",
+ "name": "项目查询-查看设备",
+ "font_class": "xiangmuchaxun-chakanshebei",
+ "unicode": "e682",
+ "unicode_decimal": 59010
+ },
+ {
+ "icon_id": "13543355",
+ "name": "elasticsearch Elasticsearch",
+ "font_class": "elasticsearchElasticsearch",
+ "unicode": "e6a1",
+ "unicode_decimal": 59041
+ },
+ {
+ "icon_id": "1308482",
+ "name": "511统计_树图",
+ "font_class": "511tongji_shutu",
+ "unicode": "e64a",
+ "unicode_decimal": 58954
+ },
+ {
+ "icon_id": "8084555",
+ "name": "分享",
+ "font_class": "fenxiang1",
+ "unicode": "e615",
+ "unicode_decimal": 58901
+ },
+ {
+ "icon_id": "9148583",
+ "name": "分享",
+ "font_class": "fenxiang2",
+ "unicode": "e60f",
+ "unicode_decimal": 58895
+ },
+ {
+ "icon_id": "9810108",
+ "name": "分享",
+ "font_class": "fenxiang_2",
+ "unicode": "e600",
+ "unicode_decimal": 58880
+ },
+ {
+ "icon_id": "10064575",
+ "name": "告警-紧急",
+ "font_class": "NMStubiao-",
+ "unicode": "e628",
+ "unicode_decimal": 58920
+ },
+ {
+ "icon_id": "13186637",
+ "name": "完成安全事件",
+ "font_class": "wanchenganquanshijian",
+ "unicode": "e68a",
+ "unicode_decimal": 59018
+ },
+ {
+ "icon_id": "14772380",
+ "name": "eventbridge 消息事件总线",
+ "font_class": "eventbridgexiaoxishijianzongxian",
+ "unicode": "e74d",
+ "unicode_decimal": 59213
+ },
+ {
+ "icon_id": "16852593",
+ "name": "树",
+ "font_class": "shu",
+ "unicode": "e629",
+ "unicode_decimal": 58921
+ },
+ {
+ "icon_id": "16800949",
+ "name": "设备关机",
+ "font_class": "shebeiguanji",
+ "unicode": "e61d",
+ "unicode_decimal": 58909
+ },
+ {
+ "icon_id": "1111782",
+ "name": "好房拓 4.0.0 iconfont_短信",
+ "font_class": "haofangtuo400iconfontduanxin",
+ "unicode": "e6d8",
+ "unicode_decimal": 59096
+ },
+ {
+ "icon_id": "3703026",
+ "name": "业务参数",
+ "font_class": "navicon-ywcs",
+ "unicode": "e661",
+ "unicode_decimal": 58977
+ },
+ {
+ "icon_id": "3851361",
+ "name": "列表",
+ "font_class": "liebiao",
+ "unicode": "e660",
+ "unicode_decimal": 58976
+ },
+ {
+ "icon_id": "3858850",
+ "name": "编辑",
+ "font_class": "bianji",
+ "unicode": "e60c",
+ "unicode_decimal": 58892
+ },
+ {
+ "icon_id": "5203312",
+ "name": "邮件",
+ "font_class": "youjian",
+ "unicode": "e63a",
+ "unicode_decimal": 58938
+ },
+ {
+ "icon_id": "5321887",
+ "name": "社交钉钉",
+ "font_class": "shejiaodingding",
+ "unicode": "e678",
+ "unicode_decimal": 59000
+ },
+ {
+ "icon_id": "6627754",
+ "name": "字典管理",
+ "font_class": "zidianguanli",
+ "unicode": "e624",
+ "unicode_decimal": 58916
+ },
+ {
+ "icon_id": "7092362",
+ "name": "图表",
+ "font_class": "tubiao",
+ "unicode": "e73f",
+ "unicode_decimal": 59199
+ },
+ {
+ "icon_id": "9307592",
+ "name": "钉钉",
+ "font_class": "dingding",
+ "unicode": "e690",
+ "unicode_decimal": 59024
+ },
+ {
+ "icon_id": "10392609",
+ "name": "短信",
+ "font_class": "duanxin",
+ "unicode": "e603",
+ "unicode_decimal": 58883
+ },
+ {
+ "icon_id": "13592918",
+ "name": "directmail 邮件推送",
+ "font_class": "directmailyoujiantuisong",
+ "unicode": "e714",
+ "unicode_decimal": 59156
+ },
+ {
+ "icon_id": "16589013",
+ "name": "设备设施",
+ "font_class": "shebeisheshi",
+ "unicode": "e61c",
+ "unicode_decimal": 58908
+ },
+ {
+ "icon_id": "6249282",
+ "name": "通知",
+ "font_class": "tongzhi",
+ "unicode": "e606",
+ "unicode_decimal": 58886
+ },
+ {
+ "icon_id": "7450630",
+ "name": "日志",
+ "font_class": "rizhi",
+ "unicode": "e663",
+ "unicode_decimal": 58979
+ },
+ {
+ "icon_id": "11103449",
+ "name": "触发器配置-灰",
+ "font_class": "chufaqipeizhi-hui",
+ "unicode": "e689",
+ "unicode_decimal": 59017
+ },
+ {
+ "icon_id": "17566612",
+ "name": "vcs 视觉计算服务",
+ "font_class": "vcsshijuejisuanfuwu",
+ "unicode": "e759",
+ "unicode_decimal": 59225
+ },
+ {
+ "icon_id": "17755673",
+ "name": "设备",
+ "font_class": "bar_icon_shebei",
+ "unicode": "e60a",
+ "unicode_decimal": 58890
+ },
+ {
+ "icon_id": "1327507",
+ "name": "user-before",
+ "font_class": "user-before",
+ "unicode": "e617",
+ "unicode_decimal": 58903
+ },
+ {
+ "icon_id": "12353050",
+ "name": "科目维护图标",
+ "font_class": "kemuweihutubiao",
+ "unicode": "e60b",
+ "unicode_decimal": 58891
+ },
+ {
+ "icon_id": "2152435",
+ "name": "会计科目维护",
+ "font_class": "accounting-subjects",
+ "unicode": "e677",
+ "unicode_decimal": 58999
+ },
+ {
+ "icon_id": "7553622",
+ "name": "成本查询",
+ "font_class": "RectangleCopy",
+ "unicode": "e6dd",
+ "unicode_decimal": 59101
+ },
+ {
+ "icon_id": "12453907",
+ "name": "成本数据管理",
+ "font_class": "chengbenshujuguanli",
+ "unicode": "e6c7",
+ "unicode_decimal": 59079
+ },
+ {
+ "icon_id": "13745309",
+ "name": "基本数据",
+ "font_class": "jibenshuju",
+ "unicode": "e71d",
+ "unicode_decimal": 59165
+ },
+ {
+ "icon_id": "7193675",
+ "name": "B-省市区",
+ "font_class": "B-shengshiqu",
+ "unicode": "e72d",
+ "unicode_decimal": 59181
+ },
+ {
+ "icon_id": "16065650",
+ "name": "组织机构",
+ "font_class": "zuzhijigou",
+ "unicode": "e66e",
+ "unicode_decimal": 58990
+ },
+ {
+ "icon_id": "10885920",
+ "name": "按钮",
+ "font_class": "anniu",
+ "unicode": "e8c5",
+ "unicode_decimal": 59589
+ },
+ {
+ "icon_id": "7588087",
+ "name": "菜单",
+ "font_class": "caidan2",
+ "unicode": "e61b",
+ "unicode_decimal": 58907
+ },
+ {
+ "icon_id": "343234",
+ "name": "问号",
+ "font_class": "wenhao",
+ "unicode": "e67f",
+ "unicode_decimal": 59007
+ },
+ {
+ "icon_id": "485800",
+ "name": "垃圾桶",
+ "font_class": "lajitong",
+ "unicode": "e636",
+ "unicode_decimal": 58934
+ },
+ {
+ "icon_id": "524416",
+ "name": "重置密码",
+ "font_class": "zhongzhimima",
+ "unicode": "e620",
+ "unicode_decimal": 58912
+ },
+ {
+ "icon_id": "666885",
+ "name": "设置",
+ "font_class": "shezhi",
+ "unicode": "e68f",
+ "unicode_decimal": 59023
+ },
+ {
+ "icon_id": "666902",
+ "name": "中转",
+ "font_class": "zhongzhuan",
+ "unicode": "e69b",
+ "unicode_decimal": 59035
+ },
+ {
+ "icon_id": "1226780",
+ "name": "add",
+ "font_class": "add",
+ "unicode": "e6b9",
+ "unicode_decimal": 59065
+ },
+ {
+ "icon_id": "1226781",
+ "name": "minus",
+ "font_class": "minus",
+ "unicode": "e6ba",
+ "unicode_decimal": 59066
+ },
+ {
+ "icon_id": "1388130",
+ "name": "password",
+ "font_class": "password",
+ "unicode": "e622",
+ "unicode_decimal": 58914
+ },
+ {
+ "icon_id": "1824319",
+ "name": "用户",
+ "font_class": "yonghu",
+ "unicode": "e604",
+ "unicode_decimal": 58884
+ },
+ {
+ "icon_id": "2881221",
+ "name": "权限",
+ "font_class": "quanxian",
+ "unicode": "e633",
+ "unicode_decimal": 58931
+ },
+ {
+ "icon_id": "3280236",
+ "name": "角色",
+ "font_class": "jiaose1",
+ "unicode": "e64c",
+ "unicode_decimal": 58956
+ },
+ {
+ "icon_id": "3299246",
+ "name": "字典",
+ "font_class": "zidian",
+ "unicode": "e716",
+ "unicode_decimal": 59158
+ },
+ {
+ "icon_id": "4374688",
+ "name": "参数设置",
+ "font_class": "cssz",
+ "unicode": "e672",
+ "unicode_decimal": 58994
+ },
+ {
+ "icon_id": "4880425",
+ "name": "编辑",
+ "font_class": "bianji1",
+ "unicode": "e642",
+ "unicode_decimal": 58946
+ },
+ {
+ "icon_id": "5472800",
+ "name": "用户权限",
+ "font_class": "dfzq-",
+ "unicode": "e609",
+ "unicode_decimal": 58889
+ },
+ {
+ "icon_id": "6693043",
+ "name": "分享",
+ "font_class": "fenxiang",
+ "unicode": "e641",
+ "unicode_decimal": 58945
+ },
+ {
+ "icon_id": "10213484",
+ "name": "授权",
+ "font_class": "shouquan1",
+ "unicode": "e634",
+ "unicode_decimal": 58932
+ },
+ {
+ "icon_id": "13416544",
+ "name": "左箭头",
+ "font_class": "jiantou",
+ "unicode": "e653",
+ "unicode_decimal": 58963
+ },
+ {
+ "icon_id": "13416596",
+ "name": "左箭头",
+ "font_class": "jiantou-copy-copy",
+ "unicode": "e654",
+ "unicode_decimal": 58964
+ }
+ ]
+}
diff --git a/report-ui/src/assets/iconfont/iconfont.svg b/report-ui/src/assets/iconfont/iconfont.svg
new file mode 100644
index 00000000..38fcb918
--- /dev/null
+++ b/report-ui/src/assets/iconfont/iconfont.svg
@@ -0,0 +1,254 @@
+
+
+
+
+
+Created by iconfont
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/assets/iconfont/iconfont.ttf b/report-ui/src/assets/iconfont/iconfont.ttf
new file mode 100644
index 00000000..3bcde297
Binary files /dev/null and b/report-ui/src/assets/iconfont/iconfont.ttf differ
diff --git a/report-ui/src/assets/iconfont/iconfont.woff b/report-ui/src/assets/iconfont/iconfont.woff
new file mode 100644
index 00000000..eaf7ed0d
Binary files /dev/null and b/report-ui/src/assets/iconfont/iconfont.woff differ
diff --git a/report-ui/src/assets/iconfont/iconfont.woff2 b/report-ui/src/assets/iconfont/iconfont.woff2
new file mode 100644
index 00000000..b690d7aa
Binary files /dev/null and b/report-ui/src/assets/iconfont/iconfont.woff2 differ
diff --git a/report-ui/src/assets/images/404/404.png b/report-ui/src/assets/images/404/404.png
new file mode 100644
index 00000000..3d8e2305
Binary files /dev/null and b/report-ui/src/assets/images/404/404.png differ
diff --git a/report-ui/src/assets/images/404/404_cloud.png b/report-ui/src/assets/images/404/404_cloud.png
new file mode 100644
index 00000000..c6281d09
Binary files /dev/null and b/report-ui/src/assets/images/404/404_cloud.png differ
diff --git a/report-ui/src/assets/images/banner1.png b/report-ui/src/assets/images/banner1.png
new file mode 100644
index 00000000..c7d421b5
Binary files /dev/null and b/report-ui/src/assets/images/banner1.png differ
diff --git a/report-ui/src/assets/images/charts.jpg b/report-ui/src/assets/images/charts.jpg
new file mode 100644
index 00000000..8d7ea0b5
Binary files /dev/null and b/report-ui/src/assets/images/charts.jpg differ
diff --git a/report-ui/src/assets/images/close.png b/report-ui/src/assets/images/close.png
new file mode 100644
index 00000000..9d295754
Binary files /dev/null and b/report-ui/src/assets/images/close.png differ
diff --git a/report-ui/src/assets/images/editor.png b/report-ui/src/assets/images/editor.png
new file mode 100644
index 00000000..53f68d32
Binary files /dev/null and b/report-ui/src/assets/images/editor.png differ
diff --git a/report-ui/src/assets/images/home-logo.png b/report-ui/src/assets/images/home-logo.png
new file mode 100644
index 00000000..f23da128
Binary files /dev/null and b/report-ui/src/assets/images/home-logo.png differ
diff --git a/report-ui/src/assets/images/login.png b/report-ui/src/assets/images/login.png
new file mode 100644
index 00000000..840e2ab1
Binary files /dev/null and b/report-ui/src/assets/images/login.png differ
diff --git a/report-ui/src/assets/images/rightIcon.png b/report-ui/src/assets/images/rightIcon.png
new file mode 100644
index 00000000..adf99b29
Binary files /dev/null and b/report-ui/src/assets/images/rightIcon.png differ
diff --git a/report-ui/src/assets/images/user/appro.png b/report-ui/src/assets/images/user/appro.png
new file mode 100644
index 00000000..fffea0b9
Binary files /dev/null and b/report-ui/src/assets/images/user/appro.png differ
diff --git a/report-ui/src/assets/images/user/appro2.png b/report-ui/src/assets/images/user/appro2.png
new file mode 100644
index 00000000..39ac3711
Binary files /dev/null and b/report-ui/src/assets/images/user/appro2.png differ
diff --git a/report-ui/src/assets/images/user/avatar.gif b/report-ui/src/assets/images/user/avatar.gif
new file mode 100644
index 00000000..fdbd32c6
Binary files /dev/null and b/report-ui/src/assets/images/user/avatar.gif differ
diff --git a/report-ui/src/assets/styles/common.css b/report-ui/src/assets/styles/common.css
new file mode 100644
index 00000000..d9a249b1
--- /dev/null
+++ b/report-ui/src/assets/styles/common.css
@@ -0,0 +1,76 @@
+/* 滚动条 */
+ ::-webkit-scrollbar {
+ /*垂直滚动条的宽*/
+ width: 10px;
+ /*垂直滚动条的高*/
+ height: 10px;
+ }
+
+ ::-webkit-scrollbar-track-piece {
+ /*修改滚动条的背景和圆角*/
+ background: #F7F7F7;
+ -webkit-border-radius: 7px;
+ }
+
+ /*修改垂直滚动条的样式*/
+ ::-webkit-scrollbar-thumb:vertical {
+ background-color: #dcdfe6;
+ -webkit-border-radius: 7px;
+ }
+
+ /*修改水平滚动条的样式*/
+ ::-webkit-scrollbar-thumb:horizontal {
+ background-color: #dcdfe6;
+ -webkit-border-radius: 7px;
+ }
+
+ /* IE7 */
+ input:focus, a:focus, button:focus, textarea:focus {
+ outline: none
+ }
+ input:-webkit-autofill {
+ /* -webkit-box-shadow: 0 0 0px 1000px black inset !important; */
+ /* background-color: #ffffff !important;*/
+ /* background-image: none !important;
+ color: white !important; */
+ box-shadow: 0 0 0px 1000px rgb(229, 233, 238) inset !important;
+ -webkit-box-shadow: 0 0 0px 1000px rgba(0, 0, 0,1) inset !important;
+ border: 0px solid #CCC!important;
+ -webkit-text-fill-color: #FFF;
+
+ }
+ /* input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
+ background-color: #040406 !important;
+ background-image: none !important;
+ color: white !important;
+ } */
+ ::-ms-clear {
+ display: none;
+ }
+
+ ::-ms-reveal {
+ display: none;
+ }
+
+ .on-focus:focus {
+ border: 1px solid #5BC0DE;
+ }
+ .clearfix::after{
+ content: '';
+ display: block;
+ clear: both;
+ height: 0;
+ width:100%;
+ }
+ .mt10{
+ margin-top: 10px;
+ }
+ .fr{
+ float: right;
+ }
+ .fl{
+ float: left;
+}
+.el-table td{
+ padding: 8px 0;
+}
\ No newline at end of file
diff --git a/report-ui/src/assets/styles/element-ui.scss b/report-ui/src/assets/styles/element-ui.scss
new file mode 100644
index 00000000..3d1aa712
--- /dev/null
+++ b/report-ui/src/assets/styles/element-ui.scss
@@ -0,0 +1,95 @@
+ //to reset element-ui default css
+.el-upload {
+ input[type="file"] {
+ display: none !important;
+ }
+}
+
+.el-upload__input {
+ display: none;
+}
+
+
+// 解决table 因为body部分滚动条 header 错位问题:
+.el-table--border th.gutter:last-of-type {
+ display: block !important;
+ width: 17px !important;
+}
+
+//暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461
+.el-dialog {
+ transform: none;
+ left: 0;
+ position: relative;
+ margin: 0 auto;
+
+ .el-dialog__header{
+ background-color: rgb(48, 77, 167);
+ color: #fff;
+ .el-dialog__title{
+ color: #fff;
+ }
+ .el-dialog__headerbtn i {
+ color: #fff;
+ }
+ }
+}
+
+.el-tooltip__popper{
+ max-width: 80%;
+}
+
+//element ui upload
+.upload-container {
+ .el-upload {
+ width: 100%;
+ .el-upload-dragger {
+ width: 100%;
+ height: 200px;
+ }
+ }
+}
+//element ui 带选择列的input
+.el-input-group {
+ display: inline-table !important;
+}
+.input-with-select{
+ .el-input-group__prepend{
+ .el-select{
+ width: 105px;
+ }
+ }
+}
+//element in-line form 一行两个带图村输入框
+.el-form--inline{
+ .el-form-item{
+ width: 45%;
+ margin-right: 25px;
+ .el-form-item__label {
+ font-size: 12px;
+ line-height: 17px;
+ padding: 0 0 5px;
+ }
+ .el-form-item__content{
+ .el-input{
+ .el-input__inner{
+ // padding-left: 40px;
+ }
+ .el-input__prefix{
+ left: 0px;
+ background-color: #f5f7fa;
+ color: #909399;
+ vertical-align: middle;
+ display: table-cell;
+ border: 1px solid #dcdfe6;
+ border-radius: 4px;
+ width: 40px;
+ height: 98%;
+ white-space: nowrap;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/report-ui/src/assets/styles/index.scss b/report-ui/src/assets/styles/index.scss
new file mode 100644
index 00000000..98a6bdb9
--- /dev/null
+++ b/report-ui/src/assets/styles/index.scss
@@ -0,0 +1,192 @@
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+
+body {
+ height: 100%;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+ font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+}
+
+label {
+ font-weight: 700;
+}
+
+html {
+ height: 100%;
+ box-sizing: border-box;
+}
+
+#app{
+ height: 100%;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+a,
+a:focus,
+a:hover {
+ cursor: pointer;
+ color: inherit;
+ outline: none;
+ text-decoration: none;
+}
+
+div:focus{
+ outline: none;
+ }
+
+a:focus,
+a:active {
+ outline: none;
+}
+
+a,
+a:focus,
+a:hover {
+ cursor: pointer;
+ color: inherit;
+ text-decoration: none;
+}
+
+.clearfix {
+ &:after {
+ visibility: hidden;
+ display: block;
+ font-size: 0;
+ content: " ";
+ clear: both;
+ height: 0;
+ }
+}
+
+//main-container全局样式
+.app-main{
+ min-height: 100%
+}
+
+.app-container {
+ padding: 20px;
+}
+
+.filter-container {
+ padding-bottom: 10px;
+ .filter-item {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 10px;
+ }
+}
+.float-r{
+ float: right;
+}
+.float-l{
+ float: left;
+}
+/*日志折叠面板定制*/
+.log .el-collapse{
+ border-top:0;
+ border-bottom:0;
+}
+.log .el-collapse-item__header {
+ height: 40px;
+ line-height: 40px;
+ cursor: pointer;
+ border: 1px solid #fff;
+ background:rgba(145,163,177,.15);
+ font-size: 14px;
+ color: #666;
+ -webkit-transition: border-bottom-color .3s;
+ transition: border-bottom-color .3s;
+ outline: 0;
+ padding: 0 20px;
+}
+.log .el-collapse-item__wrap {
+ will-change: height;
+ overflow: hidden;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ border-bottom: 1px solid #fff;
+ background: #263C7C;
+
+}
+.log .el-collapse-item__content{
+ font-size: 14px;
+ color: #FFFFFF;
+ padding: 20px;
+}
+.log .el-collapse-item__arrow{
+ margin-top: 14px;
+ float: right;
+ margin-right: -77px;
+}
+.log .icon-btn_style, .log .icon-btn_style:hover {
+ background: none;
+ border: 0;
+ padding: 0;
+}
+//大屏展示的一些样式
+.my-dialog{
+ .el-dialog{
+ background: #062B69;
+ border:1px solid #5DDAF6
+ }
+ .el-dialog__header{
+ border-bottom:1px solid #5DDAF6;
+ text-align: center;
+ }
+ .el-dialog__title{
+ color: #5CDCF9;
+ }
+ .el-input__inner{
+ background:#091E43;
+ border-color: #254E97;
+ }
+ .el-date-editor .el-range__icon{
+ color: #5CDCF9;
+ }
+ input {
+ background:#091E43;
+ }
+ .el-date-editor .el-range-input{
+ color: #5CDCF9;
+ }
+ .form-handle{
+ .el-form-item__label{
+ color: #5CDCF9;
+ font-weight: 500;
+ }
+ }
+ .el-form-item{
+ margin-bottom: 10px;
+ }
+ .el-textarea__inner,.el-select:hover .el-input__inner{
+ background-color: #091E43;
+ border-color: #254E97;
+ border-bottom:1px solid #254E97;
+ }
+ .el-button--blue{
+ color: #FFF;
+ background-color: #224788;
+ border-color: #224788;
+ }
+ .el-button--green{
+ color: #FFF;
+ background-color: #2092AD;
+ border-color: #2092AD;
+ }
+}
+.el-input--prefix .el-input__inner{
+ padding-left: 45px;
+}
+.el-input-group__append, .el-input-group__prepend{
+ color: #333;
+}
\ No newline at end of file
diff --git a/report-ui/src/assets/styles/mixin.scss b/report-ui/src/assets/styles/mixin.scss
new file mode 100644
index 00000000..601d7a03
--- /dev/null
+++ b/report-ui/src/assets/styles/mixin.scss
@@ -0,0 +1,27 @@
+@mixin clearfix {
+ &:after {
+ content: "";
+ display: table;
+ clear: both;
+ }
+}
+
+@mixin scrollBar {
+ &::-webkit-scrollbar-track-piece {
+ background: #d3dce6;
+ }
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+ &::-webkit-scrollbar-thumb {
+ background: #99a9bf;
+ border-radius: 20px;
+ }
+}
+
+@mixin relative {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
diff --git a/report-ui/src/assets/styles/sidebar.scss b/report-ui/src/assets/styles/sidebar.scss
new file mode 100644
index 00000000..e7837561
--- /dev/null
+++ b/report-ui/src/assets/styles/sidebar.scss
@@ -0,0 +1,136 @@
+#app {
+ // 主体区域
+ .main-container {
+ min-height: 100%;
+ transition: margin-left .28s;
+ margin-left: 180px;
+ position: relative;
+ }
+ // 侧边栏
+ .sidebar-container {
+ transition: width 0.28s;
+ width: 180px !important;
+ height: 100%;
+ position: fixed;
+ font-size: 0px;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1001;
+ overflow: hidden;
+ box-shadow: 1px 1px 4px #e6e6e6;
+ //reset element-ui css
+ .horizontal-collapse-transition {
+ transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+ }
+ .el-scrollbar__bar.is-vertical{
+ right: 0px;
+ }
+ .scrollbar-wrapper {
+ overflow-x: hidden!important;
+
+ .el-scrollbar__view {
+ height:calc(100vh - 70px);
+ }
+ }
+ .is-horizontal {
+ display: none;
+ }
+ a {
+ display: inline-block;
+ width: 100%;
+ overflow: hidden;
+ }
+ .svg-icon {
+ margin-right: 16px;
+ }
+ .el-menu {
+ border: none;
+ height: 100%;
+ width: 100% !important;
+ }
+ .is-active > .el-submenu__title{
+ color: #333!important;
+ }
+ }
+ .hideSidebar {
+ .sidebar-container {
+ width: 36px !important;
+ }
+ .main-container {
+ margin-left: 36px;
+ }
+ .submenu-title-noDropdown {
+ padding-left: 10px !important;
+ position: relative;
+ .el-tooltip {
+ padding: 0 10px !important;
+ }
+ }
+ .el-submenu {
+ overflow: hidden;
+ &>.el-submenu__title {
+ padding-left: 10px !important;
+ .el-submenu__icon-arrow {
+ display: none;
+ }
+ }
+ }
+ .el-menu--collapse {
+ .el-submenu {
+ &>.el-submenu__title {
+ &>span {
+ height: 0;
+ width: 0;
+ overflow: hidden;
+ visibility: hidden;
+ display: inline-block;
+ }
+ }
+ }
+ }
+ }
+ .sidebar-container .nest-menu .el-submenu>.el-submenu__title,
+ .sidebar-container .el-submenu .el-menu-item {
+ min-width: 180px !important;
+ background-color: #fff !important;
+ &:hover {
+ color: #406be0 !important;
+ font-weight: bold;
+ }
+ }
+ .el-menu--collapse .el-menu .el-submenu {
+ min-width: 180px !important;
+ }
+
+ //适配移动端
+ .mobile {
+ .main-container {
+ margin-left: 0px;
+ }
+ .sidebar-container {
+ transition: transform .28s;
+ width: 180px !important;
+ }
+ &.hideSidebar {
+ .sidebar-container {
+ transition-duration: 0.3s;
+ transform: translate3d(-180px, 0, 0);
+ }
+ }
+ }
+ .withoutAnimation {
+ .main-container,
+ .sidebar-container {
+ transition: none;
+ }
+ }
+}
+
+.el-menu--vertical{
+ & >.el-menu{
+ .svg-icon{
+ margin-right: 16px;
+ }
+ }
+}
diff --git a/report-ui/src/assets/styles/transition.scss b/report-ui/src/assets/styles/transition.scss
new file mode 100644
index 00000000..8dd9b04a
--- /dev/null
+++ b/report-ui/src/assets/styles/transition.scss
@@ -0,0 +1,46 @@
+//globl transition css
+
+/*fade*/
+.fade-enter-active,
+.fade-leave-active {
+ transition: opacity 0.28s;
+}
+
+.fade-enter,
+.fade-leave-active {
+ opacity: 0;
+}
+
+/*fade-transform*/
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+ transition: all .5s;
+}
+.fade-transform-enter {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+.fade-transform-leave-to {
+ opacity: 0;
+ transform: translateX(30px);
+}
+
+/*fade*/
+.breadcrumb-enter-active,
+.breadcrumb-leave-active {
+ transition: all .5s;
+}
+
+.breadcrumb-enter,
+.breadcrumb-leave-active {
+ opacity: 0;
+ transform: translateX(20px);
+}
+
+.breadcrumb-move {
+ transition: all .5s;
+}
+
+.breadcrumb-leave-active {
+ position: absolute;
+}
diff --git a/report-ui/src/assets/styles/variables.scss b/report-ui/src/assets/styles/variables.scss
new file mode 100644
index 00000000..2fee827b
--- /dev/null
+++ b/report-ui/src/assets/styles/variables.scss
@@ -0,0 +1,4 @@
+//sidebar
+$menuBg:#304156;
+$subMenuBg:#1f2d3d;
+$menuHover:#001528;
diff --git a/report-ui/src/components/Breadcrumb/index.vue b/report-ui/src/components/Breadcrumb/index.vue
new file mode 100644
index 00000000..90fd9cec
--- /dev/null
+++ b/report-ui/src/components/Breadcrumb/index.vue
@@ -0,0 +1,67 @@
+
+
+
+
+ {{ item.meta.title }}
+ {{ item.meta.title }}
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/Dictionary/index.vue b/report-ui/src/components/Dictionary/index.vue
new file mode 100644
index 00000000..911775f2
--- /dev/null
+++ b/report-ui/src/components/Dictionary/index.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/Hamburger/index.vue b/report-ui/src/components/Hamburger/index.vue
new file mode 100644
index 00000000..27cf6ea4
--- /dev/null
+++ b/report-ui/src/components/Hamburger/index.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/LgModal.vue b/report-ui/src/components/LgModal.vue
new file mode 100644
index 00000000..01d51be6
--- /dev/null
+++ b/report-ui/src/components/LgModal.vue
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+ {{statusText}}
+
+
+
+
+
+
+
+ this is Modal-content
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/Modal.vue b/report-ui/src/components/Modal.vue
new file mode 100644
index 00000000..cea1d118
--- /dev/null
+++ b/report-ui/src/components/Modal.vue
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+ {{statusText}}
+
+
+ ×
+
+
+
+
+ this is Modal-content
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/SmModal.vue b/report-ui/src/components/SmModal.vue
new file mode 100644
index 00000000..de6d3f74
--- /dev/null
+++ b/report-ui/src/components/SmModal.vue
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+
+ {{statusText}}
+
+
+ ×
+
+
+
+ this is Modal-content
+
+
+
+
+ 确定
+
+
+ 取消
+ {{sure}}
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/codeSelect.vue b/report-ui/src/components/codeSelect.vue
new file mode 100644
index 00000000..6c91c292
--- /dev/null
+++ b/report-ui/src/components/codeSelect.vue
@@ -0,0 +1,154 @@
+/*
+* 使用方式
+* 根据/data/basecode.js中字典值,生成下拉列表
+* @property dictname ENABLE_FLAG
+* @property placeholder
+* @property style
+*/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/configForm.vue b/report-ui/src/components/configForm.vue
new file mode 100644
index 00000000..5c7e1c37
--- /dev/null
+++ b/report-ui/src/components/configForm.vue
@@ -0,0 +1,89 @@
+/*
+* 新增数据源时,根据不同的连接类型,渲染扩展输入字段drivreConfig表单
+* @property dictname ENABLE_FLAG
+* @property placeholder
+* @property style
+*/
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/components/dataPicker.vue b/report-ui/src/components/dataPicker.vue
new file mode 100644
index 00000000..7af06b22
--- /dev/null
+++ b/report-ui/src/components/dataPicker.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/components/eachForm.vue b/report-ui/src/components/eachForm.vue
new file mode 100644
index 00000000..8c915b87
--- /dev/null
+++ b/report-ui/src/components/eachForm.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{option}}
+
+
+
+
+
+ {{option}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/components/verifition/Verify.vue b/report-ui/src/components/verifition/Verify.vue
new file mode 100644
index 00000000..9c6f32bd
--- /dev/null
+++ b/report-ui/src/components/verifition/Verify.vue
@@ -0,0 +1,465 @@
+
+
+
+
+ 请完成安全验证
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/verifition/Verify/VerifyPoints.vue b/report-ui/src/components/verifition/Verify/VerifyPoints.vue
new file mode 100644
index 00000000..5fd915c4
--- /dev/null
+++ b/report-ui/src/components/verifition/Verify/VerifyPoints.vue
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+
+
+
+ {{index + 1}}
+
+
+
+
+
+ {{text}}
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/components/verifition/Verify/VerifySlide.vue b/report-ui/src/components/verifition/Verify/VerifySlide.vue
new file mode 100644
index 00000000..f3829a70
--- /dev/null
+++ b/report-ui/src/components/verifition/Verify/VerifySlide.vue
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+
+
+ {{tipWords}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/components/verifition/api/index.js b/report-ui/src/components/verifition/api/index.js
new file mode 100644
index 00000000..faf1c36e
--- /dev/null
+++ b/report-ui/src/components/verifition/api/index.js
@@ -0,0 +1,27 @@
+/**
+ * 此处可直接引用自己项目封装好的 axios 配合后端联调
+ */
+
+
+// import request from "./../utils/axios" //组件内部封装的axios
+import request from "@/api/axios.js" //调用项目封装的axios
+
+//获取验证图片 以及token
+export function reqGet(data) {
+ return request({
+ url: 'auth-service/user/captcha/get',
+ method: 'post',
+ data
+ })
+}
+
+//滑动或者点选验证
+export function reqCheck(data) {
+ return request({
+ url: 'auth-service/user/captcha/check',
+ method: 'post',
+ data
+ })
+}
+
+
diff --git a/report-ui/src/components/verifition/utils/ase.js b/report-ui/src/components/verifition/utils/ase.js
new file mode 100644
index 00000000..4c1c5594
--- /dev/null
+++ b/report-ui/src/components/verifition/utils/ase.js
@@ -0,0 +1,11 @@
+import CryptoJS from 'crypto-js'
+/**
+ * @word 要加密的内容
+ * @keyWord String 服务器随机返回的关键字
+ * */
+export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
+ var key = CryptoJS.enc.Utf8.parse(keyWord);
+ var srcs = CryptoJS.enc.Utf8.parse(word);
+ var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
+ return encrypted.toString();
+}
diff --git a/report-ui/src/components/verifition/utils/axios.js b/report-ui/src/components/verifition/utils/axios.js
new file mode 100644
index 00000000..610d4032
--- /dev/null
+++ b/report-ui/src/components/verifition/utils/axios.js
@@ -0,0 +1,30 @@
+import axios from 'axios';
+
+axios.defaults.baseURL = process.env.BASE_API;
+
+const service = axios.create({
+ timeout: 40000,
+ headers: {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'Content-Type': 'application/json; charset=UTF-8'
+ },
+})
+service.interceptors.request.use(
+ config => {
+ return config
+ },
+ error => {
+ Promise.reject(error)
+ }
+)
+
+// response interceptor
+service.interceptors.response.use(
+ response => {
+ const res = response.data;
+ return res
+ },
+ error => {
+ }
+)
+export default service
diff --git a/report-ui/src/components/verifition/utils/util.js b/report-ui/src/components/verifition/utils/util.js
new file mode 100644
index 00000000..55f65d42
--- /dev/null
+++ b/report-ui/src/components/verifition/utils/util.js
@@ -0,0 +1,36 @@
+export function resetSize(vm) {
+ var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度
+
+ var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth
+ var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight
+
+ if (vm.imgSize.width.indexOf('%') != -1) {
+ img_width = parseInt(this.imgSize.width) / 100 * parentWidth + 'px'
+ } else {
+ img_width = this.imgSize.width;
+ }
+
+ if (vm.imgSize.height.indexOf('%') != -1) {
+ img_height = parseInt(this.imgSize.height) / 100 * parentHeight + 'px'
+ } else {
+ img_height = this.imgSize.height
+ }
+
+ if (vm.barSize.width.indexOf('%') != -1) {
+ bar_width = parseInt(this.barSize.width) / 100 * parentWidth + 'px'
+ } else {
+ bar_width = this.barSize.width
+ }
+
+ if (vm.barSize.height.indexOf('%') != -1) {
+ bar_height = parseInt(this.barSize.height) / 100 * parentHeight + 'px'
+ } else {
+ bar_height = this.barSize.height
+ }
+
+ return {imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height}
+}
+
+export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
+export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']
+export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']
\ No newline at end of file
diff --git a/report-ui/src/extend.js b/report-ui/src/extend.js
new file mode 100644
index 00000000..6855f947
--- /dev/null
+++ b/report-ui/src/extend.js
@@ -0,0 +1,21 @@
+// 对Date的扩展,将 Date 转化为指定格式的String
+// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
+// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
+// 例子:
+// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
+// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
+Date.prototype.Format = function (fmt) { //author: meizz
+ var o = {
+ "M+": this.getMonth() + 1, //月份
+ "d+": this.getDate(), //日
+ "h+": this.getHours(), //小时
+ "m+": this.getMinutes(), //分
+ "s+": this.getSeconds(), //秒
+ "q+": Math.floor((this.getMonth() + 3) / 3), //季度
+ "S": this.getMilliseconds() //毫秒
+ };
+ if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+ for (var k in o)
+ if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+ return fmt;
+}
\ No newline at end of file
diff --git a/report-ui/src/filter/index.js b/report-ui/src/filter/index.js
new file mode 100644
index 00000000..274751a2
--- /dev/null
+++ b/report-ui/src/filter/index.js
@@ -0,0 +1,88 @@
+import { setItem, getItem } from '@/utils/storage';
+
+// 字典
+export function basecode(value, dicName) {
+ if (value === undefined || value === null) {
+ return ''
+ }
+ if (dicName === undefined || dicName === null) {
+ return value
+ }
+
+ var basecode = JSON.parse(localStorage.getItem('queryForCodeSelect'))
+ var dictList = basecode[dicName]
+ var dictLabel = value
+ for (var i = 0; i < dictList.length; i++) {
+ var codeItem = dictList[i]
+ if(codeItem.value == value || codeItem.labelEng == value){
+ dictLabel = codeItem.label
+ break
+ }
+ }
+ return dictLabel;
+}
+
+
+// 根据字典值获取数据
+export function getDataByCode(keyCode) {
+ var dict = basecode[this.keyCode]
+ let list = []
+ for (var key in dict) {
+ list.push({
+ 'value': key,
+ 'text': dict[key]
+ })
+ }
+ return list
+}
+
+//保留两位小数
+export function fixed(value){
+var intVal = null;
+if(typeof value == 'string' && /^[0-9.]+$/.test(value)){
+ intVal = parseInt(value);
+}
+if(typeof value == 'number'){
+ intVal = value;
+}
+if(intVal == null){
+ return value;
+}else{
+ return (Math.round(value*100)/100).toFixed(2);
+}
+}
+
+// 时间戳转日期
+export function formatTimestamp(value) {
+ if (value == null) {
+ return ''
+ }
+ var date = new Date(value)
+ var y = date.getFullYear()
+ var m = date.getMonth() + 1
+ m = m < 10 ? ('0' + m) : m
+ var d = date.getDate()
+ d = d < 10 ? ('0' + d) : d
+ var h = date.getHours()
+ h = h < 10 ? ('0' + h) : h
+ var minute = date.getMinutes()
+ var second = date.getSeconds()
+ minute = minute < 10 ? ('0' + minute) : minute
+ second = second < 10 ? ('0' + second) : second
+ return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second
+}
+
+
+// 时间戳转日期
+export function formatDate(value) {
+ if (value == null) {
+ return ''
+ }
+ var date = new Date(value)
+ var y = date.getFullYear()
+ var m = date.getMonth() + 1
+ m = m < 10 ? ('0' + m) : m
+ var d = date.getDate()
+ d = d < 10 ? ('0' + d) : d
+ return y + '-' + m + '-' + d
+}
\ No newline at end of file
diff --git a/report-ui/src/main.js b/report-ui/src/main.js
new file mode 100644
index 00000000..51895c44
--- /dev/null
+++ b/report-ui/src/main.js
@@ -0,0 +1,37 @@
+import Vue from 'vue'
+
+// element-ui
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
+import 'normalize.css/normalize.css'// A modern alternative to CSS resets
+import '@/assets/styles/common.css'
+import '@/assets/styles/index.scss'// custome global css
+
+// app router vuex filter mixins
+import App from './App'
+import router from './router'
+import store from './store'
+import * as filter from './filter'
+import mixins from '@/mixins'
+
+// permission control
+import '@/permission'
+
+import '@/extend'
+
+// enable element zh-cn
+Vue.use(ElementUI, { zhLocale })
+
+// register global filter.
+Object.keys(filter).forEach(key => {
+ Vue.filter(key, filter[key])
+})
+
+// register global mixins.
+Vue.mixin(mixins)
+
+Vue.config.productionTip = false
+
+// create the app instance.
+new Vue({ el: '#app', router, store, render: h => h(App) })
diff --git a/report-ui/src/mixins/access.js b/report-ui/src/mixins/access.js
new file mode 100644
index 00000000..d23c8a75
--- /dev/null
+++ b/report-ui/src/mixins/access.js
@@ -0,0 +1,119 @@
+import { setItem, getItem } from '@/utils/storage';
+
+export default {
+ data() {
+ return {
+ }
+ },
+ computed: {
+ getUser: function(){
+ // var user = getItem('user');
+ var user =JSON.parse(localStorage.getItem('user'))
+ if(user != null ){
+ return user;
+ }else{
+ return {};
+ }
+ },
+ isAdmin() {
+ if (this.getUser == null) {
+ return false
+ }
+ return this.getUser.userId === 1
+ },
+ opLoginName() {
+ return this.getUser == null ? '' : this.getUser.userName
+ },
+ opNikeName() {
+ return this.getUser == null ? '' : this.getUser.nikeName
+ },
+ opUserType() {
+ return this.getUser == null ? '' : this.getUser.userType
+ },
+ opAuthorities() {
+ return this.getUser == null ? [] : this.getUser.authorityWithOrgIds
+ }
+ },
+ created() {
+ },
+ mounted() {
+ },
+ destroyed() {
+ },
+ methods: {
+ hasPermission(permissionStr, orgIds) {
+ //判断用户权限列表是否为空
+ if (this.opAuthorities == null) {
+ return false
+ }
+ if(this.isAdmin){
+ return true;
+ }
+ if(permissionStr && permissionStr.indexOf('|') !== -1) {
+ let flag = false
+ let arr = permissionStr.split('|')
+ for(let i=0; i< arr.length; i++) {
+ let a = arr[i].replace(/(^\s*)|(\s*$)/g, "");
+ if (this.opAuthorities.hasOwnProperty(a)) {
+ flag = true
+ }
+ }
+ return flag
+ }
+ //登录用户没有某个操作权限
+ if (!this.opAuthorities.hasOwnProperty(permissionStr)) {
+ return false
+ }
+ //如果当前验证,不包含项目级别验证,直接返回
+ if (typeof(orgIds) == 'undefined' || orgIds == null) {
+ return true
+ }
+ //验证登录用户是否有某个项目的有操作权限
+ var orgIdsHasPermission = this.opAuthorities[permissionStr]
+ //如果projectIds是个数字,只要验证登录用户是否有该项目的操作权限
+ if (typeof orgIds == 'number') {
+ if (orgIdsHasPermission.indexOf(orgIds) > -1) {
+ return true
+ }else{
+ return false
+ }
+ }else{
+ var result = false
+ for (var i in orgIdsHasPermission) {
+ var flag = orgIds.indexOf(orgIdsHasPermission[i]) > -1
+ if (flag) {
+ result = true
+ }
+ }
+ return result
+ }
+ },
+ //深拷贝
+ deepClone(obj){
+ var temp = JSON.stringify(obj);
+ return JSON.parse(temp);
+ },
+
+ //从所有字典中,取某个字典的列表
+ getDict(dictname){
+ var basecode = JSON.parse(localStorage.getItem('queryForCodeSelect'));
+ var dictList = basecode[dictname]
+ return dictList;
+ },
+ //从某个字典的列表,获取某个字典对象
+ getDictCode(dictname, codeValue , value='value'){
+ //如果 codeValue传过来的是字符串 all 则字典数组返回
+ var dictList = this.getDict(dictname);
+ for (var i = 0; i < dictList.length; i++) {
+ var codeItem = dictList[i]
+ if(codeItem[value] == codeValue){
+ return codeItem;
+ }
+ if(codeValue =='all'){
+ return dictList
+ }
+ }
+ return {};
+ },
+ }
+}
diff --git a/report-ui/src/mixins/common.js b/report-ui/src/mixins/common.js
new file mode 100644
index 00000000..61fda6be
--- /dev/null
+++ b/report-ui/src/mixins/common.js
@@ -0,0 +1,90 @@
+export default {
+ data() {
+ return {
+ }
+ },
+ computed: {
+ },
+ created() {
+ },
+ mounted() {
+ },
+ destroyed() {
+ },
+ methods: {
+ goBack() {
+ this.$router.go(-1)
+ },
+ refresh() {
+ this.$router.go(0)
+ },
+ parseString(object) {
+ if (typeof object === 'undefined' || object == null) {
+ return ''
+ }
+ if (typeof object === 'number') {
+ return object.toString()
+ }
+ if (typeof object === 'boolean') {
+ return object.toString()
+ }
+ if (typeof object === 'object') {
+ return JSON.stringify(object)
+ }
+ return ''
+ },
+ isBlank(val) {
+ if (typeof val === 'undefined') {
+ return true
+ }
+ if (val == null || val === '') {
+ return true
+ }
+ return false
+ },
+ // 封装定制删除数组中的值
+ contains(a, obj) {
+ var i = a.length
+ while (i--) {
+ if (a[i] === obj) {
+ return i
+ }
+ }
+ return false
+ },
+ //获取url后边参数
+ getUrlKey: function(name) {
+ return (
+ decodeURIComponent(
+ (new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(
+ /\+/g,
+ '%20'
+ )
+ ) || null
+ )
+ },
+ /**
+ *
+ */
+ resetForm(data) {
+ let formKeys = Object.keys(data)
+ for (let k of formKeys) {
+ data[k] = null
+ }
+ },
+ sortArray(propertyName){
+ return function(object1,object2){
+ var value1 = object1[propertyName];
+ var value2 = object2[propertyName];
+
+ if(value1 < value2){
+ return -1;
+ }else if(value1 > value2){
+ return 1;
+ }else{
+ return 0;
+ }
+ }
+ }
+ }
+}
diff --git a/report-ui/src/mixins/index.js b/report-ui/src/mixins/index.js
new file mode 100644
index 00000000..34de13f6
--- /dev/null
+++ b/report-ui/src/mixins/index.js
@@ -0,0 +1,7 @@
+import access from '@/mixins/access'
+import common from '@/mixins/common'
+import queryform from '@/mixins/queryform'
+
+export default {
+ mixins: [access, common, queryform]
+}
diff --git a/report-ui/src/mixins/queryform.js b/report-ui/src/mixins/queryform.js
new file mode 100644
index 00000000..39e0e97c
--- /dev/null
+++ b/report-ui/src/mixins/queryform.js
@@ -0,0 +1,111 @@
+import miment from 'miment'
+export default {
+ data() {
+ return {
+ // form select-input key
+ selectInput: {
+ keyname: '',
+ keyword: ''
+ },
+
+ //日期时间快捷选项
+ datetimeRangePickerOptions:{
+ shortcuts: [{
+ text: '今天',
+ onClick(picker) {
+ const end = new Date();
+ const start = new Date(new Date(new Date().getTime()).setHours(0, 0, 0, 0));
+ picker.$emit('pick', [start, end]);
+ }
+ },{
+ text: '昨天',
+ onClick(picker) {
+ const start=new Date(new Date(new Date().getTime()-24*60*60*1000).setHours(0, 0, 0, 0));
+ const end=new Date(new Date(new Date().getTime()-24*60*60*1000).setHours(23, 59, 59, 999));
+ picker.$emit('pick', [start, end]);
+ }
+ },{
+ text: '最近一周',
+ onClick(picker) {
+ const end = new Date();
+ const start = new Date();
+ start.setTime(miment().add(-1, 'ww').stamp());
+ picker.$emit('pick', [start, end]);
+ }
+ }, {
+ text: '最近一个月',
+ onClick(picker) {
+ const end = new Date();
+ const start = new Date();
+ start.setTime(miment().add(-1, 'MM').stamp());
+ picker.$emit('pick', [start, end]);
+ }
+ }, {
+ text: '最近三个月',
+ onClick(picker) {
+ const end = new Date();
+ const start = new Date();
+ start.setTime(miment().add(-3, 'MM').stamp());
+ picker.$emit('pick', [start, end]);
+ }
+ }],
+ // disabledDate(time){
+ // return time.getTime() > Date.now()
+ // }
+ }
+ }
+ },
+ computed: {
+ },
+ created() {
+ },
+ mounted() {
+ },
+ destroyed() {
+ },
+ methods: {
+ // 搜索重置搜索页码
+ search(){
+ this.params.currentPage=1;
+ this.queryByPage();
+ },
+ // 把selectInput中的值赋到params查询对象中
+ parseParamsBySelectInput(keyname, keyword) {
+ if (this.params === undefined || this.params === null) {
+ console.warn('query form must bind to params object in vue data')
+ return
+ }
+ // if (!this.params.hasOwnProperty(keyname)) {
+ // console.warn('params has no field:' + keyname)
+ // return
+ // }
+ if (keyword !== undefined ) {
+ this.params[keyname] = keyword.trim()
+ }
+ },
+ resetForm(data) {
+ let formKeys = Object.keys(data)
+ for (let k of formKeys) {
+ data[k] = null
+ }
+ },
+ handlerInputchange(val){
+ this.parseParamsBySelectInput(this.selectInput.keyname, val)
+ }
+ },
+ watch: {
+ 'selectInput.keyname'(newVal, oldVal) {
+ this.resetForm(this.params)
+ this.params.currentPage = 1
+ this.params.pageSize = 10
+ this.parseParamsBySelectInput(newVal, this.selectInput.keyword)
+ },
+ 'selectInput.keyword'(newVal, oldVal) {
+ if (!this.selectInput.keyname) return
+ this.parseParamsBySelectInput(this.selectInput.keyname, newVal)
+ }
+ // 'selectInput.keyword'(newVal, oldVal) {
+ // this.parseParamsBySelectInput(this.selectInput.keyname, newVal)
+ // }
+ }
+}
diff --git a/report-ui/src/permission.js b/report-ui/src/permission.js
new file mode 100644
index 00000000..4a72028d
--- /dev/null
+++ b/report-ui/src/permission.js
@@ -0,0 +1,53 @@
+import router from './router'
+import store from './store'
+import NProgress from 'nprogress' // Progress 进度条
+import 'nprogress/nprogress.css'// Progress 进度条样式
+import { setItem, getItem } from '@/utils/storage';
+
+export default router
+var whiteList = ['/login']
+// 判断是否需要登录权限 以及是否登录
+router.beforeEach((to, from, next) => {
+
+ NProgress.start()
+ var token = getItem('token');
+ var accessUser = getItem('accessUser');
+ // 如果有token
+ if (token) {
+ if (to.path == '/login') {
+ next('/index')
+ NProgress.done()
+ }else{
+ next()
+ }
+ // 如果没有token
+ }else {
+ /* has no token */
+ console.log(token,to.meta)
+ if ((token == null || token == '' || token ==undefined || accessUser == {}) && (to.meta != null && to.meta.requireAuth == true)) { // 在免登录白名单,直接进入
+ next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
+ NProgress.done()
+ } else {
+ next()
+ }
+ }
+ // if (to.path == '/' || to.path == '/login') {
+ // if (token != null && token != '' && accessUser != null && accessUser != {}) {
+ // next('/index')
+ // NProgress.done()
+ // } else {
+ // next()
+ // }
+ // } else {
+ // if ((token == null || token == '' || accessUser == {}) && (to.meta != null && to.meta.requireAuth == true)) {
+ // next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
+ // NProgress.done()
+ // } else {
+ // next()
+ // }
+ // }
+})
+
+router.afterEach(() => {
+ NProgress.done() // 结束Progress
+})
diff --git a/report-ui/src/router/index.js b/report-ui/src/router/index.js
new file mode 100644
index 00000000..72554b2c
--- /dev/null
+++ b/report-ui/src/router/index.js
@@ -0,0 +1,70 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+
+// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading;
+// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading
+
+Vue.use(Router)
+
+/* Layout */
+import Layout from '../views/layout/Layout'
+
+/**
+* hidden: true if `hidden:true` will not show in the sidebar(default is false)
+* alwaysShow: true if set true, will always show the root menu, whatever its child routes length
+* if not set alwaysShow, only more than one route under the children
+* it will becomes nested mode, otherwise not show the root menu
+* redirect: noredirect if `redirect:noredirect` will no redirect in the breadcrumb
+* name:'router-name' the name is used by (must set!!!)
+* meta : {
+ title: 'title' the name show in submenu and breadcrumb (recommend set)
+ icon: 'svg-name' the icon show in the sidebar,
+ AuthKey: 'roleManage:find', 该页面进入的权限码
+ keepAlive: true, 该页面需要缓存(注意: name值必须设置 与组件内部name 一致 配合isback属性)
+ isback : false
+ }
+* AuthKey: 'roleManage:find' 该页面进入的权限码
+**/
+export const constantRouterMap = [
+ { path: '/login', component: () => import('@/views/login'), hidden: true },
+ {
+ path: '/helpCenList', component: () => import('@/views/helpCenList/list'), hidden: true,
+ children: [
+ { path: 'list', component: () => import('@/views/helpCenList/list-title'), hidden: true },
+ { path: 'detail', component: () => import('@/views/helpCenList/list-detail'), hidden: true },
+ { path: 'search', component: () => import('@/views/helpCenList/list-search'), hidden: true }
+ ]
+ },
+ {
+ path: '/index',
+ component: Layout,
+ redirect: '/access/accessAuthority',
+ name: '首页',
+ meta: { title: '首页1', icon: 'iconhome2' },
+ children: [
+ { path: '', name: 'accessUser', component: () => import('@/views/home/index'), meta: { title: '首页', icon: 'iconhome2', keepAlive: true, isBack: true } },
+ ]
+ },
+ {
+ path: '/report',
+ component: Layout,
+ redirect: '/report/datasource',
+ name: '报表管理',
+ meta: { title: '报表管理', icon: 'iconnavicon-ywcs' },
+ children: [
+ { path: 'datasource', name: 'datasource', component: () => import('@/views/report/datasource/index'), meta: { title: '数据源', icon: 'iconeventbridgexiaoxishijianzongxian', keepAlive: true, isBack: true } },
+ { path: 'resultset', name: 'resultset', component: () => import('@/views/report/resultset/index'), meta: { title: '数据集', icon: 'iconalikafkaxiaoxiduilieKafka', keepAlive: true, isBack: true } },
+ { path: 'report', name: 'reportIndex', component: () => import('@/views/report/report/index'), meta: { title: '报表管理', icon: 'iconnavicon-ywcs', keepAlive: true, isBack: true } },
+ { path: 'bigscreen', name: 'bigscreen', component: () => import('@/views/report/bigscreen/index'), meta: { title: '大屏报表', icon: 'iconchufaqipeizhi-hui', keepAlive: true, isBack: true } },
+ { path: 'excelreport', name: 'excelreport', component: () => import('@/views/report/excelreport/index'), meta: { title: '表格报表', icon: 'iconliebiao', keepAlive: true, isBack: true } },
+ ]
+ },
+ { path: '/404', component: () => import('@/views/404'), hidden: true },
+ { path: '*', redirect: '/index', hidden: true },
+]
+
+export default new Router({
+ // mode: 'history', //后端支持可开
+ scrollBehavior: () => ({ y: 0 }),
+ routes: constantRouterMap
+})
\ No newline at end of file
diff --git a/report-ui/src/store/actions.js b/report-ui/src/store/actions.js
new file mode 100644
index 00000000..529efbc2
--- /dev/null
+++ b/report-ui/src/store/actions.js
@@ -0,0 +1,6 @@
+
+const actions = {
+
+}
+
+export default actions
diff --git a/report-ui/src/store/getters.js b/report-ui/src/store/getters.js
new file mode 100644
index 00000000..4b53b480
--- /dev/null
+++ b/report-ui/src/store/getters.js
@@ -0,0 +1,10 @@
+import cacheView from "./modules/cachaView"
+
+const getters = {
+ sidebar: state => state.app.sidebar,
+ device: state => state.app.device,
+ token: state => state.user.token,
+ accessUser: state => state.user.accessUser,
+ cacheViews: state => state.cacheView.cacheViews
+}
+export default getters
diff --git a/report-ui/src/store/index.js b/report-ui/src/store/index.js
new file mode 100644
index 00000000..f011f382
--- /dev/null
+++ b/report-ui/src/store/index.js
@@ -0,0 +1,30 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import actions from './actions'
+import getters from './getters'
+import mutations from './mutations'
+import app from './modules/app'
+import user from './modules/user'
+import cacheView from './modules/cachaView'
+import help from './modules/help'
+
+Vue.use(Vuex)
+
+const initPlugin = store => {
+}
+
+const store = new Vuex.Store({
+ modules: {
+ app,
+ user,
+ cacheView,
+ help
+ },
+ state: { },
+ plugins: [initPlugin],
+ actions,
+ mutations,
+ getters
+})
+
+export default store
diff --git a/report-ui/src/store/modules/app.js b/report-ui/src/store/modules/app.js
new file mode 100644
index 00000000..f4872415
--- /dev/null
+++ b/report-ui/src/store/modules/app.js
@@ -0,0 +1,43 @@
+import Cookies from 'js-cookie'
+
+const app = {
+ state: {
+ sidebar: {
+ opened: !+Cookies.get('sidebarStatus'),
+ withoutAnimation: false
+ },
+ device: 'desktop'
+ },
+ mutations: {
+ TOGGLE_SIDEBAR: state => {
+ if (state.sidebar.opened) {
+ Cookies.set('sidebarStatus', 1)
+ } else {
+ Cookies.set('sidebarStatus', 0)
+ }
+ state.sidebar.opened = !state.sidebar.opened
+ state.sidebar.withoutAnimation = false
+ },
+ CLOSE_SIDEBAR: (state, withoutAnimation) => {
+ Cookies.set('sidebarStatus', 1)
+ state.sidebar.opened = false
+ state.sidebar.withoutAnimation = withoutAnimation
+ },
+ TOGGLE_DEVICE: (state, device) => {
+ state.device = device
+ }
+ },
+ actions: {
+ ToggleSideBar: ({ commit }) => {
+ commit('TOGGLE_SIDEBAR')
+ },
+ CloseSideBar({ commit }, { withoutAnimation }) {
+ commit('CLOSE_SIDEBAR', withoutAnimation)
+ },
+ ToggleDevice({ commit }, device) {
+ commit('TOGGLE_DEVICE', device)
+ }
+ }
+}
+
+export default app
diff --git a/report-ui/src/store/modules/cachaView.js b/report-ui/src/store/modules/cachaView.js
new file mode 100644
index 00000000..7ffd021c
--- /dev/null
+++ b/report-ui/src/store/modules/cachaView.js
@@ -0,0 +1,22 @@
+
+const cacheView = {
+ state: {
+ cacheViews: []
+ },
+
+ mutations: {
+ ADD_CACHEVIEW: (state, view) => {
+ if (state.cacheViews.includes(view.name)) return
+ if (view.meta && view.meta.keepAlive) {
+ state.cacheViews.push(view.name)
+ }
+ }
+ },
+ actions: {
+ addCachedView({ commit }, view ) {
+ commit('ADD_CACHEVIEW', view)
+ }
+ }
+}
+
+export default cacheView
diff --git a/report-ui/src/store/modules/help.js b/report-ui/src/store/modules/help.js
new file mode 100644
index 00000000..5a5cc8e6
--- /dev/null
+++ b/report-ui/src/store/modules/help.js
@@ -0,0 +1,16 @@
+const help = {
+ state: {
+ id: 0,
+ val: '',
+ title: ''
+ },
+ mutations: {
+ setCategory(state, val) {
+ state.id = 0
+ state.val = val.value
+ state.title = val.label
+ }
+ }
+}
+
+export default help
\ No newline at end of file
diff --git a/report-ui/src/store/modules/user.js b/report-ui/src/store/modules/user.js
new file mode 100644
index 00000000..67f63262
--- /dev/null
+++ b/report-ui/src/store/modules/user.js
@@ -0,0 +1,75 @@
+import { login, logout } from '@/api/login'
+import { setToken, delToken, setAccessUser, delAccessUser } from '@/utils/auth'
+
+const user = {
+ state: {
+ token: '', // 登录后的token
+ accessUser: {} // 登录后的用户对象
+ },
+
+ mutations: {
+ SET_TOKEN: (state, token) => {
+ state.token = token
+ setToken(token)
+ },
+ SET_ACCESSUSER: (state, accessUser) => {
+ state.accessUser = accessUser
+ setAccessUser(accessUser)
+ }
+ },
+
+ actions: {
+ // 登录
+ Login({ commit }, userInfo) {
+ const userName = userInfo.userName.trim()
+ const password = userInfo.password.trim()
+ const captchaVerification = userInfo.captchaVerification.trim()
+ var data ={
+ userName, password,captchaVerification
+ }
+ return new Promise((resolve, reject) => {
+ login(data).then(response => {
+ const repCode = response.repCode
+ const repData = response.repData
+ if (repCode === '0000') {
+ commit('SET_TOKEN', repData.token)
+ commit('SET_ACCESSUSER', repData.accessUser)
+ resolve(response)
+ } else {
+ reject(response.repMsg)
+ }
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 登出
+ LogOut({ commit, state }) {
+ return new Promise((resolve, reject) => {
+ logout(state.token).then(() => {
+ commit('SET_TOKEN', '')
+ commit('SET_ACCESSUSER', {})
+ delToken()
+ delAccessUser()
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 前端 登出
+ FedLogOut({ commit }) {
+ return new Promise(resolve => {
+ commit('SET_TOKEN', '')
+ commit('SET_ACCESSUSER', {})
+ delToken()
+ delAccessUser()
+ resolve()
+ })
+ }
+ }
+}
+
+export default user
diff --git a/report-ui/src/store/mutations.js b/report-ui/src/store/mutations.js
new file mode 100644
index 00000000..78f7a1fb
--- /dev/null
+++ b/report-ui/src/store/mutations.js
@@ -0,0 +1,5 @@
+const mutations = {
+
+}
+
+export default mutations
diff --git a/report-ui/src/utils/aes.js b/report-ui/src/utils/aes.js
new file mode 100644
index 00000000..5f264e1a
--- /dev/null
+++ b/report-ui/src/utils/aes.js
@@ -0,0 +1,12 @@
+import CryptoJS from 'crypto-js'
+export function aesEncrypt(word){
+ var key = CryptoJS.enc.Utf8.parse("BGxdEUOZkXka4HSj");
+ var srcs = CryptoJS.enc.Utf8.parse(word);
+ var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
+ return encrypted.toString();
+}
+export function aesDecrypt(word){
+ var key = CryptoJS.enc.Utf8.parse("BGxdEUOZkXka4HSj");
+ var decrypt = CryptoJS.AES.decrypt(word, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
+ return CryptoJS.enc.Utf8.stringify(decrypt).toString();
+}
diff --git a/report-ui/src/utils/auth.js b/report-ui/src/utils/auth.js
new file mode 100644
index 00000000..6d47041f
--- /dev/null
+++ b/report-ui/src/utils/auth.js
@@ -0,0 +1,24 @@
+import Cookies from 'js-cookie'
+
+const TokenKey = 'token'
+const AccessUserKey = 'accessUser'
+
+export function getToken() {
+ return Cookies.get(TokenKey)
+}
+export function setToken(token) {
+ return Cookies.set(TokenKey, token)
+}
+export function delToken() {
+ return Cookies.remove(TokenKey)
+}
+
+export function getAccessUser() {
+ return Cookies.getJSON(AccessUserKey)
+}
+export function setAccessUser(accessUser) {
+ return Cookies.set(AccessUserKey, accessUser)
+}
+export function delAccessUser() {
+ return Cookies.remove(AccessUserKey)
+}
diff --git a/report-ui/src/utils/common.js b/report-ui/src/utils/common.js
new file mode 100644
index 00000000..b828c136
--- /dev/null
+++ b/report-ui/src/utils/common.js
@@ -0,0 +1,47 @@
+export default {
+ timestamp2String: function (timestamp, fmt) {
+ if (timestamp == null) return;
+ if (fmt == null || fmt == '') fmt = 'yyyy-MM-dd hh:mm:ss';
+ var date = new Date(timestamp);
+ var o = {
+ "M+": date.getMonth() + 1, //月份
+ "d+": date.getDate(), //日
+ "h+": date.getHours(), //小时
+ "m+": date.getMinutes(), //分
+ "s+": date.getSeconds(), //秒
+ "q+": Math.floor((date.getMonth() + 3) / 3), //季度
+ "S": date.getMilliseconds() //毫秒
+ };
+ if (/(y+)/.test(fmt))
+ fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
+ for (var k in o)
+ if (new RegExp("(" + k + ")").test(fmt))
+ fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+ return fmt;
+ },
+
+ secondsFormat: function (second) {
+ if (second == null || second == 0) {
+ return "0秒";
+ }
+ var day = Math.floor(second / (24 * 3600));
+ var hour = Math.floor((second - day * 24 * 3600) / 3600);
+ var minute = Math.floor((second - day * 24 * 3600 - hour * 3600) / 60);
+ var second = second - day * 24 * 3600 - hour * 3600 - minute * 60;
+
+ var result = "";
+ if (day > 0) {
+ result = result + day + "天";
+ }
+ if (hour > 0) {
+ result = result + hour + "时";
+ }
+ if (minute > 0) {
+ result = result + minute + "分";
+ }
+ if (second > 0) {
+ result = result + second + "秒";
+ }
+ return result;
+ }
+}
diff --git a/report-ui/src/utils/encrypted.js b/report-ui/src/utils/encrypted.js
new file mode 100644
index 00000000..44015c4e
--- /dev/null
+++ b/report-ui/src/utils/encrypted.js
@@ -0,0 +1,9 @@
+const md5 = require('js-md5')
+/**
+ * 密码加盐后MD5
+ * @param {HTMLElement} elm
+ *
+ */
+export function transPsw(val) {
+ return md5(val + 'gaea')
+}
diff --git a/report-ui/src/utils/index.js b/report-ui/src/utils/index.js
new file mode 100644
index 00000000..0cc42693
--- /dev/null
+++ b/report-ui/src/utils/index.js
@@ -0,0 +1,169 @@
+/**
+ * Created by jiachenpan on 16/11/18.
+ */
+
+export function parseTime (time, cFormat) {
+ if (arguments.length === 0) {
+ return null
+ }
+ const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
+ let date
+ if (typeof time === 'object') {
+ date = time
+ } else {
+ if (('' + time).length === 10) time = parseInt(time) * 1000
+ date = new Date(time)
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay()
+ }
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+ if (result.length > 0 && value < 10) {
+ value = '0' + value
+ }
+ return value || 0
+ })
+ return time_str
+}
+
+export function formatTime (time, option) {
+ time = +time * 1000
+ const d = new Date(time)
+ const now = Date.now()
+
+ const diff = (now - d) / 1000
+
+ if (diff < 30) {
+ return '刚刚'
+ } else if (diff < 3600) {
+ // less 1 hour
+ return Math.ceil(diff / 60) + '分钟前'
+ } else if (diff < 3600 * 24) {
+ return Math.ceil(diff / 3600) + '小时前'
+ } else if (diff < 3600 * 24 * 2) {
+ return '1天前'
+ }
+ if (option) {
+ return parseTime(time, option)
+ } else {
+ return (
+ d.getMonth() +
+ 1 +
+ '月' +
+ d.getDate() +
+ '日' +
+ d.getHours() +
+ '时' +
+ d.getMinutes() +
+ '分'
+ )
+ }
+}
+
+export function isExternal (path) {
+ return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+export function deepClone (source) {
+ if (!source && typeof source !== 'object') {
+ throw new Error('error arguments', 'shallowClone')
+ }
+ const targetObj = source.constructor === Array ? [] : {}
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
+ }
+ })
+ return targetObj
+}
+
+function padLeftZero (str) {
+ return ('00' + str).substr(str.length)
+}
+
+/**
+ * 生成uuid
+ */
+export function getUUID () {
+ var d = new Date().getTime()
+ if (window.performance && typeof window.performance.now === 'function') {
+ d += performance.now() // use high-precision timer if available
+ }
+ var uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = (d + Math.random() * 16) % 16 | 0
+ d = Math.floor(d / 16)
+ return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16)
+ })
+ return uuid
+}
+// crypto 加解密
+const CryptoJS = require('crypto-js') // 引用AES源码js
+
+const key = CryptoJS.enc.Utf8.parse('1234123412ABCDEF') // 十六位十六进制数作为密钥
+const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412') // 十六位十六进制数作为密钥偏移量
+
+// 解密方法
+export function Decrypt (word) {
+ const encryptedHexStr = CryptoJS.enc.Hex.parse(word)
+ const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
+ const decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
+ const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
+ const inside = decryptedStr.toString()
+ const i = inside.substr(-32)
+ return inside.split(i)[0]
+}
+
+// 加密方法
+export function Encrypt (word) {
+ const srcs = CryptoJS.enc.Utf8.parse(word + getUUID())
+ const encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
+ return encrypted.ciphertext.toString().toUpperCase()
+}
+
+/**
+ * 导出文件接口请求后的的公用方法
+ * res 请求后返回的response
+ * fileName 文件名
+ */
+export function downloadBlob (res, fileName) {
+ const blob = new Blob([res.data], {
+ type: 'application/vnd.ms-excel;charset=utf-8',
+ })
+ if (window.navigator && window.navigator.msSaveOrOpenBlob) {
+ // ie
+ navigator.msSaveBlob(blob, fileName || '文件' + '.xlsx')
+ } else {
+ const link = document.createElement('a')
+ // let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'})
+ link.style.display = 'none'
+ link.href = URL.createObjectURL(blob)
+ fileName && (link.download = fileName + '.xlsx') // 下载的文件名
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ }
+}
+
+// 下载文件
+export function downloadFile (obj, name, suffix) {
+ const url = window.URL.createObjectURL(new Blob([obj]))
+ const link = document.createElement('a')
+ link.style.display = 'none'
+ link.href = url
+ const fileName = parseTime(new Date()) + '-' + name + '.' + suffix
+ link.setAttribute('download', fileName)
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+}
diff --git a/report-ui/src/utils/request.js b/report-ui/src/utils/request.js
new file mode 100644
index 00000000..7744512e
--- /dev/null
+++ b/report-ui/src/utils/request.js
@@ -0,0 +1,73 @@
+import axios from 'axios'
+import { Message, MessageBox } from 'element-ui'
+import store from '../store'
+import { getToken } from '@/utils/auth'
+
+// 创建axios实例
+const service = axios.create({
+ baseURL: process.env.BASE_API, // api 的 base_url
+ timeout: 5000 // 请求超时时间
+})
+
+// request拦截器
+service.interceptors.request.use(
+ config => {
+ if (store.getters.token) {
+ config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+ }
+ return config
+ },
+ error => {
+ // Do something with request error
+ console.log(error) // for debug
+ Promise.reject(error)
+ }
+)
+
+// response 拦截器
+service.interceptors.response.use(
+ response => {
+ /**
+ * code为非20000是抛错 可结合自己业务进行修改
+ */
+ const res = response.data
+ if (res.code !== 20000) {
+ Message({
+ message: res.message,
+ type: 'error',
+ duration: 5 * 1000
+ })
+
+ // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
+ if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
+ MessageBox.confirm(
+ '你已被登出,可以取消继续留在该页面,或者重新登录',
+ '确定登出',
+ {
+ confirmButtonText: '重新登录',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }
+ ).then(() => {
+ store.dispatch('FedLogOut').then(() => {
+ location.reload() // 为了重新实例化vue-router对象 避免bug
+ })
+ })
+ }
+ return Promise.reject('error')
+ } else {
+ return response.data
+ }
+ },
+ error => {
+ console.log('err' + error) // for debug
+ Message({
+ message: error.message,
+ type: 'error',
+ duration: 5 * 1000
+ })
+ return Promise.reject(error)
+ }
+)
+
+export default service
diff --git a/report-ui/src/utils/signUtil.js b/report-ui/src/utils/signUtil.js
new file mode 100644
index 00000000..85bbc548
--- /dev/null
+++ b/report-ui/src/utils/signUtil.js
@@ -0,0 +1,108 @@
+import md5 from 'js-md5';
+
+function jsonString (obj) {
+ if (isObject(obj)) {
+ return sortObjByKey(obj);
+ } else if (isArray(obj)) {
+ var sortArray = [];
+ for (var i = 0; i < obj.length; i++) {
+ if (isObject(obj[i])) {
+ sortArray.push(sortObjByKey(obj[i]));
+ } else {
+ return obj;
+ }
+ }
+ return sortArray;
+ } else {
+ return obj;
+ }
+}
+
+// 将通讯录按照 ABCD字母的顺序排序
+function sortObjByKey (obj) {
+ var keys = Object.keys(obj).sort();
+ var newObj = {}
+ for (var i = 0; i < keys.length; i++) {
+ var index = keys[i];
+ newObj[index] = jsonString(obj[index]);
+ }
+ return newObj;
+}
+
+
+//判断是否是数组
+function isArray (obj) {
+ return Object.prototype.toString.call(obj) === '[object Array]';
+}
+
+//判断是否是对象
+function isObject (obj) {
+ return Object.prototype.toString.call(obj) === '[object Object]';
+}
+
+export default {
+ /**
+ * 第一步,将data中参数,按key升序,排除null值,用&拼接,得tempSignStr
+ * 第二步,"time=%s&" + tempSignStr + "&token=%s"
+ * 第三步,md5(第二步结果)
+ */
+ sign: function (token, data) {
+ if (typeof (data) == "undefined" || data == null) {
+ data = {};
+ }
+ var gatewayRequest = {};//currentPage pageSize orderBy data time token sign isFrom
+ var time = new Date().getTime();
+ //找出data中值非null的key,同时排除分页参数
+ //ignoreKeyList data中哪些key不参与签名
+ var dataKeyArray = [];
+ var excludeKeyArray = ['currentPage', 'pageSize', 'orderBy', 'ignoreKeyList'];
+ for (var key in data) {
+ if (data[key] == null) {
+ continue;
+ }
+ if (excludeKeyArray.indexOf(key) >= 0) {
+ gatewayRequest[key] = data[key];
+ delete data[key];
+ if (key === 'ignoreKeyList') {
+ //遍历ignoreKeyList,不参与签名校验
+ for (var i = 0; i < data[key].length; i++) {
+ delete data[data[key][i]];
+ }
+ }
+ continue;
+ }
+ dataKeyArray.push(key);
+ }
+ //将key按升序排列
+ dataKeyArray.sort();
+
+ //生成签名串"time=%s&" + tempSignStr + "&token=%s"
+ var tempSignStr = "time=" + time;
+ for (var i = 0; i < dataKeyArray.length; i++) {
+ var key = dataKeyArray[i];
+ var value = data[key];
+ tempSignStr += "&";
+ tempSignStr += key;
+ tempSignStr += "=";
+ tempSignStr += JSON.stringify(jsonString(value));
+ }
+ tempSignStr += "&token=";
+ tempSignStr += token;
+ var signStr = md5(tempSignStr);
+ gatewayRequest['data'] = data;
+ gatewayRequest['time'] = time;
+ gatewayRequest['token'] = token;
+ gatewayRequest['sign'] = signStr;
+ gatewayRequest['isFrom'] = "PC";
+ return gatewayRequest;
+ }
+
+}
+/**
+ * 密码加盐后MD5
+ * @param {HTMLElement} elm
+ *
+ */
+export function transPsw (val) {
+ return md5(val + 'gaea')
+}
diff --git a/report-ui/src/utils/storage.js b/report-ui/src/utils/storage.js
new file mode 100644
index 00000000..f7485593
--- /dev/null
+++ b/report-ui/src/utils/storage.js
@@ -0,0 +1,53 @@
+import Cookies from 'js-cookie'
+export function setItem(k, v) {
+ if(typeof(v) == "undefined" || v == null){
+ return;
+ }
+
+ var val = v;
+ if(typeof(v) == "object"){
+ val = JSON.stringify(v);
+ }
+ Cookies.set(k, val)
+ Cookies.get(k, val)
+}
+
+export function getItem(k) {
+ var val = Cookies.get(k);
+ try{
+ //如果是number boolean jsonstring是不会报错的
+ return JSON.parse(val);
+ }catch(e){
+ return val;
+ }
+}
+export function delItem(k) {
+ Cookies.remove(k);
+}
+
+
+
+export function setStorageItem(k, v) {
+ if(typeof(v) == "undefined" || v == null){
+ return;
+ }
+
+ var val = v;
+ if(typeof(v) == "object"){
+ val = JSON.stringify(v);
+ }
+ localStorage.setItem(k, val)
+}
+
+export function getStorageItem(k) {
+ var val = localStorage.getItem(k);
+ try{
+ //如果是number boolean jsonstring是不会报错的
+ return JSON.parse(val);
+ }catch(e){
+ return val;
+ }
+}
+export function delStorageItem(k) {
+ localStorage.removeItem(k);
+}
\ No newline at end of file
diff --git a/report-ui/src/utils/throttle.js b/report-ui/src/utils/throttle.js
new file mode 100644
index 00000000..68396b40
--- /dev/null
+++ b/report-ui/src/utils/throttle.js
@@ -0,0 +1,19 @@
+/**
+ * 函数节流
+ */
+export function _throttle(fn,delay){
+ let timer
+ var delay = delay || 1000; //一秒内触发一次
+ return function(...args){
+ const context = this
+ let canExecute = !timer
+ if(canExecute){
+ fn.apply(context,args)
+ }else{
+ clearTimeout(timer)
+ }
+ timer = setTimeout(() => {
+ timer = null
+ }, delay);
+ }
+}
\ No newline at end of file
diff --git a/report-ui/src/utils/validate.js b/report-ui/src/utils/validate.js
new file mode 100644
index 00000000..e1103104
--- /dev/null
+++ b/report-ui/src/utils/validate.js
@@ -0,0 +1,32 @@
+/**
+ * Created by jiachenpan on 16/11/18.
+ */
+
+export function isvalidUsername(str) {
+ const valid_map = ['admin', 'editor']
+ return valid_map.indexOf(str.trim()) >= 0
+}
+
+/* 合法uri*/
+export function validateURL(textval) {
+ const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
+ return urlregex.test(textval)
+}
+
+/* 小写字母*/
+export function validateLowerCase(str) {
+ const reg = /^[a-z]+$/
+ return reg.test(str)
+}
+
+/* 大写字母*/
+export function validateUpperCase(str) {
+ const reg = /^[A-Z]+$/
+ return reg.test(str)
+}
+
+/* 大小写字母*/
+export function validatAlphabets(str) {
+ const reg = /^[A-Za-z]+$/
+ return reg.test(str)
+}
diff --git a/report-ui/src/views/404.vue b/report-ui/src/views/404.vue
new file mode 100644
index 00000000..963bc6db
--- /dev/null
+++ b/report-ui/src/views/404.vue
@@ -0,0 +1,228 @@
+
+
+
+
+
+
OOPS!
+
+
{{ message }}
+
请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告
+
返回首页
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/dashboard/index.vue b/report-ui/src/views/dashboard/index.vue
new file mode 100644
index 00000000..97c73698
--- /dev/null
+++ b/report-ui/src/views/dashboard/index.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/helpCenList/list-detail.vue b/report-ui/src/views/helpCenList/list-detail.vue
new file mode 100644
index 00000000..64695b36
--- /dev/null
+++ b/report-ui/src/views/helpCenList/list-detail.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/views/helpCenList/list-search.vue b/report-ui/src/views/helpCenList/list-search.vue
new file mode 100644
index 00000000..e1cc9b95
--- /dev/null
+++ b/report-ui/src/views/helpCenList/list-search.vue
@@ -0,0 +1,84 @@
+
+
+
搜索"{{searchInput}} ",共找到{{totalCount}} 个相关的问题。
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/views/helpCenList/list-title.vue b/report-ui/src/views/helpCenList/list-title.vue
new file mode 100644
index 00000000..d678b231
--- /dev/null
+++ b/report-ui/src/views/helpCenList/list-title.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/views/helpCenList/list.vue b/report-ui/src/views/helpCenList/list.vue
new file mode 100644
index 00000000..9b8daf24
--- /dev/null
+++ b/report-ui/src/views/helpCenList/list.vue
@@ -0,0 +1,168 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/views/home/index.vue b/report-ui/src/views/home/index.vue
new file mode 100644
index 00000000..1790bb13
--- /dev/null
+++ b/report-ui/src/views/home/index.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/layout/Layout.vue b/report-ui/src/views/layout/Layout.vue
new file mode 100644
index 00000000..e8d7d5e0
--- /dev/null
+++ b/report-ui/src/views/layout/Layout.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/layout/components/AppMain.vue b/report-ui/src/views/layout/components/AppMain.vue
new file mode 100644
index 00000000..747bea23
--- /dev/null
+++ b/report-ui/src/views/layout/components/AppMain.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/layout/components/Navbar.vue b/report-ui/src/views/layout/components/Navbar.vue
new file mode 100644
index 00000000..3e7f8532
--- /dev/null
+++ b/report-ui/src/views/layout/components/Navbar.vue
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+ {{userName}}
+
+
+
+
+ 帮助中心
+
+
+ 修改密码
+
+
+ 注销登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/layout/components/Sidebar/Item.vue b/report-ui/src/views/layout/components/Sidebar/Item.vue
new file mode 100644
index 00000000..c12aa5c0
--- /dev/null
+++ b/report-ui/src/views/layout/components/Sidebar/Item.vue
@@ -0,0 +1,28 @@
+
diff --git a/report-ui/src/views/layout/components/Sidebar/Link.vue b/report-ui/src/views/layout/components/Sidebar/Link.vue
new file mode 100644
index 00000000..5d366f24
--- /dev/null
+++ b/report-ui/src/views/layout/components/Sidebar/Link.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/layout/components/Sidebar/SidebarItem.vue b/report-ui/src/views/layout/components/Sidebar/SidebarItem.vue
new file mode 100644
index 00000000..071552d9
--- /dev/null
+++ b/report-ui/src/views/layout/components/Sidebar/SidebarItem.vue
@@ -0,0 +1,136 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/report-ui/src/views/layout/components/Sidebar/index.vue b/report-ui/src/views/layout/components/Sidebar/index.vue
new file mode 100644
index 00000000..4c71e759
--- /dev/null
+++ b/report-ui/src/views/layout/components/Sidebar/index.vue
@@ -0,0 +1,64 @@
+
+
+
+ 在线大屏
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/layout/components/index.js b/report-ui/src/views/layout/components/index.js
new file mode 100644
index 00000000..97ee3cd1
--- /dev/null
+++ b/report-ui/src/views/layout/components/index.js
@@ -0,0 +1,3 @@
+export { default as Navbar } from './Navbar'
+export { default as Sidebar } from './Sidebar'
+export { default as AppMain } from './AppMain'
diff --git a/report-ui/src/views/layout/mixin/ResizeHandler.js b/report-ui/src/views/layout/mixin/ResizeHandler.js
new file mode 100644
index 00000000..b22c8bb6
--- /dev/null
+++ b/report-ui/src/views/layout/mixin/ResizeHandler.js
@@ -0,0 +1,41 @@
+import store from '@/store'
+
+const { body } = document
+const WIDTH = 1024
+const RATIO = 3
+
+export default {
+ watch: {
+ $route(route) {
+ if (this.device === 'mobile' && this.sidebar.opened) {
+ store.dispatch('CloseSideBar', { withoutAnimation: false })
+ }
+ }
+ },
+ beforeMount() {
+ window.addEventListener('resize', this.resizeHandler)
+ },
+ mounted() {
+ const isMobile = this.isMobile()
+ if (isMobile) {
+ store.dispatch('ToggleDevice', 'mobile')
+ store.dispatch('CloseSideBar', { withoutAnimation: true })
+ }
+ },
+ methods: {
+ isMobile() {
+ const rect = body.getBoundingClientRect()
+ return rect.width - RATIO < WIDTH
+ },
+ resizeHandler() {
+ if (!document.hidden) {
+ const isMobile = this.isMobile()
+ store.dispatch('ToggleDevice', isMobile ? 'mobile' : 'desktop')
+
+ if (isMobile) {
+ store.dispatch('CloseSideBar', { withoutAnimation: true })
+ }
+ }
+ }
+ }
+}
diff --git a/report-ui/src/views/login.vue b/report-ui/src/views/login.vue
new file mode 100644
index 00000000..f0eebacd
--- /dev/null
+++ b/report-ui/src/views/login.vue
@@ -0,0 +1,450 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ HELLO,
+
+ 在线大屏
+
+
+
+
+
+ 登录
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/form/colorPicker.vue b/report-ui/src/views/report/bigscreen/designer/form/colorPicker.vue
new file mode 100644
index 00000000..ba321654
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/form/colorPicker.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/form/contentMenu.vue b/report-ui/src/views/report/bigscreen/designer/form/contentMenu.vue
new file mode 100644
index 00000000..2e828337
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/form/contentMenu.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/form/customColorComponents.vue b/report-ui/src/views/report/bigscreen/designer/form/customColorComponents.vue
new file mode 100644
index 00000000..f957210d
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/form/customColorComponents.vue
@@ -0,0 +1,147 @@
+
+
+ 新增
+
+
+
+
+
+
+
+
+ 编辑
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/form/dynamicCollapseForm.vue b/report-ui/src/views/report/bigscreen/designer/form/dynamicCollapseForm.vue
new file mode 100644
index 00000000..2509d163
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/form/dynamicCollapseForm.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/form/dynamicComponents.vue b/report-ui/src/views/report/bigscreen/designer/form/dynamicComponents.vue
new file mode 100644
index 00000000..ae13c5a1
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/form/dynamicComponents.vue
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 刷新
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/form/dynamicForm.vue b/report-ui/src/views/report/bigscreen/designer/form/dynamicForm.vue
new file mode 100644
index 00000000..efaa753e
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/form/dynamicForm.vue
@@ -0,0 +1,286 @@
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/index.vue b/report-ui/src/views/report/bigscreen/designer/index.vue
new file mode 100644
index 00000000..a04601c9
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/index.vue
@@ -0,0 +1,685 @@
+
+
+
+
+
+
+
+
+ widgetOnDragged(evt, widget.code)">
+
+
+
+
+ {{ widget.label }}
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ widgetValueChanged('setup', val)" />
+ widgetValueChanged('collapse', val)" />
+
+
+ widgetValueChanged('data', val)" />
+
+
+ widgetValueChanged('position', val)" />
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/tools.js b/report-ui/src/views/report/bigscreen/designer/tools.js
new file mode 100644
index 00000000..21c7c13d
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/tools.js
@@ -0,0 +1,3606 @@
+const screenConfig = {
+ code: 'screen',
+ type: 'screen',
+ label: '大屏设置',
+ icon: '',
+ options: {
+ setup: [
+ {
+ type: 'el-input-number',
+ label: '大屏宽度',
+ name: 'width',
+ required: false,
+ placeholder: 'px',
+ value: '1920',
+ },
+ {
+ type: 'el-input-number',
+ label: '大屏高度',
+ name: 'height',
+ required: false,
+ placeholder: 'px',
+ value: '1080',
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'title',
+ require: false,
+ placeholder: '',
+ value: '大屏',
+ },
+ {
+ type: 'el-input-textarea',
+ label: '大屏简介',
+ name: 'description',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '背景颜色',
+ name: 'backgroundColor',
+ required: false,
+ placeholder: '',
+ value: '#000',
+ },
+ // {
+ // type: 'el-upload-picture',
+ // label: '背景图片',
+ // name: 'backgroundImage',
+ // required: false,
+ // placeholder: '',
+ // },
+ {
+ type: 'el-input-text',
+ label: '图片地址',
+ name: 'backgroundImage',
+ required: false,
+ placeholder: '',
+ value: 'http://10.108.26.197/business/file/download/adfc22ac-ed7f-4141-aeb9-ee81f16ac92d',
+ },
+ ],
+ data: [],
+ position: [],
+ },
+}
+
+const widgetTools = [
+ // type=html类型的组件
+ {
+ code: 'widget-text',
+ type: 'html',
+ label: '文本',
+ icon: 'text',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '文本框',
+ },
+ {
+ type: 'el-input-text',
+ label: '文本内容',
+ name: 'text',
+ required: false,
+ placeholder: '',
+ value: '文本框',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ value: '26',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'color',
+ required: false,
+ placeholder: '',
+ value: '#FAD400',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体间距',
+ name: 'letterSpacing',
+ required: false,
+ placeholder: '',
+ value: '0',
+ },
+ {
+ type: 'vue-color',
+ label: '字体背景',
+ name: 'background',
+ required: false,
+ placeholder: '',
+ value: 'rgba(115,170,229,.5)',
+ },
+ {
+ type: 'el-select',
+ label: '文字粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'normal', name: '正常' },
+ { code: 'bold', name: '粗体' },
+ { code: 'bolder', name: '特粗体' },
+ { code: 'lighter', name: '细体' }
+ ],
+ value: 'normal'
+ },
+ {
+ type: 'el-select',
+ label: '对齐方式',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'center', name: '居中' },
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ value: 'center'
+ },
+ ],
+
+ // 数据
+ data: [],
+
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 100,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 40
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-marquee',
+ type: 'html',
+ label: '滚动文本',
+ icon: 'marquee',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '跑马灯',
+ },
+ {
+ type: 'el-input-text',
+ label: '文本内容',
+ name: 'text',
+ required: false,
+ placeholder: '',
+ value: '滚动文本',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ value: '26',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'color',
+ required: false,
+ placeholder: '',
+ value: '#FAD400',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体间距',
+ name: 'letterSpacing',
+ required: false,
+ placeholder: '',
+ value: '0',
+ },
+ {
+ type: 'vue-color',
+ label: '字体背景',
+ name: 'background',
+ required: false,
+ placeholder: '',
+ value: 'rgba(115,170,229,.5)',
+ },
+ {
+ type: 'el-select',
+ label: '文字粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'normal', name: '正常' },
+ { code: 'bold', name: '粗体' },
+ { code: 'bolder', name: '特粗体' },
+ { code: 'lighter', name: '细体' }
+ ],
+ value: 'normal'
+ },
+ {
+ type: 'el-select',
+ label: '对齐方式',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'center', name: '居中' },
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ value: 'center'
+ },
+ {
+ type: 'el-switch',
+ label: '开启滚动',
+ name: 'marqueeSet',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-input-text',
+ label: '滚动速度',
+ name: 'marqueeQuit',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ // 数据
+ data: [],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 100,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 40,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-href',
+ type: 'html',
+ label: '超链接',
+ icon: 'href',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '超链接',
+ },
+ {
+ type: 'el-input-text',
+ label: '文本内容',
+ name: 'text',
+ required: false,
+ placeholder: '',
+ value: '超链接',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ value: '26',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'color',
+ required: false,
+ placeholder: '',
+ value: '#FAD400',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体间距',
+ name: 'letterSpacing',
+ required: false,
+ placeholder: '',
+ value: '0',
+ },
+ {
+ type: 'vue-color',
+ label: '字体背景',
+ name: 'background',
+ required: false,
+ placeholder: '',
+ value: 'rgba(115,170,229,.5)',
+ },
+ {
+ type: 'el-select',
+ label: '文字粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'normal', name: '正常' },
+ { code: 'bold', name: '粗体' },
+ { code: 'bolder', name: '特粗体' },
+ { code: 'lighter', name: '细体' }
+ ],
+ value: 'normal'
+ },
+ {
+ type: 'el-select',
+ label: '对齐方式',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'center', name: '居中' },
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ value: 'center'
+ },
+ {
+ type: 'el-radio-group',
+ label: '跳转方式',
+ name: 'jumpMode',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ {
+ code: 'self',
+ name: '本窗口',
+ },
+ {
+ code: 'other',
+ name: '新窗口',
+ },
+ ],
+ value: 'self',
+ },
+ {
+ type: 'el-input-text',
+ label: '超链地址',
+ name: 'linkAdress',
+ required: false,
+ placeholder: '',
+ value: 'http://www.baidu.com',
+ },
+ ],
+ // 数据
+ data: [],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 100,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 40,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-time',
+ type: 'html',
+ label: '当前时间',
+ icon: 'time',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '当前时间',
+ },
+ {
+ type: 'el-select',
+ label: '时间格式',
+ name: 'timeFormat',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'yyyy-MM-dd', name: '日期' },
+ { code: 'yyyy-MM-dd hh:mm', name: '日期+时分' },
+ { code: 'yyyy-MM-dd hh:mm:ss', name: '日期+时分秒' },
+ { code: 'MM-dd', name: '日期无年' },
+ { code: 'hh:mm', name: '时分' },
+ { code: 'hh:mm:ss', name: '时分秒' },
+ ],
+ value: 'yyyy-MM-dd hh:mm:ss'
+ },
+ {
+ type: 'el-input-number',
+ label: '字体间距',
+ name: 'letterSpacing',
+ required: false,
+ placeholder: '',
+ value: '0'
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ value: '26'
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'color',
+ required: false,
+ placeholder: '',
+ value: '#FAD400'
+ },
+ {
+ type: 'vue-color',
+ label: '字体背景',
+ name: 'background',
+ required: false,
+ placeholder: '',
+ value: 'rgba(115,170,229,.5)'
+ },
+ {
+ type: 'el-select',
+ label: '文字粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'normal', name: '正常' },
+ { code: 'bold', name: '粗体' },
+ { code: 'bolder', name: '特粗体' },
+ { code: 'lighter', name: '细体' }
+ ],
+ value: 'normal'
+ },
+ {
+ type: 'el-select',
+ label: '对齐方式',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'center', name: '居中' },
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ value: 'left'
+ },
+ ],
+ // 数据
+ data: [],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 300,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 100,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-image',
+ type: 'html',
+ label: '图片',
+ icon: 'image',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '图片',
+ },
+ {
+ type: 'el-switch',
+ label: '开启旋转',
+ name: 'startRotate',
+ required: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'el-slider',
+ label: '透明度',
+ name: 'transparency',
+ required: false,
+ placeholder: '',
+ value: 100
+ },
+ {
+ type: 'el-input-number',
+ label: '圆角',
+ name: 'borderRadius',
+ required: false,
+ placeholder: '',
+ value: '0'
+ },
+ {
+ type: 'el-input-text',
+ label: '图片地址',
+ name: 'imageAdress',
+ required: false,
+ placeholder: '',
+ value: 'http://pic.ik123.com/uploads/allimg/190813/12-1ZQ3095508.jpg',
+ },
+ {
+ type: 'vue-color',
+ label: '背景颜色',
+ name: 'background',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ // 数据
+ data: [],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 300,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ // {
+ // code: 'widget-slider',
+ // type: 'html',
+ // label: '轮播图片',
+ // icon: 'slider',
+ // options: {
+ // // 配置
+ // setup: [
+ // {
+ // type: 'el-input-text',
+ // label: '图层名称',
+ // name: 'layerName',
+ // required: false,
+ // placeholder: '',
+ // },
+ // {
+ // type: 'el-switch',
+ // label: '隐藏图层',
+ // name: 'hideLayer',
+ // required: false,
+ // placeholder: '',
+ // },
+ // {
+ // type: 'el-select',
+ // label: '轮播方向',
+ // name: 'tabDirection',
+ // required: false,
+ // placeholder: '',
+ // },
+ // {
+ // type: 'el-select',
+ // label: '选择器',
+ // name: 'tabSelector',
+ // required: false,
+ // placeholder: '',
+ // },
+ // {
+ // type: 'el-input-number',
+ // label: '轮播时间',
+ // name: 'tabTime',
+ // required: false,
+ // placeholder: '',
+ // },
+ // ],
+ // // 数据
+ // data: [],
+ // // 坐标
+ // position: [
+ // {
+ // type: 'el-input-number',
+ // label: '左边距',
+ // name: 'left',
+ // required: true,
+ // placeholder: 'px',
+ // },
+ // {
+ // type: 'el-input-number',
+ // label: '上边距',
+ // name: 'top',
+ // required: true,
+ // placeholder: 'px',
+ // },
+ // {
+ // type: 'el-input-number',
+ // label: '宽度',
+ // name: 'width',
+ // required: true,
+ // placeholder: '该容器在1920px大屏中的宽度',
+ // },
+ // {
+ // type: 'el-input-number',
+ // label: '高度',
+ // name: 'height',
+ // required: true,
+ // placeholder: '该容器在1080px大屏中的高度',
+ // },
+ // ],
+ // },
+ // },
+ {
+ code: 'widget-video',
+ type: 'html',
+ label: '视频',
+ icon: 'video',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: 'video',
+ },
+ {
+ type: 'el-input-text',
+ label: '地址',
+ name: 'videoAdress',
+ required: false,
+ placeholder: '',
+ value: 'https://www.w3school.com.cn//i/movie.ogg',
+ },
+ ],
+ // 数据
+ data: [],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 300,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ // {
+ // code: 'widget-table',
+ // type: 'html',
+ // label: '表格',
+ // icon: 'table',
+ // },
+ {
+ code: 'widget-iframe',
+ type: 'html',
+ label: '内联框架',
+ icon: 'iframe',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: 'iframe',
+ },
+ {
+ type: 'el-input-text',
+ label: '地址',
+ name: 'iframeAdress',
+ required: false,
+ placeholder: '',
+ value: 'http://www.baidu.com',
+ },
+ ],
+ // 数据
+ data: [],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 300,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ // {
+ // code: 'widget-universal',
+ // type: 'html',
+ // label: '全能组件',
+ // icon: 'univresal',
+ // },
+ // type=chart类型的组件
+ {
+ code: 'widget-barchart',
+ type: 'chart',
+ label: '柱形图',
+ icon: 'barChart',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '柱状图',
+ },
+ {
+ type: 'el-switch',
+ label: '竖展示',
+ name: 'verticalShow',
+ required: false,
+ placeholder: '',
+ value: false,
+ },
+ ],
+ // 折叠面板
+ collapse: [
+ {
+ name: '柱体设置',
+ list: [
+ {
+ type: 'el-slider',
+ label: '最大宽度',
+ name: 'maxWidth',
+ required: false,
+ placeholder: '',
+ value: 20,
+ },
+ {
+ type: 'el-slider',
+ label: '圆角',
+ name: 'radius',
+ require: false,
+ placeholder: '',
+ value: 8,
+ },
+ {
+ type: 'el-slider',
+ label: '最小高度',
+ name: 'minHeight',
+ require: false,
+ placeholder: '',
+ value: 20,
+ },
+ ],
+ },
+ {
+ name: '标题设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标题',
+ name: 'isNoTitle',
+ required: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'titleText',
+ required: false,
+ placeholder: '',
+ value: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'textColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'textFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'textFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体位置',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '副标题',
+ name: 'subText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'subTextFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'subTextFontSize',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: 'X轴设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '名称',
+ name: 'xName',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'hideX',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '坐标名颜色',
+ name: 'xNameColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'xNameFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-slider',
+ label: '文字角度',
+ name: 'textAngle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '文字间隔',
+ name: 'textInterval',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '轴反转',
+ name: 'reversalX',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '颜色',
+ name: 'Xcolor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字号',
+ name: 'fontSizeX',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ ],
+ },
+ {
+ name: 'Y轴设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '名称',
+ name: 'textNameY',
+ require: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShowY',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '坐标名颜色',
+ name: 'NameColorY',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'NameFontSizeY',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-switch',
+ label: '轴反转',
+ name: 'reversalY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '颜色',
+ name: 'colorY',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字号',
+ name: 'fontSizeY',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ ],
+ },
+ {
+ name: '数值设定',
+ list: [
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShow',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '提示语设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lineColor',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ }, {
+ name: '坐标轴边距设置',
+ list: [
+ {
+ type: 'el-slider',
+ label: '左边距(像素)',
+ name: 'marginLeft',
+ required: false,
+ placeholder: '',
+ value: 10,
+ }, {
+ type: 'el-slider',
+ label: '顶边距(像素)',
+ name: 'marginTop',
+ required: false,
+ placeholder: '',
+ value: 10,
+ }, {
+ type: 'el-slider',
+ label: '右边距(像素)',
+ name: 'marginRight',
+ required: false,
+ placeholder: '',
+ value: 10,
+ }, {
+ type: 'el-slider',
+ label: '底边距(像素)',
+ name: 'marginBottom',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ ],
+ }, {
+ name: '图例操作',
+ list: [
+ {
+ type: 'el-switch',
+ label: '图例',
+ name: 'isShowLegend',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lengedColor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'lengedFontSize',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '图例宽度',
+ name: 'lengedWidth',
+ required: false,
+ placeholder: '',
+ value: 15,
+ },
+ {
+ type: 'el-select',
+ label: '横向位置',
+ name: 'lateralPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '纵向位置',
+ name: 'longitudinalPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'bottom', name: '底部' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '布局前置',
+ name: 'layoutFront',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'vertical', name: '竖排' },
+ { code: 'horizontal', name: '横排' },
+ ],
+ },
+ ],
+ }, {
+ name: '自定义配色',
+ list: [
+ {
+ type: 'customColor',
+ label: '',
+ name: 'customColor',
+ required: false,
+ value: [{ color: '#ED0E0E' }, { color: '#6CCD17' }, { color: '#172CCD' }, { color: '#B817CD' }, { color: '#AFCD17' }],
+ },
+ ],
+ },
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '{"categories": ["苹果","三星","小米","oppo","vivo"],"series": [{"name": "手机品牌","data": [1000879,3400879,2300879,5400879,3400879]}]}',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'dynamicData',
+ chartType: 'widget-barchart',
+ value: '',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-linechart',
+ type: 'chart',
+ label: '折线图',
+ icon: 'lineChart',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '折线图',
+ },
+ ],
+ // 折叠面板
+ collapse: [
+ {
+ name: '折线设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标记点',
+ name: 'markPoint',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-slider',
+ label: '点大小',
+ name: 'pointSize',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-switch',
+ label: '平滑曲线',
+ name: 'smoothCurve',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-switch',
+ label: '面积堆积',
+ name: 'area',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-slider',
+ label: '面积厚度',
+ name: 'areaThickness',
+ required: false,
+ placeholder: '',
+ value: 5,
+ },
+ {
+ type: 'el-slider',
+ label: '线条宽度',
+ name: 'lineWidth',
+ required: false,
+ placeholder: '',
+ value: 4,
+ },
+ ],
+ },
+ {
+ name: '标题设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标题',
+ name: 'isNoTitle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'titleText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'textColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'textFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'textFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体位置',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '副标题',
+ name: 'subText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'subTextFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'subTextFontSize',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: 'X轴设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '名称',
+ name: 'xName',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'hideX',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '坐标名颜色',
+ name: 'xNameColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'xNameFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-slider',
+ label: '文字角度',
+ name: 'textAngle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '文字间隔',
+ name: 'textInterval',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '轴反转',
+ name: 'reversalX',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '颜色',
+ name: 'Xcolor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字号',
+ name: 'fontSizeX',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ ],
+ },
+ {
+ name: 'Y轴设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '名称',
+ name: 'textNameY',
+ require: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShowY',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '坐标名颜色',
+ name: 'NameColorY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'NameFontSizeY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '轴反转',
+ name: 'reversalY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '颜色',
+ name: 'colorY',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字号',
+ name: 'fontSizeY',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ ],
+ },
+ {
+ name: '数值设定',
+ list: [
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShow',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '提示语设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lineColor',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '坐标轴边距设置',
+ list: [
+ {
+ type: 'el-slider',
+ label: '左边距(像素)',
+ name: 'marginLeft',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-slider',
+ label: '顶边距(像素)',
+ name: 'marginTop',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-slider',
+ label: '右边距(像素)',
+ name: 'marginRight',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-slider',
+ label: '底边距(像素)',
+ name: 'marginBottom',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ ],
+ }, {
+ name: '图例操作',
+ list: [
+ {
+ type: 'el-switch',
+ label: '图例',
+ name: 'isShowLegend',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lengedColor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'lengedFontSize',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '图例宽度',
+ name: 'lengedWidth',
+ required: false,
+ placeholder: '',
+ value: 15,
+ },
+ {
+ type: 'el-select',
+ label: '横向位置',
+ name: 'lateralPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '纵向位置',
+ name: 'longitudinalPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'bottom', name: '底部' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '布局前置',
+ name: 'layoutFront',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'vertical', name: '竖排' },
+ { code: 'horizontal', name: '横排' },
+ ],
+ },
+ ],
+ }, {
+ name: '自定义配色',
+ list: [
+ {
+ type: 'customColor',
+ label: '',
+ name: 'customColor',
+ required: false,
+ value: [{ color: '#ED0E0E' }, { color: '#6CCD17' }, { color: '#172CCD' }, { color: '#B817CD' }, { color: '#AFCD17' }],
+ },
+ ],
+ },
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '{"categories": ["苹果","三星","小米","oppo","vivo"],"series": [{"name": "手机品牌","data": [1000879,3400879,2300879,5400879,3400879]}]}',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ chartType: 'widget-linechart',
+ relactiveDomValue: 'dynamicData',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-barlinechart',
+ type: 'chart',
+ label: '柱线图',
+ icon: 'barLineChart',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '柱线图',
+ },
+ ],
+ // 折叠面板
+ collapse: [
+ {
+ name: '折线设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标记点',
+ name: 'markPoint',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-slider',
+ label: '点大小',
+ name: 'pointSize',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-switch',
+ label: '平滑曲线',
+ name: 'smoothCurve',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-switch',
+ label: '面积堆积',
+ name: 'area',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-slider',
+ label: '面积厚度',
+ name: 'areaThickness',
+ required: false,
+ placeholder: '',
+ value: 5,
+ },
+ {
+ type: 'el-slider',
+ label: '线条宽度',
+ name: 'lineWidth',
+ required: false,
+ placeholder: '',
+ value: 4,
+ },
+ ],
+ }, {
+ name: '柱体设置',
+ list: [
+ {
+ type: 'el-slider',
+ label: '最大宽度',
+ name: 'maxWidth',
+ required: false,
+ placeholder: '',
+ value: 20,
+ },
+ {
+ type: 'el-slider',
+ label: '圆角',
+ name: 'radius',
+ require: false,
+ placeholder: '',
+ value: 8,
+ },
+ {
+ type: 'el-slider',
+ label: '最小高度',
+ name: 'minHeight',
+ require: false,
+ placeholder: '',
+ value: 20,
+ },
+ ],
+ }, {
+ name: '标题设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标题',
+ name: 'isNoTitle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'titleText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'textColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'textFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'textFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体位置',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '副标题',
+ name: 'subText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'subTextFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'subTextFontSize',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: 'X轴设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '名称',
+ name: 'xName',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'hideX',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '坐标名颜色',
+ name: 'xNameColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'xNameFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-slider',
+ label: '文字角度',
+ name: 'textAngle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '文字间隔',
+ name: 'textInterval',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '轴反转',
+ name: 'reversalX',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '颜色',
+ name: 'Xcolor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字号',
+ name: 'fontSizeX',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ ],
+ },
+ {
+ name: 'Y轴设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '名称',
+ name: 'textNameY',
+ require: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShowY',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '坐标名颜色',
+ name: 'NameColorY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'NameFontSizeY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '轴反转',
+ name: 'reversalY',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '颜色',
+ name: 'colorY',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字号',
+ name: 'fontSizeY',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ ],
+ },
+ {
+ name: '提示语设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lineColor',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ }, {
+ name: '坐标轴边距设置',
+ list: [
+ {
+ type: 'el-slider',
+ label: '左边距(像素)',
+ name: 'marginLeft',
+ required: false,
+ placeholder: '',
+ value: 10,
+ }, {
+ type: 'el-slider',
+ label: '顶边距(像素)',
+ name: 'marginTop',
+ required: false,
+ placeholder: '',
+ value: 10,
+ }, {
+ type: 'el-slider',
+ label: '右边距(像素)',
+ name: 'marginRight',
+ required: false,
+ placeholder: '',
+ value: 10,
+ }, {
+ type: 'el-slider',
+ label: '底边距(像素)',
+ name: 'marginBottom',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ ],
+ }, {
+ name: '图例操作',
+ list: [
+ {
+ type: 'el-switch',
+ label: '图例',
+ name: 'isShowLegend',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lengedColor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'lengedFontSize',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '图例宽度',
+ name: 'lengedWidth',
+ required: false,
+ placeholder: '',
+ value: 15,
+ },
+ {
+ type: 'el-select',
+ label: '横向位置',
+ name: 'lateralPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '纵向位置',
+ name: 'longitudinalPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'bottom', name: '底部' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '布局前置',
+ name: 'layoutFront',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'vertical', name: '竖排' },
+ { code: 'horizontal', name: '横排' },
+ ],
+ },
+ ],
+ }, {
+ name: '自定义配色',
+ list: [
+ {
+ type: 'customColor',
+ label: '',
+ name: 'customColor',
+ required: false,
+ value: [{ color: '#ED0E0E' }, { color: '#6CCD17' }],
+ },
+ ],
+ },
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '{"xAxis": ["1月", "2月", "3月", "4月", "5月","6月", "7月", "8月","9月","10月","11月","12月"],"series": [{"type": "bar","name": "货运量","data": [2.6,5.9,9,26.4,28.7,70.7,175.6,182.2,48.7,18.8,6,2.3]},{"type": "line","name": "货运总量","yAxisIndex": 1,"data": [2,2.2,3.3,4.5,6.3,10.2,20.3,23.4,23,16.5,12,6.2]}]}',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ chartType: 'widget-barlinechart',
+ relactiveDomValue: 'dynamicData',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-piechart',
+ type: 'chart',
+ label: '饼图',
+ icon: 'pieChart',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '饼图',
+ },
+ ],
+ // 折叠面板
+ collapse: [
+ {
+ name: '标题设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标题',
+ name: 'isNoTitle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'titleText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'textColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'textFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'textFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体位置',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '副标题',
+ name: 'subText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'subTextFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'subTextFontSize',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '数值设定',
+ list: [
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShow',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-switch',
+ label: '数值',
+ name: 'numberValue',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-switch',
+ label: '百分比',
+ name: 'percentage',
+ require: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ value: 14,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '提示语设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '网格线颜色',
+ name: 'lineColor',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '图例操作',
+ list: [
+ {
+ type: 'el-switch',
+ label: '图例',
+ name: 'isShowLegend',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lengedColor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'lengedFontSize',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '图例宽度',
+ name: 'lengedWidth',
+ required: false,
+ placeholder: '',
+ value: 15,
+ },
+ {
+ type: 'el-select',
+ label: '横向位置',
+ name: 'lateralPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '纵向位置',
+ name: 'longitudinalPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'bottom', name: '底部' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '布局前置',
+ name: 'layoutFront',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'vertical', name: '竖排' },
+ { code: 'horizontal', name: '横排' },
+ ],
+ },
+ ],
+ },
+ {
+ name: '自定义配色',
+ list: [
+ {
+ type: 'customColor',
+ label: '',
+ name: 'customColor',
+ required: false,
+ value: [{ color: '#ED0E0E' }, { color: '#6CCD17' }, { color: '#172CCD' }, { color: '#B817CD' }, { color: '#AFCD17' }],
+ },
+ ],
+ },
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '[{"value": 1048,"name": "搜索引擎"},{"value": 735, "name": "直接访问"},{"value": 580, "name": "邮件营销"},{"value": 484,"name":"联盟广告"},{"value":300,"name":"视频广告"}]',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ chartType: 'widget-piechart',
+ relactiveDomValue: 'dynamicData',
+ value: '',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-hollow-piechart',
+ type: 'chart',
+ label: '空心饼图',
+ icon: 'hollowPieChart',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '空心饼图',
+ },
+ ],
+ // 折叠面板
+ collapse: [
+ {
+ name: '标题设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标题',
+ name: 'isNoTitle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'titleText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'textColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'textFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'textFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体位置',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '副标题',
+ name: 'subText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'subTextFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'subTextFontSize',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '数值设定',
+ list: [
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShow',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-switch',
+ label: '数值',
+ name: 'numberValue',
+ require: false,
+ placeholder: '',
+ value: false,
+ },
+ {
+ type: 'el-switch',
+ label: '百分比',
+ name: 'percentage',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'fontWeight',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '提示语设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '网格线颜色',
+ name: 'lineColor',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '图例操作',
+ list: [
+ {
+ type: 'el-switch',
+ label: '图例',
+ name: 'isShowLegend',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lengedColor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'lengedFontSize',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '图例宽度',
+ name: 'lengedWidth',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-select',
+ label: '横向位置',
+ name: 'lateralPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '纵向位置',
+ name: 'longitudinalPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'bottom', name: '底部' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '布局前置',
+ name: 'layoutFront',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'vertical', name: '竖排' },
+ { code: 'horizontal', name: '横排' },
+ ],
+ },
+ ],
+ },
+ {
+ name: '自定义配色',
+ list: [
+ {
+ type: 'customColor',
+ label: '',
+ name: 'customColor',
+ required: false,
+ value: [{ color: '#ED0E0E' }, { color: '#6CCD17' }, { color: '#172CCD' }, { color: '#B817CD' }, { color: '#AFCD17' }],
+ },
+ ],
+ },
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '[{"value": 1048,"name": "搜索引擎"},{"value": 735, "name": "直接访问"},{"value": 580, "name": "邮件营销"},{"value": 484,"name":"联盟广告"},{"value":300,"name":"视频广告"}]',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ chartType: 'widget-hollow-piechart',
+ relactiveDomValue: 'dynamicData',
+ value: '',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-funnel',
+ type: 'chart',
+ label: '漏斗图',
+ icon: 'funnel',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '漏斗图',
+ },
+ ],
+ // 折叠面板
+ collapse: [
+ {
+ name: '文字设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '显示',
+ name: 'isShow',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'fontSize',
+ require: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'color',
+ require: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'fontWeight',
+ require: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-switch',
+ label: '反转',
+ name: 'reversal',
+ require: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '标题设置',
+ list: [
+ {
+ type: 'el-switch',
+ label: '标题',
+ name: 'isNoTitle',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '标题',
+ name: 'titleText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'textColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'textFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'textFontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体位置',
+ name: 'textAlign',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '副标题',
+ name: 'subText',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'subTextColor',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体粗细',
+ name: 'subTextFontWeight',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'el-input-number',
+ label: '字体大小',
+ name: 'subTextFontSize',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '提示语设置',
+ list: [
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'fontSize',
+ required: false,
+ placeholder: '',
+ },
+ {
+ type: 'vue-color',
+ label: '网格线颜色',
+ name: 'lineColor',
+ required: false,
+ placeholder: '',
+ },
+ ],
+ },
+ {
+ name: '图例操作',
+ list: [
+ {
+ type: 'el-switch',
+ label: '图例',
+ name: 'isShowLegend',
+ required: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'vue-color',
+ label: '字体颜色',
+ name: 'lengedColor',
+ required: false,
+ placeholder: '',
+ value: '#fff',
+ },
+ {
+ type: 'el-input-text',
+ label: '字体大小',
+ name: 'lengedFontSize',
+ required: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '图例宽度',
+ name: 'lengedWidth',
+ required: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-select',
+ label: '横向位置',
+ name: 'lateralPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'left', name: '左对齐' },
+ { code: 'right', name: '右对齐' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '纵向位置',
+ name: 'longitudinalPosition',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'top', name: '顶部' },
+ { code: 'bottom', name: '底部' },
+ ],
+ },
+ {
+ type: 'el-select',
+ label: '布局前置',
+ name: 'layoutFront',
+ required: false,
+ placeholder: '',
+ selectOptions: [
+ { code: 'vertical', name: '竖排' },
+ { code: 'horizontal', name: '横排' },
+ ],
+ },
+ ],
+ },
+ {
+ name: '自定义配色',
+ list: [
+ {
+ type: 'customColor',
+ label: '',
+ name: 'customColor',
+ required: false,
+ value: [{ color: '#ED0E0E' }, { color: '#6CCD17' }, { color: '#172CCD' }, { color: '#B817CD' }, { color: '#AFCD17' }],
+ },
+ ],
+ },
+ ],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '[{"value": 60,"name": "访问"},{"value": 40, "name": "咨询"},{"value": 20, "name": "订单"},{"value": 80,"name":"点击"},{"value":100,"name":"展现"}]',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ chartType: 'widget-funnel',
+ relactiveDomValue: 'dynamicData',
+ value: '',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ {
+ code: 'widget-gauge',
+ type: 'chart',
+ label: '仪表盘',
+ icon: 'speed',
+ options: {
+ // 配置
+ setup: [
+ {
+ type: 'el-input-text',
+ label: '图层名称',
+ name: 'layerName',
+ required: false,
+ placeholder: '',
+ value: '仪表盘',
+ },
+ {
+ type: 'el-input-number',
+ label: '刻度线粗度',
+ name: 'tickMarkWeight',
+ require: false,
+ placeholder: '',
+ value: 10,
+ },
+ {
+ type: 'el-switch',
+ label: '显示刻度值',
+ name: 'showScaleValue',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-switch',
+ label: '显示刻度线',
+ name: 'showTickMarks',
+ require: false,
+ placeholder: '',
+ value: true,
+ },
+ {
+ type: 'el-input-number',
+ label: '刻度字号',
+ name: 'scaleFontSize',
+ require: false,
+ placeholder: '',
+ value: 16,
+ },
+ {
+ type: 'el-input-number',
+ label: '指标字号',
+ name: 'targetFontSize',
+ require: false,
+ placeholder: '',
+ value: 20,
+ },
+ ],
+ // 折叠面板
+ collapse: [],
+ // 数据
+ data: [
+ {
+ type: 'el-radio-group',
+ label: '数据类型',
+ name: 'dataType',
+ require: false,
+ placeholder: '',
+ selectValue: true,
+ selectOptions: [
+ {
+ code: 'staticData',
+ name: '静态数据',
+ },
+ {
+ code: 'dynamicData',
+ name: '动态数据',
+ },
+ ],
+ value: 'staticData',
+ },
+ {
+ type: 'el-button',
+ label: '静态数据',
+ name: 'staticData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ relactiveDomValue: 'staticData',
+ value: '{"value": 50, "name": "名称", "unit": "%"}',
+ },
+ {
+ type: 'dycustComponents',
+ label: '',
+ name: 'dynamicData',
+ required: false,
+ placeholder: 'px',
+ relactiveDom: 'dataType',
+ chartType: 'widget-gauge',
+ relactiveDomValue: 'dynamicData',
+ value: '',
+ },
+ ],
+ // 坐标
+ position: [
+ {
+ type: 'el-input-number',
+ label: '左边距',
+ name: 'left',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '上边距',
+ name: 'top',
+ required: false,
+ placeholder: 'px',
+ value: 0,
+ },
+ {
+ type: 'el-input-number',
+ label: '宽度',
+ name: 'width',
+ required: false,
+ placeholder: '该容器在1920px大屏中的宽度',
+ value: 400,
+ },
+ {
+ type: 'el-input-number',
+ label: '高度',
+ name: 'height',
+ required: false,
+ placeholder: '该容器在1080px大屏中的高度',
+ value: 200,
+ },
+ ],
+ },
+ },
+ // {
+ // code: 'widget-china-map',
+ // type: 'chart',
+ // label: '中国地图',
+ // icon: 'chinaMapChart',
+ // },
+]
+
+const getToolByCode = function(code) {
+ // 获取大屏底层设置属性
+ if (code == 'screen') {
+ return screenConfig
+ }
+ // 获取组件
+ var item = widgetTools.find(function(item, index, arrs) {
+ return item.code === code
+ })
+ return item
+}
+
+export { widgetTools, getToolByCode }
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/temp.vue b/report-ui/src/views/report/bigscreen/designer/widget/temp.vue
new file mode 100644
index 00000000..5b7b5d3a
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/temp.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widget.vue b/report-ui/src/views/report/bigscreen/designer/widget/widget.vue
new file mode 100644
index 00000000..5df3721d
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widget.vue
@@ -0,0 +1,154 @@
+
+
+
+
+ onDragstop(ev, index)"
+ @resizing="(ev) => onResizing(ev, index)"
+ >
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetBarchart.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetBarchart.vue
new file mode 100644
index 00000000..f4d7b2f7
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetBarchart.vue
@@ -0,0 +1,323 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetBarlinechart.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetBarlinechart.vue
new file mode 100644
index 00000000..8db50ba4
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetBarlinechart.vue
@@ -0,0 +1,382 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetFunnel.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetFunnel.vue
new file mode 100644
index 00000000..5b58ef1b
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetFunnel.vue
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetGauge.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetGauge.vue
new file mode 100644
index 00000000..e4aa13d5
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetGauge.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetHollowPiechart.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetHollowPiechart.vue
new file mode 100644
index 00000000..4bedb578
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetHollowPiechart.vue
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetHref.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetHref.vue
new file mode 100644
index 00000000..5c7a04a8
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetHref.vue
@@ -0,0 +1,71 @@
+
+
+ {{ styleColor.text }}
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetIframe.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetIframe.vue
new file mode 100644
index 00000000..6bd2fb84
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetIframe.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetImage.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetImage.vue
new file mode 100644
index 00000000..1abf8667
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetImage.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetLinechart.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetLinechart.vue
new file mode 100644
index 00000000..0dacec38
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetLinechart.vue
@@ -0,0 +1,306 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetMarquee.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetMarquee.vue
new file mode 100644
index 00000000..89d18123
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetMarquee.vue
@@ -0,0 +1,69 @@
+
+
+ {{ styleColor.text }}
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetPiechart.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetPiechart.vue
new file mode 100644
index 00000000..4e4c129b
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetPiechart.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetSlider.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetSlider.vue
new file mode 100644
index 00000000..e085c0d2
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetSlider.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetText.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetText.vue
new file mode 100644
index 00000000..9e1e8dd7
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetText.vue
@@ -0,0 +1,67 @@
+
+
+ {{ styleColor.text }}
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetTime.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetTime.vue
new file mode 100644
index 00000000..eb25f205
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetTime.vue
@@ -0,0 +1,99 @@
+
+ {{ timestr }}
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/designer/widget/widgetVideo.vue b/report-ui/src/views/report/bigscreen/designer/widget/widgetVideo.vue
new file mode 100644
index 00000000..d416eff2
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/designer/widget/widgetVideo.vue
@@ -0,0 +1,60 @@
+
+ 您的浏览器不支持 video 标签。
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/index.vue b/report-ui/src/views/report/bigscreen/index.vue
new file mode 100644
index 00000000..991b5190
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/index.vue
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+ {{ item.time }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/bigscreen/viewer/index.vue b/report-ui/src/views/report/bigscreen/viewer/index.vue
new file mode 100644
index 00000000..6330ad9a
--- /dev/null
+++ b/report-ui/src/views/report/bigscreen/viewer/index.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/datasource/index.vue b/report-ui/src/views/report/datasource/index.vue
new file mode 100644
index 00000000..a13867c3
--- /dev/null
+++ b/report-ui/src/views/report/datasource/index.vue
@@ -0,0 +1,411 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/excelreport/designer/drag.js b/report-ui/src/views/report/excelreport/designer/drag.js
new file mode 100644
index 00000000..71355c4c
--- /dev/null
+++ b/report-ui/src/views/report/excelreport/designer/drag.js
@@ -0,0 +1,175 @@
+import Vue from 'vue'
+Vue.directive('dragx', (el, binding, vnode) => {
+ // 默认参数
+ let defaultOpts = {
+ dragDirection: 'n, e, s, w, ne, se, sw, nw, all', // 东 e 西 w 南 s 北 n 东北ne 东南 se 西南 sw 西北 nw 全部 all
+ dragContainerId: '',
+ dragBarClass: '', // 类选择器
+ resizeEdge: 10,
+ dirctDom: true,
+ canDrag: true,
+ canResize: true
+ }
+ let isMove = false;
+ binding.value = binding.value || {};
+ let cfg = Object.assign({}, defaultOpts, binding.value);
+
+ // 获取目标元素 resize方向
+ function getDirection (e) {
+ let el = e.currentTarget;
+ let dir = '';
+ let rect = el.getBoundingClientRect();
+ let win = el.ownerDocument.defaultView;
+ let offset = {
+ top: rect.top + win.pageYOffset,
+ left: rect.left + win.pageXOffset,
+ right: rect.right + win.pageXOffset,
+ bottom: rect.bottom + win.pageYOffset,
+ }
+ // 东 E 西 W 南 S 北 N
+ if (e.pageY > offset.top && e.pageY < offset.top + cfg.resizeEdge) {
+ dir += 'n'
+ }
+ else if (e.pageY < offset.bottom && e.pageY > offset.bottom - cfg.resizeEdge) {
+ dir += 's'
+ }
+ if (e.pageX > offset.left && e.pageX < offset.left + cfg.resizeEdge) {
+ dir += 'w';
+ }
+ else if (e.pageX < offset.right && e.pageX > offset.right - cfg.resizeEdge) {
+ dir += 'e';
+ }
+ if (binding.value) {
+ let directions = cfg.dragDirection.split(',');
+ for (let i = 0; i < directions.length; i++) {
+ let handle = directions[i].replace(/(^\s*)|(\s*$)/g, '');
+ if (handle == 'all' || handle === dir) {
+ return dir
+ }
+ }
+ }
+ return '';
+ }
+
+ el.onmousedown = function (e) {
+ isMove = false;
+ // drag1
+ if (cfg.dragBarClass.length > 0 && e.target.classList.contains(cfg.dragBarClass)) {
+ isMove = true;
+ document.body.style.cursor = 'move';
+ }
+ let dir = getDirection(e);
+ let style = window.getComputedStyle(el);
+ function getStyleNumValue (key) {
+ return parseInt(style.getPropertyValue(key), 10)
+ }
+ let rect = el.getBoundingClientRect();
+ let data = {
+ width: getStyleNumValue("width"),
+ height: getStyleNumValue("height"),
+ left: getStyleNumValue("left"),
+ top: getStyleNumValue("top"),
+ borderLeft: getStyleNumValue("border-left-width"),
+ borderTop: getStyleNumValue("border-top-width"),
+ borderRight: getStyleNumValue("border-right-width"),
+ borderBottom: getStyleNumValue("border-bottom-width"),
+ deltX: e.pageX - rect.left, // 鼠标在元素内位置
+ deltY: e.pageY - rect.top,
+ startX: rect.left, // 元素的位置
+ startY: rect.top
+ };
+ if (dir === '' && !isMove) return;
+ // 创建遮罩
+ let mask = document.createElement("div");
+ mask.style.cssText = "position:absolute;top:0px;bottom:0px;left:0px;right:0px;";
+ document.body.appendChild(mask);
+ document.onmousemove = function (edom) {
+ // 获取当前鼠标位置
+ // 右
+ if (dir.indexOf("e") > -1) {
+ data.width = edom.pageX - data.startX + data.borderLeft + data.borderRight;
+ }
+ // 下
+ if (dir.indexOf("s") > -1) {
+ data.height = edom.pageY - data.startY + data.borderBottom + data.borderTop;
+ }
+ // 上
+ if (dir.indexOf("n") > -1) {
+ let deltheight = data.startY + data.borderBottom + data.borderTop - edom.pageY;
+ data.height += deltheight;
+ data.top -= deltheight;
+ data.startY -= deltheight;
+ }
+ // 左
+ if (dir.indexOf("w") > -1) {
+ let deltwidth = data.startX + data.borderLeft + data.borderRight - edom.pageX;
+ data.width += deltwidth;
+ data.left -= deltwidth;
+ data.startX -= deltwidth;
+ }
+ // 移动
+ if (isMove && cfg.canDrag) {
+ let targetPageX = edom.pageX;
+ let targetPageY = edom.pageY;
+ let deltX = targetPageX - data.startX - data.deltX;
+ let deltY = targetPageY - data.startY - data.deltY;
+ let newLeft = parseInt(getStyleNumValue('left') || '0', 10) + deltX;
+ let newTop = parseInt(getStyleNumValue('top') || '0', 10) + deltY;
+ console.log(window.innerWidth + data.borderLeft + data.borderRight - data.width - cfg.resizeEdge)
+ if (newLeft <= 0) {
+ newLeft = 0
+ }
+ else if (newLeft >= window.innerWidth - data.width - cfg.resizeEdge) {
+ newLeft = window.innerWidth - data.width - cfg.resizeEdge
+ }
+ if (newTop <= 0) {
+ newTop = 0
+ }
+ else if (newTop >= window.innerHeight - data.height - cfg.resizeEdge) {
+ newLeft = window.innerHeight - data.height - cfg.resizeEdge
+ }
+ data.left = newLeft;
+ data.top = newTop;
+ data.startX = data.startX + deltX;
+ data.startY = data.startY + deltY;
+ }
+ // 缩放
+ if (cfg.dirctDom) {
+ if (cfg.canResize) {
+ el.style.width = data.width + "px";
+ el.style.height = data.height + "px";
+ }
+ if (cfg.canDrag) {
+ el.style.left = data.left + 'px';
+ el.style.top = data.top + 'px';
+ }
+ }
+ el.dispatchEvent(new CustomEvent('bindUpdate', { detail: data }))
+ }
+ document.onmouseup = function (e) {
+ document.body.style.cursor = '';
+ document.onmousemove = null;
+ document.onmouseup = null;
+ isMove = false;
+ document.body.removeChild(mask);
+ }
+ document.body.style.cursor = dir + '-resize';
+ }
+
+ el.onmousemove = function (e) {
+ if (cfg.dragBarClass.length > 0 && e.target.classList.contains(cfg.dragBarClass) && cfg.canDrag) {
+ el.style.cursor = 'move';
+ return;
+ }
+ let dir = getDirection(e);
+ if (dir !== '') {
+ el.style.cursor = dir + '-resize';
+ return;
+ }
+ el.style.cursor = '';
+ }
+
+ el.onmouseleave = function (e) {
+ el.style.cursor = '';
+ }
+})
diff --git a/report-ui/src/views/report/excelreport/designer/index-copy.vue b/report-ui/src/views/report/excelreport/designer/index-copy.vue
new file mode 100644
index 00000000..364e05be
--- /dev/null
+++ b/report-ui/src/views/report/excelreport/designer/index-copy.vue
@@ -0,0 +1,861 @@
+
+
+
+
+
+ 数据集管理
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ changed(val,qrCodeForm.colorDark)" />
+
+
+ changed(val,qrCodeForm.colorLight)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ changed(val,barCodeForm.lineColor)" />
+
+
+ changed(val,barCodeForm.background)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/excelreport/designer/index.vue b/report-ui/src/views/report/excelreport/designer/index.vue
new file mode 100644
index 00000000..64f27e65
--- /dev/null
+++ b/report-ui/src/views/report/excelreport/designer/index.vue
@@ -0,0 +1,821 @@
+
+
+
+
+
+ 数据集管理
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ changed(val,qrCodeForm.colorDark)" />
+
+
+ changed(val,qrCodeForm.colorLight)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ changed(val,barCodeForm.lineColor)" />
+
+
+ changed(val,barCodeForm.background)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/excelreport/index.vue b/report-ui/src/views/report/excelreport/index.vue
new file mode 100644
index 00000000..66d98ba2
--- /dev/null
+++ b/report-ui/src/views/report/excelreport/index.vue
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
{{ groupItem.groupName }}
+
+
{{ report.reportName }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/excelreport/viewer/index.vue b/report-ui/src/views/report/excelreport/viewer/index.vue
new file mode 100644
index 00000000..5ebc7136
--- /dev/null
+++ b/report-ui/src/views/report/excelreport/viewer/index.vue
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+ 表格查询
+
+
{{ item.name }}
+
+ {{ son.name }}:
+
+
+
+ 查询
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/report/index.vue b/report-ui/src/views/report/report/index.vue
new file mode 100644
index 00000000..e327d4fb
--- /dev/null
+++ b/report-ui/src/views/report/report/index.vue
@@ -0,0 +1,409 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
新增
+
+
+
+
+
+
+ {{scope.row.reportType | reportTableType}}
+
+
+
+
+
+
+ {{scope.row.reportGroup | filterPushType}}
+
+
+
+
+
+
+
+
+
+ 预览
+ 设计
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/src/views/report/resultset/index.vue b/report-ui/src/views/report/resultset/index.vue
new file mode 100644
index 00000000..6ffece5e
--- /dev/null
+++ b/report-ui/src/views/report/resultset/index.vue
@@ -0,0 +1,966 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+ 查看
+
+
+
+
+
+
+
+
+ 编辑
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 必选
+ 高级规则
+
+
+
+
+ 加入分页参数
+
+
+
+
+
+
+
+
+
+
+ 字典项名称:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
新增
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/report-ui/static/Crane.png b/report-ui/static/Crane.png
new file mode 100644
index 00000000..93608590
Binary files /dev/null and b/report-ui/static/Crane.png differ
diff --git a/report-ui/static/__MACOSX/._背景 2.mp4 b/report-ui/static/__MACOSX/._背景 2.mp4
new file mode 100644
index 00000000..3c5cc1bc
Binary files /dev/null and b/report-ui/static/__MACOSX/._背景 2.mp4 differ
diff --git a/report-ui/static/bg_01.jpg b/report-ui/static/bg_01.jpg
new file mode 100644
index 00000000..979f6b1d
Binary files /dev/null and b/report-ui/static/bg_01.jpg differ
diff --git a/report-ui/static/bianzu.png b/report-ui/static/bianzu.png
new file mode 100644
index 00000000..f050534e
Binary files /dev/null and b/report-ui/static/bianzu.png differ
diff --git a/report-ui/static/daiqueren.png b/report-ui/static/daiqueren.png
new file mode 100644
index 00000000..b427be22
Binary files /dev/null and b/report-ui/static/daiqueren.png differ
diff --git a/report-ui/static/difengxian.png b/report-ui/static/difengxian.png
new file mode 100644
index 00000000..aabfc0ca
Binary files /dev/null and b/report-ui/static/difengxian.png differ
diff --git a/report-ui/static/es.png b/report-ui/static/es.png
new file mode 100644
index 00000000..5518031f
Binary files /dev/null and b/report-ui/static/es.png differ
diff --git a/report-ui/static/fanghuoqiang.png b/report-ui/static/fanghuoqiang.png
new file mode 100644
index 00000000..2b791016
Binary files /dev/null and b/report-ui/static/fanghuoqiang.png differ
diff --git a/report-ui/static/favicon-aj.ico b/report-ui/static/favicon-aj.ico
new file mode 100644
index 00000000..0974d853
Binary files /dev/null and b/report-ui/static/favicon-aj.ico differ
diff --git a/report-ui/static/favicon.ico b/report-ui/static/favicon.ico
new file mode 100644
index 00000000..1f80c113
Binary files /dev/null and b/report-ui/static/favicon.ico differ
diff --git a/report-ui/static/gaofengxian.png b/report-ui/static/gaofengxian.png
new file mode 100644
index 00000000..d28b4981
Binary files /dev/null and b/report-ui/static/gaofengxian.png differ
diff --git a/report-ui/static/header.png b/report-ui/static/header.png
new file mode 100644
index 00000000..d2d94f1a
Binary files /dev/null and b/report-ui/static/header.png differ
diff --git a/report-ui/static/header01.jpg b/report-ui/static/header01.jpg
new file mode 100644
index 00000000..b237744a
Binary files /dev/null and b/report-ui/static/header01.jpg differ
diff --git a/report-ui/static/htlogo.png b/report-ui/static/htlogo.png
new file mode 100644
index 00000000..6b09b30c
Binary files /dev/null and b/report-ui/static/htlogo.png differ
diff --git a/report-ui/static/htname.png b/report-ui/static/htname.png
new file mode 100644
index 00000000..76d88818
Binary files /dev/null and b/report-ui/static/htname.png differ
diff --git a/report-ui/static/iconsheji-.png b/report-ui/static/iconsheji-.png
new file mode 100644
index 00000000..a6fc49c4
Binary files /dev/null and b/report-ui/static/iconsheji-.png differ
diff --git a/report-ui/static/iconsheji-2.png b/report-ui/static/iconsheji-2.png
new file mode 100644
index 00000000..914a455f
Binary files /dev/null and b/report-ui/static/iconsheji-2.png differ
diff --git a/report-ui/static/index-bottom-left.png b/report-ui/static/index-bottom-left.png
new file mode 100644
index 00000000..edec1b23
Binary files /dev/null and b/report-ui/static/index-bottom-left.png differ
diff --git a/report-ui/static/index-bottom-right.png b/report-ui/static/index-bottom-right.png
new file mode 100644
index 00000000..ea512a6b
Binary files /dev/null and b/report-ui/static/index-bottom-right.png differ
diff --git a/report-ui/static/index-center.png b/report-ui/static/index-center.png
new file mode 100644
index 00000000..3f080e9a
Binary files /dev/null and b/report-ui/static/index-center.png differ
diff --git a/report-ui/static/index-top-left.png b/report-ui/static/index-top-left.png
new file mode 100644
index 00000000..9e1f8cdc
Binary files /dev/null and b/report-ui/static/index-top-left.png differ
diff --git a/report-ui/static/index-top-right.png b/report-ui/static/index-top-right.png
new file mode 100644
index 00000000..f0d9f03a
Binary files /dev/null and b/report-ui/static/index-top-right.png differ
diff --git a/report-ui/static/jiaohuanji.png b/report-ui/static/jiaohuanji.png
new file mode 100644
index 00000000..b229c51e
Binary files /dev/null and b/report-ui/static/jiaohuanji.png differ
diff --git a/report-ui/static/left.png b/report-ui/static/left.png
new file mode 100644
index 00000000..d622ea55
Binary files /dev/null and b/report-ui/static/left.png differ
diff --git a/report-ui/static/login_box.png b/report-ui/static/login_box.png
new file mode 100644
index 00000000..313d45ed
Binary files /dev/null and b/report-ui/static/login_box.png differ
diff --git a/report-ui/static/logo-dp.png b/report-ui/static/logo-dp.png
new file mode 100644
index 00000000..90788c4b
Binary files /dev/null and b/report-ui/static/logo-dp.png differ
diff --git a/report-ui/static/logo.png b/report-ui/static/logo.png
new file mode 100644
index 00000000..705212cc
Binary files /dev/null and b/report-ui/static/logo.png differ
diff --git a/report-ui/static/logo1.png b/report-ui/static/logo1.png
new file mode 100644
index 00000000..b48d8a5e
Binary files /dev/null and b/report-ui/static/logo1.png differ
diff --git a/report-ui/static/luyouqi.png b/report-ui/static/luyouqi.png
new file mode 100644
index 00000000..93c8b069
Binary files /dev/null and b/report-ui/static/luyouqi.png differ
diff --git a/report-ui/static/no.png b/report-ui/static/no.png
new file mode 100644
index 00000000..db01abc8
Binary files /dev/null and b/report-ui/static/no.png differ
diff --git a/report-ui/static/ocean.png b/report-ui/static/ocean.png
new file mode 100644
index 00000000..22a92d63
Binary files /dev/null and b/report-ui/static/ocean.png differ
diff --git a/report-ui/static/right.png b/report-ui/static/right.png
new file mode 100644
index 00000000..35921224
Binary files /dev/null and b/report-ui/static/right.png differ
diff --git a/report-ui/static/shebei.png b/report-ui/static/shebei.png
new file mode 100644
index 00000000..9595424a
Binary files /dev/null and b/report-ui/static/shebei.png differ
diff --git a/report-ui/static/shijianxuanze.png b/report-ui/static/shijianxuanze.png
new file mode 100644
index 00000000..773a4b58
Binary files /dev/null and b/report-ui/static/shijianxuanze.png differ
diff --git a/report-ui/static/ship.png b/report-ui/static/ship.png
new file mode 100644
index 00000000..591c9ea0
Binary files /dev/null and b/report-ui/static/ship.png differ
diff --git a/report-ui/static/timg.jpg b/report-ui/static/timg.jpg
new file mode 100644
index 00000000..c530bf5a
Binary files /dev/null and b/report-ui/static/timg.jpg differ
diff --git a/report-ui/static/title.png b/report-ui/static/title.png
new file mode 100644
index 00000000..fd118d01
Binary files /dev/null and b/report-ui/static/title.png differ
diff --git a/report-ui/static/tuichu.png b/report-ui/static/tuichu.png
new file mode 100644
index 00000000..07edd82c
Binary files /dev/null and b/report-ui/static/tuichu.png differ
diff --git a/report-ui/static/wuxian.png b/report-ui/static/wuxian.png
new file mode 100644
index 00000000..3e75753a
Binary files /dev/null and b/report-ui/static/wuxian.png differ
diff --git a/report-ui/static/youyi.png b/report-ui/static/youyi.png
new file mode 100644
index 00000000..66e8aafd
Binary files /dev/null and b/report-ui/static/youyi.png differ
diff --git a/report-ui/static/zhexian.png b/report-ui/static/zhexian.png
new file mode 100644
index 00000000..8b8fa9ae
Binary files /dev/null and b/report-ui/static/zhexian.png differ
diff --git a/report-ui/static/zhongfengxian.png b/report-ui/static/zhongfengxian.png
new file mode 100644
index 00000000..9ddb954b
Binary files /dev/null and b/report-ui/static/zhongfengxian.png differ