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

+ +
+
+
    + +
  • + +
    返回
    +
    &#xe63b;
    +
  • + +
  • + +
    下载
    +
    &#xe639;
    +
  • + +
  • + +
    下载
    +
    &#xe784;
    +
  • + +
  • + +
    邮箱
    +
    &#xe769;
    +
  • + +
  • + +
    绑定手机
    +
    &#xe64d;
    +
  • + +
  • + +
    手机
    +
    &#xe854;
    +
  • + +
  • + +
    52-手机
    +
    &#xe871;
    +
  • + +
  • + +
    home
    +
    &#xe610;
    +
  • + +
  • + +
    home
    +
    &#xe61a;
    +
  • + +
  • + +
    Kafka
    +
    &#xe65a;
    +
  • + +
  • + +
    数据接入—Kafka集群
    +
    &#xe64f;
    +
  • + +
  • + +
    kafka
    +
    &#xe6f2;
    +
  • + +
  • + +
    elasticsearch-Elasticsearch
    +
    &#xe853;
    +
  • + +
  • +  +
    apachekafka
    +
    &#xeb3f;
    +
  • + +
  • + +
    elasticsearch
    +
    &#xeb85;
    +
  • + +
  • + +
    问题反馈
    +
    &#xe8d1;
    +
  • + +
  • + +
    问题反馈
    +
    &#xe70e;
    +
  • + +
  • + +
    问题反馈
    +
    &#xe643;
    +
  • + +
  • + +
    alikafka 消息队列Kafka
    +
    &#xe8a4;
    +
  • + +
  • + +
    项目查询-查看设备
    +
    &#xe682;
    +
  • + +
  • + +
    elasticsearch Elasticsearch
    +
    &#xe6a1;
    +
  • + +
  • + +
    511统计_树图
    +
    &#xe64a;
    +
  • + +
  • + +
    分享
    +
    &#xe615;
    +
  • + +
  • + +
    分享
    +
    &#xe60f;
    +
  • + +
  • + +
    分享
    +
    &#xe600;
    +
  • + +
  • + +
    告警-紧急
    +
    &#xe628;
    +
  • + +
  • + +
    完成安全事件
    +
    &#xe68a;
    +
  • + +
  • + +
    eventbridge 消息事件总线
    +
    &#xe74d;
    +
  • + +
  • + +
    +
    &#xe629;
    +
  • + +
  • + +
    设备关机
    +
    &#xe61d;
    +
  • + +
  • + +
    好房拓 4.0.0 iconfont_短信
    +
    &#xe6d8;
    +
  • + +
  • + +
    业务参数
    +
    &#xe661;
    +
  • + +
  • + +
    列表
    +
    &#xe660;
    +
  • + +
  • + +
    编辑
    +
    &#xe60c;
    +
  • + +
  • + +
    邮件
    +
    &#xe63a;
    +
  • + +
  • + +
    社交钉钉
    +
    &#xe678;
    +
  • + +
  • + +
    字典管理
    +
    &#xe624;
    +
  • + +
  • + +
    图表
    +
    &#xe73f;
    +
  • + +
  • + +
    钉钉
    +
    &#xe690;
    +
  • + +
  • + +
    短信
    +
    &#xe603;
    +
  • + +
  • + +
    directmail 邮件推送
    +
    &#xe714;
    +
  • + +
  • + +
    设备设施
    +
    &#xe61c;
    +
  • + +
  • + +
    通知
    +
    &#xe606;
    +
  • + +
  • + +
    日志
    +
    &#xe663;
    +
  • + +
  • + +
    触发器配置-灰
    +
    &#xe689;
    +
  • + +
  • + +
    vcs 视觉计算服务
    +
    &#xe759;
    +
  • + +
  • + +
    设备
    +
    &#xe60a;
    +
  • + +
  • + +
    user-before
    +
    &#xe617;
    +
  • + +
  • + +
    科目维护图标
    +
    &#xe60b;
    +
  • + +
  • + +
    会计科目维护
    +
    &#xe677;
    +
  • + +
  • + +
    成本查询
    +
    &#xe6dd;
    +
  • + +
  • + +
    成本数据管理
    +
    &#xe6c7;
    +
  • + +
  • + +
    基本数据
    +
    &#xe71d;
    +
  • + +
  • + +
    B-省市区
    +
    &#xe72d;
    +
  • + +
  • + +
    组织机构
    +
    &#xe66e;
    +
  • + +
  • + +
    按钮
    +
    &#xe8c5;
    +
  • + +
  • + +
    菜单
    +
    &#xe61b;
    +
  • + +
  • + +
    问号
    +
    &#xe67f;
    +
  • + +
  • + +
    垃圾桶
    +
    &#xe636;
    +
  • + +
  • + +
    重置密码
    +
    &#xe620;
    +
  • + +
  • + +
    设置
    +
    &#xe68f;
    +
  • + +
  • + +
    中转
    +
    &#xe69b;
    +
  • + +
  • + +
    add
    +
    &#xe6b9;
    +
  • + +
  • + +
    minus
    +
    &#xe6ba;
    +
  • + +
  • + +
    password
    +
    &#xe622;
    +
  • + +
  • + +
    用户
    +
    &#xe604;
    +
  • + +
  • + +
    权限
    +
    &#xe633;
    +
  • + +
  • + +
    角色
    +
    &#xe64c;
    +
  • + +
  • + +
    字典
    +
    &#xe716;
    +
  • + +
  • + +
    参数设置
    +
    &#xe672;
    +
  • + +
  • + +
    编辑
    +
    &#xe642;
    +
  • + +
  • + +
    用户权限
    +
    &#xe609;
    +
  • + +
  • + +
    分享
    +
    &#xe641;
    +
  • + +
  • + +
    授权
    +
    &#xe634;
    +
  • + +
  • + +
    左箭头
    +
    &#xe653;
    +
  • + +
  • + +
    左箭头
    +
    &#xe654;
    +
  • + +
+
+

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">&#x33;</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 @@ + + + + + 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 @@ + + + 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 @@ + + + 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 @@ + + + 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 @@ + + + + \ 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 @@ + + \ 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 @@ + + + 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 @@ + + + + + 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 @@ + + + \ 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 @@ + + + + + + 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 @@ + + + + + + + + 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 @@ + + + + + + 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 @@ + + + + + + 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 @@ + + + + + + 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 @@ +