Commit c33202184940458304af0c41de9c0aab52257664

Authored by qiangmj
0 parents

init

Showing 433 changed files with 876640 additions and 0 deletions

Too many changes to show.

To preserve performance only 40 of 433 files are displayed.

.babelrc 0 → 100644
  1 +++ a/.babelrc
  1 +{
  2 + "presets": [
  3 + ["env", {
  4 + "modules": false,
  5 + "targets": {
  6 + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
  7 + }
  8 + }],
  9 + "stage-2"
  10 + ],
  11 + "plugins":["transform-vue-jsx", "transform-runtime"]
  12 +}
... ...
.editorconfig 0 → 100644
  1 +++ a/.editorconfig
  1 +# http://editorconfig.org
  2 +root = true
  3 +
  4 +[*]
  5 +charset = utf-8
  6 +indent_style = space
  7 +indent_size = 2
  8 +end_of_line = lf
  9 +insert_final_newline = true
  10 +trim_trailing_whitespace = true
  11 +
  12 +[*.md]
  13 +insert_final_newline = false
  14 +trim_trailing_whitespace = false
... ...
.gitignore 0 → 100644
  1 +++ a/.gitignore
  1 +.DS_Store
  2 +node_modules/
  3 +dist/
  4 +npm-debug.log*
  5 +yarn-debug.log*
  6 +yarn-error.log*
  7 +package-lock.json
  8 +
  9 +# Editor directories and files
  10 +.idea
  11 +.vscode
  12 +*.suo
  13 +*.ntvs*
  14 +*.njsproj
  15 +*.sln
... ...
.postcssrc.js 0 → 100644
  1 +++ a/.postcssrc.js
  1 +// https://github.com/michael-ciniawsky/postcss-load-config
  2 +
  3 +module.exports = {
  4 + "plugins": {
  5 + "postcss-import": {},
  6 + "postcss-url": {},
  7 + // to edit target browsers: use "browserslist" field in package.json
  8 + "autoprefixer": {}
  9 + }
  10 +}
... ...
Dockerfile 0 → 100644
  1 +++ a/Dockerfile
  1 +# Dockerfile
  2 +FROM nginx:alpine
  3 +COPY dist/ /usr/share/nginx/html/
  4 +EXPOSE 80
0 5 \ No newline at end of file
... ...
build/build.js 0 → 100644
  1 +++ a/build/build.js
  1 +'use strict'
  2 +require('./check-versions')()
  3 +
  4 +//process.env.NODE_ENV = 'production'
  5 +
  6 +const ora = require('ora')
  7 +const rm = require('rimraf')
  8 +const path = require('path')
  9 +const chalk = require('chalk')
  10 +const webpack = require('webpack')
  11 +const config = require('../config')
  12 +const webpackConfig = require('./webpack.prod.conf')
  13 +
  14 +const spinner = ora('building for ' + process.env.NODE_ENV + '...')
  15 +spinner.start()
  16 +
  17 +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  18 + if (err) throw err
  19 + webpack(webpackConfig, (err, stats) => {
  20 + spinner.stop()
  21 + if (err) throw err
  22 + process.stdout.write(
  23 + stats.toString({
  24 + colors: true,
  25 + modules: false,
  26 + children: false,
  27 + chunks: false,
  28 + chunkModules: false
  29 + }) + '\n\n'
  30 + )
  31 +
  32 + if (stats.hasErrors()) {
  33 + console.log(chalk.red(' Build failed with errors.\n'))
  34 + process.exit(1)
  35 + }
  36 +
  37 + console.log(chalk.cyan(' Build complete.\n'))
  38 + console.log(
  39 + chalk.yellow(
  40 + ' Tip: built files are meant to be served over an HTTP server.\n' +
  41 + " Opening index.html over file:// won't work.\n"
  42 + )
  43 + )
  44 + })
  45 +})
... ...
build/check-versions.js 0 → 100644
  1 +++ a/build/check-versions.js
  1 +'use strict'
  2 +const chalk = require('chalk')
  3 +const semver = require('semver')
  4 +const packageConfig = require('../package.json')
  5 +const shell = require('shelljs')
  6 +
  7 +function exec(cmd) {
  8 + return require('child_process')
  9 + .execSync(cmd)
  10 + .toString()
  11 + .trim()
  12 +}
  13 +
  14 +const versionRequirements = [
  15 + {
  16 + name: 'node',
  17 + currentVersion: semver.clean(process.version),
  18 + versionRequirement: packageConfig.engines.node
  19 + }
  20 +]
  21 +
  22 +if (shell.which('npm')) {
  23 + versionRequirements.push({
  24 + name: 'npm',
  25 + currentVersion: exec('npm --version'),
  26 + versionRequirement: packageConfig.engines.npm
  27 + })
  28 +}
  29 +
  30 +module.exports = function() {
  31 + const warnings = []
  32 +
  33 + for (let i = 0; i < versionRequirements.length; i++) {
  34 + const mod = versionRequirements[i]
  35 +
  36 + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
  37 + warnings.push(
  38 + mod.name +
  39 + ': ' +
  40 + chalk.red(mod.currentVersion) +
  41 + ' should be ' +
  42 + chalk.green(mod.versionRequirement)
  43 + )
  44 + }
  45 + }
  46 +
  47 + if (warnings.length) {
  48 + console.log('')
  49 + console.log(
  50 + chalk.yellow(
  51 + 'To use this template, you must update following to modules:'
  52 + )
  53 + )
  54 + console.log()
  55 +
  56 + for (let i = 0; i < warnings.length; i++) {
  57 + const warning = warnings[i]
  58 + console.log(' ' + warning)
  59 + }
  60 +
  61 + console.log()
  62 + process.exit(1)
  63 + }
  64 +}
... ...
build/logo.png 0 → 100644

16.4 KB

build/utils.js 0 → 100644
  1 +++ a/build/utils.js
  1 +'use strict'
  2 +const path = require('path')
  3 +const config = require('../config')
  4 +const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  5 +const packageConfig = require('../package.json')
  6 +
  7 +exports.assetsPath = function(_path) {
  8 + const assetsSubDirectory =
  9 + process.env.NODE_ENV === 'production'
  10 + ? config.build.assetsSubDirectory
  11 + : config.dev.assetsSubDirectory
  12 +
  13 + return path.posix.join(assetsSubDirectory, _path)
  14 +}
  15 +
  16 +exports.cssLoaders = function(options) {
  17 + options = options || {}
  18 +
  19 + const cssLoader = {
  20 + loader: 'css-loader',
  21 + options: {
  22 + sourceMap: options.sourceMap
  23 + }
  24 + }
  25 +
  26 + const postcssLoader = {
  27 + loader: 'postcss-loader',
  28 + options: {
  29 + sourceMap: options.sourceMap
  30 + }
  31 + }
  32 +
  33 + // generate loader string to be used with extract text plugin
  34 + function generateLoaders(loader, loaderOptions) {
  35 + const loaders = []
  36 +
  37 + // Extract CSS when that option is specified
  38 + // (which is the case during production build)
  39 + if (options.extract) {
  40 + loaders.push(MiniCssExtractPlugin.loader)
  41 + } else {
  42 + loaders.push('vue-style-loader')
  43 + }
  44 +
  45 + loaders.push(cssLoader)
  46 +
  47 + if (options.usePostCSS) {
  48 + loaders.push(postcssLoader)
  49 + }
  50 +
  51 + if (loader) {
  52 + loaders.push({
  53 + loader: loader + '-loader',
  54 + options: Object.assign({}, loaderOptions, {
  55 + sourceMap: options.sourceMap
  56 + })
  57 + })
  58 + }
  59 +
  60 + return loaders
  61 + }
  62 + // https://vue-loader.vuejs.org/en/configurations/extract-css.html
  63 + return {
  64 + css: generateLoaders(),
  65 + postcss: generateLoaders(),
  66 + less: generateLoaders('less'),
  67 + sass: generateLoaders('sass', {
  68 + indentedSyntax: true
  69 + }),
  70 + scss: generateLoaders('sass'),
  71 + stylus: generateLoaders('stylus'),
  72 + styl: generateLoaders('stylus')
  73 + }
  74 +}
  75 +
  76 +// Generate loaders for standalone style files (outside of .vue)
  77 +exports.styleLoaders = function(options) {
  78 + const output = []
  79 + const loaders = exports.cssLoaders(options)
  80 +
  81 + for (const extension in loaders) {
  82 + const loader = loaders[extension]
  83 + output.push({
  84 + test: new RegExp('\\.' + extension + '$'),
  85 + use: loader
  86 + })
  87 + }
  88 +
  89 + return output
  90 +}
  91 +
  92 +exports.createNotifierCallback = () => {
  93 + const notifier = require('node-notifier')
  94 +
  95 + return (severity, errors) => {
  96 + if (severity !== 'error') return
  97 +
  98 + const error = errors[0]
  99 + const filename = error.file && error.file.split('!').pop()
  100 +
  101 + notifier.notify({
  102 + title: packageConfig.name,
  103 + message: severity + ': ' + error.name,
  104 + subtitle: filename || '',
  105 + icon: path.join(__dirname, 'logo.png')
  106 + })
  107 + }
  108 +}
... ...
build/vue-loader.conf.js 0 → 100644
  1 +++ a/build/vue-loader.conf.js
  1 +'use strict'
  2 +
  3 +module.exports = {
  4 + //You can set the vue-loader configuration by yourself.
  5 +}
