askin 2 years ago
parent
commit
a33eabf2f5
45 changed files with 20638 additions and 0 deletions
  1. 10 0
      sources/client/vrv-platform/.postcssrc.js
  2. BIN
      sources/client/vrv-platform/build/logo.png
  3. 101 0
      sources/client/vrv-platform/build/utils.js
  4. 22 0
      sources/client/vrv-platform/build/vue-loader.conf.js
  5. 82 0
      sources/client/vrv-platform/build/webpack.base.conf.js
  6. 95 0
      sources/client/vrv-platform/build/webpack.dev.conf.js
  7. 145 0
      sources/client/vrv-platform/build/webpack.prod.conf.js
  8. 69 0
      sources/client/vrv-platform/config/index.js
  9. 4 0
      sources/client/vrv-platform/config/prod.env.js
  10. 12 0
      sources/client/vrv-platform/index.html
  11. 22 0
      sources/client/vrv-platform/src/App.vue
  12. BIN
      sources/client/vrv-platform/src/assets/logo.png
  13. 108 0
      sources/client/vrv-platform/src/config/api.js
  14. 27 0
      sources/client/vrv-platform/src/main.js
  15. 59 0
      sources/client/vrv-platform/src/router/index.js
  16. 194 0
      sources/client/vrv-platform/src/views/login/login.vue
  17. 130 0
      sources/client/vrv-platform/src/views/menu/menu.vue
  18. 305 0
      sources/client/vrv-platform/src/views/project/project.vue
  19. 284 0
      sources/client/vrv-platform/src/views/user/user.vue
  20. 7474 0
      sources/client/vrv-platform/yarn.lock
  21. 29 0
      sources/client/vrv11/README.md
  22. 5 0
      sources/client/vrv11/postcss.config.js
  23. 17 0
      sources/client/vrv11/public/index.html
  24. 20 0
      sources/client/vrv11/src/App.vue
  25. BIN
      sources/client/vrv11/src/assets/login_bg.png
  26. BIN
      sources/client/vrv11/src/assets/logo_banner.jpg
  27. 156 0
      sources/client/vrv11/src/components/menu-choose-box/MenuChooseBox.vue
  28. 115 0
      sources/client/vrv11/src/config/api.js
  29. 214 0
      sources/client/vrv11/src/config/routes.js
  30. 182 0
      sources/client/vrv11/src/main.js
  31. 9 0
      sources/client/vrv11/src/router.js
  32. 16 0
      sources/client/vrv11/src/store.js
  33. 299 0
      sources/client/vrv11/src/views/Login.vue
  34. 0 0
      sources/client/vrv11/src/views/device-alarm-record/List.vue
  35. 0 0
      sources/client/vrv11/src/views/device/List.vue
  36. 0 0
      sources/client/vrv11/src/views/gateway/List.vue
  37. 569 0
      sources/client/vrv11/src/views/home/Home.vue
  38. 404 0
      sources/client/vrv11/src/views/home/TaskDetail.vue
  39. 334 0
      sources/client/vrv11/src/views/home/TaskList.vue
  40. 0 0
      sources/client/vrv11/src/views/operator-log/List.vue
  41. 0 0
      sources/client/vrv11/src/views/operator/List.vue
  42. 334 0
      sources/client/vrv11/src/views/project/List.vue
  43. 0 0
      sources/client/vrv11/src/views/user/List.vue
  44. 21 0
      sources/client/vrv11/vue.config.js
  45. 8771 0
      sources/client/vrv11/yarn.lock

+ 10 - 0
sources/client/vrv-platform/.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": {}
+  }
+}

BIN
sources/client/vrv-platform/build/logo.png


+ 101 - 0
sources/client/vrv-platform/build/utils.js

@@ -0,0 +1,101 @@
+'use strict'
+const path = require('path')
+const config = require('../config')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const packageConfig = require('../package.json')
+
+exports.assetsPath = function (_path) {
+  const assetsSubDirectory = process.env.NODE_ENV === 'production'
+    ? config.build.assetsSubDirectory
+    : config.dev.assetsSubDirectory
+
+  return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function (options) {
+  options = options || {}
+
+  const cssLoader = {
+    loader: 'css-loader',
+    options: {
+      sourceMap: options.sourceMap
+    }
+  }
+
+  const postcssLoader = {
+    loader: 'postcss-loader',
+    options: {
+      sourceMap: options.sourceMap
+    }
+  }
+
+  // generate loader string to be used with extract text plugin
+  function generateLoaders (loader, loaderOptions) {
+    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
+
+    if (loader) {
+      loaders.push({
+        loader: loader + '-loader',
+        options: Object.assign({}, loaderOptions, {
+          sourceMap: options.sourceMap
+        })
+      })
+    }
+
+    // Extract CSS when that option is specified
+    // (which is the case during production build)
+    if (options.extract) {
+      return ExtractTextPlugin.extract({
+        use: loaders,
+        fallback: 'vue-style-loader'
+      })
+    } else {
+      return ['vue-style-loader'].concat(loaders)
+    }
+  }
+
+  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+  return {
+    css: generateLoaders(),
+    postcss: generateLoaders(),
+    less: generateLoaders('less'),
+    sass: generateLoaders('sass', { indentedSyntax: true }),
+    scss: generateLoaders('sass'),
+    stylus: generateLoaders('stylus'),
+    styl: generateLoaders('stylus')
+  }
+}
+
+// Generate loaders for standalone style files (outside of .vue)
+exports.styleLoaders = function (options) {
+  const output = []
+  const loaders = exports.cssLoaders(options)
+
+  for (const extension in loaders) {
+    const loader = loaders[extension]
+    output.push({
+      test: new RegExp('\\.' + extension + '$'),
+      use: loader
+    })
+  }
+
+  return output
+}
+
+exports.createNotifierCallback = () => {
+  const notifier = require('node-notifier')
+
+  return (severity, errors) => {
+    if (severity !== 'error') return
+
+    const error = errors[0]
+    const filename = error.file && error.file.split('!').pop()
+
+    notifier.notify({
+      title: packageConfig.name,
+      message: severity + ': ' + error.name,
+      subtitle: filename || '',
+      icon: path.join(__dirname, 'logo.png')
+    })
+  }
+}

+ 22 - 0
sources/client/vrv-platform/build/vue-loader.conf.js

@@ -0,0 +1,22 @@
+'use strict'
+const utils = require('./utils')
+const config = require('../config')
+const isProduction = process.env.NODE_ENV === 'production'
+const sourceMapEnabled = isProduction
+  ? config.build.productionSourceMap
+  : config.dev.cssSourceMap
+
+module.exports = {
+  loaders: utils.cssLoaders({
+    sourceMap: sourceMapEnabled,
+    extract: isProduction
+  }),
+  cssSourceMap: sourceMapEnabled,
+  cacheBusting: config.dev.cacheBusting,
+  transformToRequire: {
+    video: ['src', 'poster'],
+    source: 'src',
+    img: 'src',
+    image: 'xlink:href'
+  }
+}

+ 82 - 0
sources/client/vrv-platform/build/webpack.base.conf.js

@@ -0,0 +1,82 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const config = require('../config')
+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: process.env.NODE_ENV === 'production'
+      ? config.build.assetsPublicPath
+      : config.dev.assetsPublicPath
+  },
+  resolve: {
+    extensions: ['.js', '.vue', '.json'],
+    alias: {
+      'vue$': 'vue/dist/vue.esm.js',
+      '@': resolve('src'),
+    }
+  },
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: vueLoaderConfig
+      },
+      {
+        test: /\.js$/,
+        loader: 'babel-loader',
+        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
+      },
+      {
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('img/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('media/[name].[hash:7].[ext]')
+        }
+      },
+      {
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+        loader: 'url-loader',
+        options: {
+          limit: 10000,
+          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+        }
+      }
+    ]
+  },
+  node: {
+    // prevent webpack from injecting useless setImmediate polyfill because Vue
+    // source contains it (although only uses it if it's native).
+    setImmediate: false,
+    // prevent webpack from injecting mocks to Node native modules
+    // that does not make sense for the client
+    dgram: 'empty',
+    fs: 'empty',
+    net: 'empty',
+    tls: 'empty',
+    child_process: 'empty'
+  }
+}

+ 95 - 0
sources/client/vrv-platform/build/webpack.dev.conf.js

@@ -0,0 +1,95 @@
+'use strict'
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const path = require('path')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+const portfinder = require('portfinder')
+
+const HOST = process.env.HOST
+const PORT = process.env.PORT && Number(process.env.PORT)
+
+const devWebpackConfig = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
+  },
+  // cheap-module-eval-source-map is faster for development
+  devtool: config.dev.devtool,
+
+  // these devServer options should be customized in /config/index.js
+  devServer: {
+    clientLogLevel: 'warning',
+    historyApiFallback: {
+      rewrites: [
+        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
+      ],
+    },
+    hot: true,
+    contentBase: false, // since we use CopyWebpackPlugin.
+    compress: true,
+    host: HOST || config.dev.host,
+    port: PORT || config.dev.port,
+    open: config.dev.autoOpenBrowser,
+    overlay: config.dev.errorOverlay
+      ? { warnings: false, errors: true }
+      : false,
+    publicPath: config.dev.assetsPublicPath,
+    proxy: config.dev.proxyTable,
+    quiet: true, // necessary for FriendlyErrorsPlugin
+    watchOptions: {
+      poll: config.dev.poll,
+    }
+  },
+  plugins: [
+    new webpack.DefinePlugin({
+      'process.env': require('../config/dev.env')
+    }),
+    new webpack.HotModuleReplacementPlugin(),
+    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
+    new webpack.NoEmitOnErrorsPlugin(),
+    // https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: 'index.html',
+      inject: true
+    }),
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.dev.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ]
+})
+
+module.exports = new Promise((resolve, reject) => {
+  portfinder.basePort = process.env.PORT || config.dev.port
+  portfinder.getPort((err, port) => {
+    if (err) {
+      reject(err)
+    } else {
+      // publish the new Port, necessary for e2e tests
+      process.env.PORT = port
+      // add port to devServer config
+      devWebpackConfig.devServer.port = port
+
+      // Add FriendlyErrorsPlugin
+      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
+        compilationSuccessInfo: {
+          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
+        },
+        onErrors: config.dev.notifyOnErrors
+        ? utils.createNotifierCallback()
+        : undefined
+      }))
+
+      resolve(devWebpackConfig)
+    }
+  })
+})

+ 145 - 0
sources/client/vrv-platform/build/webpack.prod.conf.js

@@ -0,0 +1,145 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+
+const env = require('../config/prod.env')
+
+const webpackConfig = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({
+      sourceMap: config.build.productionSourceMap,
+      extract: true,
+      usePostCSS: true
+    })
+  },
+  devtool: config.build.productionSourceMap ? config.build.devtool : false,
+  output: {
+    path: config.build.assetsRoot,
+    filename: utils.assetsPath('js/[name].[chunkhash].js'),
+    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
+  },
+  plugins: [
+    // http://vuejs.github.io/vue-loader/en/workflow/production.html
+    new webpack.DefinePlugin({
+      'process.env': env
+    }),
+    new UglifyJsPlugin({
+      uglifyOptions: {
+        compress: {
+          warnings: false
+        }
+      },
+      sourceMap: config.build.productionSourceMap,
+      parallel: true
+    }),
+    // extract css into its own file
+    new ExtractTextPlugin({
+      filename: utils.assetsPath('css/[name].[contenthash].css'),
+      // Setting the following option to `false` will not extract CSS from codesplit chunks.
+      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
+      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 
+      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
+      allChunks: true,
+    }),
+    // Compress extracted CSS. We are using this plugin so that possible
+    // duplicated CSS from different components can be deduped.
+    new OptimizeCSSPlugin({
+      cssProcessorOptions: config.build.productionSourceMap
+        ? { safe: true, map: { inline: false } }
+        : { safe: true }
+    }),
+    // generate dist index.html with correct asset hash for caching.
+    // you can customize output by editing /index.html
+    // see https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: config.build.index,
+      template: 'index.html',
+      inject: true,
+      minify: {
+        removeComments: true,
+        collapseWhitespace: true,
+        removeAttributeQuotes: true
+        // more options:
+        // https://github.com/kangax/html-minifier#options-quick-reference
+      },
+      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
+      chunksSortMode: 'dependency'
+    }),
+    // keep module.id stable when vendor modules does not change
+    new webpack.HashedModuleIdsPlugin(),
+    // enable scope hoisting
+    new webpack.optimize.ModuleConcatenationPlugin(),
+    // split vendor js into its own file
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'vendor',
+      minChunks (module) {
+        // any required modules inside node_modules are extracted to vendor
+        return (
+          module.resource &&
+          /\.js$/.test(module.resource) &&
+          module.resource.indexOf(
+            path.join(__dirname, '../node_modules')
+          ) === 0
+        )
+      }
+    }),
+    // extract webpack runtime and module manifest to its own file in order to
+    // prevent vendor hash from being updated whenever app bundle is updated
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'manifest',
+      minChunks: Infinity
+    }),
+    // This instance extracts shared chunks from code splitted chunks and bundles them
+    // in a separate chunk, similar to the vendor chunk
+    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'app',
+      async: 'vendor-async',
+      children: true,
+      minChunks: 3
+    }),
+
+    // copy custom static assets
+    new CopyWebpackPlugin([
+      {
+        from: path.resolve(__dirname, '../static'),
+        to: config.build.assetsSubDirectory,
+        ignore: ['.*']
+      }
+    ])
+  ]
+})
+
+if (config.build.productionGzip) {
+  const CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+  webpackConfig.plugins.push(
+    new CompressionWebpackPlugin({
+      asset: '[path].gz[query]',
+      algorithm: 'gzip',
+      test: new RegExp(
+        '\\.(' +
+        config.build.productionGzipExtensions.join('|') +
+        ')$'
+      ),
+      threshold: 10240,
+      minRatio: 0.8
+    })
+  )
+}
+
+if (config.build.bundleAnalyzerReport) {
+  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
+}
+
+module.exports = webpackConfig

+ 69 - 0
sources/client/vrv-platform/config/index.js

@@ -0,0 +1,69 @@
+'use strict'
+// Template version: 1.3.1
+// see http://vuejs-templates.github.io/webpack for documentation.
+
+const path = require('path')
+
+module.exports = {
+  dev: {
+
+    // Paths
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+    proxyTable: {},
+
+    // Various Dev Server settings
+    host: 'localhost', // can be overwritten by process.env.HOST
+    port: 8081, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
+    autoOpenBrowser: false,
+    errorOverlay: true,
+    notifyOnErrors: true,
+    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
+
+
+    /**
+     * Source Maps
+     */
+
+    // https://webpack.js.org/configuration/devtool/#development
+    devtool: 'cheap-module-eval-source-map',
+
+    // If you have problems debugging vue-files in devtools,
+    // set this to false - it *may* help
+    // https://vue-loader.vuejs.org/en/options.html#cachebusting
+    cacheBusting: true,
+
+    cssSourceMap: true
+  },
+
+  build: {
+    // Template for index.html
+    index: path.resolve(__dirname, '../dist/index.html'),
+
+    // Paths
+    assetsRoot: path.resolve(__dirname, '../dist'),
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+
+    /**
+     * Source Maps
+     */
+
+    productionSourceMap: true,
+    // https://webpack.js.org/configuration/devtool/#production
+    devtool: '#source-map',
+
+    // Gzip off by default as many popular static hosts such as
+    // Surge or Netlify already gzip all static assets for you.
+    // Before setting to `true`, make sure to:
+    // npm install --save-dev compression-webpack-plugin
+    productionGzip: false,
+    productionGzipExtensions: ['js', 'css'],
+
+    // Run the build command with an extra argument to
+    // View the bundle analyzer report after build finishes:
+    // `npm run build --report`
+    // Set to `true` or `false` to always turn it on or off
+    bundleAnalyzerReport: process.env.npm_config_report
+  }
+}