... ...
build/webpack.base.conf.js 0 → 100644
  1 +++ a/build/webpack.base.conf.js
  1 +'use strict'
  2 +const path = require('path')
  3 +const utils = require('./utils')
  4 +const config = require('../config')
  5 +const {
  6 + VueLoaderPlugin
  7 +} = require('vue-loader')
  8 +const vueLoaderConfig = require('./vue-loader.conf')
  9 +
  10 +function resolve(dir) {
  11 + return path.join(__dirname, '..', dir)
  12 +}
  13 +
  14 +module.exports = {
  15 + context: path.resolve(__dirname, '../'),
  16 + entry: {
  17 + app: './src/main.js'
  18 + },
  19 + output: {
  20 + path: config.build.assetsRoot,
  21 + filename: '[name].js',
  22 + publicPath: config.build.assetsPublicPath //process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
  23 + },
  24 + resolve: {
  25 + extensions: ['.js', '.vue', '.json'],
  26 + alias: {
  27 + '@': resolve('src')
  28 + }
  29 + },
  30 + module: {
  31 + rules: [{
  32 + test: /\.vue$/,
  33 + loader: 'vue-loader',
  34 + options: vueLoaderConfig
  35 + },
  36 + {
  37 + test: /\.js$/,
  38 + loader: 'babel-loader',
  39 + include: [
  40 + resolve('src'),
  41 + resolve('test'),
  42 + resolve('node_modules/webpack-dev-server/client')
  43 + ]
  44 + },
  45 + {
  46 + test: /\.svg$/,
  47 + loader: 'svg-sprite-loader',
  48 + include: [resolve('src/icons')],
  49 + options: {
  50 + symbolId: 'icon-[name]'
  51 + }
  52 + },
  53 + {
  54 + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  55 + loader: 'url-loader',
  56 + exclude: [resolve('src/icons')],
  57 + options: {
  58 + limit: 10000,
  59 + name: utils.assetsPath('img/[name].[hash:7].[ext]')
  60 + }
  61 + },
  62 + {
  63 + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
  64 + loader: 'url-loader',
  65 + options: {
  66 + limit: 10000,
  67 + name: utils.assetsPath('media/[name].[hash:7].[ext]')
  68 + }
  69 + },
  70 + {
  71 + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  72 + loader: 'url-loader',
  73 + options: {
  74 + limit: 10000,
  75 + name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
  76 + }
  77 + }
  78 + ]
  79 + },
  80 + plugins: [new VueLoaderPlugin()],
  81 + node: {
  82 + // prevent webpack from injecting useless setImmediate polyfill because Vue
  83 + // source contains it (although only uses it if it's native).
  84 + setImmediate: false,
  85 + // prevent webpack from injecting mocks to Node native modules
  86 + // that does not make sense for the client
  87 + dgram: 'empty',
  88 + fs: 'empty',
  89 + net: 'empty',
  90 + tls: 'empty',
  91 + child_process: 'empty'
  92 + }
  93 +}
... ...
build/webpack.dev.conf.js 0 → 100644
  1 +++ a/build/webpack.dev.conf.js
  1 +'use strict'
  2 +const path = require('path')
  3 +const utils = require('./utils')
  4 +const webpack = require('webpack')
  5 +const config = require('../config')
  6 +const merge = require('webpack-merge')
  7 +const baseWebpackConfig = require('./webpack.base.conf')
  8 +const HtmlWebpackPlugin = require('html-webpack-plugin')
  9 +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
  10 +const portfinder = require('portfinder')
  11 +
  12 +function resolve(dir) {
  13 + return path.join(__dirname, '..', dir)
  14 +}
  15 +
  16 +const HOST = process.env.HOST
  17 +const PORT = process.env.PORT && Number(process.env.PORT)
  18 +
  19 +const devWebpackConfig = merge(baseWebpackConfig, {
  20 + mode: 'development',
  21 + output: {
  22 + path: config.build.assetsRoot,
  23 + filename: '[name].js',
  24 + publicPath: config.dev.assetsPublicPath
  25 + },
  26 + module: {
  27 + rules: utils.styleLoaders({
  28 + sourceMap: config.dev.cssSourceMap,
  29 + usePostCSS: true
  30 + })
  31 + },
  32 + // cheap-module-eval-source-map is faster for development
  33 + devtool: config.dev.devtool,
  34 +
  35 + // these devServer options should be customized in /config/index.js
  36 + devServer: {
  37 + clientLogLevel: 'warning',
  38 + historyApiFallback: true,
  39 + hot: true,
  40 + compress: true,
  41 + host: HOST || config.dev.host,
  42 + port: PORT || config.dev.port,
  43 + open: config.dev.autoOpenBrowser,
  44 + overlay: config.dev.errorOverlay
  45 + ? { warnings: false, errors: true }
  46 + : false,
  47 + publicPath: config.dev.assetsPublicPath,
  48 + proxy: config.dev.proxyTable,
  49 + quiet: true, // necessary for FriendlyErrorsPlugin
  50 + watchOptions: {
  51 + poll: config.dev.poll
  52 + }
  53 + },
  54 + plugins: [
  55 + new webpack.DefinePlugin({
  56 + 'process.env': require('../config/dev.env')
  57 + }),
  58 + new webpack.HotModuleReplacementPlugin(),
  59 + // https://github.com/ampedandwired/html-webpack-plugin
  60 + new HtmlWebpackPlugin({
  61 + filename: 'index.html',
  62 + template: 'index.html',
  63 + inject: true,
  64 + favicon: resolve('static/favicon.ico'),
  65 + title: 'vue-admin-template'
  66 + })
  67 + ]
  68 +})
  69 +
  70 +module.exports = new Promise((resolve, reject) => {
  71 + portfinder.basePort = process.env.PORT || config.dev.port
  72 + portfinder.getPort((err, port) => {
  73 + if (err) {
  74 + reject(err)
  75 + } else {
  76 + // publish the new Port, necessary for e2e tests
  77 + process.env.PORT = port
  78 + // add port to devServer config
  79 + devWebpackConfig.devServer.port = port
  80 +
  81 + // Add FriendlyErrorsPlugin
  82 + devWebpackConfig.plugins.push(
  83 + new FriendlyErrorsPlugin({
  84 + compilationSuccessInfo: {
  85 + messages: [
  86 + `Your application is running here: http://${
  87 + devWebpackConfig.devServer.host
  88 + }:${port}`
  89 + ]
  90 + },
  91 + onErrors: config.dev.notifyOnErrors
  92 + ? utils.createNotifierCallback()
  93 + : undefined
  94 + })
  95 + )
  96 +
  97 + resolve(devWebpackConfig)
  98 + }
  99 + })
  100 +})
... ...
build/webpack.prod.conf.js 0 → 100644
  1 +++ a/build/webpack.prod.conf.js
  1 +'use strict'
  2 +const path = require('path')
  3 +const utils = require('./utils')
  4 +const webpack = require('webpack')
  5 +const config = require('../config')
  6 +const merge = require('webpack-merge')
  7 +const baseWebpackConfig = require('./webpack.base.conf')
  8 +const CopyWebpackPlugin = require('copy-webpack-plugin')
  9 +const HtmlWebpackPlugin = require('html-webpack-plugin')
  10 +const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
  11 +const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  12 +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
  13 +const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
  14 +
  15 +function resolve(dir) {
  16 + return path.join(__dirname, '..', dir)
  17 +}
  18 +
  19 +var env = require('../config/dev.env')
  20 +if (process.env.NODE_ENV === 'testing') {
  21 + env = require('../config/test.env')
  22 +}
  23 +if (process.env.NODE_ENV === 'production') {
  24 + env = require('../config/prod.env')
  25 +}
  26 +
  27 +// For NamedChunksPlugin
  28 +const seen = new Set()
  29 +const nameLength = 4
  30 +
  31 +const webpackConfig = merge(baseWebpackConfig, {
  32 + mode: 'production',
  33 + module: {
  34 + rules: utils.styleLoaders({
  35 + sourceMap: config.build.productionSourceMap,
  36 + extract: true,
  37 + usePostCSS: true
  38 + })
  39 + },
  40 + devtool: config.build.productionSourceMap ? config.build.devtool : false,
  41 + output: {
  42 + path: config.build.assetsRoot,
  43 + filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
  44 + chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
  45 + },
  46 + plugins: [
  47 + // http://vuejs.github.io/vue-loader/en/workflow/production.html
  48 + new webpack.DefinePlugin({
  49 + 'process.env': env
  50 + }),
  51 + // extract css into its own file
  52 + new MiniCssExtractPlugin({
  53 + filename: utils.assetsPath('css/[name].[contenthash:8].css'),
  54 + chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
  55 + }),
  56 + // generate dist index.html with correct asset hash for caching.
  57 + // you can customize output by editing /index.html
  58 + // see https://github.com/ampedandwired/html-webpack-plugin
  59 + new HtmlWebpackPlugin({
  60 + filename: config.build.index,
  61 + template: 'index.html',
  62 + inject: true,
  63 + favicon: resolve('static/favicon.ico'),
  64 + title: 'vue-admin-template',
  65 + minify: {
  66 + removeComments: true,
  67 + collapseWhitespace: true,
  68 + removeAttributeQuotes: true
  69 + // more options:
  70 + // https://github.com/kangax/html-minifier#options-quick-reference
  71 + }
  72 + // default sort mode uses toposort which cannot handle cyclic deps
  73 + // in certain cases, and in webpack 4, chunk order in HTML doesn't
  74 + // matter anyway
  75 + }),
  76 + new ScriptExtHtmlWebpackPlugin({
  77 + //`runtime` must same as runtimeChunk name. default is `runtime`
  78 + inline: /runtime\..*\.js$/
  79 + }),
  80 + // keep chunk.id stable when chunk has no name
  81 + new webpack.NamedChunksPlugin(chunk => {
  82 + if (chunk.name) {
  83 + return chunk.name
  84 + }
  85 + const modules = Array.from(chunk.modulesIterable)
  86 + if (modules.length > 1) {
  87 + const hash = require('hash-sum')
  88 + const joinedHash = hash(modules.map(m => m.id).join('_'))
  89 + let len = nameLength
  90 + while (seen.has(joinedHash.substr(0, len))) len++
  91 + seen.add(joinedHash.substr(0, len))
  92 + return `chunk-${joinedHash.substr(0, len)}`
  93 + } else {
  94 + return modules[0].id
  95 + }
  96 + }),
  97 + // keep module.id stable when vender modules does not change
  98 + new webpack.HashedModuleIdsPlugin(),
  99 + // copy custom static assets
  100 + new CopyWebpackPlugin([{
  101 + from: path.resolve(__dirname, '../static'),
  102 + to: config.build.assetsSubDirectory,
  103 + ignore: ['.*']
  104 + }])
  105 + ],
  106 + optimization: {
  107 + splitChunks: {
  108 + chunks: 'all',
  109 + cacheGroups: {
  110 + libs: {
  111 + name: 'chunk-libs',
  112 + test: /[\\/]node_modules[\\/]/,
  113 + priority: 10,
  114 + chunks: 'initial' // 只打包初始时依赖的第三方
  115 + },
  116 + elementUI: {
  117 + name: 'chunk-elementUI', // 单独将 elementUI 拆包
  118 + priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
  119 + test: /[\\/]node_modules[\\/]element-ui[\\/]/
  120 + }
  121 + }
  122 + },
  123 + runtimeChunk: 'single',
  124 + minimizer: [
  125 + new UglifyJsPlugin({
  126 + uglifyOptions: {
  127 + mangle: {
  128 + safari10: true
  129 + }
  130 + },
  131 + sourceMap: config.build.productionSourceMap,
  132 + cache: true,
  133 + parallel: true
  134 + }),
  135 + // Compress extracted CSS. We are using this plugin so that possible
  136 + // duplicated CSS from different components can be deduped.
  137 + new OptimizeCSSAssetsPlugin()
  138 + ]
  139 + }
  140 +})
  141 +
  142 +if (config.build.productionGzip) {
  143 + const CompressionWebpackPlugin = require('compression-webpack-plugin')
  144 +
  145 + webpackConfig.plugins.push(
  146 + new CompressionWebpackPlugin({
  147 + asset: '[path].gz[query]',
  148 + algorithm: 'gzip',
  149 + test: new RegExp(
  150 + '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
  151 + ),
  152 + threshold: 10240,
  153 + minRatio: 0.8
  154 + })
  155 + )
  156 +}
  157 +
  158 +if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) {
  159 + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  160 + .BundleAnalyzerPlugin
  161 +
  162 + if (config.build.bundleAnalyzerReport) {
  163 + webpackConfig.plugins.push(
  164 + new BundleAnalyzerPlugin({
  165 + analyzerPort: 8080,
  166 + generateStatsFile: false
  167 + })
  168 + )
  169 + }
  170 +
  171 + if (config.build.generateAnalyzerReport) {
  172 + webpackConfig.plugins.push(
  173 + new BundleAnalyzerPlugin({
  174 + analyzerMode: 'static',
  175 + reportFilename: 'bundle-report.html',
  176 + openAnalyzer: false
  177 + })
  178 + )
  179 + }
  180 +}
  181 +
  182 +module.exports = webpackConfig
... ...
config/dev.env.js 0 → 100644
  1 +++ a/config/dev.env.js
  1 +'use strict'
  2 +const merge = require('webpack-merge')
  3 +const prodEnv = require('./prod.env')
  4 +
  5 +module.exports = merge(prodEnv, {
  6 + NODE_ENV: '"development"',
  7 + BASE_API: '"http://127.0.0.1:8080/xlyReport"',
  8 + API_WS: '"ws://127.0.0.1:8080/api/websocket"'
  9 +})
... ...
config/index.js 0 → 100644
  1 +++ a/config/index.js
  1 +'use strict'
  2 +// Template version: 1.2.6
  3 +// see http://vuejs-templates.github.io/webpack for documentation.
  4 +
  5 +const path = require('path')
  6 +
  7 +module.exports = {
  8 + dev: {
  9 + // Paths
  10 + assetsSubDirectory: 'static',
  11 + assetsPublicPath: '/',
  12 + proxyTable: {},
  13 +
  14 + // Various Dev Server settings
  15 + host: 'localhost', // can be overwritten by process.env.HOST
  16 + port: 8888, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
  17 + autoOpenBrowser: true,
  18 + errorOverlay: true,
  19 + notifyOnErrors: false,
  20 + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
  21 +
  22 + // Use Eslint Loader?
  23 + // If true, your code will be linted during bundling and
  24 + // linting errors and warnings will be shown in the console.
  25 + useEslint: true,
  26 + // If true, eslint errors and warnings will also be shown in the error overlay
  27 + // in the browser.
  28 + showEslintErrorsInOverlay: false,
  29 +
  30 + /**
  31 + * Source Maps
  32 + */
  33 +
  34 + // https://webpack.js.org/configuration/devtool/#development
  35 + devtool: 'cheap-source-map',
  36 +
  37 + // CSS Sourcemaps off by default because relative paths are "buggy"
  38 + // with this option, according to the CSS-Loader README
  39 + // (https://github.com/webpack/css-loader#sourcemaps)
  40 + // In our experience, they generally work as expected,
  41 + // just be aware of this issue when enabling this option.
  42 + cssSourceMap: false
  43 + },
  44 +
  45 + build: {
  46 + // Template for index.html
  47 + index: path.resolve(__dirname, '../dist/index.html'),
  48 +
  49 + // Paths
  50 + assetsRoot: path.resolve(__dirname, '../dist'),
  51 + assetsSubDirectory: 'static',
  52 +
  53 + /**
  54 + * You can set by youself according to actual condition
  55 + * You will need to set this if you plan to deploy your site under a sub path,
  56 + * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
  57 + * then assetsPublicPath should be set to "/bar/".
  58 + * In most cases please use '/' !!!
  59 + */
  60 + assetsPublicPath: '/',
  61 +
  62 + /**
  63 + * Source Maps
  64 + */
  65 +
  66 + productionSourceMap: false,
  67 + // https://webpack.js.org/configuration/devtool/#production
  68 + devtool: 'source-map',
  69 +
  70 + // Gzip off by default as many popular static hosts such as
  71 + // Surge or Netlify already gzip all static assets for you.
  72 + // Before setting to `true`, make sure to:
  73 + // npm install --save-dev compression-webpack-plugin
  74 + productionGzip: false,
  75 + productionGzipExtensions: ['js', 'css'],
  76 +
  77 + // Run the build command with an extra argument to
  78 + // View the bundle analyzer report after build finishes:
  79 + // `npm run build --report`
  80 + // Set to `true` or `false` to always turn it on or off
  81 + bundleAnalyzerReport: process.env.npm_config_report || false,
  82 +
  83 + // `npm run build:prod --generate_report`
  84 + generateAnalyzerReport: process.env.npm_config_generate_report || false
  85 + }
  86 +}
... ...
config/prod.env.js 0 → 100644
  1 +++ a/config/prod.env.js
  1 +'use strict'
  2 +module.exports = {
  3 + NODE_ENV: '"production"',
  4 + BASE_API: '"./"'
  5 +}
... ...
config/test.env.js 0 → 100644
  1 +++ a/config/test.env.js
  1 +'use strict'
  2 +const merge = require('webpack-merge')
  3 +const prodEnv = require('./prod.env')
  4 +
  5 +module.exports = merge(prodEnv, {
  6 + NODE_ENV: '"testing"',
  7 + BASE_API: '"./"'
  8 +})
... ...
index.html 0 → 100644
  1 +++ a/index.html
  1 +<!DOCTYPE html>
  2 +<html>
  3 +
  4 +<head>
  5 + <meta charset="utf-8">
  6 + <meta name="viewport" content="width=device-width,initial-scale=1.0">
  7 + <title>上海小羚羊大屏报表系统</title>
  8 + <link rel='stylesheet' href='./static/luckysheet/plugins/css/pluginsCss.css' />
  9 + <link rel='stylesheet' href='./static/luckysheet/plugins/plugins.css' />
  10 + <link rel='stylesheet' href='./static/luckysheet/css/luckysheet.css' />
  11 + <script src="./static/luckysheet/plugins/js/plugin.js"></script>
  12 + <script src="./static/luckysheet/luckysheet.umd.js"></script>
  13 +
  14 +</head>
  15 +
  16 +<body>
  17 + <div id="app"></div>
  18 +</body>
  19 +
  20 +</html>