+ 4 - 0
sources/client/vrv-platform/config/prod.env.js

@@ -0,0 +1,4 @@
+'use strict'
+module.exports = {
+  NODE_ENV: '"production"'
+}

+ 12 - 0
sources/client/vrv-platform/index.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <title>demo_project</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 22 - 0
sources/client/vrv-platform/src/App.vue

@@ -0,0 +1,22 @@
+<template>
+  <div id="app">
+    <router-view/>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'App'
+}
+</script>
+
+<style>
+#app {
+  font-family: 'Avenir', Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
+  margin-top: 60px;
+}
+</style>

BIN
sources/client/vrv-platform/src/assets/logo.png


+ 108 - 0
sources/client/vrv-platform/src/config/api.js

@@ -0,0 +1,108 @@
+//路径
+const root = "http://127.0.0.1:8088";
+
+//接口auth
+const api = {
+    user: {
+      list: `${root}/user/list`,
+      add: `${root}/user/add`,
+      update: `${root}/user/update`,
+      detail: `${root}/user/detail`,
+      delete: `${root}/user/delete`,
+      batchDelete: `${root}/user/batchDelete`,
+      bindRole: `${root}/user/bindRole`,
+      bindOperator: `${root}/user/bindOperator`,
+    },
+    operator: {
+      list: `${root}/operator/list`,
+      add: `${root}/operator/add`,
+      update: `${root}/operator/update`,
+      detail: `${root}/operator/detail`,
+      delete: `${root}/operator/delete`,
+      batchDelete: `${root}/operator/batchDelete`
+    },
+    project: {
+      list: `${root}/project/list`,
+      add: `${root}/project/add`,
+      update: `${root}/project/update`,
+      detail: `${root}/project/detail`,
+      delete: `${root}/project/delete`,
+      batchDelete: `${root}/project/batchDelete`
+    },
+    gateway: {
+      list: `${root}/gateway/list`,
+      add: `${root}/gateway/add`,
+      update: `${root}/gateway/update`,
+      detail: `${root}/gateway/detail`,
+      delete: `${root}/gateway/delete`,
+      batchDelete: `${root}/gateway/batchDelete`
+    },
+    device: {
+      list: `${root}/device/list`,
+      add: `${root}/device/add`,
+      update: `${root}/device/update`,
+      detail: `${root}/device/detail`,
+      delete: `${root}/device/delete`,
+      batchDelete: `${root}/device/batchDelete`,
+    },
+    deviceParam: {
+      list: `${root}/deviceParam/list`,
+      add: `${root}/deviceParam/add`,
+      update: `${root}/deviceParam/update`,
+      detail: `${root}/deviceParam/detail`,
+      delete: `${root}/deviceParam/delete`,
+      batchDelete: `${root}/deviceParam/batchDelete`,
+    },
+    deviceAlarmRecord: {
+      list: `${root}/deviceAlarmRecord/list`,
+      add: `${root}/deviceAlarmRecord/add`,
+      update: `${root}/deviceAlarmRecord/update`,
+      detail: `${root}/deviceAlarmRecord/detail`,
+      delete: `${root}/deviceAlarmRecord/delete`,
+      batchDelete: `${root}/deviceAlarmRecord/batchDelete`,
+    },
+    deviceAlarmConfig: {
+      list: `${root}/deviceAlarmConfig/list`,
+      add: `${root}/deviceAlarmConfig/add`,
+      update: `${root}/deviceAlarmConfig/update`,
+      detail: `${root}/deviceAlarmConfig/detail`,
+      delete: `${root}/deviceAlarmConfig/delete`,
+      batchDelete: `${root}/deviceAlarmConfig/batchDelete`,
+    },
+    deviceAlarmRepairRecord: {
+      list: `${root}/deviceAlarmRepairRecord/list`,
+      add: `${root}/deviceAlarmRepairRecord/add`,
+      update: `${root}/deviceAlarmRepairRecord/update`,
+      detail: `${root}/deviceAlarmRepairRecord/detail`,
+      delete: `${root}/deviceAlarmRepairRecord/delete`,
+      batchDelete: `${root}/deviceAlarmRepairRecord/batchDelete`,
+    },
+    operatorLog: {
+      list: `${root}/operatorLog/list`,
+      add: `${root}/operatorLog/add`,
+      update: `${root}/operatorLog/update`,
+      detail: `${root}/operatorLog/detail`,
+      delete: `${root}/operatorLog/delete`,
+      batchDelete: `${root}/operatorLog/batchDelete`,
+    },
+    auth: {
+      verifyCode: `${root}/auth/verifyCode`,
+      login: `${root}/auth/login`,
+      updateUserPassword: `${root}/auth/updateUserPassword`,
+      userInfo: `${root}/auth/userInfo`,
+      logout: `${root}/auth/logout`,
+    },
+    menu: {}
+  }
+;
+
+export default Object.assign(
+  {
+    $base: {
+      root: root,
+    },
+
+
+  },
+  api
+)

+ 27 - 0
sources/client/vrv-platform/src/main.js

@@ -0,0 +1,27 @@
+// The Vue build version to load with the `import` command
+// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
+import Vue from 'vue'
+import App from './App'
+
+
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import axios from 'axios'
+import api from './config/api'
+import router from "./router";
+
+Vue.prototype.axios = axios
+Vue.prototype.api = api
+
+Vue.use(ElementUI);
+Vue.config.productionTip = false
+
+/* eslint-disable no-new */
+new Vue({
+  el: '#app',
+  router,
+  components: {App},
+  template: '<App/>'
+})
+
+

+ 59 - 0
sources/client/vrv-platform/src/router/index.js

@@ -0,0 +1,59 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+
+
+import project from '@/views/project/project'
+import user from '@/views/user/user'
+import login from '@/views/login/login'
+import menu from '@/views/menu/menu'
+import operator from '@/views/operator/list'
+import gateway from '@/views/gateway/list'
+import device from '@/views/device/list'
+
+
+import operatorList from "../views/operator/list";
+import gatewayList from "../views/gateway/list";
+import deviceList from "../views/device/list";
+
+Vue.use(Router)
+
+export default new Router({
+  routes: [
+    {
+      path: '/project',
+      name: 'project',
+      component: project
+    }, {
+      path: '/user',
+      name: 'user',
+      component: user
+    },
+    {
+      path: '/',
+      name: 'login',
+      component: login
+    },
+    {
+      path: '/menu',
+      name: 'menu',
+      component: menu
+    },
+    {
+      path: '/operator',
+      name: 'operator',
+      component: operatorList
+    }
+    ,
+    {
+      path: '/gateway',
+      name: 'gateway',
+      component: gatewayList
+    }
+    ,
+    {
+      path: '/device',
+      name: 'device',
+      component: deviceList
+    }
+  ]
+})

+ 194 - 0
sources/client/vrv-platform/src/views/login/login.vue

@@ -0,0 +1,194 @@
+<template>
+  <transition name="el-fade-in-linear">
+    <div id="login">
+      <div class="login-box">
+
+        <!--        <div class="slider-banner-box">-->
+        <!--          <img src="../assets/logo_banner.jpg" width="100%" height="100%" alt="">-->
+        <!--        </div>-->
+
+        <div class="login-form">
+
+          <div style="display: inline-block;text-align: left;width: 80%">
+
+            <div class="title">
+              <!--              <img v-if="appInfo.logo" :src="`${$api.commonFile.download}?code=${appInfo.logo}`" style="height: 50px;"-->
+              <!--                   alt="">-->
+              <!--              <img v-else src="../assets/cloudgo_logo.png" style="height: 50px;" alt="">-->
+            </div>
+
+            <el-form ref="form" :rules="formRules" :model="form">
+
+              <el-form-item prop="account">
+
+                <div class="input-group">
+                  <el-input
+                    prefix-icon="el-icon-user"
+                    :autofocus="true"
+                    placeholder="请输入用户名"
+                    v-model="form.account">
+                  </el-input>
+                </div>
+              </el-form-item>
+
+              <el-form-item prop="password">
+                <div class="input-group">
+                  <el-input
+                    prefix-icon="el-icon-lock"
+                    placeholder="请输入密码"
+                    type="password"
+                    v-model="form.password">
+                  </el-input>
+                </div>
+              </el-form-item>
+
+              <el-form-item prop="verifyCode" :error="formErrorMsg.verifyCode">
+                <div class="input-group">
+                  <el-input
+                    prefix-icon="el-icon-circle-check"
+                    placeholder="请输入图形验证码"
+                    class="verify-input"
+                    v-model="form.verifyCode">
+                  </el-input>
+
+                  <img @click="handleRefreshVerifyCode" class="verify-img" :src="verifyCodeUrl" style="cursor: pointer"
+                       alt="">
+                </div>
+              </el-form-item>
+
+
+              <!--                            <div class="input-group" style="margin-bottom: 20px;">-->
+              <!--                                <label>记住我?</label>-->
+              <!--                                <el-switch-->
+              <!--                                        v-model="rememberMe"-->
+              <!--                                        on-text=""-->
+              <!--                                        off-text="">-->
+              <!--                                </el-switch>-->
+              <!--                            </div>-->
+              <div class="input-group">
+                <el-button @click="login" type="primary" :loading="isBtnLoading">{{ btnText }}
+                </el-button>
+              </div>
+
+            </el-form>
+
+
+          </div>
+
+        </div>
+
+      </div>
+    </div>
+  </transition>
+</template>
+
+<script>
+export default {
+  name: "login",
+  data() {
+    return {
+      // appInfo: {},
+      form: {
+        account: '',
+        password: '',
+        verifyCode: '',
+      },
+      formErrorMsg: {
+        account: '',
+        password: '',
+        verifyCode: '',
+      },
+      formRules: {
+        account: [
+          {required: true, message: '请输入用户名', trigger: 'blur'},
+        ],
+        password: [
+          {required: true, message: '请输入密码', trigger: 'blur'},
+        ],
+        verifyCode: [
+          {required: true, message: '请输入验证码', trigger: 'blur'},
+        ]
+      },
+      rememberMe: false,
+      isBtnLoading: false,
+      verifyCodeUrl: '',
+    };
+  },
+  computed: {
+    btnText() {
+      if (this.isBtnLoading) return '登录中...';
+      return '登录';
+    }
+  },
+
+  created() {
+    this.handleRefreshVerifyCode();
+  },
+
+  methods: {
+
+    handleRefreshVerifyCode() {
+      let vm = this;
+      vm.axios.get(vm.api.auth.verifyCode).then((resp) => {
+        console.log(resp)
+      })
+    },
+
+    login() {
+
+      this.isBtnLoading = true;
+      let vm = this;
+
+      vm.axios.post(vm.api.auth.login, vm.form).then((resp) => {
+
+        //  vm.router.push({path: '/project'});
+        vm.$router.push('/menu')
+        // if (resp.data.status === 200) {
+        //
+        //   console.log(resp.data.data)
+        //
+        //   //存储登录用户信息
+        //   sessionStorage.setItem('login-user-info', resp.data.data.userBean);
+        //   sessionStorage.setItem('remember-me', vm.rememberMe);
+        //
+        //   vm.router.push({path: '/project'});
+        // } else if (resp.data.status === 400) {
+        //
+        //
+        //   resp.data.data.errorFields.forEach(function (a) {
+        //
+        //     vm.formErrorMsg[a.name] = '';
+        //     vm.$nextTick(() => {
+        //       vm.formErrorMsg[a.name] = a.message;
+        //     });
+        //
+        //
+        //   });
+        //
+        //   if (resp.data.desc) {
+        //     vm.$message({
+        //       type: "error",
+        //       message: resp.data.desc
+        //     });
+        //   }
+        //   vm.isBtnLoading = false;
+        //
+        //
+        // } else {
+        //   vm.$message({
+        //     type: 'error',
+        //     message: resp.data.desc
+        //   });
+        //   vm.isBtnLoading = false;
+        // }
+
+      });
+
+    }
+  },
+
+}
+</script>
+
+<style>
+</style>

+ 130 - 0
sources/client/vrv-platform/src/views/menu/menu.vue