... ...
package.json 0 → 100644
  1 +++ a/package.json
  1 +{
  2 + "name": "mirror-manager",
  3 + "version": "3.8.0",
  4 + "description": "mirror-manager",
  5 + "author": "mirror-team@www.xlyprint.com.cn",
  6 + "scripts": {
  7 + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  8 + "start": "npm run dev",
  9 + "build": "cross-env NODE_ENV=production node build/build.js",
  10 + "build:dev": "cross-env NODE_ENV=development node build/build.js",
  11 + "build:test": "cross-env NODE_ENV=testing node build/build.js",
  12 + "build:prod": "cross-env NODE_ENV=production node build/build.js"
  13 + },
  14 + "dependencies": {
  15 + "@ckeditor/ckeditor5-build-decoupled-document": "^23.1.0",
  16 + "@smallwei/avue": "^2.8.23",
  17 + "axios": "0.18.0",
  18 + "chokidar": "^3.5.2",
  19 + "codemirror": "^5.58.1",
  20 + "crypto-js": "^3.1.9-1",
  21 + "echarts": "^4.9.0",
  22 + "echarts-gl": "^1.1.1",
  23 + "element-ui": "^2.9.2",
  24 + "js-cookie": "2.2.0",
  25 + "jsbarcode": "^3.11.4",
  26 + "miment": "^0.0.9",
  27 + "moment": "^2.29.1",
  28 + "monaco-editor": "^0.20.0",
  29 + "normalize.css": "7.0.0",
  30 + "nprogress": "0.2.0",
  31 + "qrcodejs2": "0.0.2",
  32 + "sortablejs": "^1.10.2",
  33 + "uninstall": "0.0.0",
  34 + "v-chart": "^1.0.0",
  35 + "vue": "2.6.11",
  36 + "vue-codemirror": "^4.0.6",
  37 + "vue-color": "^2.8.1",
  38 + "vue-drag-resize": "^1.5.4",
  39 + "vue-echarts": "^5.0.0-beta.0",
  40 + "vue-json-editor": "^1.4.3",
  41 + "vue-router": "3.0.1",
  42 + "vue-ruler-tool": "^1.2.4",
  43 + "vue-superslide": "^0.1.1",
  44 + "vuedraggable": "^2.24.1",
  45 + "vuex": "3.0.1"
  46 + },
  47 + "devDependencies": {
  48 + "autoprefixer": "8.5.0",
  49 + "babel-core": "6.26.0",
  50 + "babel-helper-vue-jsx-merge-props": "2.0.3",
  51 + "babel-loader": "7.1.5",
  52 + "babel-plugin-syntax-jsx": "6.18.0",
  53 + "babel-plugin-transform-runtime": "6.23.0",
  54 + "babel-plugin-transform-vue-jsx": "3.7.0",
  55 + "babel-preset-env": "1.7.0",
  56 + "babel-preset-stage-2": "6.24.1",
  57 + "chalk": "2.4.1",
  58 + "copy-webpack-plugin": "4.5.2",
  59 + "cross-env": "^5.2.0",
  60 + "css-loader": "1.0.0",
  61 + "eventsource-polyfill": "0.9.6",
  62 + "file-loader": "1.1.11",
  63 + "friendly-errors-webpack-plugin": "1.7.0",
  64 + "html-webpack-plugin": "4.0.0-alpha",
  65 + "js-md5": "^0.7.3",
  66 + "mini-css-extract-plugin": "0.4.1",
  67 + "monaco-editor-webpack-plugin": "^4.1.1",
  68 + "node-notifier": "5.2.1",
  69 + "node-sass": "^4.7.2",
  70 + "optimize-css-assets-webpack-plugin": "5.0.0",
  71 + "ora": "3.0.0",
  72 + "path-to-regexp": "2.4.0",
  73 + "portfinder": "1.0.16",
  74 + "postcss-import": "12.0.0",
  75 + "postcss-loader": "2.1.6",
  76 + "postcss-url": "7.3.2",
  77 + "rimraf": "2.6.2",
  78 + "sass-loader": "7.0.3",
  79 + "script-ext-html-webpack-plugin": "2.0.1",
  80 + "semver": "5.5.0",
  81 + "shelljs": "0.8.2",
  82 + "svg-sprite-loader": "3.8.0",
  83 + "svgo": "1.0.5",
  84 + "uglifyjs-webpack-plugin": "1.2.7",
  85 + "url-loader": "1.0.1",
  86 + "vue-loader": "15.3.0",
  87 + "vue-style-loader": "4.1.2",
  88 + "vue-template-compiler": "2.6.11",
  89 + "webpack": "4.16.5",
  90 + "webpack-bundle-analyzer": "2.13.1",
  91 + "webpack-cli": "3.1.0",
  92 + "webpack-dev-server": "3.1.5",
  93 + "webpack-merge": "4.1.4"
  94 + },
  95 + "engines": {
  96 + "node": ">= 6.0.0",
  97 + "npm": ">= 3.0.0"
  98 + },
  99 + "browserslist": [
  100 + "> 1%",
  101 + "last 2 versions",
  102 + "not ie <= 8"
  103 + ],
  104 + "main": ".postcssrc.js",
  105 + "keywords": [],
  106 + "license": "ISC"
  107 +}
... ...
src/App.vue 0 → 100644
  1 +++ a/src/App.vue
  1 +<template>
  2 + <div id="app">
  3 + <router-view v-if="isRouterAlive" />
  4 + </div>
  5 +</template>
  6 +
  7 +<script>
  8 +import "@/assets/iconfont/iconfont.css";
  9 +import { initDictToLocalstorage } from "@/api/dict-data";
  10 +export default {
  11 + name: "App",
  12 + provide() {
  13 + return {
  14 + reload: this.reload
  15 + };
  16 + },
  17 + data() {
  18 + return {
  19 + isRouterAlive: false
  20 + };
  21 + },
  22 + watch: {
  23 + $route(to, form) {
  24 + if (to.path == "/login") {
  25 + this.queryDictName();
  26 + }
  27 + }
  28 + },
  29 + computed: {},
  30 + created() {
  31 + this.queryDictName();
  32 + },
  33 + methods: {
  34 + queryDictName() {
  35 + // 初始化数据字典到浏览器本地缓存
  36 + initDictToLocalstorage(() => {
  37 + this.isRouterAlive = true;
  38 + });
  39 + },
  40 + reload() {
  41 + this.isRouterAlive = false;
  42 + this.$nextTick(function() {
  43 + this.isRouterAlive = true;
  44 + });
  45 + }
  46 + }
  47 +};
  48 +</script>
... ...
src/api/GaeaReport.js 0 → 100644
  1 +++ a/src/api/GaeaReport.js
  1 +import request from '@/utils/request'
  2 +
  3 +// 设计报表
  4 +export function design(data) {
  5 + return request({
  6 + url: 'report/design',
  7 + method: 'post',
  8 + data,
  9 + })
  10 +}
  11 +
  12 +// 预览报表,渲染数据
  13 +export function preview(data) {
  14 + return request({
  15 + url: 'reportExcel/preview',
  16 + method: 'post',
  17 + data,
  18 + })
  19 +}
  20 +
  21 +// 导出报表
  22 +export function exportExcel(data) {
  23 + return request({
  24 + url: 'reportExcel/exportExcel',
  25 + method: 'post',
  26 + data,
  27 + })
  28 +}
  29 +
  30 +// 导出报表
  31 +export function exportPdf(data) {
  32 + return request({
  33 + url: 'reportExcel/exportPdf',
  34 + method: 'post',
  35 + data,
  36 + })
  37 +}
  38 +
  39 +// 获取所有数据集
  40 +export function queryAllDataSet() {
  41 + return request({
  42 + url: 'dataSet/queryAllDataSet',
  43 + method: 'get',
  44 + })
  45 +}
  46 +
  47 +// 获取对应数据集的列集合
  48 +export function detail(data) {
  49 + return request({
  50 + url: 'dataSet/detailBysetId/' + data,
  51 + method: 'get',
  52 + })
  53 +}
  54 +
  55 +// 获取对应数据集的列集合
  56 +export function detailBysetCode(data) {
  57 + return request({
  58 + url: 'dataSet/detailBysetCode/' + data,
  59 + method: 'get',
  60 + })
  61 +}
  62 +
  63 +// 根据reportCode获取报表表格详情
  64 +export function detailByReportCode(data) {
  65 + return request({
  66 + url: 'reportExcel/detailByReportCode/' + data,
  67 + method: 'get',
  68 + })
  69 +}