@@ -0,0 +1,130 @@
+<template>
+  <div id="menu">
+    <el-aside>
+      <el-row class="tac">
+        <el-col :span="24">
+          <el-menu
+            default-active="1"
+            class="el-menu-vertical-demo"
+            @open="handleOpen"
+            @close="handleClose">
+
+
+            <el-submenu index="1">
+              <template slot="title">
+                <span>数据可视化大屏</span>
+              </template>
+            </el-submenu>
+
+            <el-submenu index="2">
+              <template slot="title">
+                <i class="iconfont"></i>
+                <span @click="operator">运营商管理</span>
+              </template>
+            </el-submenu>
+
+            <el-submenu index="3">
+              <template slot="title">
+                <span @click="project">项目管理</span>
+              </template>
+
+              <el-submenu index="3-1">
+                <template slot="title">
+                  <span @click="gateway">网关管理</span>
+                </template>
+
+                <el-submenu index="3-2">
+                  <template slot="title">
+                    <span @click="device">设备管理</span>
+                  </template>
+
+                </el-submenu>
+
+              </el-submenu>
+
+            </el-submenu>
+
+            <el-submenu index="4">
+              <template slot="title">
+                <span>报警管理</span>
+              </template>
+            </el-submenu>
+
+            <el-submenu index="5">
+              <template slot="title">
+                <span>操作日志</span>
+              </template>
+            </el-submenu>
+
+            <el-submenu index="6">
+              <template slot="title">
+                <span>用户管理</span>
+              </template>
+            </el-submenu>
+
+            <el-submenu index="7">
+              <template slot="title">
+                <span>权限设置</span>
+              </template>
+            </el-submenu>
+
+
+          </el-menu>
+        </el-col>
+      </el-row>
+    </el-aside>
+
+  </div>
+
+</template>
+
+<script>
+export default {
+  name: "menu",
+
+  data() {
+    return {
+      index: '1',
+
+    }
+
+
+  },
+
+  created: function () {
+    let vm = this;
+   // vm.$router.push('/project')
+    this.project(index);
+  },
+
+  methods: {
+    handleOpen(key, keyPath) {
+      console.log(key, keyPath);
+    }
+    ,
+    handleClose(key, keyPath) {
+      console.log(key, keyPath);
+    },
+    project(index) {
+      let vm = this;
+      vm.$router.push('/project')
+    },
+    operator(index){
+      let vm = this;
+      vm.$router.push('/operator')
+    },
+    gateway(index) {
+      let vm = this;
+      vm.$router.push('/gateway')
+    },
+    device(index){
+      let vm = this;
+      vm.$router.push('/device')
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>

+ 305 - 0
sources/client/vrv-platform/src/views/project/project.vue

@@ -0,0 +1,305 @@
+<template>
+  <div id="project">
+    <el-container>
+
+      <el-main>
+        <el-form :inline="true" :model="searchFormData">
+          <el-form-item label="项目名称">
+            <el-input placeholder="项目名称" size="small" v-model="searchFormData.name"></el-input>
+          </el-form-item>
+          <el-form-item label="省份">
+            <el-input placeholder="省份" size="small" v-model="searchFormData.province"></el-input>
+          </el-form-item>
+          <el-form-item label="城市">
+            <el-input placeholder="城市" size="small" v-model="searchFormData.city"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" size="small" @click="search(searchFormData)">搜索</el-button>
+          </el-form-item>
+
+          <el-form-item>
+            <el-button type="primary" size="small" @click="showAdd">新增</el-button>
+          </el-form-item>
+
+
+          <el-dialog title="项目" :visible.sync="dialogFormVisible">
+            <el-form label-position="left" :model="formData">
+              <el-form-item label="栏目名称">
+                <el-input v-model="formData.name"></el-input>
+              </el-form-item>
+              <el-form-item label="项目省份">
+                <el-input v-model="formData.province"></el-input>
+              </el-form-item>
+              <el-form-item label="项目城市">
+                <el-input v-model="formData.city"></el-input>
+              </el-form-item>
+              <el-form-item label="客户名称">
+                <el-input v-model="formData.customer"></el-input>
+              </el-form-item>
+              <el-form-item label="客户电话">
+                <el-input v-model="formData.customerTel"></el-input>
+              </el-form-item>
+            </el-form>
+
+            <div slot="footer" class="dialog-footer">
+              <el-button @click="cancel()">取 消</el-button>
+              <el-button type="primary" @click="addOrEditMehtond()">确 定</el-button>
+            </div>
+          </el-dialog>
+
+        </el-form>
+
+
+        <el-table :data="tableData">
+
+          <el-table-column prop="name" label="项目名称"></el-table-column>
+          <el-table-column prop="customer" label="客户名称"></el-table-column>
+          <el-table-column prop="customerTel" label="客户电话"></el-table-column>
+          <el-table-column prop="province" label="项目省份"></el-table-column>
+          <el-table-column prop="city" label="项目城市"></el-table-column>
+
+          <el-table-column label="操作">
+            <template slot-scope="scope">
+              <el-button type="primary" size="small" @click="showEdit(scope.row)">修改</el-button>
+              <el-button type="danger" size="small" @click="del(scope.row)">删除</el-button>
+              <el-button type="primary" size="small" @click="gateway">网关</el-button>
+            </template>
+          </el-table-column>
+
+        </el-table>
+
+        <el-pagination
+          background
+          layout="prev, pager, next"
+          :page-size="pager.pageSize"
+          :current-page="pager.pageIndex"
+          :total="pager.itemCount"
+          @current-change="handleCurrentChange"
+        >
+        </el-pagination>
+      </el-main>
+
+    </el-container>
+  </div>
+</template>
+
+
+<script>
+import axios from "axios";
+
+export default {
+  name: 'project',
+  data() {
+    return {
+      addOrEdit: 1,
+
+      dialogFormVisible: false,
+
+      pager: {
+        pageSize: 2,
+        pageIndex: 1,
+        itemCount: 0,
+      },
+
+      tableData:
+        [{
+          name: '1',
+          customer: '1',
+          customerTel: '1',
+          province: '1',
+          city: '1',
+          code: '',
+          valid: '',
+        }],
+      formData: {
+        name: '1',
+        customer: '1',
+        customerTel: '1',
+        province: '1',
+        city: '1',
+        code: '',
+        valid: '',
+      },
+      searchFormData:
+        {
+          name: '',
+          province: '',
+          city: ''
+        }
+    }
+  },
+
+  created: function () {
+    this.loadData();
+  },
+
+  methods: {
+    //切换页码
+    handleCurrentChange(index) {
+      this.loadData(index)
+    },
+
+    loadData(index) {
+      const vm = this;
+      vm.axios.get('http://localhost:8088/project/list', {
+        params: {
+          pageSize: 5,
+          pageIndex: index ? index : 1,
+          name: this.searchFormData.name,
+          province: this.searchFormData.province,
+          city: this.searchFormData.city,
+        }
+      })
+        .then((response) => {
+          // vm.paper = response.data.data.paper;
+          //console.log(response.data.data);
+
+          vm.pager = response.data.data.pager
+
+          vm.tableData = response.data.data.projects;
+        })
+    },
+    search(searchFormData) {
+      //console.log(this.searchFormData)
+      this.loadData();
+    },
+    showAdd() {
+      this.dialogFormVisible = true;
+
+      this.formData.name = '';
+      this.formData.province = '';
+      this.formData.city = '';
+      this.formData.customer = '';
+      this.formData.customerTel = '';
+      this.addOrEdit = 1
+    },
+
+    showEdit(row) {
+
+      console.log(row)
+
+      this.dialogFormVisible = true;
+
+      this.formData = row
+
+      this.addOrEdit = 2
+    },
+
+
+    addOrEditMehtond() {
+      const vm = this;
+      if (this.addOrEdit == 2) {
+        vm.axios.get('http://localhost:8088/project/update', {
+          params: {
+            code: this.formData.code,
+            name: this.formData.name,
+            province: this.formData.province,
+            city: this.formData.city,
+            customer: this.formData.customer,
+            customerTel: this.formData.customerTel,
+          }
+        })
+          .then((response) => {
+            console.log(response)
+
+            if (response.data.status == 200) {
+
+              this.$message({
+                type: 'success',
+                showClose: true,
+                message: response.data.desc
+              })
+            }
+
+            this.dialogFormVisible = false;
+
+            this.loadData();
+
+          })
+          .catch(() => {
+          });
+      }
+
+      if (this.addOrEdit == 1) {
+        vm.axios.get('http://localhost:8088/project/add', {
+          params: {
+            name: this.formData.name,
+            province: this.formData.province,
+            city: this.formData.city,
+            customer: this.formData.customer,
+            customerTel: this.formData.customerTel
+          }
+        })
+          .then((response) => {
+            if (response.data.status == 200) {
+
+              this.dialogFormVisible = false;
+
+              this.$message({
+                type: 'success',
+                showClose: true,
+                message: response.data.desc
+              })
+
+              this.loadData();
+            }
+          })
+      }
+    },
+
+    del(row) {
+      const vm = this;
+      this.$confirm('确认删除', '提示', {
+        type: 'warning'
+      }).then(() => {
+        vm.axios.get('http://localhost:8088/project/delete', {
+          params: {
+            code: row.code,
+          }
+        })
+          .then((response) => {
+            console.log(response)
+            if (response.data.status == 200) {
+              this.$message({
+                type: 'success',
+                showClose: true,
+                message: response.data.desc
+              })
+
+            }
+            this.loadData();
+          })
+      })
+        .catch(() => {
+          this.$message({
+            type: 'info',
+            showClose: true,
+            message: '取消删除'
+          })
+        });
+    },
+    cancel() {
+      this.$message({
+        message: '操作取消',
+        showClose: true,
+        type: 'info'
+      });
+
+      this.dialogFormVisible = false;
+    },
+
+    gateway(){
+      let vm = this;
+      vm.$router.push('/gateway')
+    }
+
+
+  }
+
+
+}
+</script>
+
+<style scoped>
+
+</style>

+ 284 - 0
sources/client/vrv-platform/src/views/user/user.vue

@@ -0,0 +1,284 @@
+<template>
+  <div id="user">
+    <el-main>
+      <el-form :inline="true" :model="searchFormData">
+        <el-form-item label="用户名称">
+          <el-input placeholder="用户名称" size="small" v-model="searchFormData.realname"></el-input>
+        </el-form-item>
+        <el-form-item label="账号">
+          <el-input placeholder="账号" size="small" v-model="searchFormData.account"></el-input>
+        </el-form-item>
+        <el-form-item label="密码">
+          <el-input placeholder="密码" size="small" v-model="searchFormData.roleFlag"></el-input>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button type="primary" size="small" @click="search(searchFormData)">搜索</el-button>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button type="primary" size="small" @click="showAdd">新增</el-button>
+        </el-form-item>
+
+        <el-dialog title="用户" :visible.sync="dialogFormVisible">
+          <el-form label-position="left" :model="formData">
+            <el-form-item label="用户名称">
+              <el-input v-model="formData.realname"></el-input>
+            </el-form-item>
+            <el-form-item label="账号">
+              <el-input v-model="formData.account"></el-input>
+            </el-form-item>
+            <el-form-item label="角色">
+              <el-input v-model="formData.roleFlag"></el-input>
+            </el-form-item>
+          </el-form>
+
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="cancel()">取 消</el-button>
+            <el-button type="primary" @click="addOrEditMehtond()">确 定</el-button>
+          </div>
+        </el-dialog>
+
+      </el-form>
+
+
+      <el-table :data="tableData">
+
+        <el-table-column prop="realname" label="用户名称"></el-table-column>
+        <el-table-column prop="account" label="账号"></el-table-column>
+        <el-table-column prop="roleFlag" label="角色"></el-table-column>
+
+
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button type="primary" size="small" @click="showEdit(scope.row)">修改</el-button>
+            <el-button type="danger" size="small" @click="del(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+
+      </el-table>
+
+      <el-pagination
+        background
+        layout="prev, pager, next"
+        :page-size="pager.pageSize"
+        :current-page="pager.pageIndex"
+        :total="pager.itemCount"
+        @current-change="handleCurrentChange"
+      >
+      </el-pagination>
+
+    </el-main>
+  </div>
+
+</template>
+
+<script>
+export default {
+  name: 'user',
+  data() {
+    return {
+
+      addOrEdit: 1,
+
+      dialogFormVisible: false,
+
+      pager: {
+        pageSize: 2,
+        pageIndex: 1,
+        itemCount: 0,
+      },
+
+      tableData:
+        [{
+          realname: '',
+          account: '',
+          roleFlag: '',
+          code: '',
+          valid: '',
+        }],
+      formData: {
+        realname: '',
+        account: '',
+        roleFlag: '',
+        code: '',
+        valid: '',
+      },
+      searchFormData:
+        {
+          realname: '',
+          account: '',
+          roleFlag: '',
+        }
+    }
+  },
+
+  created: function () {
+    this.loadData();
+  },
+
+  methods: {
+    //切换页码
+    handleCurrentChange(index) {
+      this.loadData(index)
+    },
+
+    loadData(index) {
+      const vm = this;
+      vm.axios.get('http://localhost:8088/user/list', {
+        params: {
+          pageSize: 3,
+          pageIndex: index ? index : 1,
+          realname: this.searchFormData.realname,
+          account: this.searchFormData.account,
+          password: this.searchFormData.roleFlag,
+        }
+      })
+        .then((response) => {
+          // vm.paper = response.data.data.paper;
+          //console.log(response.data.data);
+
+          vm.pager = response.data.data.pager
+
+          vm.tableData = response.data.data.users;
+        })
+    },
+    search(searchFormData) {
+      //console.log(this.searchFormData)
+      this.loadData();
+    },
+    showAdd() {
+      this.dialogFormVisible = true;
+
+      this.formData.realname = '';
+      this.formData.account = '';
+      this.formData.roleFlag = '';
+
+      this.addOrEdit = 1
+    },
+
+    showEdit(row) {
+
+      console.log(row)
+
+      this.dialogFormVisible = true;
+
+      this.formData = row
+
+      this.addOrEdit = 2
+    },
+
+
+    addOrEditMehtond() {
+      const vm = this;
+      if (this.addOrEdit == 2) {
+        vm.axios.get('http://localhost:8088/user/update', {
+          params: {
+            code: this.formData.code,
+            realname: this.formData.realname,
+            account: this.formData.account,
+            password: this.formData.roleFlag
+          }
+        })
+          .then((response) => {
+            console.log(response)
+
+            if (response.data.status == 200) {
+
+              this.$message({
+                type: 'success',
+                showClose: true,
+                message: response.data.desc
+              })
+            }
+
+            this.dialogFormVisible = false;
+
+            this.loadData();
+
+          })
+          .catch(() => {
+          });
+      }
+
+      if (this.addOrEdit == 1) {
+        vm.axios.get('http://localhost:8088/user/add', {
+          params: {
+            realname: this.formData.realname,
+            account: this.formData.account,
+            password: this.formData.roleFlag
+          }
+        })
+          .then((response) => {
+            if (response.data.status == 200) {
+
+              this.dialogFormVisible = false;
+
+              this.$message({
+                type: 'success',
+                showClose: true,
+                message: response.data.desc
+              })
+
+              this.loadData();
+            }
+          })
+      }
+    },
+
+    del(row) {
+      const vm = this;
+      this.$confirm('确认删除', '提示', {
+        type: 'warning'
+      }).then(() => {
+        vm.axios.get('http://localhost:8088/user/delete', {
+          params: {
+            code: row.code,
+          }
+        })
+          .then((response) => {
+            console.log(response)
+            if (response.data.status == 200) {
+              this.$message({
+                type: 'success',
+                showClose: true,
+                message: response.data.desc
+              })
+
+            }
+            this.loadData();
+          })
+      })
+        .catch(() => {
+          this.$message({
+            type: 'info',
+            showClose: true,
+            message: '取消删除'
+          })
+        });
+    },
+    cancel() {
+      this.$message({
+        message: '操作取消',
+        showClose: true,
+        type: 'info'
+      });
+
+      this.dialogFormVisible = false;
+
+    },
+
+  }
+}
+</script>
+
+<style>
+#app {
+  font-family: 'Avenir', Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
+  margin-top: 60px;
+}
+</style>

File diff suppressed because it is too large
+ 7474 - 0
sources/client/vrv-platform/yarn.lock


+ 29 - 0
sources/client/vrv11/README.md

@@ -0,0 +1,29 @@
+# gov-scafe-platform
+
+## Project setup
+```
+yarn install
+```
+
+### Compiles and hot-reloads for development
+```
+yarn run serve
+```
+
+### Compiles and minifies for production
+```
+yarn run build
+```
+
+### Run your tests
+```
+yarn run test
+```
+
+### Lints and fixes files
+```
+yarn run lint
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).

+ 5 - 0
sources/client/vrv11/postcss.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  plugins: {
+    autoprefixer: {}
+  }
+}

+ 17 - 0
sources/client/vrv11/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+<!--    <link rel="icon" href="<%= BASE_URL %>favicon.ico">-->
+    <title>系统正在加载中....</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but cloudgo-acs-platform doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 20 - 0
sources/client/vrv11/src/App.vue

@@ -0,0 +1,20 @@
+<template>
+  <div id="app">
+    <transition name="el-fade-in-linear">
+      <router-view/>
+    </transition>
+  </div>
+</template>
+
+<style lang="scss">
+
+  * {
+    font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
+  }
+
+  html, body, #app {
+    height: 100%;
+    position: relative;
+    overflow: hidden;
+  }
+</style>

BIN
sources/client/vrv11/src/assets/login_bg.png


BIN
sources/client/vrv11/src/assets/logo_banner.jpg


+ 156 - 0
sources/client/vrv11/src/components/menu-choose-box/MenuChooseBox.vue

@@ -0,0 +1,156 @@
+<template>
+    <el-tabs type="border-card" v-model="currentTabName" class="menu-choose-box" @tab-click="handleTabClick" style="padding: 0">
+        <el-tab-pane v-for="menu in menus" v-bind:key="menu.code" :label="menu.name" :name="menu.code" :style="{height: height ? height : 'auto'}"
+                     style="overflow-y: scroll;padding: 15px">
+
+            <el-tree
+
+                    :default-expand-all="true"
+                    :check-strictly="true"
+                    @check-change="handleCheckChange"
+                    :default-checked-keys="checkMenuItemCodes"
+                    :data="menu.tree"
+                    show-checkbox
+                    node-key="code"
+                    :props="defaultProps">
+            </el-tree>
+
+            <input type="hidden" v-model="value">
+
+        </el-tab-pane>
+    </el-tabs>
+</template>
+
+<script>
+    export default {
+        name: "MenuChooseBox",
+        props:{
+            value: {
+                type: Array,
+                default:function () {
+                    return [] ;
+                }
+            },
+            height: {
+                type: String,
+                default:''
+            },
+        },
+        data() {
+            return {
+                menus: [],
+                currentTabName: '',
+                defaultProps: {
+                    children: 'children',
+                    label: 'name'
+                },
+                checkMenuItemCodes: [],
+            }
+        },
+        watch:{
+
+            value(n,o){
+
+                if(!o.length && n.length){
+                    this.checkMenuItemCodes = this.value;
+
+                }
+
+
+            },
+
+            checkMenuItemCodes:{
+                deep:true,
+                handler:function (e) {
+                    this.$emit('input',e);
+                }
+            }
+        },
+        methods: {
+
+            handleCheckChange(e, check) {
+
+                let vm = this;
+
+                if (check) {
+
+                    if (this.checkMenuItemCodes.indexOf(e.code) === -1) {
+                        vm.checkMenuItemCodes.push(e.code);
+                    }
+
+                } else {
+
+                    if (this.checkMenuItemCodes.indexOf(e.code) !== -1) {
+                        vm.checkMenuItemCodes.splice(this.checkMenuItemCodes.indexOf(e.code),1);
+                    }
+
+                }
+            },
+
+            handleTabClick(tab) {
+
+
+                let vm = this;
+
+                let menu = vm.menus.find((m) => {
+                    return m.code === tab.name
+                });
+
+
+                if (menu && !menu.tree) {
+
+                    vm.$http.post(vm.$api.menu.tree, vm.$qs.stringify({code: tab.name})).then((resp) => {
+                        vm.$set(menu, 'tree', resp.data.data.menuItems);
+                    });
+
+                }
+            }
+        },
+        created() {
+
+            let vm = this;
+
+            //加载菜单数据
+            vm.$http.post(vm.$api.menu.list, vm.$qs.stringify({onPage: false})).then((resp) => {
+                vm.menus = resp.data.data.menus;
+
+
+                //加载第一个菜单项
+                vm.$http.post(vm.$api.menu.tree, vm.$qs.stringify({code: vm.menus[0].code})).then((resp) => {
+                    vm.$set(vm.menus[0], 'tree', resp.data.data.menuItems);
+                    vm.currentTabName = vm.menus[0].code;
+                });
+
+            })
+
+
+        }
+    }
+</script>
+
+<style lang="scss" scoped>
+
+    .el-tabs--border-card {
+        box-shadow: none;
+    }
+
+
+</style>
+
+<style lang="scss">
+
+    .menu-choose-box {
+
+
+        .el-tabs__header {
+            background-color: #ffffff;
+
+        }
+
+        .el-tabs__content{
+            padding: 0 !important;
+        }
+
+    }
+
+</style>

+ 115 - 0
sources/client/vrv11/src/config/api.js

@@ -0,0 +1,115 @@
+//域名
+const domain = window.location.host + "/api";
+
+//端口
+const port = null;
+
+//路径
+const root = window.location.protocol + "//" + domain + (port ? (":" + port) : "");
+
+//接口auth
+const api = {
+        user: {
+            list: `${root}/user/list`,
+            add: `${root}/user/add`,
+            update: `${root}/user/update`,
+            detail: `${root}/user/detail`,
+            delete: `${root}/user/delete`,
+            batchDelete: `${root}/user/batchDelete`,
+            bindRole: `${root}/user/bindRole`,
+            bindOperator: `${root}/user/bindOperator`,
+        },
+        operator: {
+            list: `${root}/operator/list`,
+            add: `${root}/operator/add`,
+            update: `${root}/operator/update`,
+            detail: `${root}/operator/detail`,
+            delete: `${root}/operator/delete`,
+            batchDelete: `${root}/operator/batchDelete`
+        },
+        project: {
+            list: `${root}/project/list`,
+            add: `${root}/project/add`,
+            update: `${root}/project/update`,
+            detail: `${root}/project/detail`,
+            delete: `${root}/project/delete`,
+            batchDelete: `${root}/project/batchDelete`
+        },
+        gateway: {
+            list: `${root}/gateway/list`,
+            add: `${root}/gateway/add`,
+            update: `${root}/gateway/update`,
+            detail: `${root}/gateway/detail`,
+            delete: `${root}/gateway/delete`,
+            batchDelete: `${root}/gateway/batchDelete`
+        },
+        device: {
+            list: `${root}/device/list`,
+            add: `${root}/device/add`,
+            update: `${root}/device/update`,
+            detail: `${root}/device/detail`,
+            delete: `${root}/device/delete`,
+            batchDelete: `${root}/device/batchDelete`,
+        },
+        deviceParam: {
+            list: `${root}/deviceParam/list`,
+            add: `${root}/deviceParam/add`,
+            update: `${root}/deviceParam/update`,
+            detail: `${root}/deviceParam/detail`,
+            delete: `${root}/deviceParam/delete`,
+            batchDelete: `${root}/deviceParam/batchDelete`,
+        },
+        deviceAlarmRecord: {
+            list: `${root}/deviceAlarmRecord/list`,
+            add: `${root}/deviceAlarmRecord/add`,
+            update: `${root}/deviceAlarmRecord/update`,
+            detail: `${root}/deviceAlarmRecord/detail`,
+            delete: `${root}/deviceAlarmRecord/delete`,
+            batchDelete: `${root}/deviceAlarmRecord/batchDelete`,
+        },
+        deviceAlarmConfig: {
+            list: `${root}/deviceAlarmConfig/list`,
+            add: `${root}/deviceAlarmConfig/add`,
+            update: `${root}/deviceAlarmConfig/update`,
+            detail: `${root}/deviceAlarmConfig/detail`,
+            delete: `${root}/deviceAlarmConfig/delete`,
+            batchDelete: `${root}/deviceAlarmConfig/batchDelete`,
+        },
+        deviceAlarmRepairRecord: {
+            list: `${root}/deviceAlarmRepairRecord/list`,
+            add: `${root}/deviceAlarmRepairRecord/add`,
+            update: `${root}/deviceAlarmRepairRecord/update`,
+            detail: `${root}/deviceAlarmRepairRecord/detail`,
+            delete: `${root}/deviceAlarmRepairRecord/delete`,
+            batchDelete: `${root}/deviceAlarmRepairRecord/batchDelete`,
+        },
+        operatorLog: {
+            list: `${root}/operatorLog/list`,
+            add: `${root}/operatorLog/add`,
+            update: `${root}/operatorLog/update`,
+            detail: `${root}/operatorLog/detail`,
+            delete: `${root}/operatorLog/delete`,
+            batchDelete: `${root}/operatorLog/batchDelete`,
+        },
+        auth: {
+            verifyCode: `${root}/auth/verifyCode`,
+            login: `${root}/auth/login`,
+            updateUserPassword: `${root}/auth/updateUserPassword`,
+            userInfo: `${root}/auth/userInfo`,
+            logout: `${root}/auth/logout`,
+        }
+    }
+;
+
+export default Object.assign(
+    {
+        $base: {
+            domain: domain,
+            port: port,
+            root: root,
+        },
+
+
+    },
+    api
+)

+ 214 - 0
sources/client/vrv11/src/config/routes.js

@@ -0,0 +1,214 @@
+import Index from 'fastboot-admin/src/views/common/Index.vue'
+
+export default [
+    {
+
+        path: '/epssys',
+        name: 'index',
+        meta: {tab: false},
+        component: Index,
+        // eslint-disable-next-line no-sparse-arrays
+        children: [
+            {
+                path: '/home',
+                name: 'home',
+                component: () => import(/* webpackChunkName: "views" */ '../views/home/Home'),
+            }, {
+                path: '/home/task-list',
+                name: 'task-list',
+                meta: {title: '楼栋派送任务', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/home/TaskList'),
+            } ,{
+                path: '/home/task-detail',
+                name: 'task-detail',
+                meta: {title: '楼栋派送任务详情', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/home/TaskDetail'),
+            },
+            {
+
+                path: '/building-manager/list',
+                name: 'building-manager-list',
+                meta: {title: '区域楼栋列表', tab: true,keepAlive:true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/building-manager/List'),
+            }, {
+
+                path: '/building-manager/add',
+                name: 'building-manager-add',
+                meta: {title: '区域楼栋新增', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/building-manager/Add'),
+            }, {
+
+                path: '/building-manager/edit',
+                name: 'building-manager-edit',
+                meta: {title: '区域楼栋编辑', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/building-manager/Edit'),
+            }, {
+                path: '/exception-template-manager/list',
+                name: 'exception-template-manager-list',
+                meta: {title: '异常原因模板列表', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/exception-template-manager/List'),
+            }, {
+
+                path: '/exception-template-manager/add',
+                name: 'exception-template-manager-add',
+                meta: {title: '异常原因模板新增', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/exception-template-manager/Add'),
+            }, {
+
+                path: '/exception-template-manager/edit',
+                name: 'exception-template-manager-edit',
+                meta: {title: '异常原因模板编辑', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/exception-template-manager/Edit'),
+            }, {
+                path: '/delivery-time-manager/list',
+                name: 'delivery-time-manager-list',
+                meta: {title: '配送时间段列表', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/delivery-time-manager/List'),
+            }, {
+
+                path: '/delivery-time-manager/add',
+                name: 'delivery-time-manager-add',
+                meta: {title: '配送时间段新增', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/delivery-time-manager/Add'),
+            }, {
+
+                path: '/delivery-time-manager/edit',
+                name: 'delivery-time-manager-edit',
+                meta: {title: '配送时间段编辑', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/delivery-time-manager/Edit'),
+            }, {
+                path: '/eps-employee-manager/list',
+                name: 'eps-employee-manager-list',
+                meta: {title: '员工列表', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/eps-employee-manager/List'),
+            }, {
+
+                path: '/eps-employee-manager/add',
+                name: 'eps-employee-manager-add',
+                meta: {title: '员工新增', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/eps-employee-manager/Add'),
+            }, {
+
+                path: '/eps-employee-manager/edit',
+                name: 'eps-employee-manager-edit',
+                meta: {title: '员工编辑', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/eps-employee-manager/Edit'),
+            }, {
+                path: '/coupon-manager/list',
+                name: 'coupon-manager-list',
+                meta: {title: '优惠卷列表', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/coupon-manager/List'),
+            }, {
+                path: '/coupon-manager/receive-list',
+                name: 'coupon-manager-receive-list',
+                meta: {title: '优惠劵领取记录', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/coupon-manager/ReceiveList'),
+            }, {
+
+                path: '/coupon-manager/add',
+                name: 'coupon-manager-add',
+                meta: {title: '优惠卷新增', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/coupon-manager/Add'),
+            }, {
+
+                path: '/coupon-manager/edit',
+                name: 'coupon-manager-edit',
+                meta: {title: '优惠卷编辑', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/coupon-manager/Edit'),
+            }, {
+                path: '/member-manager/list',
+                name: 'member-manager-list',
+                meta: {title: '会员列表', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/List'),
+            }, {
+
+                path: '/member-manager/receiving-list',
+                name: 'member-manager-receiving-list',
+                meta: {title: '会员寄件记录', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/ReceivingList'),
+            }, {
+
+                path: '/member-manager/refuse-list',
+                name: 'member-manager-refuse-list',
+                meta: {title: '会员预拒收记录', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/RefuseList'),
+            }, {
+
+                path: '/member-manager/receiving-detail',
+                name: 'member-manager-receiving-detail',
+                meta: {title: '会员寄件详情', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/ReceivingDetail'),
+            }, {
+
+                path: '/member-manager/delivery-list',
+                name: 'member-manager-delivery-list',
+                meta: {title: '会员收件记录', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/DeliveryList'),
+            }, {
+
+                path: '/member-manager/delivery-detail',
+                name: 'member-manager-delivery-detail',
+                meta: {title: '会员收件记录详情', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/DeliveryDetail'),
+            }, {
+
+                path: '/member-manager/detail',
+                name: 'member-manager-detail',
+                meta: {title: '会员详情', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/Detail'),
+            }, {
+
+                path: '/member-manager/delivery-verify',
+                name: 'member-manager-delivery-verify',
+                meta: {title: '会员快件核销', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/member-manager/DeliveryVerify'),
+            }
+            , {
+
+                path: '/receiving-record-manager/list',
+                name: 'receiving-record-manager-list',
+                meta: {title: '揽件列表', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/receiving-record-manager/List'),
+            }, {
+
+                path: '/receiving-record-manager/detail',
+                name: 'receiving-record-manager-detail',
+                meta: {title: '揽件详情', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/receiving-record-manager/Detail'),
+            }, {
+
+                path: '/receiving-record-manager/edit',
+                name: 'receiving-record-manager-edit',
+                meta: {title: '揽件编辑', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/receiving-record-manager/Edit'),
+            }
+            , {
+                path: '/delivery-record-manager/list',
+                name: 'delivery-record-manager-list',
+                meta: {title: '配送件列表', tab: true,keepAlive:true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/delivery-record-manager/List'),
+            },
+            , {
+
+                path: '/delivery-record-manager/verify',
+                name: 'delivery-record-manager-verify',
+                meta: {title: '配送件核销', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/delivery-record-manager/Verify'),
+            }, {
+
+                path: '/delivery-record-manager/detail',
+                name: 'delivery-record-manager-detail',
+                meta: {title: '配送件详情', tab: true},
+                component: () => import(/* webpackChunkName: "views" */ '../views/delivery-record-manager/Detail'),
+            }
+
+        ]
+    },
+    {
+
+        path: '/login',
+        name: 'login',
+        component: () => import(/* webpackChunkName: "views" */ '../views/Login'),
+    }
+]
+;

+ 182 - 0
sources/client/vrv11/src/main.js

@@ -0,0 +1,182 @@
+import Vue from 'vue'
+import App from './App.vue'
+import _ from 'lodash'
+import router from './router'
+import store from './store'
+console.log(router);
+
+//引入element
+import ElementUI from 'element-ui';
+import {Message} from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+Vue.use(ElementUI);
+
+
+//引入Fastboot UI库
+import  FastbootUI from 'fastboot-ui/src/components';
+import 'fastboot-ui/src/scss/element-theme.scss'
+
+Vue.use(FastbootUI);
+
+// import FastbootAdmin from 'fastboot-admin';
+// import DictSelect from "fastboot-admin/src/components/DictSelect.vue";
+// import OrgCascader from "fastboot-admin/src/components/OrgCascader.vue";
+// import DictText from "fastboot-admin/src/components/DictText.vue";
+// import AreaCascader from "fastboot-admin/src/components/AreaCascader.vue";
+// import RoleSelect from "fastboot-admin/src/components/RoleSelect.vue";
+
+// Vue.component(DictSelect.name,DictSelect);
+// Vue.component(OrgCascader.name,OrgCascader);
+// Vue.component(AreaCascader.name,AreaCascader);
+// Vue.component(DictText.name,DictText);
+// Vue.component(RoleSelect.name,RoleSelect);
+
+
+//引入全局工具和配置
+import qs from 'qs'
+import axios from 'axios'
+
+//引入接口
+import baseApi from './config/api'
+let api = _.defaultsDeep(baseApi);
+// router.addRoutes(FastbootAdmin.routes)
+
+import moment from 'moment'
+
+import utils from './util/utils'
+
+Vue.prototype.$moment = moment;
+Vue.prototype.$api = api ;
+Vue.prototype.$http = axios;
+Vue.prototype.$qs = qs;
+Vue.prototype.$utils = utils;
+axios.defaults.withCredentials = true;
+
+Vue.config.productionTip = false
+
+
+//http响应拦截器
+Vue.prototype.$http.interceptors.response.use(resp => {
+
+
+  //如果未授权,则跳转至授权页面
+  if(resp.data.status === 401){
+
+    if(sessionStorage.getItem("login-user-info") != null){
+      Message.warning("30分钟未操作自动退出登录");
+    }
+
+    sessionStorage.removeItem("login-user-info");
+
+
+
+
+    router.push("/login");
+
+
+  }
+
+  //如果未授权,则跳转至授权页面
+  if(resp.data.status === 403){
+    router.push("/no-permission");
+  }
+
+  return resp;
+
+}, error => {
+  console.log(error);
+  return Promise.reject(error)
+});
+
+
+
+
+
+
+//加载系统信息
+// axios.post(api.app.appInfo).then((resp)=>{
+//
+//   window.appInfo = resp.data.data.appInfo;
+//   try {
+//     window.appSetting = JSON.parse(resp.data.data.appInfo.setting);
+//   }catch (e) {
+//     window.appSetting = {};
+//   }
+//
+//   if(!window.appSetting){
+//     window.appSetting={};
+//   }
+//
+//   if(window.appInfo.logo){
+//     window.appInfo.logoUrl = `${api.commonFile.download}?code=${window.appInfo.logo}`;
+//   }
+//
+//
+//   if(window.appInfo.name){
+//     document.title=window.appInfo.name;
+//   }else{
+//     document.title="未配置系统名称";
+//   }
+//
+//
+//   //路由拦截器
+//   router.beforeEach((to,form,next)=>{
+//
+//
+//
+//
+//     if(to.path.startsWith('/update-user-password')){
+//       next();
+//       if(window.updatePassword){
+//         Message.warning("请修改密码再进行操作!");
+//       }
+//       return;
+//     }
+//
+//
+//     if(sessionStorage.getItem("login-user-info") != null){
+//
+//
+//       let userInfo = JSON.parse(sessionStorage.getItem("login-user-info"));
+//
+//
+//
+//
+//       if(window.appSetting["UPDATE_PWD_INTERVAL"] && window.appSetting["UPDATE_PWD_INTERVAL"].value !== "0"){
+//
+//         if(!userInfo.lastUpdatePwdTime){
+//           window.updatePassword = true;
+//
+//           next('/update-user-password')
+//           return ;
+//         }
+//
+//         if(userInfo.lastUpdatePwdTime <= parseInt(window.appSetting["UPDATE_PWD_INTERVAL"]) * 24 * 60 * 60 * 1000){
+//           next('/update-user-password');
+//           return;
+//         }
+//
+//         next();
+//
+//
+//
+//       }else{
+//         next();
+//       }
+//
+//     }else{
+//       next();
+//     }
+//
+//   });
+//
+//   window.routeViewType = 'route';
+//
+//   new Vue({
+//     router,
+//     store,
+//     render: h => h(App)
+//   }).$mount('#app');
+//
+// });
+

+ 9 - 0
sources/client/vrv11/src/router.js

@@ -0,0 +1,9 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+import routes from './config/routes'
+Vue.use(Router);
+export default new Router({
+    // mode: 'history',
+    // base: process.env.BASE_URL,
+    routes: routes
+})

+ 16 - 0
sources/client/vrv11/src/store.js

@@ -0,0 +1,16 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+  state: {
+
+  },
+  mutations: {
+
+  },
+  actions: {
+
+  }
+})

+ 299 - 0
sources/client/vrv11/src/views/Login.vue

@@ -0,0 +1,299 @@
+<template>
+  <transition name="el-fade-in-linear">
+    <div id="login-page">
+      <div class="login-box">
+
+        <div class="slider-banner-box">
+          <img src="../assets/logo_banner.jpg" width="100%" height="100%" alt="">
+        </div>
+
+        <div class="login-form">
+
+          <div style="display: inline-block;text-align: left;width: 80%">
+
+            <div class="title">
+<!--              <img v-if="appInfo.logo" :src="`${$api.commonFile.download}?code=${appInfo.logo}`" style="height: 50px;"-->
+<!--                   alt="">-->
+<!--              <img v-else src="../assets/cloudgo_logo.png" style="height: 50px;" alt="">-->
+            </div>
+
+            <el-form ref="form" :rules="formRules" :model="form">
+
+              <el-form-item prop="account">
+
+                <div class="input-group">
+                  <el-input
+                      prefix-icon="el-icon-user"
+                      :autofocus="true"
+                      placeholder="请输入用户名"
+                      v-model="form.account">
+                  </el-input>
+                </div>
+              </el-form-item>
+
+              <el-form-item prop="password">
+                <div class="input-group">
+                  <el-input
+                      prefix-icon="el-icon-lock"
+                      placeholder="请输入密码"
+                      type="password"
+                      v-model="form.password">
+                  </el-input>
+                </div>
+              </el-form-item>
+
+              <el-form-item prop="verifyCode" :error="formErrorMsg.verifyCode">
+                <div class="input-group">
+                  <el-input
+                      prefix-icon="el-icon-circle-check"
+                      placeholder="请输入图形验证码"
+                      class="verify-input"
+                      v-model="form.verifyCode"
+                  >
+                  </el-input>
+
+                  <img @click="handleRefreshVerifyCode" class="verify-img" :src="verifyCodeUrl" style="cursor: pointer"
+                       alt="">
+                </div>
+              </el-form-item>
+
+
+              <!--                            <div class="input-group" style="margin-bottom: 20px;">-->
+              <!--                                <label>记住我?</label>-->
+              <!--                                <el-switch-->
+              <!--                                        v-model="rememberMe"-->
+              <!--                                        on-text=""-->
+              <!--                                        off-text="">-->
+              <!--                                </el-switch>-->
+              <!--                            </div>-->
+              <div class="input-group">
+                <el-button @click="login" type="primary" :loading="isBtnLoading">{{ btnText }}
+                </el-button>
+              </div>
+
+            </el-form>
+
+
+          </div>
+
+        </div>
+
+      </div>
+    </div>
+  </transition>
+</template>
+
+<script>
+export default {
+  name: "Login",
+  data() {
+    return {
+      // appInfo: {},
+      form: {
+        account: '',
+        password: '',
+        verifyCode: '',
+      },
+      formErrorMsg: {
+        account: '',
+        password: '',
+        verifyCode: '',
+      },
+      formRules: {
+        account: [
+          {required: true, message: '请输入用户名', trigger: 'blur'},
+        ],
+        password: [
+          {required: true, message: '请输入密码', trigger: 'blur'},
+        ],
+        verifyCode: [
+          {required: true, message: '请输入验证码', trigger: 'blur'},
+        ]
+      },
+      rememberMe: false,
+      isBtnLoading: false,
+      verifyCodeUrl: '',
+    };
+  },
+  computed: {
+    btnText() {
+      if (this.isBtnLoading) return '登录中...';
+      return '登录';
+    }
+  },
+  methods: {
+
+    handleRefreshVerifyCode() {
+      let vm = this;
+      vm.$http.get(vm.api.auth.verifyCode)
+    },
+
+    login() {
+
+      this.isBtnLoading = true;
+      let vm = this;
+
+      this.$refs.form.validate((valid) => {
+
+        if (valid) {
+
+          vm.$http.post(vm.api.auth.login, vm.$qs.stringify(vm.form)).then((resp) => {
+
+            if (resp.data.status === 200) {
+
+              console.log(resp.data.data)
+
+              //存储登录用户信息
+              sessionStorage.setItem('login-user-info', JSON.stringify(resp.data.data.userbran));
+              sessionStorage.setItem('remember-me', JSON.stringify(vm.rememberMe));
+
+              vm.$router.push({path: '/'});
+            } else if (resp.data.status === 400) {
+
+
+              resp.data.data.errorFields.forEach(function (a) {
+
+                vm.formErrorMsg[a.name] = '';
+                vm.$nextTick(() => {
+                  vm.formErrorMsg[a.name] = a.message;
+                });
+
+
+              });
+
+              if (resp.data.desc) {
+                vm.$message({
+                  type: "error",
+                  message: resp.data.desc
+                });
+              }
+              vm.isBtnLoading = false;
+
+
+            } else {
+              vm.$message({
+                type: 'error',
+                message: resp.data.desc
+              });
+              vm.isBtnLoading = false;
+            }
+
+          });
+
+        } else {
+          vm.isBtnLoading = false;
+        }
+
+      });
+
+
+    }
+  },
+  created() {
+    // this.appInfo = window.appInfo ? window.appInfo : {};
+    this.handleRefreshVerifyCode();
+  }
+}
+</script>
+
+<style lang="scss">
+
+
+#login-page {
+  width: 100vw;
+  height: 100vh;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background-image: url("../assets/login_bg.png");
+  background-position: center;
+  background-size: 100%;
+
+  /*.el-form-item{*/
+  /*     margin-bottom: 0;*/
+  /*}*/
+
+
+  .login-box {
+    position: relative;
+    display: flex;
+    /*flex-direction: column;*/
+    /*align-items: center;*/
+    width: 930px;
+    height: 420px;
+    /*border-radius: 10px;*/
+    background: rgba(255, 255, 255, 1);
+    top: -40px;
+
+
+    .slider-banner-box {
+      width: 530px;
+      display: inline-block;
+      float: left
+    }
+
+    .login-form {
+      width: calc(100% - 530px);
+      float: left;
+      display: inline-block;
+      text-align: center;
+
+      .title {
+        position: relative;
+        color: #c01920;
+        font-weight: bold;
+        font-size: 30px;
+        text-align: center;
+        line-height: 2.2;
+        margin-bottom: 20px;
+        margin-top: 20px;
+        width: 100%;
+        /*text-shadow: #000000 0 0 5px ;*/
+        display: inline-block;
+      }
+
+
+      .input-group {
+        /*margin-bottom: 20px;*/
+        display: inline-block;
+        width: 100%;
+
+        .verify-input {
+          width: 50%;
+          /*float: left*/
+        }
+
+        .verify-img {
+          height: 40px;
+          width: calc(50% - 10px);
+          display: inline-block;
+          vertical-align: bottom;
+          margin-left: 10px;
+          float: right;
+        }
+
+        button {
+          width: 100%;
+          border: none;
+        }
+      }
+    }
+
+
+  }
+
+  .login-footer {
+
+    position: absolute;
+    bottom: -40px;
+    text-align: center;
+    color: #242C37;
+    font-weight: bold;
+    width: 100%;
+    left: 0px;
+
+  }
+
+}
+
+</style>

+ 0 - 0
sources/client/vrv11/src/views/device-alarm-record/List.vue


+ 0 - 0
sources/client/vrv11/src/views/device/List.vue


+ 0 - 0
sources/client/vrv11/src/views/gateway/List.vue


+ 569 - 0
sources/client/vrv11/src/views/home/Home.vue

@@ -0,0 +1,569 @@
+<template>
+    <div class="home-box">
+
+        <el-row>
+            <el-col :span="6">
+                <el-card class="top-count">
+                    <div class="top-count-title">总派件数量</div>
+                    <div class="top-count-size">{{taskCount.allDeliveryRecordCount}}</div>
+                </el-card>
+            </el-col>
+            <el-col :span="6">
+                <el-card class="top-count">
+                    <div class="top-count-title">待派件数量</div>
+                    <div class="top-count-size">{{taskCount.allWaitDeliveryRecordCount}}</div>
+                </el-card>
+            </el-col>
+            <el-col :span="6">
+                <el-card class="top-count">
+                    <div class="top-count-title">总揽件数量</div>
+                    <div class="top-count-size">{{taskCount.allReceivingRecordCount}}</div>
+                </el-card>
+            </el-col>
+            <el-col :span="6">
+                <el-card class="top-count">
+                    <div class="top-count-title">待揽件数量</div>
+                    <div class="top-count-size">{{taskCount.allWaitReceivingRecordCount}}</div>
+                </el-card>
+            </el-col>
+        </el-row>
+
+        <el-row>
+            <div class="btn-box" style="margin-bottom: 0;">
+                <el-button type="info" @click="showSendMsgBox()">发送消息通知</el-button>
+            </div>
+
+        </el-row>
+
+        <el-row>
+            <div class="btn-box">上午(派/揽)件情况</div>
+
+            <fb-list-body :pager="morningPager"
+                          @handlePagerSizeChange="handleMorningPagerSizeChange"
+                          @handlePagerIndexChange="handleMorningPagerIndexChange">
+                <template slot="btn-group">
+                    <div></div>
+                </template>
+                <template slot="search-form">
+                    <div>
+                        <el-form>
+                            <el-form-item class="search-form-item" label="区域楼栋">
+                                <el-cascader
+                                        ref="morningSearchBuildings"
+                                        :props="{value:'code',label:'name', checkStrictly: true }"
+                                        v-model="morningSearchForm.buildingCode"
+                                        :options="tree"
+                                        @change="handleMorningChange"></el-cascader>
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                </template>
+                <template slot="table">
+                    <el-table
+                            v-loading="morningLoading"
+                            :data="morningTables"
+                            border
+                            ref="mTable"
+                            column-key="buildingName"
+                            :filter-method="filterBuildingName">
+                        <el-table-column
+                                fixed
+                                prop="buildingName"
+                                label="楼栋名称"
+                                width="200">
+                        </el-table-column>
+                        <el-table-column
+                                prop="deliveryRecordCount"
+                                label="总派件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="signedDeliveryRecordCount"
+                                label="已派件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="waitDeliveryRecordCount"
+                                label="待派件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="receivingRecordCount"
+                                label="总揽件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="receivedReceivingRecordCount"
+                                label="已揽件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="waitReceivingRecordCount"
+                                label="待揽件数">
+                        </el-table-column>
+
+                        <el-table-column
+                                v-bind:key="item.code"
+                                v-for="item in morningHeads"
+                                :prop="item.code"
+                                :label="item.times">
+                            <template slot-scope="scope">
+                                <div>待派/已派:{{getDeliveryDesc(scope.row, item)}}件</div>
+                                <div>待揽/已揽:{{getReceivingDesc(scope.row, item)}}件</div>
+                            </template>
+                        </el-table-column>
+
+                        <el-table-column
+                                prop="address"
+                                label="操作"
+                                width="180">
+                            <template slot-scope="scope">
+                                <el-link type="primary" @click="handleBuildingTaskList(scope.row)" :underline="false">
+                                    楼栋任务
+                                </el-link>
+                            </template>
+                        </el-table-column>
+
+                    </el-table>
+                </template>
+
+            </fb-list-body>
+
+        </el-row>
+
+        <el-row>
+            <div class="btn-box">下午(派/揽)件情况</div>
+            <fb-list-body :pager="afternoonPager"
+                          @handlePagerSizeChange="handleAfternoonPagerSizeChange"
+                          @handlePagerIndexChange="handleAfternoonPagerIndexChange">
+                <template slot="btn-group">
+                    <div></div>
+                </template>
+                <template slot="search-form">
+                    <div>
+                        <el-form>
+                            <el-form-item class="search-form-item" label="区域楼栋">
+                                <el-cascader
+                                        ref="afternoonSearchBuildings"
+                                        :props="{value:'code',label:'name', checkStrictly: true }"
+                                        v-model="afternoonSearchForm.buildingCode"
+                                        :options="tree"
+                                        @change="handleAfternoonChange"></el-cascader>
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                </template>
+                <template slot="table">
+                    <el-table
+                            v-loading="afternoonLoading"
+                            :data="afternoonTables"
+                            border
+                            ref="aTable"
+                            column-key="buildingName">
+                        <el-table-column
+                                fixed
+                                prop="buildingName"
+                                label="楼栋名称"
+                                width="200">
+                        </el-table-column>
+                        <el-table-column
+                                prop="deliveryRecordCount"
+                                label="总派件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="signedDeliveryRecordCount"
+                                label="已派件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="waitDeliveryRecordCount"
+                                label="待派件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="receivingRecordCount"
+                                label="总揽件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="receivedReceivingRecordCount"
+                                label="已揽件数">
+                        </el-table-column>
+                        <el-table-column
+                                prop="waitReceivingRecordCount"
+                                label="待揽件数">
+                        </el-table-column>
+
+                        <el-table-column
+                                v-bind:key="item.code"
+                                v-for="item in afternoonHeads"
+                                :prop="item.code"
+                                :label="item.times">
+                            <template slot-scope="scope">
+                                <div>待派/已派:{{getDeliveryDesc(scope.row, item)}}件</div>
+                                <div>待揽/已揽:{{getReceivingDesc(scope.row, item)}}件</div>
+                            </template>
+                        </el-table-column>
+
+                        <el-table-column
+                                prop="address"
+                                label="操作"
+                                width="180">
+                            <template slot-scope="scope">
+                                <el-link type="primary" @click="handleBuildingTaskList(scope.row)" :underline="false">
+                                    楼栋任务
+                                </el-link>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                </template>
+            </fb-list-body>
+
+        </el-row>
+
+
+        <el-dialog title="发送消息通知" :visible.sync="showSendMsg">
+            <el-form :model="msgForm">
+                <el-form-item placeholder="请选择楼栋" class="search-form-item" label="楼栋区域" label-width="80px">
+                    <el-cascader
+                            style="width: 300px"
+                            ref="searchBuildings"
+                            :props="{value:'code',label:'name', checkStrictly: true }"
+                            v-model="msgForm.buildingCode"
+                            :options="tree"
+                            @change="handleBuildingChange"></el-cascader>
+                </el-form-item>
+
+                <el-form-item label="时间段" label-width="80px">
+                    <el-checkbox-group v-model="msgForm.deliveryTimeCodes">
+                        <el-checkbox v-bind:key="time.code" v-for="time in deliveryTimes" :value="time.code"
+                                     :label="time.times"></el-checkbox>
+                    </el-checkbox-group>
+                </el-form-item>
+                <el-form-item label="户号" label-width="80px">
+                    <el-select v-model="msgForm.houseNumber" placeholder="请选择户号" style="width: 300px">
+                        <el-option label="全部" value=""></el-option>
+                        <el-option v-bind:key="number" v-for="number in houseNumbers" :label="number"
+                                   :value="number"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="通知类型" label-width="80px">
+                    <el-checkbox-group v-model="msgForm.types">
+                        <el-checkbox label="到站通知" value="MP_ARRIVE_NOTICE"></el-checkbox>
+                        <el-checkbox label="派件通知" value="MP_DELIVERY_NOTICE"></el-checkbox>
+                        <el-checkbox label="派件异常通知" value="MP_DELIVERY_EXCEPTION_NOTICE"></el-checkbox>
+                        <el-checkbox label="揽件通知" value="MP_RECEIVING_NOTICE"></el-checkbox>
+                        <el-checkbox label="揽件异常通知" value="MP_RECEIVED_EXCEPTION_NOTICE"></el-checkbox>
+                    </el-checkbox-group>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click="showSendMsg = false">取 消</el-button>
+                <el-button type="primary" @click="send">确 定</el-button>
+            </div>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+    export default {
+        props: {},
+        data() {
+            return {
+                showSendMsg: false,
+                msgForm: {
+                    types: [],
+                    deliveryTimeCodes: [],
+                    houseNumber: '',
+                    buildingCodes:  []
+                },
+                morningSearchForm: {
+                    buildingCode: '',
+                    buildingCodes: [],
+                },
+                afternoonSearchForm: {
+                    buildingCode: '',
+                    buildingCodes: []
+                },
+                tree: [],
+                houseNumbers: [],
+                deliveryTimes: [],
+                morningHeads: [],
+                afternoonHeads: [],
+                morningTableData: [],
+                afternoonTableData: [],
+                afternoonLoading: true,
+                morningLoading: true,
+                taskCount: {},
+                buildingCodes: [],
+                morningPager: {
+                    pageSize: 10
+                    , pageIndex: 1,
+                    itemCount: 0
+                },
+                afternoonPager: {
+                    pageSize: 10
+                    , pageIndex: 1,
+                    itemCount: 0
+                },
+                morningBuildingNameKeyword: '',
+                afternoonBuildingNameKeyword: '',
+            }
+        },
+        watch: {
+            "morningPager.pageIndex": {
+                handler() {
+                    this.loadMorningCount();
+                },
+                deep: true,
+                immediate: true
+            },
+            "morningPager.pageSize": {
+                handler() {
+                    this.loadMorningCount();
+                },
+                deep: true
+            },
+            "afternoonPager.pageIndex": {
+                handler() {
+                    this.loadAfternoonCount();
+                },
+                deep: true,
+                immediate: true
+            },
+            "afternoonPager.pageSize": {
+                handler() {
+                    this.loadAfternoonCount();
+                },
+                deep: true
+            }
+        },
+        methods: {
+            handleAfternoonChange() {
+                let vm = this
+                let buildingCodes = []
+                let checkedNodes = vm.$refs.afternoonSearchBuildings.getCheckedNodes();
+                vm.loadChildren(checkedNodes,buildingCodes);
+                vm.afternoonSearchForm.buildingCodes = buildingCodes;
+                vm.loadAfternoonCount();
+            },
+            handleMorningChange() {
+                let vm = this
+                let buildingCodes = []
+                let checkedNodes = vm.$refs.morningSearchBuildings.getCheckedNodes();
+                vm.loadChildren(checkedNodes,buildingCodes);
+                vm.morningSearchForm.buildingCodes = buildingCodes;
+                vm.loadMorningCount();
+            },
+            send() {
+                let vm = this;
+                let buildingCode = "";
+                if (vm.msgForm.buildingCodes && vm.msgForm.buildingCodes.length > 0) {
+                    buildingCode = vm.msgForm.buildingCodes[vm.msgForm.buildingCodes.length - 1]
+                }
+                vm.$http.post(vm.$api.messageNoticeRecord.sendAll, {
+                    types: vm.msgForm.types,
+                    deliveryTimeCodes: vm.msgForm.deliveryTimeCodes,
+                    houseNumber: vm.msgForm.houseNumber,
+                    buildingCode: buildingCode
+                }).then((resp) => {
+                    if(resp.data.status === 200){
+                        vm.$message({type:'success',message:resp.data.desc});
+                    }else{
+                        vm.$message({type:'error',message:resp.data.desc});
+                    }
+                })
+            },
+            handleAfternoonPagerSizeChange(e) {
+                this.afternoonPager.pageSize = e;
+            },
+            handleAfternoonPagerIndexChange(e) {
+                this.afternoonPager.pageIndex = e;
+            },
+            handleMorningPagerSizeChange(e) {
+                this.morningPager.pageSize = e;
+            },
+            handleMorningPagerIndexChange(e) {
+                this.morningPager.pageIndex = e;
+            },
+            showSendMsgBox() {
+                let vm = this;
+                vm.showSendMsg = true;
+                vm.loadBuildingTree();
+            },
+            houseNumberList() {
+                let vm = this;
+                vm.msgForm.houseNumber = ''
+                vm.$http.post(vm.$api.building.houseNumberList, vm.$qs.stringify(
+                    {
+                        code: vm.buildingCodes[vm.buildingCodes.length - 1]
+                    }
+                )).then((resp) => {
+                    vm.houseNumbers = resp.data.data.houseNumbers;
+                })
+            },
+            loadBuildingTree() {
+                let vm = this;
+                vm.$http.post(vm.$api.building.tree, {}).then((resp) => {
+                    vm.tree = resp.data.data.buildings;
+                    vm.tree.unshift({name: "全部", code: ""})
+                })
+            },
+            loadChildren(nodes, arr) {
+                let vm = this
+                for (let i = 0; i < nodes.length; i++) {
+                    if (nodes[i].children && nodes[i].children.length > 0) {
+                        vm.loadChildren(nodes[i].children, arr)
+                    }
+                    arr.push(nodes[i].value)
+                }
+            },
+            handleBuildingChange() {
+                let vm = this
+                let buildingCodes = []
+                let checkedNodes = vm.$refs.searchBuildings.getCheckedNodes();
+                vm.loadChildren(checkedNodes, buildingCodes)
+                if (buildingCodes.length === 1 && buildingCodes[0] === '') {
+                    vm.buildingCodes = []
+                    vm.houseNumbers = []
+                } else {
+                    vm.buildingCodes = buildingCodes
+                    vm.houseNumberList();
+                }
+            },
+            filterBuildingName() {
+
+            },
+            handleBuildingTaskList(item) {
+                this.$router.push({path: '/home/task-list', query: {buildingCode: item.buildingCode}});
+            },
+            getReceivingDesc(row, item) {
+                return row[item.code].waitReceivingCount + '/' + row[item.code].receivedReceivingCount;
+            },
+            getDeliveryDesc(row, item) {
+                return row[item.code].waitDeliveryCount + '/' + row[item.code].signedDeliveryCount;
+            },
+            loadTimeList() {
+                let vm = this;
+                vm.$http.post(vm.$api.deliveryTime.list, vm.$qs.stringify({onPage: false})).then((resp) => {
+                    vm.deliveryTimes = resp.data.data.deliveryTimes;
+                    // 区分上午下午
+                    let m = [];
+                    let a = [];
+                    for (let i = 0; i < vm.deliveryTimes.length; i++) {
+                        if (vm.deliveryTimes[i].type === 'MORNING') {
+                            m.push(vm.deliveryTimes[i])
+                        } else if (vm.deliveryTimes[i].type === 'AFTERNOON') {
+                            a.push(vm.deliveryTimes[i])
+                        }
+                    }
+                    vm.morningHeads = m;
+                    vm.afternoonHeads = a;
+                    this.loadCount()
+                })
+            },
+            loadMorningCount() {
+                let vm = this;
+                vm.morningLoading = true
+                vm.$http.post(vm.$api.count.loadMorningTaskCount, vm.$qs.stringify({
+                    onPage: true,
+                    pageIndex: vm.morningPager.pageIndex,
+                    codes: vm.morningSearchForm.buildingCodes,
+                    pageSize: vm.morningPager.pageSize
+                })).then((resp) => {
+                    vm.morningTableData = resp.data.data.taskCount.morningCounts;
+                    vm.morningPager.pageIndex = resp.data.data.pager.pageIndex;
+                    vm.morningPager.pageSize = resp.data.data.pager.pageSize;
+                    vm.morningPager.itemCount = resp.data.data.pager.itemCount;
+                    vm.morningLoading = false
+                    vm.$nextTick(() => {
+                        vm.$refs.mTable.doLayout();
+                        vm.morningLoading = false
+                    });
+                })
+            },
+            loadAfternoonCount() {
+                let vm = this;
+                vm.afternoonLoading = true
+                vm.$http.post(vm.$api.count.loadAfternoonTaskCount, vm.$qs.stringify({
+                    onPage: true,
+                    pageIndex: vm.afternoonPager.pageIndex,
+                    codes: vm.afternoonSearchForm.buildingCodes,
+                    pageSize: vm.afternoonPager.pageSize
+                })).then((resp) => {
+                    vm.afternoonTableData = resp.data.data.taskCount.afternoonCounts;
+                    vm.afternoonPager.pageIndex = resp.data.data.pager.pageIndex;
+                    vm.afternoonPager.pageSize = resp.data.data.pager.pageSize;
+                    vm.afternoonPager.itemCount = resp.data.data.pager.itemCount;
+                    vm.afternoonLoading = false
+                    vm.$nextTick(() => {
+                        vm.$refs.mTable.doLayout();
+                    });
+                })
+            },
+            loadCount() {
+                let vm = this;
+                vm.$http.post(vm.$api.count.loadTaskCount, {}).then((resp) => {
+                    vm.taskCount = resp.data.data.taskCount;
+                })
+
+                vm.loadMorningCount();
+                vm.loadAfternoonCount();
+            }
+        },
+        mounted() {
+
+            this.loadTimeList()
+        },
+        created() {
+            let vm = this;
+            this.$http.post(vm.$api.building.tree,{}).then((resp)=>{
+                vm.tree = resp.data.data.buildings;
+            })
+        },
+        computed: {
+            afternoonTables() {
+                let vm = this;
+
+                if (vm.afternoonBuildingNameKeyword) {
+                    return vm.afternoonTableData.filter(data => {
+                        return Object.keys(data).some(key => {
+                            return String(data[key]).indexOf(vm.afternoonBuildingNameKeyword) > -1;
+                        })
+                    })
+                }
+                return vm.afternoonTableData;
+            },
+            morningTables() {
+                let vm = this;
+
+                if (vm.morningBuildingNameKeyword) {
+                    return vm.morningTableData.filter(data => {
+                        return Object.keys(data).some(key => {
+                            return String(data[key]).indexOf(vm.morningBuildingNameKeyword) > -1;
+                        })
+                    })
+                }
+                return vm.morningTableData;
+            }
+        }
+    };
+</script>
+
+<style scoped>
+    .top-count {
+        width: 90%;
+        height: 140px;
+        text-align: center;
+    }
+
+    .top-count-title {
+        font-size: 28px;
+        margin-top: 10px;
+        margin-bottom: 20px;
+        color: #666666;
+    }
+
+    .top-count-size {
+        font-size: 24px;
+    }
+
+    .btn-box {
+        margin-top: 20px;
+        margin-bottom: 20px;
+        font-size: 20px;
+    }
+</style>

+ 404 - 0
sources/client/vrv11/src/views/home/TaskDetail.vue

@@ -0,0 +1,404 @@
+<template>
+    <fb-form-body>
+        <el-form :model="formData" ref="form" label-width="150px" class="fb-form">
+
+
+            <el-form-item label="快递单号:">
+                {{formData.trackingNumber}}
+            </el-form-item>
+            <el-form-item label="收件人:">
+                {{formData.addressee}}
+            </el-form-item>
+            <el-form-item label="手机号码:">
+                {{formData.addresseeMobileNumber}}
+            </el-form-item>
+            <el-form-item label="楼栋名称:">
+                {{formData.buildingName ? formData.buildingName : '-'}}
+            </el-form-item>
+            <el-form-item label="户号:">
+                {{formData.houseNumber ? formData.houseNumber : '-'}}
+            </el-form-item>
+            <el-form-item label="派送方式:">
+                {{formData.deliveryMethod ? getDeliveryMethodName(formData.deliveryMethod) : '-'}}
+            </el-form-item>
+            <el-form-item label="派送员:">
+                {{formData.deliveryman ? formData.deliveryman : '-'}}
+            </el-form-item>
+            <el-form-item label="派送员手机:">
+                {{formData.deliverymanMobileNumber ? formData.deliverymanMobileNumber : '-'}}
+            </el-form-item>
+            <el-form-item label="通知情况:">
+                {{formData.noticeState ? getNoticeStateName(formData.noticeState) : '-'}}
+            </el-form-item>
+            <el-form-item label="状态:">
+                {{formData.state ? getStateName(formData.state) : '-'}}
+            </el-form-item>
+            <el-form-item label="派件异常次数:">
+                {{formData.exceptionCount}}
+            </el-form-item>
+
+        </el-form>
+        <hr style="margin-bottom: 20px;">
+        <div>
+            <el-button type="primary" @click="showUpdateState=true">用户签收</el-button>
+            <el-button type="danger" @click="showAddException()">配送异常</el-button>
+            <el-button @click="showDeliveryTimes()">修改配送方式/时间</el-button>
+            <el-button @click="showHistory=true">查看配送历史</el-button>
+        </div>
+
+        <el-dialog
+                title="配送历史"
+                :visible.sync="showHistory"
+                width="30%">
+            <div style="margin-bottom: 20px;" v-bind:key="index" v-for="(item,index) in formData.deliveryHistory">
+                <span>{{item.time}}</span>
+                <span style="margin-left: 40px;">{{item.desc}}</span>
+            </div>
+            <span slot="footer" class="dialog-footer">
+            <el-button @click="showHistory = false">取 消</el-button>
+            <el-button type="primary" @click="showHistory = false">确 定</el-button>
+          </span>
+        </el-dialog>
+
+        <el-dialog
+                title="用户签收"
+                :visible.sync="showUpdateState"
+                width="30%">
+            <el-form :inline="true">
+                <el-row>
+                    <el-form-item label="签收结果">
+                        <el-select v-model="updateStateForm.state" placeholder="请选择揽件方式">
+                            <el-option label="正常签收" value="SIGNED"></el-option>
+                            <el-option label="拒收" value="REFUSE"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-row>
+                <el-row>
+                    <el-form-item label="签收描述">
+                        <el-input
+                                style="width: 500px"
+                                type="textarea"
+                                :rows="3"
+                                placeholder="请输入内容"
+                                v-model="updateStateForm.remarks">
+                        </el-input>
+                    </el-form-item>
+                </el-row>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+            <el-button @click="showUpdateState = false">取 消</el-button>
+            <el-button type="primary" @click="updateState">确 定</el-button>
+          </span>
+        </el-dialog>
+
+        <el-dialog
+                title="添加异常"
+                :visible.sync="showExceptionList"
+                width="30%">
+            <el-table
+                    highlight-current-row
+                    @current-change="handleCurrentChange"
+                    :data="exceptionList">
+                <el-table-column
+                        prop="number"
+                        label="原因码"
+                >
+                    <template scope="scope">
+                        {{scope.row.number ? scope.row.number :'(无)' }}
+                    </template>
+                </el-table-column>
+                <el-table-column
+                        prop="description"
+                        label="文字描述"
+                >
+                    <template scope="scope">
+                        {{scope.row.description ? scope.row.description :'(无)' }}
+                    </template>
+                </el-table-column>
+
+            </el-table>
+            <span slot="footer" class="dialog-footer">
+            <el-button @click="showExceptionList = false">取 消</el-button>
+            <el-button type="primary" @click="addException">确 定</el-button>
+          </span>
+        </el-dialog>
+
+        <el-dialog
+                title="修改派送方式与时间"
+                :visible.sync="showUpdateDeliveryMethodTime"
+                width="30%">
+            <el-form :inline="true">
+                <el-row>
+                    <el-form-item label="派送方式">
+                        <el-select @change="showTime" v-model="updateDeliveryMethodTimeForm.deliveryMethod" placeholder="请选择揽件方式">
+                            <el-option label="送货上门" value="DELIVERY"></el-option>
+                            <el-option label="自取" value="SELF"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-row>
+                <el-row v-if="showDeliveryTime">
+                    <el-form-item label="派送时间">
+                        <el-select v-model="updateDeliveryMethodTimeForm.deliveryTimeCode" placeholder="请选择揽件时段">
+                            <el-option v-bind:key="time.code" v-for="time in deliveryTimes"
+                                       :label="$moment(time.startTime).format('HH:mm:ss') + ' - ' + $moment(time.endTime).format('HH:mm:ss')"
+                                       :value="time.code"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-row>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+            <el-button @click="showUpdateDeliveryMethodTime = false">取 消</el-button>
+            <el-button type="primary" @click="updateDeliveryMethodTime">确 定</el-button>
+          </span>
+        </el-dialog>
+
+    </fb-form-body>
+</template>
+
+<script>
+    export default {
+        name: "ExceptionTemplateEdit",
+        data() {
+            return {
+                api: {
+                    detail: this.$api.deliveryRecord.detail,
+                    updateState: this.$api.deliveryRecord.updateState,
+                    timeList: this.$api.deliveryTime.list,
+                    updateDeliveryMethodTime: this.$api.deliveryRecord.updateDeliveryMethodTime,
+                },
+                deliveryTimes: [],
+                exceptionList: [],
+                showExceptionList: false,
+                showUpdateDeliveryMethodTime: false,
+                showHistory: false,
+                showUpdateState: false,
+                updateDeliveryMethodTimeForm: {
+                    deliveryMethod: '',
+                    deliveryTimeCode: ''
+                },
+                formData: {},
+                updateStateForm: {},
+                states: [
+                    {
+                        name: "已签收",
+                        value: "SIGNED",
+                    }, {
+                        name: "派送中",
+                        value: "DELIVERING",
+                    }, {
+                        name: "待派送",
+                        value: "WAIT",
+                    }, {
+                        name: "待取货",
+                        value: "WAIT_SIGNED",
+                    }, {
+                        name: "异常",
+                        value: "EXCEPTION",
+                    }, {
+                        name: "拒收",
+                        value: "REFUSE",
+                    }
+                ],
+                verifyStates: [
+                    {
+                        name: "已核销",
+                        value: "VERIFIED",
+                    },
+                    {
+                        name: "未核销",
+                        value: "NOT_VERIFIED",
+                    }, {
+                        name: "未签收",
+                        value: "NOT_SIGNED",
+                    },
+                ], deliveryMethods: [
+                    {
+                        name: "送货上门",
+                        value: "DELIVERY",
+                    },
+                    {
+                        name: "自取",
+                        value: "SELF",
+                    }
+                ]
+                , noticeStates: [
+                    {
+                        name: "已发送",
+                        value: "SUCCESS",
+                    },
+                    {
+                        name: "未发送",
+                        value: "NOT_SENT",
+                    }
+                    ,
+                    {
+                        name: "发送失败",
+                        value: "FAIL",
+                    }
+                ],
+                showDeliveryTime: false,
+                currentExceptionCode: ''
+
+            }
+
+        },
+        methods: {
+            updateDeliveryMethodTime() {
+                let vm = this;
+                vm.showUpdateDeliveryMethodTime = true;
+                this.$http.post(this.api.updateDeliveryMethodTime, vm.$qs.stringify({
+                    code: vm.formData.code,
+                    deliveryMethod: vm.updateDeliveryMethodTimeForm.deliveryMethod,
+                    deliveryTimeCode: vm.updateDeliveryMethodTimeForm.deliveryTimeCode,
+                })).then((resp) => {
+                    vm.showUpdateDeliveryMethodTime = false;
+                    if (resp.data.status === 200) {
+                        vm.$message({
+                            type: 'success',
+                            message: resp.data.desc
+                        });
+                    } else {
+                        vm.$message({
+                            type: 'error',
+                            message: resp.data.desc
+                        });
+                    }
+                    vm.loadDetail();
+                })
+            },
+            showTime() {
+                let vm = this;
+                if (vm.updateDeliveryMethodTimeForm.deliveryMethod === 'DELIVERY') {
+                    vm.showDeliveryTime = true;
+                    vm.showDeliveryTimes();
+                } else {
+                    vm.showDeliveryTime = false;
+                }
+            },
+            showDeliveryTimes() {
+                let vm = this;
+                vm.showUpdateDeliveryMethodTime = true;
+                this.$http.post(this.api.timeList, vm.$qs.stringify({onPage: false})).then((resp) => {
+                    vm.deliveryTimes = resp.data.data.deliveryTimes;
+                })
+            },
+            addException() {
+                let vm = this
+                this.$http.post(vm.$api.deliveryRecord.addDeliveryException, vm.$qs.stringify({
+                    code: vm.formData.code,
+                    exceptionTemplateCode: vm.currentExceptionCode,
+                })).then(function (resp) {
+                    vm.exceptionList = resp.data.data.exceptionTemplates;
+                    if (resp.data.status === 200) {
+                        vm.$message({
+                            type: 'success',
+                            message: resp.data.desc
+                        });
+                    } else {
+                        vm.$message({
+                            type: 'error',
+                            message: resp.data.desc
+                        });
+                    }
+                    vm.loadDetail();
+                });
+                vm.showExceptionList = false;
+            },
+            handleCurrentChange(val) {
+                let vm = this;
+                if (val && val.code) {
+                    vm.currentExceptionCode = val.code
+                }
+
+            },
+            showAddException() {
+                let vm = this;
+                vm.showExceptionList = true;
+                vm.currentExceptionCode = ''
+                vm.loadExceptionList();
+            },
+            loadExceptionList() {
+                let vm = this;
+                this.$http.post(vm.$api.exceptionTemplate.list, vm.$qs.stringify({
+                    onPage: false
+                })).then(function (resp) {
+                    vm.exceptionList = resp.data.data.exceptionTemplates;
+                });
+            },
+            updateState() {
+                let vm = this;
+                this.$http.post(this.api.updateState, vm.$qs.stringify({
+                    code: vm.formData.code,
+                    state: vm.updateStateForm.state,
+                    remarks: vm.updateStateForm.remarks
+                })).then(function (resp) {
+                    vm.showUpdateState = false
+
+                    if (resp.data.status === 200) {
+                        vm.$message({
+                            type: 'success',
+                            message: resp.data.desc
+                        });
+                    } else {
+                        vm.$message({
+                            type: 'error',
+                            message: resp.data.desc
+                        });
+                    }
+
+                    vm.loadDetail();
+
+                });
+            },
+            getNoticeStateName(value) {
+                for (let i = 0; i < this.noticeStates.length; i++) {
+                    if (this.noticeStates[i].value === value) {
+                        return this.noticeStates[i].name
+                    }
+                }
+            },
+            getDeliveryMethodName(value) {
+                for (let i = 0; i < this.deliveryMethods.length; i++) {
+                    if (this.deliveryMethods[i].value === value) {
+                        return this.deliveryMethods[i].name
+                    }
+                }
+            },
+            getStateName(value) {
+                for (let i = 0; i < this.states.length; i++) {
+                    if (this.states[i].value === value) {
+                        return this.states[i].name
+                    }
+                }
+            },
+            getVerifyStateName(value) {
+                for (let i = 0; i < this.verifyStates.length; i++) {
+                    if (this.verifyStates[i].value === value) {
+                        return this.verifyStates[i].name
+                    }
+                }
+            },
+            loadDetail() {
+                let vm = this;
+                this.$http.post(this.api.detail, this.$qs.stringify(this.$route.query)).then(function (resp) {
+                    // 赋值
+                    vm.formData = resp.data.data.deliveryRecord
+                    vm.updateDeliveryMethodTimeForm.deliveryMethod = vm.formData.deliveryMethod;
+                    vm.updateDeliveryMethodTimeForm.deliveryTimeCode = vm.formData.deliveryTimeCode;
+                });
+            }
+        },
+
+        created() {
+            let vm = this;
+            vm.loadDetail();
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+    .fb-form {
+        max-width: 500px;
+    }
+
+</style>

+ 334 - 0
sources/client/vrv11/src/views/home/TaskList.vue

@@ -0,0 +1,334 @@
+<template>
+    <fb-list-body :pager="pager"
+                  @handlePagerSizeChange="handlePagerSizeChange"
+                  @handlePagerIndexChange="handlePagerIndexChange"
+    >
+
+        <template slot="btn-group">
+            <el-button icon="el-icon-search" @click.stop="handleSearch">查询</el-button>
+        </template>
+
+        <template slot="search-form">
+
+            <el-form-item class="search-form-item" label="频次">
+                <el-select v-model="searchForm.deliveryTimeType" placeholder="请选择频次">
+                    <el-option label="全部" value=""></el-option>
+                    <el-option label="上午" value="MORNING"></el-option>
+                    <el-option label="下午" value="AFTERNOON"></el-option>
+                </el-select>
+            </el-form-item>
+
+            <el-form-item class="search-form-item" label="户号">
+                <el-input v-model="searchForm.houseNumber" placeholder="请输入户号"></el-input>
+            </el-form-item>
+
+            <el-form-item class="search-form-item" label="收件人">
+                <el-input v-model="searchForm.addressee" placeholder="请输入姓名"></el-input>
+            </el-form-item>
+
+            <el-form-item class="search-form-item" label="手机号码">
+                <el-input v-model="searchForm.addresseeMobileNumber" placeholder="请输入手机号码"></el-input>
+            </el-form-item>
+
+        </template>
+
+        <template slot="table">
+
+
+            <el-table :data="tableData" @selection-change="handleSelectionChange" @row-dblclick="handleEdit">
+
+                <el-table-column
+                        label="派送楼栋"
+                >
+                    <template scope="scope">
+                        {{scope.row.buildingName ? scope.row.buildingName :'-' }}
+                    </template>
+                </el-table-column>
+
+                <el-table-column
+                        label="户号"
+                >
+                    <template scope="scope">
+                        {{scope.row.houseNumber ? scope.row.houseNumber :'-' }}
+                    </template>
+                </el-table-column>
+
+                <el-table-column
+                        label="收件人">
+                    <template scope="scope">
+                        {{scope.row.addressee ? scope.row.addressee :'-' }}
+                    </template>
+                </el-table-column>
+
+                <el-table-column
+                        label="收件人手机号"
+                >
+                    <template scope="scope">
+                        {{scope.row.addresseeMobileNumber ? scope.row.addresseeMobileNumber :'-' }}
+                    </template>
+                </el-table-column>
+
+
+                <el-table-column
+                        label="快递单号"
+                >
+                    <template scope="scope">
+                        {{scope.row.trackingNumber ? scope.row.trackingNumber :'-' }}
+                    </template>
+                </el-table-column>
+
+                <el-table-column
+                        label="派送时间段"
+                >
+                    <template scope="scope">
+                        {{scope.row.type ? getTypeName(scope.row.type) :'' }}
+                        {{' '}}
+                        {{scope.row.deliveryStartTime | dateFormat("hh:mm:ss")}}
+                        {{' - '}}
+                        {{scope.row.deliveryEndTime | dateFormat("hh:mm:ss")}}
+                    </template>
+                </el-table-column>
+
+
+                <el-table-column
+                        label="状态"
+                >
+                    <template scope="scope">
+                        {{scope.row.state ? getStateName(scope.row.state) :'-' }}
+                    </template>
+                </el-table-column>
+
+
+                <el-table-column
+                        fixed="right"
+                        label="操作">
+                    <template slot-scope="scope">
+                        <el-link style="margin-left: 10px;" type="primary" @click="handleDetail(scope.row)" :underline="false">详情</el-link>
+                    </template>
+                </el-table-column>
+
+            </el-table>
+        </template>
+
+
+    </fb-list-body>
+</template>
+
+<script>
+
+    export default {
+        name: "ExceptionTemplateList",
+        components: {},
+        props:{
+          timestamp:{type:Number,default:function () {
+                  return new Date().getTime()
+              }},
+        },
+        data() {
+            return {
+                api:{
+                    list:this.$api.deliveryRecord.list,
+                },
+                deliveryTimes: [],
+                businesses: [],
+                searchForm: {
+                    addressee: '',
+                    buildingCode: '',
+                    addresseeMobileNumber: '',
+                    houseNumber: '',
+                    deliveryTimeType:''
+                },
+                types: [
+                    {
+                        name: "上午",
+                        key: "MORNING"
+                    },
+                    {
+                        name: "下午",
+                        key: "AFTERNOON"
+                    }
+                ],
+                states: [
+                    {
+                        name: "已签收",
+                        value: "SIGNED",
+                    },{
+                        name: "派送中",
+                        value: "DELIVERING",
+                    },{
+                        name: "待派送",
+                        value: "WAIT",
+                    },{
+                        name: "待取货",
+                        value: "WAIT_SIGNED",
+                    },{
+                        name: "异常",
+                        value: "EXCEPTION",
+                    },{
+                        name: "拒收",
+                        value: "REFUSE",
+                    }
+                ],
+
+                tableData:[],
+                tree:[],
+                selection:[],
+                pager: {
+                    pageSize: 10
+                    , pageIndex: 1,
+                    itemCount: 0
+                }
+            }
+        },
+        computed: {
+            searchParams() {
+                return Object.assign({}, this.$route.query,this.searchForm,this.pager);
+            }
+        },
+        watch:{
+            timestamp(){
+              this.handleSearch();
+            },
+            "pager.pageIndex":{
+                handler() {
+                    this.$router.updateQuery({path: this.$route.path, query: this.searchParams});
+                    this.handleSearch();
+
+                },
+                deep:true,
+                immediate:true
+            },
+            "pager.pageSize":{
+                handler() {
+
+                    this.$router.updateQuery({path: this.$route.path, query: this.searchParams});
+                    this.handleSearch();
+
+                },
+                deep:true
+            }
+
+        },
+        methods: {
+            getTypeName(key) {
+                for (let i = 0; i < this.types.length; i++) {
+                    if (this.types[i].key === key) {
+                        return this.types[i].name;
+                    }
+                }
+            },
+
+
+            getStateName(value) {
+                for (let i = 0; i < this.states.length; i++) {
+                    if (this.states[i].value === value) {
+                        return this.states[i].name
+                    }
+                }
+            },
+            handleEdit(e) {
+
+                if(e && e.code){
+                    this.$router.push({path:'edit',query:{code:e.code}});
+                    return;
+                }
+
+                if(!this.selection.length){
+                    this.$message({type:'warning',message:'未选择记录'});
+                    return ;
+                }
+
+                if(this.selection.length > 1){
+                    this.$message({type:'warning',message:'一次只能编辑一条数据'});
+                    return ;
+                }
+
+                this.$router.push({path:'edit',query:{code:this.selection[0].code}});
+            },
+            handleDetail(e) {
+                if(e && e.code){
+                    this.$router.push({path:'task-detail',query:{code:e.code}});
+                    return;
+                }
+
+                this.$router.push({path:'task-detail',query:{code:this.selection[0].code}});
+            },
+            handleDelete(row){
+
+
+                let vm = this;
+
+                vm.$confirm('您现在正在进行删除操作, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+
+                    vm.$http.post(vm.api.delete,vm.$qs.stringify({code:row.code})).then((resp)=>{
+                        if(resp.data.status === 200){
+                            vm.$message({type:'success',message:resp.data.desc});
+                            vm.handleSearch();
+                        }else{
+                            vm.$message({type:'error',message:resp.data.desc});
+
+                        }
+                    })
+
+
+
+                }).catch(() => {
+                    // this.$message({
+                    //     type: 'info',
+                    //     message: '已取消删除'
+                    // });
+                });
+
+            },
+            handleSelectionChange(selection){
+                console.log(selection);
+                this.selection = selection;
+            },
+            handlePagerSizeChange(e){
+                this.pager.pageSize = e;
+            },
+            handlePagerIndexChange(e){
+                this.pager.pageIndex = e;
+            },
+            handleSearch() {
+                let vm = this;
+                let buildingCode = this.$route.query['buildingCode'];
+                this.$http.post(this.api.list,this.$qs.stringify({
+                    addressee: vm.searchForm.addressee,
+                    houseNumber: vm.searchForm.houseNumber,
+                    addresseeMobileNumber: vm.searchForm.addresseeMobileNumber,
+                    buildingCode: buildingCode,
+                    pageIndex: vm.pager.pageIndex,
+                    pageSize: vm.pager.pageSize,
+                    deliveryTimeType: vm.searchForm.deliveryTimeType
+                })).then((resp)=>{
+                    console.log(resp.data.data.deliveryRecords)
+                    vm.tableData = resp.data.data.deliveryRecords;
+
+                    //处理分页
+                    vm.pager.pageIndex = resp.data.data.pager.pageIndex;
+                    vm.pager.pageSize = resp.data.data.pager.pageSize;
+                    vm.pager.itemCount = resp.data.data.pager.itemCount;
+
+                })
+            }
+        },
+        created() {
+            let vm = this;
+            for (let key in this.searchForm){
+                 if(this.$route.query[key]){
+                     this.searchForm[key]= this.$route.query[key];
+                 }
+            }
+
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 0 - 0
sources/client/vrv11/src/views/operator-log/List.vue


+ 0 - 0
sources/client/vrv11/src/views/operator/List.vue


+ 334 - 0
sources/client/vrv11/src/views/project/List.vue

@@ -0,0 +1,334 @@
+<template>
+  <div class="home-box">
+    <el-main>
+      <el-form :inline="true" :model="searchFormData">
+        <el-form-item label="项目名称">
+          <el-input placeholder="项目名称" size="small" v-model="searchFormData.name"></el-input>
+        </el-form-item>
+        <el-form-item label="省份">
+          <el-input placeholder="省份" size="small" v-model="searchFormData.province"></el-input>
+        </el-form-item>
+        <el-form-item label="城市">
+          <el-input placeholder="城市" size="small" v-model="searchFormData.city"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" size="small" @click="search(searchFormData)">搜索</el-button>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button type="primary" size="small" @click="showAdd">新增</el-button>
+        </el-form-item>
+
+
+        <el-dialog title="项目" :visible.sync="dialogFormVisible">
+          <el-form label-position="left" :model="formData">
+            <el-form-item label="栏目名称">
+              <el-input v-model="formData.name"></el-input>
+            </el-form-item>
+            <el-form-item label="项目省份">
+              <el-input v-model="formData.province"></el-input>
+            </el-form-item>
+            <el-form-item label="项目城市">
+              <el-input v-model="formData.city"></el-input>
+            </el-form-item>
+            <el-form-item label="客户名称">
+              <el-input v-model="formData.customer"></el-input>
+            </el-form-item>
+            <el-form-item label="客户电话">
+              <el-input v-model="formData.customerTel"></el-input>
+            </el-form-item>
+          </el-form>
+
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="cancel()">取 消</el-button>
+            <el-button type="primary" @click="addOrEditMehtond()">确 定</el-button>
+          </div>
+        </el-dialog>
+
+      </el-form>
+
+
+      <el-table :data="tableData">
+
+        <el-table-column prop="name" label="项目名称"></el-table-column>
+        <el-table-column prop="customer" label="客户名称"></el-table-column>
+        <el-table-column prop="customerTel" label="客户电话"></el-table-column>
+        <el-table-column prop="province" label="项目省份"></el-table-column>
+        <el-table-column prop="city" label="项目城市"></el-table-column>
+
+        <el-table-column label="操作">
+          <template slot-scope="scope">
+            <el-button type="primary" size="small" @click="showEdit(scope.row)">修改</el-button>
+            <el-button type="danger" size="small" @click="del(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+
+      </el-table>
+
+      <el-pagination
+          background
+          layout="prev, pager, next"
+          :page-size="pager.pageSize"
+          :current-page="pager.pageIndex"
+          :total="pager.itemCount"
+          @current-change="handleCurrentChange"
+      >
+      </el-pagination>
+    </el-main>
+
+
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'project',
+  data() {
+    return {
+      addOrEdit: 1,
+
+      dialogFormVisible: false,
+
+      pager: {
+        pageSize: 2,
+        pageIndex: 1,
+        itemCount: 0,
+      },
+
+      tableData:
+          [{
+            name: '1',
+            customer: '1',
+            customerTel: '1',
+            province: '1',
+            city: '1',
+            code: '',
+            valid: '',
+          }],
+      formData: {
+        name: '1',
+        customer: '1',
+        customerTel: '1',
+        province: '1',
+        city: '1',
+        code: '',
+        valid: '',
+      },
+      searchFormData:
+          {
+            name: '',
+            province: '',
+            city: ''
+          }
+    }
+  },
+
+  created: function () {
+    this.loadData();
+  },
+
+  methods: {
+    //切换页码
+    handleCurrentChange(index) {
+      this.loadData(index)
+    },
+
+    loadData(index) {
+      let vm = this;
+      this.pager.pageIndex = vm.pager.pageIndex;
+      this.pager.pageSize = vm.pager.pageSize;
+      this.$http.post(this.api.list,this.$qs.stringify(this.searchParams)).then((resp)=>{
+
+
+        for(let key in resp.data.data){
+          if(resp.data.data[key] instanceof Array){
+            vm.tableData = resp.data.data[key];
+          }
+        }
+
+        //处理分页
+        vm.pager.pageIndex = resp.data.data.pager.pageIndex;
+        vm.pager.pageSize = resp.data.data.pager.pageSize;
+        vm.pager.itemCount = resp.data.data.pager.itemCount;
+
+      })
+
+
+
+
+      const vm = this;
+      vm.$http.get(vm.api.list, {
+        params: {
+          pageSize: 3,
+          pageIndex: index ? index : 1,
+          name: this.searchFormData.name,
+          province: this.searchFormData.province,
+          city: this.searchFormData.city,
+        }
+      })
+          .then((response) => {
+            // vm.paper = response.data.data.paper;
+            //console.log(response.data.data);
+
+            vm.pager = response.data.data.pager
+
+            vm.tableData = response.data.data.projects;
+          })
+    },
+    search(searchFormData) {
+      //console.log(this.searchFormData)
+      this.loadData();
+    },
+    showAdd() {
+      this.dialogFormVisible = true;
+
+      this.formData.name = '';
+      this.formData.province = '';
+      this.formData.city = '';
+      this.formData.customer = '';
+      this.formData.customerTel = '';
+      this.addOrEdit = 1
+    },
+
+    showEdit(row) {
+
+      console.log(row)
+
+      this.dialogFormVisible = true;
+
+      this.formData = row
+
+      this.addOrEdit = 2
+    },
+
+
+    addOrEditMehtond() {
+      const vm = this;
+      if (this.addOrEdit == 2) {
+        vm.axios.get('http://localhost:8088/project/update', {
+          params: {
+            code: this.formData.code,
+            name: this.formData.name,
+            province: this.formData.province,
+            city: this.formData.city,
+            customer: this.formData.customer,
+            customerTel: this.formData.customerTel,
+          }
+        })
+            .then((response) => {
+              console.log(response)
+
+              if (response.data.status == 200) {
+
+                this.$message({
+                  type: 'success',
+                  showClose: true,
+                  message: response.data.desc
+                })
+              }
+
+              this.dialogFormVisible = false;
+
+              this.loadData();
+
+            })
+            .catch(() => {
+            });
+      }
+
+      if (this.addOrEdit == 1) {
+        vm.axios.get('http://localhost:8088/project/add', {
+          params: {
+            name: this.formData.name,
+            province: this.formData.province,
+            city: this.formData.city,
+            customer: this.formData.customer,
+            customerTel: this.formData.customerTel
+          }
+        })
+            .then((response) => {
+              if (response.data.status == 200) {
+
+                this.dialogFormVisible = false;
+
+                this.$message({
+                  type: 'success',
+                  showClose: true,
+                  message: response.data.desc
+                })
+
+                this.loadData();
+              }
+            })
+      }
+    },
+
+    del(row) {
+      const vm = this;
+      this.$confirm('确认删除', '提示', {
+        type: 'warning'
+      }).then(() => {
+        vm.axios.get('http://localhost:8088/project/delete', {
+          params: {
+            code: row.code,
+          }
+        })
+            .then((response) => {
+              console.log(response)
+              if (response.data.status == 200) {
+                this.$message({
+                  type: 'success',
+                  showClose: true,
+                  message: response.data.desc
+                })
+
+              }
+              this.loadData();
+            })
+      })
+          .catch(() => {
+            this.$message({
+              type: 'info',
+              showClose: true,
+              message: '取消删除'
+            })
+          });
+    },
+    cancel() {
+      this.$message({
+        message: '操作取消',
+        showClose: true,
+        type: 'info'
+      });
+
+      this.dialogFormVisible = false;
+    }
+  }
+}
+</script>
+
+<style scoped>
+.top-count {
+  width: 90%;
+  height: 140px;
+  text-align: center;
+}
+
+.top-count-title {
+  font-size: 28px;
+  margin-top: 10px;
+  margin-bottom: 20px;
+  color: #666666;
+}
+
+.top-count-size {
+  font-size: 24px;
+}
+
+.btn-box {
+  margin-top: 20px;
+  margin-bottom: 20px;
+  font-size: 20px;
+}
+</style>

+ 0 - 0
sources/client/vrv11/src/views/user/List.vue


+ 21 - 0
sources/client/vrv11/vue.config.js

@@ -0,0 +1,21 @@
+
+
+module.exports = {
+    transpileDependencies: [
+        // 'vue-echarts',
+        // 'resize-detector'
+    ],
+    devServer: {
+        port: 8081,
+        proxy: {
+            '/api': {
+              target: 'http://127.0.0.1:5030',
+                changeOrigin: true,
+                ws: true,
+                pathRewrite: {
+                    '^/api': ''
+                }
+            }
+        }
+    },
+};

File diff suppressed because it is too large
+ 8771 - 0
sources/client/vrv11/yarn.lock