... ...
src/api/accessAuthority.js 0 → 100644
  1 +++ a/src/api/accessAuthority.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function accessAuthorityList(params) {
  4 + return request({
  5 + url: 'accessAuthority/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function accessAuthorityAdd(data) {
  12 + return request({
  13 + url: 'accessAuthority',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function accessAuthorityDeleteBatch(data) {
  20 + return request({
  21 + url: 'accessAuthority/delete/batch',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function accessAuthorityUpdate(data) {
  28 + return request({
  29 + url: 'accessAuthority',
  30 + method: 'put', data,
  31 + })
  32 +}
  33 +
  34 +export function accessAuthorityDetail(data) {
  35 + return request({
  36 + url: 'accessAuthority/' + data.id,
  37 + method: 'get',
  38 + params: { accessKey: data.accessKey }
  39 + })
  40 +}
  41 +
  42 +export default { accessAuthorityList, accessAuthorityAdd, accessAuthorityDeleteBatch, accessAuthorityUpdate, accessAuthorityDetail }
... ...
src/api/accessRole.js 0 → 100644
  1 +++ a/src/api/accessRole.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function accessRoleList (params) {
  4 + return request({
  5 + url: 'accessRole/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function accessRoleAdd (data) {
  12 + return request({
  13 + url: 'accessRole',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function accessRoleDeleteBatch (data) {
  20 + return request({
  21 + url: 'accessRole/delete/batch',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function accessRoleUpdate (data) {
  28 + return request({
  29 + url: 'accessRole',
  30 + method: 'put', data,
  31 + })
  32 +}
  33 +
  34 +export function accessRoleDetail (data) {
  35 + return request({
  36 + url: 'accessRole/' + data.id,
  37 + method: 'get',
  38 + params: { accessKey: data.accessKey }
  39 + })
  40 +}
  41 +
  42 +export function accessRoleAuthorityTree (roleCode) {
  43 + return request({
  44 + url: 'accessRole/authorityTree/' + roleCode,
  45 + method: 'get',
  46 + })
  47 +}
  48 +
  49 +export function saveAuthorityTree (data) {
  50 + return request({
  51 + url: 'accessRole/saveAuthorityTree',
  52 + method: 'post',
  53 + data
  54 + })
  55 +}
  56 +
  57 +
  58 +export default { accessRoleList, accessRoleAdd, accessRoleDeleteBatch, accessRoleUpdate, accessRoleDetail, accessRoleAuthorityTree, saveAuthorityTree }
... ...
src/api/accessUser.js 0 → 100644
  1 +++ a/src/api/accessUser.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function accessUserList (params) {
  4 + return request({
  5 + url: 'accessUser/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function accessUserAdd (data) {
  12 + return request({
  13 + url: 'accessUser',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function accessUserDeleteBatch (data) {
  20 + return request({
  21 + url: 'accessUser/delete/batch',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function accessUserUpdate (data) {
  28 + return request({
  29 + url: 'accessUser',
  30 + method: 'put', data,
  31 + })
  32 +}
  33 +
  34 +export function accessUserDetail (data) {
  35 + return request({
  36 + url: 'accessUser/' + data.id,
  37 + method: 'get',
  38 + params: { accessKey: data.accessKey }
  39 + })
  40 +}
  41 +
  42 +
  43 +export function getRoleTree (loginName) {
  44 + return request({
  45 + url: 'accessUser/roleTree/' + loginName,
  46 + method: 'get',
  47 + })
  48 +}
  49 +
  50 +export function saveRoleTree (data) {
  51 + return request({
  52 + url: 'accessUser/saveRoleTree',
  53 + method: 'post',
  54 + data
  55 + })
  56 +}
  57 +
  58 +
  59 +export default { accessUserList, accessUserAdd, accessUserDeleteBatch, accessUserUpdate, accessUserDetail, getRoleTree, saveRoleTree }
... ...
src/api/axios.js 0 → 100644
  1 +++ a/src/api/axios.js
  1 +import axios from 'axios';
  2 +import { Message, MessageBox } from 'element-ui';
  3 +axios.defaults.baseURL = process.env.BASE_API
  4 +const service = axios.create({
  5 + withCredentials: false,
  6 + timeout: 60000,
  7 + headers: {
  8 + 'Content-Type': 'application/json',
  9 + }
  10 +})
  11 +
  12 +service.interceptors.request.use(
  13 + config => {
  14 + return config
  15 + },
  16 + error => {
  17 + // Do something with request error
  18 + Promise.reject(error)
  19 + }
  20 +)
  21 +
  22 +// response interceptor
  23 +service.interceptors.response.use(
  24 + response => {
  25 + const res = response.data;
  26 + if (res.code == 200) {
  27 + return res
  28 + }
  29 +
  30 + else if (res.code == '50014') {
  31 + //登录超时或被登出,弹确认框,用户确认后,跳转到登录页面
  32 + MessageBox({
  33 + message: "当前登录已失效或异地登录,请重新登录",
  34 + type: 'error',
  35 + duration: 3 * 1000,
  36 + }).then(() => {
  37 + sessionStorage.clear();
  38 + localStorage.clear();
  39 + window.location.href = "/";
  40 + }).catch(err => {
  41 + })
  42 + } else if (res.code == "3100" || res.code == "3101") {
  43 + return res;
  44 + }
  45 + else {
  46 + Message({
  47 + message: res.repMsg || res.message,
  48 + type: 'error',
  49 + duration: 3 * 1000
  50 + })
  51 + return res;
  52 + }
  53 + },
  54 + error => {
  55 + var errorStatus = error.response.code;
  56 + var errorData = error.response.data;
  57 + var messageTxt = "";
  58 + if (errorStatus != 200) {
  59 + messageTxt = "服务器内部错误,请联系管理员";
  60 + } else {
  61 + messageTxt = '失败原因:' + errorData.code + '--' + errorData.repMsg;
  62 + }
  63 + Message({
  64 + message: messageTxt,
  65 + type: 'error',
  66 + duration: 5 * 1000
  67 + })
  68 + }
  69 +)
  70 +
  71 +export default service
... ...
src/api/bigscreen.js 0 → 100644
  1 +++ a/src/api/bigscreen.js
  1 +import request from '@/utils/request'
  2 +import { getShareToken, getToken } from "@/utils/auth";
  3 +import axios from 'axios';
  4 +
  5 +// 保存大屏设计
  6 +export function insertDashboard(data) {
  7 + return request({
  8 + url: 'reportDashboard',
  9 + method: 'post',
  10 + data,
  11 + })
  12 +}
  13 +
  14 +// 预览、查询大屏详情
  15 +export function detailDashboard(data) {
  16 + return request({
  17 + url: 'reportDashboard/' + data,
  18 + headers: { 'Share-Token': getShareToken(), 'Authorization': getToken() },
  19 + method: 'get',
  20 + })
  21 +}
  22 +
  23 +// 数据集查询
  24 +export function queryAllDataSet(data) {
  25 + return request({
  26 + url: 'dataSet/queryAllDataSet',
  27 + method: 'get',
  28 +
  29 + })
  30 +}
  31 +
  32 +// 获取数据集信息
  33 +export function detailBysetId(data) {
  34 + return request({
  35 + url: 'dataSet/detailBysetId/' + data,
  36 + method: 'get',
  37 + })
  38 +}
  39 +
  40 +// 获取动态数据
  41 +export function getData(data) {
  42 + return request({
  43 + url: 'reportDashboard/getData',
  44 + method: 'post',
  45 + headers: { 'Share-Token': getShareToken(), 'Authorization': getToken() },
  46 + data,
  47 + })
  48 +}
  49 +
  50 +// 导出大屏
  51 +export function exportDashboard(data) {
  52 + return new Promise((resolve) =>{
  53 + axios({
  54 + method:'get',
  55 + url: process.env.BASE_API + '/reportDashboard/export',
  56 + headers: { 'Authorization': getToken() },
  57 + params:data,
  58 + responseType:'blob'
  59 + }).then(res =>{
  60 + resolve(res.data);
  61 + }).catch(err =>{
  62 + resolve('error');
  63 + })
  64 + })
  65 +
  66 +}
  67 +
  68 +// 导入大屏
  69 +export function importDashboard(data) {
  70 + return request({
  71 + url: 'reportDashboard/import',
  72 + method: 'post',
  73 + data,
  74 + })
  75 +}
... ...
src/api/calculation/calculation.js 0 → 100644
  1 +++ a/src/api/calculation/calculation.js
  1 +import request from '@/api/axios'
  2 +
  3 +// 分页查询
  4 +export const reqPageList = data => {
  5 + return request({
  6 + url: '/analysis-service/calculate/queryByPage',
  7 + method: 'post',
  8 + data
  9 + })
  10 +}
  11 +
  12 +// 新增
  13 +export const reqAddDeviceType = data => {
  14 + return request({
  15 + url: '/analysis-service/calculate/create',
  16 + method: 'post',
  17 + data
  18 + })
  19 +}
  20 +
  21 +// 编辑
  22 +export const reqEditDeviceType = data => {
  23 + return request({
  24 + url: '/analysis-service/calculate/updateById',
  25 + method: 'post',
  26 + data
  27 + })
  28 +}
  29 +
  30 +// 删除
  31 +export const reqDeleteDeviceType = data => {
  32 + return request({
  33 + url: '/analysis-service/calculate/deleteByIds',
  34 + method: 'post',
  35 + data
  36 + })
  37 +}
  38 +
  39 +// 根据id查明细
  40 +export const reqDetail = data => {
  41 + return request({
  42 + url: '/analysis-service/calculate/queryById',
  43 + method: 'post',
  44 + data
  45 + })
  46 +}
  47 +
  48 +// 根据监控项id 拉取监控项树结构
  49 +export const reqItemTree = data => {
  50 + return request({
  51 + url: '/analysis-service/item/tree',
  52 + method: 'post',
  53 + data
  54 + })
  55 +}
  56 +
  57 +// 计算执行sql 语句
  58 +export const reqExecuteSql = data => {
  59 + return request({
  60 + url: '/analysis-service/calculate/executeSql',
  61 + method: 'post',
  62 + data
  63 + })
  64 +}
... ...
src/api/common.js 0 → 100644
  1 +++ a/src/api/common.js
  1 +/*
  2 + * @Author: qianlishi
  3 + * @Date: 2020-07-13 15:13:34
  4 + * @Last Modified by: qianlishi
  5 + * @Last Modified time: 2021-03-15 13:28:28
  6 + */
  7 +
  8 +import request from '@/utils/request'
  9 +
  10 +// 数据字典接口
  11 +export function dataDictionary (dictName) {
  12 + return request({
  13 + url: '/gaeaDict/select/' + dictName,
  14 + method: 'GET',
  15 + })
  16 +}
  17 +
  18 +// 图片上传接口
  19 +export function uploadImg (data) {
  20 + return request({
  21 + url: '/file/upload',
  22 + method: 'POST',
  23 + data,
  24 + })
  25 +}
... ...
src/api/dict-data.js 0 → 100644
  1 +++ a/src/api/dict-data.js
  1 +/*
  2 + * @Author: qianlishi
  3 + * @Date: 2020-07-13 15:13:17
  4 + * @Last Modified by: qianlishi
  5 + * @Last Modified time: 2020-12-15 15:34:34
  6 + */
  7 +import request from '@/utils/request'
  8 +import { setStorageItem } from '@/utils/storage'
  9 +// 数据字典和基础数据查询的相关接口
  10 +
  11 +/**
  12 + * 数据字典多类型编码查询接口
  13 + * type参数 类型 String
  14 + * type参数 格式 'type'
  15 + */
  16 +export function getDictList (type) {
  17 + return request({
  18 + url: `/gaeaDict/select/${type}`,
  19 + method: 'get',
  20 + })
  21 +}
  22 +export function getDictCodes (project) {
  23 + return request({
  24 + url: `/gaeaDict/selectAll/${project}`,
  25 + method: 'get',
  26 + })
  27 +}
  28 +
  29 +/**
  30 + * 数据字典多类型编码查询接口
  31 + * typeList参数 类型 Array
  32 + * typeList参数 格式 ['type1','type2',...]
  33 + */
  34 +export function getMultipleDictList (typeList) {
  35 + const types = typeList + ''
  36 + return request({
  37 + url: `/v1/dict/types`,
  38 + method: 'get',
  39 + params: { types },
  40 + })
  41 +}
  42 +
  43 +/**
  44 + * 主数据编码查询接口
  45 + * typeList参数 类型 Array
  46 + * typeList参数 格式 ['type1','type2',...]
  47 + */
  48 +export function getBaseDataList (typeList) {
  49 + const types = typeList + ''
  50 + return request({
  51 + url: `/v1/master/types`,
  52 + method: 'get',
  53 + params: { types },
  54 + })
  55 +}
  56 +
  57 +// 查询所有数据字典接口
  58 +export function getAllDict() {
  59 + return request({
  60 + url: '/gaeaDict/all',
  61 + method: 'GET',
  62 + })
  63 +}
  64 +
  65 +// 将所有接口初始化到浏览器本地缓存
  66 +export function initDictToLocalstorage(callback) {
  67 + getAllDict().then((res) => {
  68 + if (res.code != 200) {
  69 + console.error('初始化数据字典到local storage失败: ' + res.message)
  70 + return
  71 + }
  72 +
  73 + // 保存数据字典到localStorage
  74 + setStorageItem('AJReportDict', res.data)
  75 + if (callback != null) {
  76 + callback()
  77 + }
  78 + })
  79 +}
... ...
src/api/dict.js 0 → 100644
  1 +++ a/src/api/dict.js
  1 +import request from '@/utils/request'
  2 +
  3 +// 字典管理查询
  4 +export function getDictList(params) {
  5 + return request({
  6 + url: '/gaeaDict/pageList',
  7 + method: 'GET',
  8 + params,
  9 + })
  10 +}
  11 +// 获取单个字典数据
  12 +export function getDictItems(dictCode) {
  13 + return request({
  14 + url: `/gaeaDict/select/${dictCode}`,
  15 + method: 'get',
  16 + })
  17 +}
  18 +// 字典管理新增
  19 +export function dictAdd(data) {
  20 + return request({
  21 + url: '/gaeaDict',
  22 + method: 'POST',
  23 + data,
  24 + })
  25 +}
  26 +
  27 +// 字典管理编辑
  28 +export function dictEdit(data) {
  29 + return request({
  30 + url: '/gaeaDict',
  31 + method: 'PUT',
  32 + data,
  33 + })
  34 +}
  35 +
  36 +export function dictDetail(data) {
  37 + return request({
  38 + url: '/gaeaDict/' + data.id,
  39 + method: 'get',
  40 + params: { accessKey: data.accessKey },
  41 + })
  42 +}
  43 +
  44 +// 字典管理批量删除
  45 +export function dictsDelect(data) {
  46 + return request({
  47 + url: `/gaeaDict/delete/batch`,
  48 + method: 'POST',
  49 + data,
  50 + })
  51 +}
  52 +
  53 +/**
  54 + * 刷新数据字典
  55 + * @param data
  56 + */
  57 +export function freshDict(data) {
  58 + return request({
  59 + url: '/gaeaDict/freshDict',
  60 + method: 'POST',
  61 + data,
  62 + })
  63 +}
  64 +
  65 +// 获取国家省份城市
  66 +export function queryCountryCity(value) {
  67 + return request({
  68 + url: `/countryCity/select`,
  69 + method: 'get',
  70 + params: {
  71 + value: value,
  72 + },
  73 + })
  74 +}
  75 +export default { dictDetail, getDictList, dictAdd, dictEdit, dictsDelect }
... ...
src/api/dictItem.js 0 → 100644
  1 +++ a/src/api/dictItem.js
  1 +import request from '@/utils/request'
  2 +
  3 +// 字典项管理查询
  4 +export function dictItemPageList(params) {
  5 + return request({
  6 + url: '/gaeaDictItem/pageList',
  7 + method: 'GET',
  8 + params,
  9 + })
  10 +}
  11 +
  12 +// 字典项管理新增
  13 +export function dictItemAdd(data) {
  14 + return request({
  15 + url: '/gaeaDictItem',
  16 + method: 'POST',
  17 + data,
  18 + })
  19 +}
  20 +
  21 +// 字典项管理编辑
  22 +export function dictItemEdit(data) {
  23 + return request({
  24 + url: '/gaeaDictItem',
  25 + method: 'PUT',
  26 + data,
  27 + })
  28 +}
  29 +
  30 +// 字典项管理批量删除
  31 +export function dictsItemDelect(data) {
  32 + return request({
  33 + url: `/gaeaDictItem/delete/batch`,
  34 + method: 'POST',
  35 + data,
  36 + })
  37 +}
  38 +
  39 +export function dictItemDetail(data) {
  40 + return request({
  41 + url: '/gaeaDictItem/' + data.id,
  42 + method: 'get',
  43 + params: { accessKey: data.accessKey },
  44 + })
  45 +}
  46 +
  47 +export default { dictItemDetail, dictItemPageList, dictItemAdd, dictItemEdit, dictsItemDelect }
... ...
src/api/file.js 0 → 100644
  1 +++ a/src/api/file.js
  1 +/*
  2 + * @Author: zyk
  3 + * @Date: 2021-02-23 15:13:17
  4 + * @Last Modified by: zyk
  5 + * @Last Modified time: 2021-03-15 13:28:36
  6 + */
  7 +import request from '@/utils/request'
  8 +// 导出中心
  9 +
  10 +export function download(fileId) {
  11 + return request({
  12 + url: `/file/download/${fileId}`,
  13 + responseType: 'blob',
  14 + method: 'GET',
  15 + })
  16 +}
  17 +
  18 +export function fileList(params) {
  19 + return request({
  20 + url: '/file/pageList',
  21 + method: 'GET',
  22 + params,
  23 + })
  24 +}
  25 +
  26 +export function fileAdd(data) {
  27 + return request({
  28 + url: '/file',
  29 + method: 'post',
  30 + data,
  31 + })
  32 +}
  33 +
  34 +export function fileDel(data) {
  35 + return request({
  36 + url: `/file/delete/batch`,
  37 + method: 'POST',
  38 + data,
  39 + })
  40 +}
  41 +
  42 +export function fileUpdate(data) {
  43 + return request({
  44 + url: '/file',
  45 + method: 'put',
  46 + data,
  47 + })
  48 +}
  49 +
  50 +export function fileDetail(data) {
  51 + return request({
  52 + url: '/file/' + data.id,
  53 + method: 'get',
  54 + params: data,
  55 + })
  56 +}
  57 +
  58 +export default { fileList, fileAdd, fileDel, fileUpdate, fileDetail }
... ...
src/api/login/index.js 0 → 100644
  1 +++ a/src/api/login/index.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function login (data) {
  4 + return request({
  5 + url: 'accessUser/login',
  6 + method: 'post',
  7 + data
  8 + })
  9 +}
  10 +
  11 +export function logout () {
  12 + return request({
  13 + url: 'accessUser/logout',
  14 + method: 'post'
  15 + })
  16 +}
  17 +
  18 +// 登录之后 根据旧修改密码
  19 +export function reqUpdatePassword (data) {
  20 + return request({
  21 + url: '/accessUser/updatePassword',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
... ...
src/api/report.js 0 → 100644
  1 +++ a/src/api/report.js
  1 +/*
  2 + * @Author: qianlishi
  3 + * @Date: 2020-07-13 15:13:37
  4 + * @Last Modified by: qianlishi
  5 + * @Last Modified time: 2021-03-04 10:46:26
  6 + */
  7 +import request from '@/utils/request'
  8 +
  9 +// resultset
  10 +export function dataSetPreview (data) {
  11 + return request({
  12 + url: `/dataSet/detailBysetId/${data.id}`,
  13 + method: 'get',
  14 + })
  15 +}
  16 +
  17 +export function addDataSet (data) {
  18 + return request({
  19 + url: '/dataSet',
  20 + method: 'post',
  21 + data,
  22 + })
  23 +}
  24 +export function editDataSet (data) {
  25 + return request({
  26 + url: '/dataSet',
  27 + method: 'put',
  28 + data,
  29 + })
  30 +}
  31 +// delete dataset
  32 +export function deleteDataSet (data) {
  33 + return request({
  34 + url: '/dataSet/' + data.id,
  35 + method: 'delete',
  36 + data,
  37 + })
  38 +}
  39 +// 下拉数据源
  40 +export function queryAllDataSourceSet (data) {
  41 + return request({
  42 + url: '/dataSource/queryAllDataSource',
  43 + method: 'get',
  44 + data,
  45 + })
  46 +}
  47 +// 数据集高级规则js验证
  48 +export function verificationSet (data) {
  49 + return request({
  50 + url: '/dataSetParam/verification',
  51 + method: 'post',
  52 + data,
  53 + })
  54 +}
  55 +// 测试数据转换,以及返回数据table列表
  56 +export function testTransformSet (data) {
  57 + return request({
  58 + url: '/dataSet/testTransform',
  59 + method: 'post',
  60 + data,
  61 + })
  62 +}
  63 +
  64 +// report
  65 +export function reportPageList (params) {
  66 + return request({
  67 + url: '/report/pageList',
  68 + method: 'get',
  69 + params,
  70 + })
  71 +}
  72 +// report
  73 +export function addReport (data) {
  74 + return request({
  75 + url: '/report',
  76 + method: 'post',
  77 + data,
  78 + })
  79 +}
  80 +
  81 +// report
  82 +export function editReport (data) {
  83 + return request({
  84 + url: '/report',
  85 + method: 'put',
  86 + data,
  87 + })
  88 +}
  89 +
  90 +// report
  91 +export function delReport (data) {
  92 + return request({
  93 + url: '/report/delReport',
  94 + method: 'delete',
  95 + data,
  96 + })
  97 +}
  98 +
  99 +// report
  100 +export function detailReport (id, accessKey) {
  101 + return request({
  102 + url: `/report/${id}?accessKey=${accessKey}`,
  103 + method: 'get',
  104 + })
  105 +}
  106 +
  107 +// reportExcel
  108 +export function addReportExcel (data) {
  109 + return request({
  110 + url: '/reportExcel',
  111 + method: 'post',
  112 + data,
  113 + })
  114 +}
  115 +
  116 +// reportExcel
  117 +export function editReportExcel (data) {
  118 + return request({
  119 + url: '/reportExcel',
  120 + method: 'put',
  121 + data,
  122 + })
  123 +}
  124 +// /dataSet/pageList
  125 +export function dataSetPageList (params) {
  126 + return request({
  127 + url: '/dataSet/pageList',
  128 + method: 'GET',
  129 + params,
  130 + })
  131 +}
... ...
src/api/reportDataSet.js 0 → 100644
  1 +++ a/src/api/reportDataSet.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function reportDataSetList(params) {
  4 + return request({
  5 + url: 'dataSet/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function reportDataSetAdd(data) {
  12 + return request({
  13 + url: 'dataSet',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function reportDataSetDeleteBatch(data) {
  20 + return request({
  21 + url: 'dataSet/delete/batch',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function reportDataSetUpdate(data) {
  28 + return request({
  29 + url: 'dataSet',
  30 + method: 'put', data,
  31 + })
  32 +}
  33 +
  34 +export function reportDataSetDetail(data) {
  35 + return request({
  36 + url: 'dataSet/' + data.id,
  37 + method: 'get',
  38 + params: { accessKey: data.accessKey }
  39 + })
  40 +}
  41 +
  42 +export default { reportDataSetList, reportDataSetAdd, reportDataSetDeleteBatch, reportDataSetUpdate, reportDataSetDetail }
... ...
src/api/reportDataSource.js 0 → 100644
  1 +++ a/src/api/reportDataSource.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function reportDataSourceList(params) {
  4 + return request({
  5 + url: 'dataSource/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function reportDataSourceAdd(data) {
  12 + return request({
  13 + url: 'dataSource',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function reportDataSourceDeleteBatch(data) {
  20 + return request({
  21 + url: 'dataSource/delete/batch',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function reportDataSourceUpdate(data) {
  28 + return request({
  29 + url: 'dataSource',
  30 + method: 'put',
  31 + data
  32 + })
  33 +}
  34 +
  35 +export function reportDataSourceDetail(data) {
  36 + return request({
  37 + url: 'dataSource/' + data.id,
  38 + method: 'get',
  39 + params: { accessKey: data.accessKey }
  40 + })
  41 +}
  42 +
  43 +export function testConnection (data) {
  44 + return request({
  45 + url: '/dataSource/testConnection',
  46 + method: 'post',
  47 + data,
  48 + })
  49 +}
  50 +
  51 +export default { reportDataSourceList, reportDataSourceAdd, reportDataSourceDeleteBatch, reportDataSourceUpdate, reportDataSourceDetail, testConnection}
... ...
src/api/reportShare.js 0 → 100644
  1 +++ a/src/api/reportShare.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function reportShareList(params) {
  4 + return request({
  5 + url: 'reportShare/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function reportShareAdd(data) {
  12 + return request({
  13 + url: 'reportDashboard/share',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function excelShareAdd(data) {
  20 + return request({
  21 + url: 'reportExcel/share',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function reportShareDelay(data) {
  28 + return request({
  29 + url: 'reportShare/shareDelay',
  30 + method: 'post',
  31 + data
  32 + })
  33 +}
  34 +
  35 +export function reportShareDeleteBatch(data) {
  36 + return request({
  37 + url: 'reportShare/delete/batch',
  38 + method: 'post',
  39 + data
  40 + })
  41 +}
  42 +
  43 +export function reportShareUpdate(data) {
  44 + return request({
  45 + url: 'reportShare',
  46 + method: 'put', data,
  47 + })
  48 +}
  49 +
  50 +export function reportShareDetail(data) {
  51 + return request({
  52 + url: 'reportShare/' + data.id,
  53 + method: 'get',
  54 + params: {accessKey: data.accessKey}
  55 + })
  56 +}
  57 +
  58 +export function reportShareDetailByCode(data) {
  59 + return request({
  60 + url: 'reportShare/detailByCode',
  61 + method: 'get',
  62 + params: {shareCode: data}
  63 + })
  64 +}
  65 +
  66 +export default {reportShareList, reportShareAdd, reportShareDeleteBatch, reportShareUpdate, reportShareDetail}
... ...
src/api/reportmanage.js 0 → 100644
  1 +++ a/src/api/reportmanage.js
  1 +import request from '@/utils/request'
  2 +
  3 +export function reportList(params) {
  4 + return request({
  5 + url: '/report/pageList',
  6 + method: 'GET',
  7 + params,
  8 + })
  9 +}
  10 +
  11 +export function reportAdd(data) {
  12 + return request({
  13 + url: '/report',
  14 + method: 'post',
  15 + data
  16 + })
  17 +}
  18 +
  19 +export function reportDeleteBatch(data) {
  20 + return request({
  21 + url: '/report/delete/batch',
  22 + method: 'post',
  23 + data
  24 + })
  25 +}
  26 +
  27 +export function reportUpdate(data) {
  28 + return request({
  29 + url: '/report',
  30 + method: 'put', data,
  31 + })
  32 +}
  33 +
  34 +export function reportDetail(data) {
  35 + return request({
  36 + url: '/report/' + data.id,
  37 + method: 'get',
  38 + params: { accessKey: data.accessKey }
  39 + })
  40 +}
  41 +
  42 +export function reportCopy(data) {
  43 + return request({
  44 + url: '/report/copy',
  45 + method: 'post',
  46 + data
  47 + })
  48 +}
  49 +
  50 +export default { reportList, reportAdd, reportDeleteBatch, reportUpdate, reportDetail }
... ...
src/api/upload.js 0 → 100644
  1 +++ a/src/api/upload.js
  1 +import axios from 'axios';
  2 +import { Message, MessageBox } from 'element-ui';
  3 +import { delItem } from '@/utils/storage';
  4 +
  5 +axios.defaults.baseURL = process.env.BASE_API
  6 +
  7 +const service = axios.create({
  8 + withCredentials: true,
  9 + timeout: 60000,
  10 + headers: {
  11 + 'Content-Type': 'multipart/form-data'
  12 + }
  13 +})
  14 +
  15 +// response interceptor
  16 +service.interceptors.response.use(
  17 + response => {
  18 + const res = response.data;
  19 + if (res.repCode == '0000') {
  20 + return res
  21 + }
  22 + else if (res.repCode == '0024') {
  23 +
  24 + //登录超时或被登出,弹确认框,用户确认后,跳转到登录页面
  25 + MessageBox({
  26 + message: "当前登录已失效或异地登录,请重新登录",
  27 + type: 'error',
  28 + duration: 3 * 1000,
  29 + }).then(() => {
  30 + console.log(1)
  31 + sessionStorage.clear();
  32 + localStorage.clear();
  33 + // location.reload();
  34 + window.location.href = "/";
  35 + }).catch(err => {
  36 + console.log(2)
  37 + })
  38 + }else if(res.repCode == "3100" || res.repCode == "3101"){
  39 + return res;
  40 + }
  41 + else {
  42 + Message({
  43 + message: res.repMsg,
  44 + type: 'error',
  45 + duration: 3 * 1000
  46 + })
  47 + return res;
  48 + }
  49 + },
  50 + error => {
  51 + var errorStatus = error.response.status;
  52 + var errorData = error.response.data;
  53 + var messageTxt = "";
  54 + if (errorStatus != 200) {
  55 + messageTxt = "服务器内部错误,请联系管理员";
  56 + } else {
  57 + messageTxt = '失败原因:' + errorData.repCode + '--' + errorData.repMsg;
  58 + }
  59 + Message({
  60 + message: messageTxt,
  61 + type: 'error',
  62 + duration: 5 * 1000
  63 + })
  64 + }
  65 +)
  66 +
  67 +export default service
0 68 \ No newline at end of file
... ...
src/assets/iconfont/demo.css 0 → 100644
  1 +++ a/src/assets/iconfont/demo.css
  1 +/* Logo 字体 */
  2 +@font-face {
  3 + font-family: "iconfont logo";
  4 + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
  5 + src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
  6 + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
  7 + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
  8 + url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
  9 +}
  10 +
  11 +.logo {
  12 + font-family: "iconfont logo";
  13 + font-size: 160px;
  14 + font-style: normal;
  15 + -webkit-font-smoothing: antialiased;
  16 + -moz-osx-font-smoothing: grayscale;
  17 +}
  18 +
  19 +/* tabs */
  20 +.nav-tabs {
  21 + position: relative;
  22 +}
  23 +
  24 +.nav-tabs .nav-more {
  25 + position: absolute;
  26 + right: 0;
  27 + bottom: 0;
  28 + height: 42px;
  29 + line-height: 42px;
  30 + color: #666;
  31 +}
  32 +
  33 +#tabs {
  34 + border-bottom: 1px solid #eee;
  35 +}
  36 +
  37 +#tabs li {
  38 + cursor: pointer;
  39 + width: 100px;
  40 + height: 40px;
  41 + line-height: 40px;
  42 + text-align: center;
  43 + font-size: 16px;
  44 + border-bottom: 2px solid transparent;
  45 + position: relative;
  46 + z-index: 1;
  47 + margin-bottom: -1px;
  48 + color: #666;
  49 +}
  50 +
  51 +
  52 +#tabs .active {
  53 + border-bottom-color: #f00;
  54 + color: #222;
  55 +}
  56 +
  57 +.tab-container .content {
  58 + display: none;
  59 +}
  60 +
  61 +/* 页面布局 */
  62 +.main {
  63 + padding: 30px 100px;
  64 + width: 960px;
  65 + margin: 0 auto;
  66 +}
  67 +
  68 +.main .logo {
  69 + color: #333;
  70 + text-align: left;
  71 + margin-bottom: 30px;
  72 + line-height: 1;
  73 + height: 110px;
  74 + margin-top: -50px;
  75 + overflow: hidden;
  76 + *zoom: 1;
  77 +}
  78 +
  79 +.main .logo a {
  80 + font-size: 160px;
  81 + color: #333;
  82 +}
  83 +
  84 +.helps {
  85 + margin-top: 40px;
  86 +}
  87 +
  88 +.helps pre {
  89 + padding: 20px;
  90 + margin: 10px 0;
  91 + border: solid 1px #e7e1cd;
  92 + background-color: #fffdef;
  93 + overflow: auto;
  94 +}
  95 +
  96 +.icon_lists {
  97 + width: 100% !important;
  98 + overflow: hidden;
  99 + *zoom: 1;
  100 +}
  101 +
  102 +.icon_lists li {
  103 + width: 100px;
  104 + margin-bottom: 10px;
  105 + margin-right: 20px;
  106 + text-align: center;
  107 + list-style: none !important;
  108 + cursor: default;
  109 +}
  110 +
  111 +.icon_lists li .code-name {
  112 + line-height: 1.2;
  113 +}
  114 +
  115 +.icon_lists .icon {
  116 + display: block;
  117 + height: 100px;
  118 + line-height: 100px;
  119 + font-size: 42px;
  120 + margin: 10px auto;
  121 + color: #333;
  122 + -webkit-transition: font-size 0.25s linear, width 0.25s linear;
  123 + -moz-transition: font-size 0.25s linear, width 0.25s linear;
  124 + transition: font-size 0.25s linear, width 0.25s linear;
  125 +}
  126 +
  127 +.icon_lists .icon:hover {
  128 + font-size: 100px;
  129 +}
  130 +
  131 +.icon_lists .svg-icon {
  132 + /* 通过设置 font-size 来改变图标大小 */
  133 + width: 1em;
  134 + /* 图标和文字相邻时,垂直对齐 */
  135 + vertical-align: -0.15em;
  136 + /* 通过设置 color 来改变 SVG 的颜色/fill */
  137 + fill: currentColor;
  138 + /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
  139 + normalize.css 中也包含这行 */
  140 + overflow: hidden;
  141 +}
  142 +
  143 +.icon_lists li .name,
  144 +.icon_lists li .code-name {
  145 + color: #666;
  146 +}
  147 +
  148 +/* markdown 样式 */
  149 +.markdown {
  150 + color: #666;
  151 + font-size: 14px;
  152 + line-height: 1.8;
  153 +}
  154 +
  155 +.highlight {
  156 + line-height: 1.5;
  157 +}
  158 +
  159 +.markdown img {
  160 + vertical-align: middle;
  161 + max-width: 100%;
  162 +}
  163 +
  164 +.markdown h1 {
  165 + color: #404040;
  166 + font-weight: 500;
  167 + line-height: 40px;
  168 + margin-bottom: 24px;
  169 +}
  170 +
  171 +.markdown h2,
  172 +.markdown h3,
  173 +.markdown h4,
  174 +.markdown h5,
  175 +.markdown h6 {
  176 + color: #404040;
  177 + margin: 1.6em 0 0.6em 0;
  178 + font-weight: 500;
  179 + clear: both;
  180 +}
  181 +
  182 +.markdown h1 {
  183 + font-size: 28px;
  184 +}
  185 +
  186 +.markdown h2 {
  187 + font-size: 22px;
  188 +}
  189 +
  190 +.markdown h3 {
  191 + font-size: 16px;
  192 +}
  193 +
  194 +.markdown h4 {
  195 + font-size: 14px;
  196 +}
  197 +
  198 +.markdown h5 {
  199 + font-size: 12px;
  200 +}
  201 +
  202 +.markdown h6 {
  203 + font-size: 12px;
  204 +}
  205 +
  206 +.markdown hr {
  207 + height: 1px;
  208 + border: 0;
  209 + background: #e9e9e9;
  210 + margin: 16px 0;
  211 + clear: both;
  212 +}
  213 +
  214 +.markdown p {
  215 + margin: 1em 0;
  216 +}
  217 +
  218 +.markdown>p,
  219 +.markdown>blockquote,
  220 +.markdown>.highlight,
  221 +.markdown>ol,
  222 +.markdown>ul {
  223 + width: 80%;
  224 +}
  225 +
  226 +.markdown ul>li {
  227 + list-style: circle;
  228 +}
  229 +
  230 +.markdown>ul li,
  231 +.markdown blockquote ul>li {
  232 + margin-left: 20px;
  233 + padding-left: 4px;
  234 +}
  235 +
  236 +.markdown>ul li p,
  237 +.markdown>ol li p {
  238 + margin: 0.6em 0;
  239 +}
  240 +
  241 +.markdown ol>li {
  242 + list-style: decimal;
  243 +}
  244 +
  245 +.markdown>ol li,
  246 +.markdown blockquote ol>li {
  247 + margin-left: 20px;
  248 + padding-left: 4px;
  249 +}
  250 +
  251 +.markdown code {
  252 + margin: 0 3px;
  253 + padding: 0 5px;
  254 + background: #eee;
  255 + border-radius: 3px;
  256 +}
  257 +
  258 +.markdown strong,
  259 +.markdown b {
  260 + font-weight: 600;
  261 +}
  262 +
  263 +.markdown>table {
  264 + border-collapse: collapse;
  265 + border-spacing: 0px;
  266 + empty-cells: show;
  267 + border: 1px solid #e9e9e9;
  268 + width: 95%;
  269 + margin-bottom: 24px;
  270 +}
  271 +
  272 +.markdown>table th {
  273 + white-space: nowrap;
  274 + color: #333;
  275 + font-weight: 600;
  276 +}
  277 +
  278 +.markdown>table th,
  279 +.markdown>table td {
  280 + border: 1px solid #e9e9e9;
  281 + padding: 8px 16px;
  282 + text-align: left;
  283 +}
  284 +
  285 +.markdown>table th {
  286 + background: #F7F7F7;
  287 +}
  288 +
  289 +.markdown blockquote {
  290 + font-size: 90%;
  291 + color: #999;
  292 + border-left: 4px solid #e9e9e9;
  293 + padding-left: 0.8em;
  294 + margin: 1em 0;
  295 +}
  296 +
  297 +.markdown blockquote p {
  298 + margin: 0;
  299 +}
  300 +
  301 +.markdown .anchor {
  302 + opacity: 0;
  303 + transition: opacity 0.3s ease;
  304 + margin-left: 8px;
  305 +}
  306 +
  307 +.markdown .waiting {
  308 + color: #ccc;
  309 +}
  310 +
  311 +.markdown h1:hover .anchor,
  312 +.markdown h2:hover .anchor,
  313 +.markdown h3:hover .anchor,
  314 +.markdown h4:hover .anchor,
  315 +.markdown h5:hover .anchor,
  316 +.markdown h6:hover .anchor {
  317 + opacity: 1;
  318 + display: inline-block;
  319 +}
  320 +
  321 +.markdown>br,
  322 +.markdown>p>br {
  323 + clear: both;
  324 +}
  325 +
  326 +
  327 +.hljs {
  328 + display: block;
  329 + background: white;
  330 + padding: 0.5em;
  331 + color: #333333;
  332 + overflow-x: auto;
  333 +}
  334 +
  335 +.hljs-comment,
  336 +.hljs-meta {
  337 + color: #969896;
  338 +}
  339 +
  340 +.hljs-string,
  341 +.hljs-variable,
  342 +.hljs-template-variable,
  343 +.hljs-strong,
  344 +.hljs-emphasis,
  345 +.hljs-quote {
  346 + color: #df5000;
  347 +}
  348 +
  349 +.hljs-keyword,
  350 +.hljs-selector-tag,
  351 +.hljs-type {
  352 + color: #a71d5d;
  353 +}
  354 +
  355 +.hljs-literal,
  356 +.hljs-symbol,
  357 +.hljs-bullet,
  358 +.hljs-attribute {
  359 + color: #0086b3;
  360 +}
  361 +
  362 +.hljs-section,
  363 +.hljs-name {
  364 + color: #63a35c;
  365 +}
  366 +
  367 +.hljs-tag {
  368 + color: #333333;
  369 +}
  370 +
  371 +.hljs-title,
  372 +.hljs-attr,
  373 +.hljs-selector-id,
  374 +.hljs-selector-class,
  375 +.hljs-selector-attr,
  376 +.hljs-selector-pseudo {
  377 + color: #795da3;
  378 +}
  379 +
  380 +.hljs-addition {
  381 + color: #55a532;
  382 + background-color: #eaffea;
  383 +}
  384 +
  385 +.hljs-deletion {
  386 + color: #bd2c00;
  387 + background-color: #ffecec;
  388 +}
  389 +
  390 +.hljs-link {
  391 + text-decoration: underline;
  392 +}
  393 +
  394 +/* 代码高亮 */
  395 +/* PrismJS 1.15.0
  396 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
  397 +/**
  398 + * prism.js default theme for JavaScript, CSS and HTML
  399 + * Based on dabblet (http://dabblet.com)
  400 + * @author Lea Verou
  401 + */
  402 +code[class*="language-"],
  403 +pre[class*="language-"] {
  404 + color: black;
  405 + background: none;
  406 + text-shadow: 0 1px white;
  407 + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  408 + text-align: left;
  409 + white-space: pre;
  410 + word-spacing: normal;
  411 + word-break: normal;
  412 + word-wrap: normal;
  413 + line-height: 1.5;
  414 +
  415 + -moz-tab-size: 4;
  416 + -o-tab-size: 4;
  417 + tab-size: 4;
  418 +
  419 + -webkit-hyphens: none;
  420 + -moz-hyphens: none;
  421 + -ms-hyphens: none;
  422 + hyphens: none;
  423 +}
  424 +
  425 +pre[class*="language-"]::-moz-selection,
  426 +pre[class*="language-"] ::-moz-selection,
  427 +code[class*="language-"]::-moz-selection,
  428 +code[class*="language-"] ::-moz-selection {
  429 + text-shadow: none;
  430 + background: #b3d4fc;
  431 +}
  432 +
  433 +pre[class*="language-"]::selection,
  434 +pre[class*="language-"] ::selection,
  435 +code[class*="language-"]::selection,
  436 +code[class*="language-"] ::selection {
  437 + text-shadow: none;
  438 + background: #b3d4fc;
  439 +}
  440 +
  441 +@media print {
  442 +
  443 + code[class*="language-"],
  444 + pre[class*="language-"] {
  445 + text-shadow: none;
  446 + }
  447 +}
  448 +
  449 +/* Code blocks */
  450 +pre[class*="language-"] {
  451 + padding: 1em;
  452 + margin: .5em 0;
  453 + overflow: auto;
  454 +}
  455 +
  456 +:not(pre)>code[class*="language-"],
  457 +pre[class*="language-"] {
  458 + background: #f5f2f0;
  459 +}
  460 +
  461 +/* Inline code */
  462 +:not(pre)>code[class*="language-"] {
  463 + padding: .1em;
  464 + border-radius: .3em;
  465 + white-space: normal;
  466 +}
  467 +
  468 +.token.comment,
  469 +.token.prolog,
  470 +.token.doctype,
  471 +.token.cdata {
  472 + color: slategray;
  473 +}
  474 +
  475 +.token.punctuation {
  476 + color: #999;
  477 +}
  478 +
  479 +.namespace {
  480 + opacity: .7;
  481 +}
  482 +
  483 +.token.property,
  484 +.token.tag,
  485 +.token.boolean,
  486 +.token.number,
  487 +.token.constant,
  488 +.token.symbol,
  489 +.token.deleted {
  490 + color: #905;
  491 +}
  492 +
  493 +.token.selector,
  494 +.token.attr-name,
  495 +.token.string,
  496 +.token.char,
  497 +.token.builtin,
  498 +.token.inserted {
  499 + color: #690;
  500 +}
  501 +
  502 +.token.operator,
  503 +.token.entity,
  504 +.token.url,
  505 +.language-css .token.string,
  506 +.style .token.string {
  507 + color: #9a6e3a;
  508 + background: hsla(0, 0%, 100%, .5);
  509 +}
  510 +
  511 +.token.atrule,
  512 +.token.attr-value,
  513 +.token.keyword {
  514 + color: #07a;
  515 +}
  516 +
  517 +.token.function,
  518 +.token.class-name {
  519 + color: #DD4A68;
  520 +}
  521 +
  522 +.token.regex,
  523 +.token.important,
  524 +.token.variable {
  525 + color: #e90;
  526 +}
  527 +
  528 +.token.important,
  529 +.token.bold {
  530 + font-weight: bold;
  531 +}
  532 +
  533 +.token.italic {
  534 + font-style: italic;
  535 +}
  536 +
  537 +.token.entity {
  538 + cursor: help;
  539 +}
... ...