hjs пре 1 година
комит
8158ffeab4
100 измењених фајлова са 3330 додато и 0 уклоњено
  1. 14 0
      .editorconfig
  2. 5 0
      .env.development
  3. 6 0
      .env.production
  4. 8 0
      .env.staging
  5. 4 0
      .eslintignore
  6. 198 0
      .eslintrc.js
  7. 16 0
      .gitignore
  8. 5 0
      .travis.yml
  9. 21 0
      LICENSE
  10. 102 0
      README-zh.md
  11. 90 0
      README.md
  12. 14 0
      babel.config.js
  13. 24 0
      jest.config.js
  14. 9 0
      jsconfig.json
  15. 57 0
      mock/index.js
  16. 81 0
      mock/mock-server.js
  17. 29 0
      mock/table.js
  18. 84 0
      mock/user.js
  19. 25 0
      mock/utils.js
  20. 69 0
      package.json
  21. 8 0
      postcss.config.js
  22. BIN
      public/alarm.mp3
  23. 5 0
      public/config.js
  24. BIN
      public/favicon.ico
  25. 19 0
      public/index.html
  26. 11 0
      src/App.vue
  27. 33 0
      src/api/exam.js
  28. 45 0
      src/api/exception_model.js
  29. 35 0
      src/api/merchants.js
  30. 75 0
      src/api/monitor_management.js
  31. 274 0
      src/api/old_api_pengwenbing.js
  32. 325 0
      src/api/ordinary_user.js
  33. 29 0
      src/api/user.js
  34. 458 0
      src/api/user_manage.js
  35. 135 0
      src/api/xiaosha.js
  36. BIN
      src/assets/404_images/404.png
  37. BIN
      src/assets/404_images/404_cloud.png
  38. BIN
      src/assets/area-del.png
  39. BIN
      src/assets/bg.png
  40. BIN
      src/assets/buildingCode.png
  41. BIN
      src/assets/default-img-home.jpg
  42. BIN
      src/assets/default-img.png
  43. BIN
      src/assets/notice-bg.png
  44. BIN
      src/assets/positioning.png
  45. BIN
      src/assets/problem-bg.png
  46. BIN
      src/assets/zfbBuildingCode.jpg
  47. 239 0
      src/components/BatchUpload/index.vue
  48. 79 0
      src/components/Breadcrumb/index.vue
  49. 413 0
      src/components/DialogDetails/index.vue
  50. 44 0
      src/components/Hamburger/index.vue
  51. 101 0
      src/components/Pagination/index.vue
  52. 60 0
      src/components/Screenfull/index.vue
  53. 62 0
      src/components/SvgIcon/index.vue
  54. BIN
      src/icons/images/avatar.jpg
  55. 1 0
      src/icons/images/avatar.js
  56. BIN
      src/icons/images/logo.png
  57. 9 0
      src/icons/index.js
  58. BIN
      src/icons/index/bg.png
  59. BIN
      src/icons/index/bg1.jpg
  60. BIN
      src/icons/index/dp.png
  61. BIN
      src/icons/index/dp2.png
  62. BIN
      src/icons/index/dp3.png
  63. BIN
      src/icons/index/dp4.png
  64. BIN
      src/icons/index/hm.png
  65. BIN
      src/icons/index/hm2.png
  66. BIN
      src/icons/index/hmmj.png
  67. BIN
      src/icons/index/hmmj2.png
  68. BIN
      src/icons/index/hs.png
  69. BIN
      src/icons/index/icon.png
  70. BIN
      src/icons/index/jkmwz.png
  71. BIN
      src/icons/index/line.png
  72. BIN
      src/icons/index/lm.png
  73. BIN
      src/icons/index/underLine.png
  74. BIN
      src/icons/index/wd.png
  75. BIN
      src/icons/index/wdzc.png
  76. BIN
      src/icons/index/yc.png
  77. BIN
      src/icons/index/ym.png
  78. BIN
      src/icons/index/ymwjz.png
  79. BIN
      src/icons/index/zj.png
  80. BIN
      src/icons/index2/bg.png
  81. BIN
      src/icons/index2/blue.png
  82. BIN
      src/icons/index2/left_bottom.png
  83. BIN
      src/icons/index2/left_top.png
  84. BIN
      src/icons/index2/left_top_line.png
  85. BIN
      src/icons/index2/red.png
  86. BIN
      src/icons/index2/school_logo.png
  87. BIN
      src/icons/index2/screen.png
  88. BIN
      src/icons/index2/title_line.png
  89. BIN
      src/icons/index2/yellow.png
  90. 0 0
      src/icons/svg/dashboard.svg
  91. 1 0
      src/icons/svg/example.svg
  92. 1 0
      src/icons/svg/exit-fullscreen.svg
  93. 1 0
      src/icons/svg/eye-open.svg
  94. 1 0
      src/icons/svg/eye.svg
  95. 0 0
      src/icons/svg/form.svg
  96. 1 0
      src/icons/svg/fullscreen.svg
  97. 1 0
      src/icons/svg/link.svg
  98. 1 0
      src/icons/svg/map.svg
  99. 1 0
      src/icons/svg/nested.svg
  100. 1 0
      src/icons/svg/password.svg

+ 14 - 0
.editorconfig

@@ -0,0 +1,14 @@
+# http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false

+ 5 - 0
.env.development

@@ -0,0 +1,5 @@
+# just a flag
+ENV = 'development'
+
+# base api   http://192.168.11.10:9100/yx-fyzd https://noise.hz-hanghui.com:8088/yx-fyzd
+VUE_APP_BASE_API = ''

+ 6 - 0
.env.production

@@ -0,0 +1,6 @@
+# just a flag
+ENV = 'production'
+
+# base api
+VUE_APP_BASE_API = '..'
+

+ 8 - 0
.env.staging

@@ -0,0 +1,8 @@
+NODE_ENV = production
+
+# just a flag
+ENV = 'staging'
+
+# base api
+VUE_APP_BASE_API = '/stage-api'
+

+ 4 - 0
.eslintignore

@@ -0,0 +1,4 @@
+build/*.js
+src/assets
+public
+dist

+ 198 - 0
.eslintrc.js

@@ -0,0 +1,198 @@
+module.exports = {
+  root: true,
+  parserOptions: {
+    parser: 'babel-eslint',
+    sourceType: 'module'
+  },
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  extends: ['plugin:vue/recommended', 'eslint:recommended'],
+
+  // add your custom rules here
+  //it is base on https://github.com/vuejs/eslint-config-vue
+  rules: {
+    "vue/max-attributes-per-line": [2, {
+      "singleline": 10,
+      "multiline": {
+        "max": 1,
+        "allowFirstLine": false
+      }
+    }],
+    "vue/singleline-html-element-content-newline": "off",
+    "vue/multiline-html-element-content-newline":"off",
+    "vue/name-property-casing": ["error", "PascalCase"],
+    "vue/no-v-html": "off",
+    'accessor-pairs': 2,
+    'arrow-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'block-spacing': [2, 'always'],
+    'brace-style': [2, '1tbs', {
+      'allowSingleLine': true
+    }],
+    'camelcase': [0, {
+      'properties': 'always'
+    }],
+    'comma-dangle': [2, 'never'],
+    'comma-spacing': [2, {
+      'before': false,
+      'after': true
+    }],
+    'comma-style': [2, 'last'],
+    'constructor-super': 2,
+    'curly': [2, 'multi-line'],
+    'dot-location': [2, 'property'],
+    'eol-last': 2,
+    'eqeqeq': ["error", "always", {"null": "ignore"}],
+    'generator-star-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'handle-callback-err': [2, '^(err|error)$'],
+    'indent': [2, 2, {
+      'SwitchCase': 1
+    }],
+    'jsx-quotes': [2, 'prefer-single'],
+    'key-spacing': [2, {
+      'beforeColon': false,
+      'afterColon': true
+    }],
+    'keyword-spacing': [2, {
+      'before': true,
+      'after': true
+    }],
+    'new-cap': [2, {
+      'newIsCap': true,
+      'capIsNew': false
+    }],
+    'new-parens': 2,
+    'no-array-constructor': 2,
+    'no-caller': 2,
+    'no-console': 'off',
+    'no-class-assign': 2,
+    'no-cond-assign': 2,
+    'no-const-assign': 2,
+    'no-control-regex': 0,
+    'no-delete-var': 2,
+    'no-dupe-args': 2,
+    'no-dupe-class-members': 2,
+    'no-dupe-keys': 2,
+    'no-duplicate-case': 2,
+    'no-empty-character-class': 2,
+    'no-empty-pattern': 2,
+    'no-eval': 2,
+    'no-ex-assign': 2,
+    'no-extend-native': 2,
+    'no-extra-bind': 2,
+    'no-extra-boolean-cast': 2,
+    'no-extra-parens': [2, 'functions'],
+    'no-fallthrough': 2,
+    'no-floating-decimal': 2,
+    'no-func-assign': 2,
+    'no-implied-eval': 2,
+    'no-inner-declarations': [2, 'functions'],
+    'no-invalid-regexp': 2,
+    'no-irregular-whitespace': 2,
+    'no-iterator': 2,
+    'no-label-var': 2,
+    'no-labels': [2, {
+      'allowLoop': false,
+      'allowSwitch': false
+    }],
+    'no-lone-blocks': 2,
+    'no-mixed-spaces-and-tabs': 2,
+    'no-multi-spaces': 2,
+    'no-multi-str': 2,
+    'no-multiple-empty-lines': [2, {
+      'max': 1
+    }],
+    'no-native-reassign': 2,
+    'no-negated-in-lhs': 2,
+    'no-new-object': 2,
+    'no-new-require': 2,
+    'no-new-symbol': 2,
+    'no-new-wrappers': 2,
+    'no-obj-calls': 2,
+    'no-octal': 2,
+    'no-octal-escape': 2,
+    'no-path-concat': 2,
+    'no-proto': 2,
+    'no-redeclare': 2,
+    'no-regex-spaces': 2,
+    'no-return-assign': [2, 'except-parens'],
+    'no-self-assign': 2,
+    'no-self-compare': 2,
+    'no-sequences': 2,
+    'no-shadow-restricted-names': 2,
+    'no-spaced-func': 2,
+    'no-sparse-arrays': 2,
+    'no-this-before-super': 2,
+    'no-throw-literal': 2,
+    'no-trailing-spaces': 2,
+    'no-undef': 2,
+    'no-undef-init': 2,
+    'no-unexpected-multiline': 2,
+    'no-unmodified-loop-condition': 2,
+    'no-unneeded-ternary': [2, {
+      'defaultAssignment': false
+    }],
+    'no-unreachable': 2,
+    'no-unsafe-finally': 2,
+    'no-unused-vars': [2, {
+      'vars': 'all',
+      'args': 'none'
+    }],
+    'no-useless-call': 2,
+    'no-useless-computed-key': 2,
+    'no-useless-constructor': 2,
+    'no-useless-escape': 0,
+    'no-whitespace-before-property': 2,
+    'no-with': 2,
+    'one-var': [2, {
+      'initialized': 'never'
+    }],
+    'operator-linebreak': [2, 'after', {
+      'overrides': {
+        '?': 'before',
+        ':': 'before'
+      }
+    }],
+    'padded-blocks': [2, 'never'],
+    'quotes': [2, 'single', {
+      'avoidEscape': true,
+      'allowTemplateLiterals': true
+    }],
+    'semi': [2, 'never'],
+    'semi-spacing': [2, {
+      'before': false,
+      'after': true
+    }],
+    'space-before-blocks': [2, 'always'],
+    'space-before-function-paren': [2, 'never'],
+    'space-in-parens': [2, 'never'],
+    'space-infix-ops': 2,
+    'space-unary-ops': [2, {
+      'words': true,
+      'nonwords': false
+    }],
+    'spaced-comment': [2, 'always', {
+      'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
+    }],
+    'template-curly-spacing': [2, 'never'],
+    'use-isnan': 2,
+    'valid-typeof': 2,
+    'wrap-iife': [2, 'any'],
+    'yield-star-spacing': [2, 'both'],
+    'yoda': [2, 'never'],
+    'prefer-const': 2,
+    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+    'object-curly-spacing': [2, 'always', {
+      objectsInObjects: false
+    }],
+    'array-bracket-spacing': [2, 'never']
+  }
+}

+ 16 - 0
.gitignore

@@ -0,0 +1,16 @@
+.DS_Store
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+tests/**/coverage/
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln

+ 5 - 0
.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js: 10
+script: npm run test
+notifications:
+  email: false

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-present PanJiaChen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 102 - 0
README-zh.md

@@ -0,0 +1,102 @@
+# vue-admin-template
+
+> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。
+
+[线上地址](http://panjiachen.github.io/vue-admin-template)
+
+[国内访问](https://panjiachen.gitee.io/vue-admin-template)
+
+目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`。
+
+## Extra
+
+如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+
+## 相关项目
+
+- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
+
+- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+
+- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
+
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
+
+- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
+- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
+- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
+- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
+- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
+
+## Build Setup
+
+```bash
+# 克隆项目
+git clone https://github.com/PanJiaChen/vue-admin-template.git
+
+# 进入项目目录
+cd vue-admin-template
+
+# 安装依赖
+npm install
+
+# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
+npm install --registry=https://registry.npm.taobao.org
+
+# 启动服务
+npm run dev
+```
+
+浏览器访问 [http://localhost:9528](http://localhost:9528)
+
+## 发布
+
+```bash
+# 构建测试环境
+npm run build:stage
+
+# 构建生产环境
+npm run build:prod
+```
+
+## 其它
+
+```bash
+# 预览发布环境效果
+npm run preview
+
+# 预览发布环境效果 + 静态资源分析
+npm run preview -- --report
+
+# 代码格式检查
+npm run lint
+
+# 代码格式检查并自动修复
+npm run lint -- --fix
+```
+
+更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
+
+## 购买贴纸
+
+你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。
+
+## Demo
+
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
+
+Copyright (c) 2017-present PanJiaChen

+ 90 - 0
README.md

@@ -0,0 +1,90 @@
+# vue-admin-template
+
+English | [简体中文](./README-zh.md)
+
+> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
+
+**Live demo:** http://panjiachen.github.io/vue-admin-template
+
+
+**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
+
+## Build Setup
+
+```bash
+# clone the project
+git clone https://github.com/PanJiaChen/vue-admin-template.git
+
+# enter the project directory
+cd vue-admin-template
+
+# install dependency
+npm install
+
+# develop
+npm run dev
+```
+
+This will automatically open http://localhost:9528
+
+## Build
+
+```bash
+# build for test environment
+npm run build:stage
+
+# build for production environment
+npm run build:prod
+```
+
+## Advanced
+
+```bash
+# preview the release environment effect
+npm run preview
+
+# preview the release environment effect + static resource analysis
+npm run preview -- --report
+
+# code format check
+npm run lint
+
+# code format check and auto fix
+npm run lint -- --fix
+```
+
+Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
+
+## Demo
+
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
+
+## Extra
+
+If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+
+For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
+
+## Related Project
+
+- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
+
+- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+
+- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
+
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
+
+Copyright (c) 2017-present PanJiaChen

+ 14 - 0
babel.config.js

@@ -0,0 +1,14 @@
+module.exports = {
+  presets: [
+    // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
+    '@vue/cli-plugin-babel/preset'
+  ],
+  'env': {
+    'development': {
+      // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
+      // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
+      // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
+      'plugins': ['dynamic-import-node']
+    }
+  }
+}

+ 24 - 0
jest.config.js

@@ -0,0 +1,24 @@
+module.exports = {
+  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
+  transform: {
+    '^.+\\.vue$': 'vue-jest',
+    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
+      'jest-transform-stub',
+    '^.+\\.jsx?$': 'babel-jest'
+  },
+  moduleNameMapper: {
+    '^@/(.*)$': '<rootDir>/src/$1'
+  },
+  snapshotSerializers: ['jest-serializer-vue'],
+  testMatch: [
+    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
+  ],
+  collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
+  coverageDirectory: '<rootDir>/tests/unit/coverage',
+  // 'collectCoverage': true,
+  'coverageReporters': [
+    'lcov',
+    'text-summary'
+  ],
+  testURL: 'http://localhost/'
+}

+ 9 - 0
jsconfig.json

@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "baseUrl": "./",
+    "paths": {
+        "@/*": ["src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}

+ 57 - 0
mock/index.js

@@ -0,0 +1,57 @@
+const Mock = require('mockjs')
+const { param2Obj } = require('./utils')
+
+const user = require('./user')
+const table = require('./table')
+
+const mocks = [
+  ...user,
+  ...table
+]
+
+// for front mock
+// please use it cautiously, it will redefine XMLHttpRequest,
+// which will cause many of your third-party libraries to be invalidated(like progress event).
+function mockXHR() {
+  // mock patch
+  // https://github.com/nuysoft/Mock/issues/300
+  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
+  Mock.XHR.prototype.send = function() {
+    if (this.custom.xhr) {
+      this.custom.xhr.withCredentials = this.withCredentials || false
+
+      if (this.responseType) {
+        this.custom.xhr.responseType = this.responseType
+      }
+    }
+    this.proxy_send(...arguments)
+  }
+
+  function XHR2ExpressReqWrap(respond) {
+    return function(options) {
+      let result = null
+      if (respond instanceof Function) {
+        const { body, type, url } = options
+        // https://expressjs.com/en/4x/api.html#req
+        result = respond({
+          method: type,
+          body: JSON.parse(body),
+          query: param2Obj(url)
+        })
+      } else {
+        result = respond
+      }
+      return Mock.mock(result)
+    }
+  }
+
+  for (const i of mocks) {
+    Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
+  }
+}
+
+module.exports = {
+  mocks,
+  mockXHR
+}
+

+ 81 - 0
mock/mock-server.js

@@ -0,0 +1,81 @@
+const chokidar = require('chokidar')
+const bodyParser = require('body-parser')
+const chalk = require('chalk')
+const path = require('path')
+const Mock = require('mockjs')
+
+const mockDir = path.join(process.cwd(), 'mock')
+
+function registerRoutes(app) {
+  let mockLastIndex
+  const { mocks } = require('./index.js')
+  const mocksForServer = mocks.map(route => {
+    return responseFake(route.url, route.type, route.response)
+  })
+  for (const mock of mocksForServer) {
+    app[mock.type](mock.url, mock.response)
+    mockLastIndex = app._router.stack.length
+  }
+  const mockRoutesLength = Object.keys(mocksForServer).length
+  return {
+    mockRoutesLength: mockRoutesLength,
+    mockStartIndex: mockLastIndex - mockRoutesLength
+  }
+}
+
+function unregisterRoutes() {
+  Object.keys(require.cache).forEach(i => {
+    if (i.includes(mockDir)) {
+      delete require.cache[require.resolve(i)]
+    }
+  })
+}
+
+// for mock server
+const responseFake = (url, type, respond) => {
+  return {
+    url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
+    type: type || 'get',
+    response(req, res) {
+      console.log('request invoke:' + req.path)
+      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
+    }
+  }
+}
+
+module.exports = app => {
+  // parse app.body
+  // https://expressjs.com/en/4x/api.html#req.body
+  app.use(bodyParser.json())
+  app.use(bodyParser.urlencoded({
+    extended: true
+  }))
+
+  const mockRoutes = registerRoutes(app)
+  var mockRoutesLength = mockRoutes.mockRoutesLength
+  var mockStartIndex = mockRoutes.mockStartIndex
+
+  // watch files, hot reload mock server
+  chokidar.watch(mockDir, {
+    ignored: /mock-server/,
+    ignoreInitial: true
+  }).on('all', (event, path) => {
+    if (event === 'change' || event === 'add') {
+      try {
+        // remove mock routes stack
+        app._router.stack.splice(mockStartIndex, mockRoutesLength)
+
+        // clear routes cache
+        unregisterRoutes()
+
+        const mockRoutes = registerRoutes(app)
+        mockRoutesLength = mockRoutes.mockRoutesLength
+        mockStartIndex = mockRoutes.mockStartIndex
+
+        console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
+      } catch (error) {
+        console.log(chalk.redBright(error))
+      }
+    }
+  })
+}

+ 29 - 0
mock/table.js

@@ -0,0 +1,29 @@
+const Mock = require('mockjs')
+
+const data = Mock.mock({
+  'items|30': [{
+    id: '@id',
+    title: '@sentence(10, 20)',
+    'status|1': ['published', 'draft', 'deleted'],
+    author: 'name',
+    display_time: '@datetime',
+    pageviews: '@integer(300, 5000)'
+  }]
+})
+
+module.exports = [
+  {
+    url: '/vue-admin-template/table/list',
+    type: 'get',
+    response: config => {
+      const items = data.items
+      return {
+        code: 20000,
+        data: {
+          total: items.length,
+          items: items
+        }
+      }
+    }
+  }
+]

+ 84 - 0
mock/user.js

@@ -0,0 +1,84 @@
+
+const tokens = {
+  admin: {
+    token: 'admin-token'
+  },
+  editor: {
+    token: 'editor-token'
+  }
+}
+
+const users = {
+  'admin-token': {
+    roles: ['admin'],
+    introduction: 'I am a super administrator',
+    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+    name: 'Super Admin'
+  },
+  'editor-token': {
+    roles: ['editor'],
+    introduction: 'I am an editor',
+    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+    name: 'Normal Editor'
+  }
+}
+
+module.exports = [
+  // user login
+  {
+    url: '/vue-admin-template/user/login',
+    type: 'post',
+    response: config => {
+      const { username } = config.body
+      const token = tokens[username]
+
+      // mock error
+      if (!token) {
+        return {
+          code: 60204,
+          message: 'Account and password are incorrect.'
+        }
+      }
+
+      return {
+        code: 20000,
+        data: token
+      }
+    }
+  },
+
+  // get user info
+  {
+    url: '/vue-admin-template/user/info\.*',
+    type: 'get',
+    response: config => {
+      const { token } = config.query
+      const info = users[token]
+
+      // mock error
+      if (!info) {
+        return {
+          code: 50008,
+          message: 'Login failed, unable to get user details.'
+        }
+      }
+
+      return {
+        code: 20000,
+        data: info
+      }
+    }
+  },
+
+  // user logout
+  {
+    url: '/vue-admin-template/user/logout',
+    type: 'post',
+    response: _ => {
+      return {
+        code: 20000,
+        data: 'success'
+      }
+    }
+  }
+]

+ 25 - 0
mock/utils.js

@@ -0,0 +1,25 @@
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+function param2Obj(url) {
+  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+  if (!search) {
+    return {}
+  }
+  const obj = {}
+  const searchArr = search.split('&')
+  searchArr.forEach(v => {
+    const index = v.indexOf('=')
+    if (index !== -1) {
+      const name = v.substring(0, index)
+      const val = v.substring(index + 1, v.length)
+      obj[name] = val
+    }
+  })
+  return obj
+}
+
+module.exports = {
+  param2Obj
+}

+ 69 - 0
package.json

@@ -0,0 +1,69 @@
+{
+  "name": "vue-admin-template",
+  "version": "4.4.0",
+  "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
+  "author": "Pan <panfree23@gmail.com>",
+  "scripts": {
+    "dev": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "build:stage": "vue-cli-service build --mode staging",
+    "preview": "node build/index.js --preview",
+    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
+    "lint": "eslint --ext .js,.vue src",
+    "test:unit": "jest --clearCache && vue-cli-service test:unit",
+    "test:ci": "npm run lint && npm run test:unit"
+  },
+  "dependencies": {
+    "axios": "0.18.1",
+    "core-js": "3.6.5",
+    "echarts": "^5.2.2",
+    "element-ui": "^2.15.6",
+    "file-saver": "^2.0.5",
+    "js-cookie": "2.2.0",
+    "normalize.css": "7.0.0",
+    "nprogress": "0.2.0",
+    "path-to-regexp": "2.4.0",
+    "pinyin-pro": "^3.11.0",
+    "qrcodejs2": "0.0.2",
+    "screenfull": "^4.2.0",
+    "vue": "2.6.10",
+    "vue-router": "3.0.6",
+    "vue-seamless-scroll": "^1.1.23",
+    "vuex": "3.1.0",
+    "xlsx": "^0.18.5"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "4.4.4",
+    "@vue/cli-plugin-eslint": "4.4.4",
+    "@vue/cli-plugin-unit-jest": "4.4.4",
+    "@vue/cli-service": "4.4.4",
+    "@vue/test-utils": "1.0.0-beta.29",
+    "autoprefixer": "9.5.1",
+    "babel-eslint": "10.1.0",
+    "babel-jest": "23.6.0",
+    "babel-plugin-dynamic-import-node": "2.3.3",
+    "chalk": "2.4.2",
+    "connect": "3.6.6",
+    "eslint": "6.7.2",
+    "eslint-plugin-vue": "6.2.2",
+    "html-webpack-plugin": "3.2.0",
+    "mockjs": "1.0.1-beta3",
+    "runjs": "4.3.2",
+    "sass": "1.26.8",
+    "sass-loader": "8.0.2",
+    "script-ext-html-webpack-plugin": "2.1.3",
+    "serve-static": "1.13.2",
+    "svg-sprite-loader": "4.1.3",
+    "svgo": "1.2.2",
+    "vue-template-compiler": "2.6.10"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions"
+  ],
+  "engines": {
+    "node": ">=8.9",
+    "npm": ">= 3.0.0"
+  },
+  "license": "MIT"
+}

+ 8 - 0
postcss.config.js

@@ -0,0 +1,8 @@
+// https://github.com/michael-ciniawsky/postcss-load-config
+
+module.exports = {
+  'plugins': {
+    // to edit target browsers: use "browserslist" field in package.json
+    'autoprefixer': {}
+  }
+}


+ 5 - 0
public/config.js

@@ -0,0 +1,5 @@
+window.g = {
+  // ApiUrl: 'http://192.168.11.11:9100/yx-fyzd', //本地
+  ApiUrl: 'https://tx.hz-hanghui.com:8088/yx-fyzd', //线上
+
+}

BIN
public/favicon.ico


+ 19 - 0
public/index.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title> <%= webpackConfig.name %> </title>
+    <script src="./config.js"></script>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= webpackConfig.name %> 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>
+

+ 11 - 0
src/App.vue

@@ -0,0 +1,11 @@
+<template>
+  <div id="app">
+    <router-view />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'App'
+}
+</script>

+ 33 - 0
src/api/exam.js

@@ -0,0 +1,33 @@
+import request from '@/utils/request'
+// 考试人员-删除
+export function examUserWhitelistDel(examUserWhitelistId) {
+  return request({
+    url: '/admin/examUserWhitelist/delete',
+    method: 'get',
+    params: { examUserWhitelistId }
+  })
+}
+// 考试人员-分页
+export function examUserWhitelist(data) {
+  return request({
+    url: '/admin/examUserWhitelist/getPageList',
+    method: 'post',
+    data: data
+  })
+}
+// 考试人员-新增
+export function examUserWhitelistInsert(data) {
+  return request({
+    url: '/admin/examUserWhitelist/insert',
+    method: 'post',
+    data: data
+  })
+}
+// 考试人员-批量导入
+export function uploadExcel(data) {
+  return request({
+    url: '/admin/examUserWhitelist/uploadExcel',
+    method: 'post',
+    data,
+  })
+}

+ 45 - 0
src/api/exception_model.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+// 黄牛列表分页
+export function getPageList(params) {
+  return request({
+    url: '/admin/userCattle/getPageList',
+    method: 'post',
+    data: params
+  })
+}
+// 获取通行的详情列表
+export function getFaceLogList(params) {
+  return request({
+    url: '/admin/userCattle/getFaceLogList',
+    method: 'post',
+    data: params
+  })
+}
+// 添加黑名单
+export function addBlack(id) {
+  return request({
+    url: '/admin/userCattle/addBlack',
+    method: 'get',
+    params: {
+      userCattleId: id
+    }
+  })
+}
+// 黄牛黑名单列表分页
+export function getCattlePageList(params) {
+  return request({
+    url: '/admin/userBlackList/getCattlePageList',
+    method: 'post',
+    data: params
+  })
+}
+// 删除黄牛黑名单
+export function deleteCattle(id) {
+  return request({
+    url: '/admin/userBlackList/deleteCattle',
+    method: 'get',
+    params: {
+       id
+    }
+  })
+}

+ 35 - 0
src/api/merchants.js

@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+// 商户号列表分页
+export function getPageList(data) {
+  return request({
+    url: '/admin/bussinessNumber/getPageList',
+    method: 'post',
+    data
+  })
+}
+// 商户号列表分页
+export function edit(data) {
+  return request({
+    url: '/admin/bussinessNumber/edit',
+    method: 'post',
+    data
+  })
+}
+// 删除商户号
+export function deleteMerchants(bussinessNumberId) {
+  return request({
+    url: '/admin/bussinessNumber/delete',
+    method: 'get',
+    params:{
+      bussinessNumberId
+    }
+  })
+}
+// 商户号批量导入
+export function uploadBussinessNumberExcel(data) {
+  return request({
+    url: '/admin/bussinessNumber/uploadBussinessNumberExcel',
+    method: 'post',
+    data
+  })
+}

+ 75 - 0
src/api/monitor_management.js

@@ -0,0 +1,75 @@
+import request from '@/utils/request'
+// 布控人员的批量导入
+export function userControlEarlyWarningListExcel(data) {
+  return request({
+    url: '/admin/userControlEarlyWarningList/userControlEarlyWarningListExcel',
+    method: 'post',
+    data
+  })
+}
+// 布控人员列表分页
+export function getPageList(data) {
+  return request({
+    url: '/admin/userControlEarlyWarningList/getPageList',
+    method: 'post',
+    data
+  })
+}
+// 新增或修改布控
+export function addOrUpdate(data) {
+  return request({
+    url: '/admin/userControlEarlyWarningList/addOrUpdate',
+    method: 'post',
+    data
+  })
+}
+// 删除布控人员
+export function deleteWarning(controlEarlyWarningId) {
+  return request({
+    url: '/admin/userControlEarlyWarningList/delete',
+    method: 'get',
+    params:{
+      controlEarlyWarningId
+    }
+  })
+}
+
+
+
+
+// 查询预警列表-分页
+export function getListLogPageInfo(data) {
+  return request({
+    url: '/admin/controlEarlyWarningListLog/getListLogPageInfo',
+    method: 'post',
+    data
+  })
+}
+// 预警信息
+export function getListLog(data) {
+  return request({
+    url: '/admin/controlEarlyWarningListLog/getListLog',
+    method: 'get',
+    params:data
+  })
+}
+
+// 预警确认
+export function earlyWarningConfirm(id) {
+  return request({
+    url: '/admin/controlEarlyWarningListLog/earlyWarningConfirm',
+    method: 'get',
+    params:{
+      id
+    }
+  })
+}
+// 导出Excel
+export function getListLogExcel(data) {
+  return request({
+    url: '/admin/controlEarlyWarningListLog/getListLogExcel',
+    method: 'post',
+    responseType: 'blob',
+    data
+  })
+}

+ 274 - 0
src/api/old_api_pengwenbing.js

@@ -0,0 +1,274 @@
+import request from '@/utils/request'
+
+export function doGetFaceDevices(params) {
+  return request({
+    url: '/admin/face/doGetFaceDevices',
+    method: 'post',
+    data: params
+  })
+}
+
+export function doEditFaceDevices(params) {
+  return request({
+    url: '/admin/face/doEditFaceDevices',
+    method: 'post',
+    data: params
+  })
+}
+
+export function doDeleteDevice(params) {
+  return request({
+    url: '/admin/face/doDeleteDevice/' + params,
+    method: 'delete'
+  })
+}
+
+export function doAuthFaceDevice(params) {
+  return request({
+    url: '/admin/face/doAuthFaceDevice/' + params,
+    method: 'get'
+  })
+}
+
+export function doStopFaceDevice(params) {
+  return request({
+    url: '/admin/face/doStopFaceDevice/' + params,
+    method: 'get'
+  })
+}
+
+export function doGetFacePass(params) {
+  return request({
+    url: '/admin/face/doGetFacePass',
+    method: 'post',
+    data: params
+  })
+}
+
+export function doGetFaceServerLog(params) {
+  return request({
+    url: '/admin/face/doGetFaceServerLog',
+    method: 'post',
+    data: params
+  })
+}
+
+export function doGetUsers(params) {
+  return request({
+    url: '/admin/face/doGetUsers',
+    method: 'post',
+    data: params
+  })
+}
+
+export function downloadFaceLog(data) {
+  return request({
+    url: '/admin/face/doGetFaceServerLogExcel',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询详情
+export function getDetails(data) {
+  return request({
+    url: '/admin/face/getDetails',
+    method: 'post',
+    data: data
+  })
+}
+
+/***********************************zyh_加入-设备列表*************************************************/
+
+// 获取设备编号
+export function getFaceDeviceList() {
+  return request({
+    url: '/admin/face/getFaceDeviceList',
+    method: 'post',
+    data: {}
+  })
+}
+
+// 全量下发
+export function issueAll(data) {
+  return request({
+    url: '/admin/userWhitelis/addSnIssued',
+    method: 'get',
+    params: data
+  })
+}
+
+// 重新下发
+export function reIssue(id) {
+  return request({
+    url: '/admin/userWhitelis/addSingle',
+    method: 'get',
+    params: {
+      id: id
+    }
+  })
+}
+
+// 重新启动
+export function restart(sn) {
+  return request({
+    url: '/admin/face/doReboot',
+    method: 'get',
+    params: {
+      sn: sn
+    }
+  })
+}
+
+/***********************************zyh_加入_logo管理*************************************************/
+
+// 获得logo
+export function getLogo() {
+  return request({
+    url: '/admin/face/getLogo',
+    method: 'get',
+    params: {}
+  })
+}
+
+// 上传logo
+export function uploadImage(data) {
+  return request({
+    url: '/upload/picture',
+    method: 'post',
+    headers: {
+      "Content-Type": "multipart/form-data",
+    },
+    data
+  })
+}
+
+// 下发logo
+export function issuedAll(data) {
+  return request({
+    url: '/admin/face/issuedAll',
+    method: 'get',
+    params: data
+  })
+}
+
+/***********************************zyh_加入_系统设置_查询详情配置*************************************************/
+
+// 获取查询详情配置列表
+export function getCheckContentList(data) {
+  return request({
+    url: '/admin/sysInquire/getList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 添加or修改
+export function addOrUpdateCheckContent(data) {
+  return request({
+    url: '/admin/sysInquire/addOrUpdate',
+    method: 'post',
+    data: data
+  })
+}
+
+
+// 删除
+export function deleteCheckContent(id) {
+  return request({
+    url: '/admin/sysInquire/delete',
+    method: 'DELETE',
+    params: {
+      id: id
+    }
+  })
+}
+
+/***********************************zyh_加入_系统设置_第三方设备设置*************************************************/
+
+// 获取第三方设备名称列表
+export function getMachineCompanyList(data) {
+  return request({
+    url: '/admin/thirdParty/getPageList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 获取第三方设备名称列表-搜索
+export function getMachineCompanyListSearch() {
+  return request({
+    url: '/admin/thirdParty/getList',
+    method: 'post',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    data: {}
+  })
+}
+
+// 添加or修改
+export function addOrUpdateMachineCompany(data) {
+  return request({
+    url: '/admin/thirdParty/edit',
+    method: 'post',
+    data: data
+  })
+}
+
+
+// 删除
+export function deleteMachineCompany(thirdPartyId) {
+  return request({
+    url: '/admin/thirdParty/delete',
+    method: 'get',
+    params: {
+      thirdPartyId: thirdPartyId
+    }
+  })
+}
+
+
+/***********************************zyh_加入_系统设置_第三方设备设置*************************************************/
+
+// 获取第三方设备名称列表
+export function getMachineTypeList(data) {
+  return request({
+    url: '/admin/deviceType/getPageList',
+    method: 'post',
+    data: data
+  })
+}
+
+// 获取第三方设备名称列表-搜索
+export function getMachineTypeListSearch() {
+  return request({
+    url: '/admin/deviceType/getList',
+    method: 'post',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    data: {}
+  })
+}
+
+// 添加or修改
+export function addOrUpdateMachineType(data) {
+  return request({
+    url: '/admin/deviceType/addOrEdit',
+    method: 'post',
+    data: data
+  })
+}
+
+
+// 删除
+export function deleteMachineType(faceDeviceTypeId) {
+  return request({
+    url: '/admin/deviceType/deleteType',
+    method: 'get',
+    params: {
+      faceDeviceTypeId: faceDeviceTypeId
+    }
+  })
+}

+ 325 - 0
src/api/ordinary_user.js

@@ -0,0 +1,325 @@
+import request from '@/utils/request'
+
+
+/******************************** 改-常客管理 ********************************/
+// 获得白名单列表
+export function getPageList(data) {
+  return request({
+    url: '/admin/userWhitelis/getPageList',
+    method: 'post',
+    data
+  })
+}
+
+// 添加白名单
+export function insert(data) {
+  return request({
+    url: '/admin/userWhitelis/insert',
+    method: 'post',
+    data
+  })
+}
+
+// 删除白名单
+export function delete_user(id) {
+  return request({
+    url: '/admin/userWhitelis/delete',
+    method: 'get',
+    params: {
+      UserWhitelistId: id
+    }
+  })
+}
+
+// 删除所有人员
+export function deleteAll() {
+  return request({
+    url: '/admin/userWhitelis/deleteAll',
+    method: 'get',
+    params: {}
+  })
+}
+
+// 编辑白名单
+export function update(data) {
+  return request({
+    url: '/admin/userWhitelis/update',
+    method: 'post',
+    data
+  })
+}
+
+// 批量导入
+export function uploadUserWhitelistExcel(data) {
+  return request({
+    url: '/admin/userWhitelis/uploadUserWhitelistExcel',
+    method: 'post',
+    headers: {
+      "Content-Type": "multipart/form-data",
+    },
+    data
+  })
+}
+// 上传图片
+export function pictureLocal(data) {
+  return request({
+    url: '/upload/pictureLocal',
+    method: 'post',
+    data
+  })
+}
+
+/******************************** 改-访客管理 ********************************/
+// 获得访客列表
+export function getPageListVisitor(data) {
+  return request({
+    url: '/admin/userVisitorList/getPageList',
+    method: 'post',
+    data
+  })
+}
+
+// 访客添加到常客
+export function addWhiteList(id) {
+  return request({
+    url: '/admin/userVisitorList/addWhite',
+    method: 'get',
+    params:{id}
+  })
+}
+// 访客批量添加到常客
+export function addWhiteAll(data) {
+  return request({
+    url: '/admin/userVisitorList/addWhiteAll',
+    method: 'post',
+    data
+  })
+}
+
+// 访客添加到黑名单
+export function addBlackList(id) {
+  return request({
+    url: '/admin/userVisitorList/addBlack',
+    method: 'get',
+    params:{id}
+  })
+}
+
+/******************************** 改-黑名单管理 ********************************/
+// 获得常客列表
+export function getPageListBlack(data) {
+  return request({
+    url: '/admin/userBlackList/getPageList',
+    method: 'post',
+    data
+  })
+}
+
+// 移除黑名单
+export function removeBlack(id) {
+  return request({
+    url: '/admin/userBlackList/delete',
+    method: 'get',
+    params: {
+      id: id
+    }
+  })
+}
+
+/******************************** 编辑账号资料 ********************************/
+// 编辑账号资料
+export function doEditSelf(data) {
+  return request({
+    url: '/admin/auth/updateAdmin',
+    method: 'post',
+    data
+  })
+}
+
+/******************************** 账号管理 ********************************/
+// 批量导入
+export function uploadAdminInfoExcel(data) {
+  return request({
+    url: '/admin/auth/uploadAdminInfoExcel',
+    method: 'post',
+    headers: {
+      "Content-Type": "multipart/form-data",
+    },
+    data
+  })
+}
+
+/******************************** 数据大屏 ********************************/
+
+// 通行信息
+export function getAdminData() {
+  return request({
+    url: 'admin/dataShow/getAdminData',
+    method: 'post',
+    data: {}
+  })
+}
+
+// 进出人员数据
+export function getInOutData(data) {
+  return request({
+    url: 'inOutStatistics/data',
+    method: 'post',
+    data
+  })
+}
+
+// 设备数量
+export function getDeviceNumber() {
+  return request({
+    url: '/admin/dataShow/getDeviceNumber',
+    method: 'post',
+    data: {}
+  })
+}
+// -----------------预约场景-------------------------
+
+// 删除预约信息
+export function appointmentDelete(placeDetailId) {
+  return request({
+    url: `/admin/place/appointmentDelete`,
+    method: 'get',
+    params:{placeDetailId}
+  })
+}
+// 预约信息保存
+export function appointmentSave(data) {
+  return request({
+    url: '/admin/place/appointmentSave',
+    method: 'post',
+    data
+  })
+}
+// 修改状态预约信息
+export function appointmentUpdate(data) {
+  return request({
+    url: '/admin/place/appointmentUpdate',
+    method: 'post',
+    data
+  })
+}
+
+// 查询
+export function getplace() {
+  return request({
+    url: '/admin/place/query',
+    method: 'get',
+    params: {}
+  })
+}
+// 基础信息保存
+export function placeSave(data) {
+  return request({
+    url: '/admin/place/save',
+    method: 'post',
+    data
+  })
+}
+// 预约列表
+// 查询
+export function appointmentPerson(data) {
+  return request({
+    url: '/admin/appointmentPerson/getPageList',
+    method: 'post',
+    data
+  })
+}
+// 详情
+export function detail(id) {
+  return request({
+    url: `/admin/appointmentPerson/detail/${id}`,
+    method: 'get',
+  })
+}
+// 重新下发
+export function issue(id) {
+  return request({
+    url: `/admin/appointmentPerson/issue/${id}`,
+    method: 'post',
+  })
+}
+// 全量下发
+export function appointmentPersonIssueAll(data) {
+  return request({
+    url: '/admin/appointmentPerson/issueAll',
+    method: 'post',
+    data
+  })
+}
+
+// 全量下发-新版(携带有效期)
+export function addSnIssued(data) {
+  return request({
+    url: `/admin/appointmentPerson/issueAll/${deviceId}`,
+    data: data,
+    method: 'get',
+  })
+}
+
+// 删除
+export function deleteId(id) {
+  return request({
+    url: `/admin/appointmentPerson/${id}`,
+    method: 'DELETE',
+  })
+}
+
+
+// -----------------健康码三方对接-------------------------
+// 分页
+export function healthCodeGetPageList(data) {
+  return request({
+    url: '/admin/healthCodeConfig/getPageList',
+    method: 'post',
+    data
+  })
+}
+// 保存
+export function healthCodeSave(data) {
+  return request({
+    url: '/admin/healthCodeConfig/save',
+    method: 'post',
+    data
+  })
+}
+// 删除
+export function healthCodeDel(id) {
+  return request({
+    url: `/admin/healthCodeConfig/del/${id}`,
+    method: 'delete',
+  })
+}
+// 获取常客有效期
+export function getUserWhitelistEffectiveTime(adminId) {
+  return request({
+    url: '/admin/userWhitelis/getUserWhitelistEffectiveTime',
+    method: 'get',
+    params: { adminId }
+  })
+}
+
+
+// 常客--批量编辑
+export function editUserWhitelistExcel(data) {
+  return request({
+    url: '/admin/userWhitelis/editUserWhitelistExcel',
+    method: 'post',
+    headers: {
+      "Content-Type": "multipart/form-data",
+    },
+    data
+  })
+}
+// 新增黑名单
+export function iuserBlackListInsert(data) {
+  return request({
+    url: '/admin/userBlackList/insert',
+    method: 'post',
+    data
+  })
+}

+ 29 - 0
src/api/user.js

@@ -0,0 +1,29 @@
+import request from '@/utils/request'
+
+export function login(data) {
+  return request({
+    url: '/admin/auth/doLogin',
+    method: 'get',
+    params: data
+  })
+}
+
+export function getInfo() {
+  return request({
+    url: '/admin/auth/doGetInfo',
+    method: 'get'
+  })
+}
+
+export function logout() {
+  return request({
+    url: '/admin/auth/doLogout',
+    method: 'get'
+  })
+}
+export function getPicture() {
+  return request({
+    url: '/upload/getPicture',
+    method: 'post'
+  })
+}

+ 458 - 0
src/api/user_manage.js

@@ -0,0 +1,458 @@
+import request from '@/utils/request'
+// (新)获取管理员列表(id 和 username)
+export function getAdminListNew(data) {
+  return request({
+    url: '/admin/auth/getAdminListNew',
+    method: 'post',
+    data
+  })
+}
+
+
+// 获得管理员列表
+export function getUserList(data) {
+  return request({
+    url: '/admin/auth/doGetAdmins',
+    method: 'post',
+    data
+  })
+}
+
+// 获得管理员列表
+export function getUserListSearch() {
+  return request({
+    url: '/admin/auth/getAdminlist',
+    method: 'post',
+  })
+}
+
+// 获得省份列表
+export function getProvince() {
+  return request({
+    url: '/admin/areaCode/getProvince',
+    method: 'get',
+    params: {}
+  })
+}
+
+// 获得城市列表
+export function getCity(areaCodeId) {
+  return request({
+    url: '/admin/areaCode/getCity',
+    method: 'get',
+    params: {
+      areaCodeId: areaCodeId
+    }
+  })
+}
+
+// 获得区县列表
+export function getArea(areaCodeId) {
+  return request({
+    url: '/admin/areaCode/getArea',
+    method: 'get',
+    params: {
+      areaCodeId: areaCodeId
+    }
+  })
+}
+
+// 获得街道列表
+export function getStreet(areaCodeId) {
+  return request({
+    url: '/admin/areaCode/getStreet',
+    method: 'get',
+    params: {
+      areaCodeId: areaCodeId
+    }
+  })
+}
+
+// 获得派出所列表
+export function getPolice(areaCodeId) {
+  return request({
+    url: '/admin/policeStationCode/getList',
+    method: 'get',
+    params: {
+      areaCodeId: areaCodeId
+    }
+  })
+}
+
+// 添加&编辑管理员
+export function doEditAdmin(data) {
+  return request({
+    url: '/admin/auth/doEditAdmin',
+    method: 'post',
+    data
+  })
+}
+
+// 删除管理员
+export function doDeleteAdmin(id) {
+  return request({
+    url: '/admin/auth/doDeleteAdmin',
+    method: 'delete',
+    params: {
+      id: id
+    }
+  })
+}
+
+/**********************************************标签管理****************************/
+// 获得标签列表
+export function getTagList(provinceId) {
+  return request({
+    url: '/admin/tag/getList',
+    method: 'get',
+    params: {
+      provinceId: provinceId || null
+    }
+  })
+}
+
+// 添加标签
+export function insert(data) {
+  return request({
+    url: '/admin/tag/insert',
+    method: 'post',
+    data
+  })
+}
+
+// 编辑标签
+export function update(data) {
+  return request({
+    url: '/admin/tag/update',
+    method: 'post',
+    data
+  })
+}
+
+// 删除标签
+export function deleteTag(tagId) {
+  return request({
+    url: '/admin/tag/delete',
+    method: 'get',
+    params: {
+      tagId: tagId
+    }
+  })
+}
+
+/**********************************************查询详情****************************/
+// 查询详情
+export function searchContent(data) {
+  return request({
+    url: '/admin/tag/insert',
+    method: 'post',
+    data
+  })
+}
+
+// 自定义字段(访客,进出记录)
+export function getContext(id) {
+  return request({
+    url: '/admin/face/getContext',
+    method: 'get',
+    params: { id }
+  })
+}
+// 自定义字段(常客)
+export function getContextById(adminId) {
+  return request({
+    url: '/admin/face/getContextById',
+    method: 'get',
+    params: { adminId }
+  })
+}
+export function getContextByWhiteId(id) {
+  return request({
+    url: '/admin/face/getContextByWhiteId',
+    method: 'get',
+    params: { id }
+  })
+}
+export function getContextByFaceLog(params) {
+  return request({
+    url: '/admin/face/getContextByFaceLog',
+    method: 'get',
+    params
+  })
+}
+// -------------------访客机接口----------------------------
+// 根据进出记录获取访客机字段
+export function getUserListFrom(params) {
+  return request({
+    url: '/admin/face/getUserListFrom',
+    method: 'get',
+    params
+  })
+}
+
+// 根据访客id获取访客机字段
+export function getVisitorListFrom(id) {
+  return request({
+    url: '/admin/face/getVisitorListFrom',
+    method: 'get',
+    params: { id }
+  })
+}
+// 根据常客id获取访客机字段
+export function getWhiteListFrom(id) {
+  return request({
+    url: '/admin/face/getWhiteListFrom',
+    method: 'get',
+    params: { id }
+  })
+}
+// 常客列表-下载模板
+export function doGetWhiteExcel() {
+  return request({
+    url: '/admin/userWhitelis/doGetWhiteExcel',
+    method: 'get',
+    responseType: 'blob',
+    params: {}
+  })
+}
+// -----------访客-------------------
+// 访客删除
+export function deleteVisitor(id) {
+  return request({
+    url: '/admin/userVisitorList/deleteVisitor',
+    method: 'get',
+    params: { id }
+  })
+}
+// 访客下发
+export function addSingle(id) {
+  return request({
+    url: '/admin/userVisitorList/addSingle',
+    method: 'get',
+    params: { id }
+  })
+}
+// 访客记录分页
+export function getDetailPageList(data) {
+  return request({
+    url: '/admin/userVisitorList/getDetailPageList',
+    method: 'post',
+    data
+  })
+}
+// 访客记录详情
+export function getDetailInfo(detailId) {
+  return request({
+    url: `/admin/userVisitorList/getDetailInfo/${detailId}`,
+    method: 'get',
+  })
+}
+
+// ----------------------常访客导出------------------------
+// 导出常客列表Excel
+export function userWhitelistExcelOut(data) {
+  return request({
+    url: '/admin/userWhitelis/userWhitelistExcelOut',
+    method: 'post',
+    data
+  })
+}
+
+// 导出访客列表Excel
+export function userVisitorlistExcelOut(data) {
+  return request({
+    url: '/admin/userVisitorList/userVisitorlistExcelOut',
+    method: 'post',
+    data
+  })
+}
+// -------------------楼宇场景-------------------
+// 添加-编辑企业
+export function saveEnterpriseAccount(data) {
+  return request({
+    url: '/admin/auth/saveEnterpriseAccount',
+    method: 'post',
+    data
+  })
+}
+// 通过账号id查询详情
+export function queryAdminById(id) {
+  return request({
+    url: `/admin/auth/queryAdminById/${id}`,
+    method: 'get',
+  })
+}
+// 企业审核
+export function audit(id, reviewStatus) {
+  return request({
+    url: `/admin/auth/audit/${id}/${reviewStatus}`,
+    method: 'post',
+  })
+}
+// 查询企业账号信息
+export function queryEnterpriseAccount(id) {
+  return request({
+    url: `/admin/auth/queryEnterpriseAccount`,
+    method: 'get',
+  })
+}
+// -----------场所码---------
+// 场所记录分页查询
+export function placeRecordList(data) {
+  return request({
+    url: '/admin/placeRecord/getPageList',
+    method: 'post',
+    data,
+  })
+}
+// 查询账号场所码信息
+export function queryPlaceInfos(adminId) {
+  return request({
+    url: `/admin/auth/queryPlaceInfos/${adminId}`,
+    method: 'get',
+  })
+}
+
+// ---------私有区域-----------
+// 获取私有区域列表
+export function getPrivateAreaList(adminId) {
+  return request({
+    url: '/admin/privateArea/getPrivateAreaList',
+    method: 'get',
+    params: { adminId }
+  })
+}
+
+// 私有区域列表分页
+export function privateAreaPageList(data) {
+  return request({
+    url: '/admin/privateArea/privateAreaPageList',
+    method: 'post',
+    data,
+  })
+}
+// 添加-修改私有区域
+export function addOrUpdatePrivateArea(data) {
+  return request({
+    url: '/admin/privateArea/addOrUpdatePrivateArea',
+    method: 'post',
+    data,
+  })
+}
+// 删除私有区域
+export function deletePrivateArea(privateAreaId) {
+  return request({
+    url: 'admin/privateArea/deletePrivateArea',
+    method: 'get',
+    params: { privateAreaId }
+  })
+}
+// 私有区域设备列表分页
+export function privateAreaDevicePageList(data) {
+  return request({
+    url: '/admin/privateArea/privateAreaDevicePageList',
+    method: 'post',
+    data,
+  })
+}
+// 获取私有区域设备列表
+export function getPrivateAreaDeviceList(privateAreaId) {
+  return request({
+    url: 'admin/privateArea/getPrivateAreaDeviceList',
+    method: 'get',
+    params: { privateAreaId }
+  })
+}
+// 私有区域人员列表分页
+export function privateAreaWhitelistPageList(data) {
+  return request({
+    url: '/admin/privateArea/privateAreaWhitelistPageList',
+    method: 'post',
+    data,
+  })
+}
+// ---------------下发任务列表----------------
+// 分页
+export function issuedList(data) {
+  return request({
+    url: '/admin/issuedTaskInfo/getPageList',
+    method: 'post',
+    data,
+  })
+}
+export function issuedCancel(id) {
+  return request({
+    url: `/admin/issuedTaskInfo/cancel/${id}`,
+    method: 'post',
+  })
+}
+// ---------------行程码-行政区域列表列表----------------
+export function riskAreaList(data) {
+  return request({
+    url: '/admin/auth/riskAreaList',
+    method: 'post',
+    data
+  })
+}
+// 推送字段
+export function fieldOptions(data) {
+  return request({
+    url: '/admin/auth/punch/field-options',
+    method: 'get',
+    params:{}
+  })
+}
+// ---------------下发删除自动化任务----------------
+// 任务列表
+export function getByPage(data) {
+  return request({
+    url: '/autoTaskInfo/getByPage',
+    method: 'post',
+    data
+  })
+}
+// 取消任务
+export function cancelTask(taskId) {
+  return request({
+    url: '/autoTaskInfo/cancelTask',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded'
+    },
+    method: 'post',
+    params:{taskId}
+  })
+}
+// ---------------系统公告----------------
+// 编辑公告
+export function systemNoticeEdit(data) {
+  return request({
+    url: '/systemNotice/edit',
+    method: 'post',
+    data
+  })
+}
+// 获取公告信息
+export function systemNoticeGetNotice(data) {
+  return request({
+    url: '/systemNotice/getNotice',
+    method: 'post',
+    data
+  })
+}
+
+// -------------场所码所属区域-------------
+export function getPlaceAreas(data) {
+  return request({
+    url: '/admin/auth/getPlaceAreas',
+    method: 'get',
+    params:{}
+  })
+}
+// -------------获取商户平台列表-------------
+export function doGetTenants(data) {
+  return request({
+    url: '/admin/face/doGetTenants',
+    method: 'post',
+    data
+  })
+}

+ 135 - 0
src/api/xiaosha.js

@@ -0,0 +1,135 @@
+import request from '@/utils/request'
+// ---------------------问题上报------------------------
+// 问题上报修改
+export function updateProblemReport(data) {
+  return request({
+    url: '/problemReport/updateProblemReport',
+    method: 'post',
+    data,
+  })
+}
+// 查询问题上报详情
+export function getProblemReportDetailById(data) {
+  return request({
+    url: '/problemReport/getProblemReportDetailById',
+    method: 'post',
+    data,
+  })
+}
+// 问题上报列表分页
+export function getProblemReportPage(data) {
+  return request({
+    url: '/problemReport/getProblemReportPage',
+    method: 'post',
+    data,
+  })
+}
+// 问题上报数据报表
+export function getProblemReportData(data) {
+  return request({
+    url: 'problemReport/getProblemReportData',
+    method: 'post',
+    data,
+  })
+}
+// ---------------------消杀------------------------
+// 消杀区域-列表分页
+export function disinfectAreaList(data) {
+  return request({
+    url: '/admin/disinfectArea/getPageList',
+    method: 'post',
+    data,
+  })
+}
+// 消杀区域-新增-修改
+export function disinfectAreaEdit(data) {
+  return request({
+    url: '/admin/disinfectArea/edit',
+    method: 'post',
+    data,
+  })
+}
+// 消杀区域-删除
+export function disinfectAreDelete(params) {
+  return request({
+    url: '/admin/disinfectArea/delete',
+    method: 'get',
+    params,
+  })
+}
+// 消杀区域-列表
+export function disinfectAreaGetList(params) {
+  return request({
+    url: '/admin/disinfectArea/getList',
+    method: 'get',
+    params,
+  })
+}
+// 消杀人员-列表分页
+export function disinfectUserList(data) {
+  return request({
+    url: '/admin/disinfectUser/getPageList',
+    method: 'post',
+    data,
+  })
+}
+// 消杀人员-新增-修改
+export function disinfectUserEdit(data) {
+  return request({
+    url: '/admin/disinfectUser/edit',
+    method: 'post',
+    data,
+  })
+}
+// 消杀人员-删除
+export function disinfectUserDel(disinfectUserId) {
+  return request({
+    url: '/admin/disinfectUser/delete',
+    method: 'get',
+    params:{disinfectUserId},
+  })
+}
+// 消杀人员的批量导入
+export function excelInput(data) {
+  return request({
+    url: '/admin/disinfectUser/excelInput',
+    method: 'post',
+    data,
+  })
+}
+
+// 消杀记录-列表分页
+export function disinfectRecordList(data) {
+  return request({
+    url: '/admin/disinfectRecord/getPageList',
+    method: 'post',
+    data,
+  })
+}
+// 导出本月通行记录
+export function monthRecords(data) {
+  return request({
+    url: '/faceLogExport/monthRecords/doc',
+    method: 'post',
+    data,
+  })
+}
+// 导出当天通行记录
+export function todayRecords(data) {
+  return request({
+    url: '/faceLogExport/todayRecords/doc',
+    method: 'post',
+    headers: {
+      "Content-Type": "application/json",
+    },
+    data,
+  })
+}
+// 导出本周通行记录
+export function weekedRecords(data) {
+  return request({
+    url: '/faceLogExport/weekedRecords/doc',
+    method: 'post',
+    data,
+  })
+}

BIN
src/assets/404_images/404.png


BIN
src/assets/404_images/404_cloud.png


BIN
src/assets/area-del.png


BIN
src/assets/bg.png


BIN
src/assets/buildingCode.png


BIN
src/assets/default-img-home.jpg


BIN
src/assets/default-img.png


BIN
src/assets/notice-bg.png


BIN
src/assets/positioning.png


BIN
src/assets/problem-bg.png


BIN
src/assets/zfbBuildingCode.jpg


+ 239 - 0
src/components/BatchUpload/index.vue

@@ -0,0 +1,239 @@
+<template>
+  <span>
+    <!-- <a href="javascript:;" class="file" v-if="fileType === 'directoryImage'">
+      上传文件
+      <input
+        type="file"
+        name="file"
+        ref="file"
+        @change="upload($event, 'directoryImage')"
+        webkitdirectory
+      />
+    </a> -->
+    <el-button
+      type="primary"
+      @click="upload"
+      v-if="fileType === 'directoryImage'"
+    >
+      确定
+    </el-button>
+    <a href="javascript:;" class="file" v-if="fileType === 'excel'">
+      批量导入
+      <input
+        type="file"
+        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
+        ID="fileSelect"
+        runat="server"
+        @change="upload($event, 'excel')"
+      />
+    </a>
+  </span>
+</template>
+
+<script>
+import * as XLSX from "xlsx";
+export default {
+  name: "BatchUpload",
+  components: {},
+  props: {
+    //图片允许的文件格式
+    formatStyles: {
+      type: Array,
+      default() {
+        return ["png", "jpg", "jpeg"];
+      },
+    },
+    //要求文件命名至少包含的项数,并指定返回的key值;----> 命名规则 A-B-C-D-E.XXX   则返回,A=name  B=idNumber  C=cardIdEx
+    needFileNameList: {
+      type: Array,
+      // default() {
+      //   return ["name", "idNumber", "cardIdEx"];
+      // },
+    },
+    //调用种类 directoryImage->文件夹图片  excel->excel文件
+    fileType: {
+      type: String,
+      default: "directoryImage",
+    },
+    file: {
+      type: FileList,
+    },
+  },
+  data() {
+    return {};
+  },
+  watch: {},
+  methods: {
+    upload(e, type) {
+      let files = e.target.files || this.file;
+      //若出现files赋值未知错误值或照片长度不对则return
+      if (!files || files.length < 1) {
+        return this.$message.error("请上传");
+      }
+      // 如果是批量上传图片走这里
+      if (this.file) {
+        if (!this.needFileNameList) {
+          return this.$message.error("请选择命名参数");
+        }
+        if (this.needFileNameList.indexOf("name") === -1) {
+          return this.$message.error("姓名为必填项");
+        }
+        if (
+          this.needFileNameList.indexOf("idNumber") > -1 ||
+          this.needFileNameList.indexOf("cardIdEx") > -1 ||
+          this.needFileNameList.indexOf("phone") > -1
+        ) {
+          //找出所有图片
+          this.getPhotoList(Array.from(files));
+        } else {
+          return this.$message.error("手机号、身份证、卡号任选其一必选");
+        }
+      }
+      //判断文件类型,调用不同的处理办法
+      switch (type) {
+        case "directoryImage":
+          //找出所有图片
+          this.getPhotoList(Array.from(files));
+          break;
+        case "excel":
+          //处理excel
+          this.getJsonList(Array.from(files));
+          break;
+        default:
+          break;
+      }
+    },
+    getPhotoList(files) {
+      let photoList = {
+        correct: [],
+        incorrect: [],
+      };
+      files.forEach((item) => {
+        let arr = item.name.split(".");
+        let formatStyle = arr[arr.length - 1];
+        //若文件类型不在指定类型中,则不处理
+        if (!this.formatStyles.includes(formatStyle)) {
+          photoList.incorrect.push({
+            reason:
+              "文件格式要求为" +
+              this.formatStyles.join(",") +
+              ",上传的类型为" +
+              formatStyle,
+            file: item,
+          });
+          return;
+        } else if (item.size > 1024 * 1024 * 2) {
+          //要求文件大小不大于指定值 单位:字节
+          photoList.incorrect.push({
+            reason:
+              "单张图片大小要求为2M内,上传的图片大小为" +
+              item.size / 1024 / 1024 +
+              "M",
+            file: item,
+          });
+          return;
+        }
+
+        let obj = this.matchNeedFileNameList(item, arr[0]);
+        photoList[obj.status ? "correct" : "incorrect"].push(obj.file);
+      });
+      this.doUpload(photoList);
+    },
+    matchNeedFileNameList(file, fileName) {
+      let arrContent = fileName.split("-");
+      let obj = {
+        status: true,
+        file: {},
+      };
+      if (
+        arrContent.length < this.needFileNameList.length ||
+        arrContent.some((name) => {
+          return !name;
+        })
+      ) {
+        return {
+          status: false,
+          file: {
+            reason:
+              "文件没有按指定要求命名,需要" + this.needFileNameList.join(","),
+            file: file,
+          },
+        };
+      }
+      this.needFileNameList.forEach((item, index) => {
+        obj.file[item] = arrContent[index].trim() || "";
+      });
+      obj.file["avatar"] = file;
+      return obj;
+    },
+    doUpload(photoList) {
+      this.$emit("getFileList", photoList);
+    },
+    // 处理excel文件的内容
+    getJsonList(files) {
+      //只处理第一个文件;
+      let file = files[0];
+      let reader = new FileReader();
+      let photoList = {
+        correct: [],
+        incorrect: [],
+      };
+      reader.readAsBinaryString(file);
+      reader.onload = (e) => {
+        // 获取传递的表格
+        let binaryString = e.target.result;
+        // 以二进制流方式读取到整份的excel 表格对象
+        let workbook = XLSX.read(binaryString, {
+          type: "binary",
+          sheetRows: 0,
+          codepage: 936,
+        });
+        let data = [];
+        // 遍历每张表读取
+        for (let sheet in workbook.Sheets) {
+          data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
+        }
+        photoList["correct"] = data;
+        this.doUpload(photoList);
+      };
+    },
+  },
+  mounted() {},
+};
+</script>
+
+<style scoped>
+/*批量导入按钮*/
+.file {
+  margin: 10px 0 0 10px;
+  position: relative;
+  background: #d0eeff;
+  border: 1px solid #99d3f5;
+  border-radius: 4px;
+  padding: 10px 20px;
+  box-sizing: border-box;
+  overflow: hidden;
+  color: #1e88c7;
+  text-decoration: none;
+  text-indent: 0;
+}
+.file input {
+  position: absolute;
+  font-size: 14px;
+  width: 106px;
+  height: 40px;
+  left: 0;
+  top: 0;
+  opacity: 0;
+  cursor: pointer;
+}
+.file:hover {
+  background: #aadffd;
+  border-color: #78c3f3;
+  color: #004974;
+  text-decoration: none;
+}
+.el-button {
+  margin-left: 10px;
+}
+</style>

+ 79 - 0
src/components/Breadcrumb/index.vue

@@ -0,0 +1,79 @@
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
+        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
+        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
+<script>
+import pathToRegexp from 'path-to-regexp'
+
+export default {
+  data() {
+    return {
+      levelList: null
+    }
+  },
+  watch: {
+    $route() {
+      this.getBreadcrumb()
+    }
+  },
+  created() {
+    this.getBreadcrumb()
+  },
+  methods: {
+    getBreadcrumb() {
+      // only show routes with meta.title
+      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
+      const first = matched[0]
+
+      // 在面包屑最顶部加入'/'路由
+      // if (!this.isDashboard(first)) {
+      //   matched = [{ path: '/dashboard', meta: { title: '主页' }}].concat(matched)
+      // }
+
+      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
+    },
+    isDashboard(route) {
+      const name = route && route.name
+      if (!name) {
+        return false
+      }
+      return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
+    },
+    pathCompile(path) {
+      // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
+      const { params } = this.$route
+      var toPath = pathToRegexp.compile(path)
+      return toPath(params)
+    },
+    handleLink(item) {
+      const { redirect, path } = item
+      if (redirect) {
+        this.$router.push(redirect)
+        return
+      }
+      this.$router.push(this.pathCompile(path))
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-breadcrumb.el-breadcrumb {
+  display: inline-block;
+  font-size: 14px;
+  line-height: 50px;
+  margin-left: 8px;
+
+  .no-redirect {
+    color: #97a8be;
+    cursor: text;
+  }
+}
+</style>

+ 413 - 0
src/components/DialogDetails/index.vue

@@ -0,0 +1,413 @@
+<template>
+  <div>
+    <el-dialog
+      title="详情"
+      :visible.sync="dialogTableVisible"
+      :before-close="cancel"
+      width="800px"
+    >
+      <el-descriptions
+        :column="2"
+        border
+        :contentStyle="CS"
+        :label-style="LS"
+        v-if="row"
+      >
+        <el-descriptions-item label="设备编号" v-if="type === 'pass_records'">{{
+          row.deviceSn
+        }}</el-descriptions-item>
+        <el-descriptions-item label="设备地点" v-if="type === 'pass_records'">{{
+          row.deviceName
+        }}</el-descriptions-item>
+
+        <el-descriptions-item label="用户姓名">{{
+          notShowData ? row.name : dialogContent.name
+        }}</el-descriptions-item>
+
+        <el-descriptions-item label="身份证号" v-if="type === 'pass_records'"
+          >{{ notShowData ? row.cardid : dialogContent.cardid }}
+          <el-button
+            type="primary"
+            size="small"
+            @click="searchContent()"
+            v-if="sysQueryConfiguration"
+            :disabled="sysQueryConfigurationStatus"
+            >查看脱敏数据</el-button
+          ></el-descriptions-item
+        >
+        <el-descriptions-item label="身份证号" v-else>{{
+          row.idNumber
+        }}</el-descriptions-item>
+
+        <el-descriptions-item label="手机号">{{
+          notShowData ? row.phone : dialogContent.phone
+        }}</el-descriptions-item>
+        <el-descriptions-item label="所属账号" v-if="type === 'pass_records'">{{
+          row.username
+        }}</el-descriptions-item>
+        <el-descriptions-item label="健康码状态" v-if="type === 'pass_records'">
+          <el-tag type="success" effect="dark" v-if="row.jkmStatus === '00'"
+            >绿码</el-tag
+          >
+          <el-tag
+            type="warning"
+            effect="dark"
+            v-else-if="row.jkmStatus === '01'"
+            >黄码</el-tag
+          >
+          <el-tag type="danger" effect="dark" v-else-if="row.jkmStatus === '10'"
+            >红码</el-tag
+          >
+          <el-tag type="info" effect="plain" v-else>未知</el-tag>
+        </el-descriptions-item>
+
+        <el-descriptions-item
+          label="省-市-区-街道"
+          v-if="type != 'pass_records'"
+        >
+          {{ row.provinceName }}-{{ row.cityName }}-{{ row.areaName }}-{{
+            row.streetName
+          }}
+        </el-descriptions-item>
+        <el-descriptions-item label="详细地址" v-if="type != 'pass_records'">
+          {{ row.address }}
+        </el-descriptions-item>
+        <el-descriptions-item label="认证状态" v-if="type === 'white_list'">
+          <el-tag effect="plain" type="success" v-if="row.status === 1"
+            >已认证</el-tag
+          >
+          <el-tag effect="plain" type="info" v-else-if="row.status === 2"
+            >未认证</el-tag
+          >
+          <el-tag effect="plain" type="info" v-else>未知</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="认证状态" v-if="type === 'pass_records'">
+          <el-tag type="" effect="plain" v-if="row.rightno === 104"
+            >访客</el-tag
+          >
+          <el-tag type="success" effect="plain" v-else-if="row.rightno === 105"
+            >员工</el-tag
+          >
+        </el-descriptions-item>
+        <el-descriptions-item label="现场照片">
+          <el-image
+            style="width: 200px; height: 200px"
+            :src="row.avatar ? row.avatar : row.photo"
+            :preview-src-list="[row.avatar ? row.avatar : row.photo]"
+          >
+          </el-image>
+        </el-descriptions-item>
+      </el-descriptions>
+      <!-- 自定义字段 -->
+      <template
+        v-if="visitToJetList.contentStatus == 1"
+      >
+        <h3>自定义字段内容</h3>
+        <el-descriptions
+          :column="2"
+          border
+          :contentStyle="CS"
+          :label-style="LS"
+        >
+          <el-descriptions-item
+            v-for="(item, index) in visitToJetList.contents"
+            :key="index"
+            :label="item.customName"
+          >
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="是否可编辑"
+              placement="top-start"
+            >
+              <i
+                class="el-icon-edit icon"
+                :style="
+                  item.isEditable === 1 ? { color: '#409eff' } : { color: '' }
+                "
+              ></i>
+            </el-tooltip>
+            <el-tooltip
+              class="item"
+              effect="dark"
+              content="是否在小程序端显示"
+              placement="top-start"
+            >
+              <i
+                class="el-icon-star-on icon"
+                :style="
+                  item.isShow === 1 ? { color: '#409eff' } : { color: '' }
+                "
+              ></i>
+            </el-tooltip>
+            <el-image
+              v-if="item.customType == '图片'"
+              style="width: 200px; height: 200px"
+              :src="item.customNameVal"
+              :preview-src-list="[item.customNameVal]"
+            >
+            </el-image>
+            <span v-else>{{
+              item.customNameVal ? item.customNameVal : "未填写"
+            }}</span>
+          </el-descriptions-item>
+        </el-descriptions>
+      </template>
+
+      <!-- 三码 -->
+      <template
+        v-if="visitToJetList.threeCodeList&&visitToJetList.threeCodeList.length > 0"
+      >
+        <h3>三码内容</h3>
+        <el-descriptions
+          class="marginbottom"
+          :column="2"
+          border
+          :contentStyle="CS"
+          :label-style="LS"
+        >
+        <!-- 健康码  -->
+          <template v-if="visitToJetList.threeCodeList.indexOf('1') > -1">
+            <el-descriptions-item label="健康码" v-if="visitToJetList.userVisitorListDetailHealth.jkm">
+              {{ visitToJetList.userVisitorListDetailHealth.jkm | noList }}
+            </el-descriptions-item>
+            <el-descriptions-item
+              label="健康码截图"
+              v-if="visitToJetList.userVisitorListDetailHealth.jkmPhoto"
+            >
+              <el-image
+                style="width: 100px; height: 100px"
+                :src="visitToJetList.userVisitorListDetailHealth.jkmPhoto"
+                :preview-src-list="[visitToJetList.userVisitorListDetailHealth.jkmPhoto]"
+              >
+              </el-image>
+            </el-descriptions-item>
+          </template>
+          <!-- 核酸 -->
+          <template v-if="visitToJetList.threeCodeList.indexOf('2') > -1">
+            <el-descriptions-item label="核酸" v-if="visitToJetList.userVisitorListDetailHealth.hs">
+              <p>【采样】{{ visitToJetList.userVisitorListDetailHealth.hsCheckTime | noList }}</p>
+              <p>【报告】{{ visitToJetList.userVisitorListDetailHealth.hsResultTime | noList }}</p>
+              <p>{{ visitToJetList.userVisitorListDetailHealth.hs | noList }}</p>
+            </el-descriptions-item>
+            <el-descriptions-item
+              label="核酸截图"
+              v-if="visitToJetList.userVisitorListDetailHealth.hsPhoto"
+            >
+              <el-image
+                style="width: 100px; height: 100px"
+                :src="visitToJetList.userVisitorListDetailHealth.hsPhoto"
+                :preview-src-list="[visitToJetList.userVisitorListDetailHealth.hsPhoto]"
+              >
+              </el-image>
+            </el-descriptions-item>
+          </template>
+          <!-- 行程码 -->
+          <template v-if="visitToJetList.threeCodeList.indexOf('3') > -1">
+            <el-descriptions-item label="行程信息" v-if="visitToJetList.userVisitorListDetailHealth.xc">
+              {{
+                visitToJetList.userVisitorListDetailHealth.xc == 1
+                  ? "未过高风险地区"
+                  : visitToJetList.userVisitorListDetailHealth.xc == 2
+                  ? "去过高风险地区"
+                  : "未知"
+              }}
+            </el-descriptions-item>
+            <el-descriptions-item
+              label="行程信息截图"
+              v-if="visitToJetList.userVisitorListDetailHealth.xcPhoto"
+            >
+              <el-image
+                style="width: 100px; height: 100px"
+                :src="visitToJetList.userVisitorListDetailHealth.xcPhoto"
+                :preview-src-list="[visitToJetList.userVisitorListDetailHealth.xcPhoto]"
+              >
+              </el-image>
+            </el-descriptions-item>
+          </template>
+        </el-descriptions>
+      </template>
+      <!-- 访客机字段 -->
+      <template class="maxHeight" v-if="visitToJetList.visitorStatus==1">
+        <h3>访客机字段内容</h3>
+        <el-descriptions
+          class="marginbottom"
+          :column="2"
+          border
+          :contentStyle="CS"
+          :label-style="LS"
+        >
+          <el-descriptions-item label="来访人单位">
+            {{ visitToJetList.userVisitorListDetailVisitor.company | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="来访人体温">
+            {{ visitToJetList.userVisitorListDetailVisitor.temperature | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="来访人车牌号码">
+            {{ visitToJetList.userVisitorListDetailVisitor.carno | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="访问事由">
+            {{ visitToJetList.userVisitorListDetailVisitor.reason | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="来访时间">
+            {{ visitToJetList.userVisitorListDetailVisitor.time | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="设备所在单位">
+            {{ visitToJetList.userVisitorListDetailVisitor.org | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item
+            label="标准比对照片"
+            v-if="visitToJetList.userVisitorListDetailVisitor.sceneXp && type === 'pass_records'"
+          >
+            <el-image
+              style="width: 200px; height: 200px"
+              :src="visitToJetList.userVisitorListDetailVisitor.sceneXp"
+              :preview-src-list="[visitToJetList.userVisitorListDetailVisitor.sceneXp]"
+            >
+            </el-image>
+          </el-descriptions-item>
+          <el-descriptions-item label="身份证照片" v-if="visitToJetList.userVisitorListDetailVisitor.xp">
+            <el-image
+              style="width: 200px; height: 200px"
+              :src="visitToJetList.userVisitorListDetailVisitor.xp"
+              :preview-src-list="[visitToJetList.userVisitorListDetailVisitor.xp]"
+            >
+            </el-image>
+          </el-descriptions-item>
+          <el-descriptions-item label="受访人单位">
+            {{ visitToJetList.userVisitorListDetailVisitor.visiteeCompany | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="受访人部门">
+            {{ visitToJetList.userVisitorListDetailVisitor.visiteeBm | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="受访人房间号">
+            {{ visitToJetList.userVisitorListDetailVisitor.visiteeRoom | noList }}
+          </el-descriptions-item>
+          <el-descriptions-item label="受访人姓名"
+            >{{ visitToJetList.userVisitorListDetailVisitor.visiteeXm | noList }}
+          </el-descriptions-item>
+        </el-descriptions>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getWhiteListFrom,
+  getVisitorListFrom,
+  getUserListFrom,
+} from "@/api/user_manage.js";
+import { checkRole } from "@/utils/checkRole";
+import { getDetails } from "@/api/old_api_pengwenbing";
+
+export default {
+  name: "",
+  props: {
+    dialogTableVisible: {
+      type: Boolean,
+      default: false,
+    },
+    // detailsList: {
+    //   type: Array,
+    // },
+    visitToJetList: {
+      type: Object,
+    },
+    row: {
+      type: Object,
+    },
+    type: {
+      type: String,
+    },
+  },
+  filters: {
+    noList(str) {
+      return str ? str : "暂无";
+    },
+  },
+  components: {},
+  data() {
+    return {
+      visitToJet_loading: false,
+      CS: {
+        // "text-align": "center", //文本居中
+        "min-width": "250px", //最小宽度
+        "word-break": "break-all", //过长时自动换行
+      },
+      LS: {
+        // color: "#000",
+        "text-align": "center",
+        // "font-weight": "600",
+        height: "40px",
+        // "background-color": "rgba(255, 97, 2, 0.1)",
+        "min-width": "110px",
+        "word-break": "keep-all",
+      },
+      // 脱敏数据信息详情
+      dialogContent: null,
+      notShowData: true,
+    };
+  },
+  methods: {
+    checkRole,
+    cancel() {
+      this.$emit("dialog", false);
+      this.notShowData = true;
+    },
+    // 查看脱敏数据
+    searchContent() {
+      this.$prompt("请输入查询密码", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        closeOnClickModal: false,
+      })
+        .then(({ value }) => {
+          getDetails({ id: this.row.logId, password: value }).then((res) => {
+            this.dialogContent = res.data;
+            this.notShowData = false;
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消查询",
+          });
+        });
+    },
+  },
+  computed: {
+    sysQueryConfigurationStatus() {
+      return this.$store.getters.sysQueryConfigurationStatus === 0;
+    },
+    sysQueryConfiguration() {
+      return this.$store.getters.sysQueryConfiguration === 1;
+    },
+  },
+  watch: {
+    visitToJetList(n) {
+    },
+  },
+  created() {},
+  mounted() {},
+};
+</script>
+
+<style scoped lang="scss">
+.icon {
+  margin-right: 7px;
+}
+.el-button {
+  margin-left: 10px;
+}
+.marginbottom {
+  margin-bottom: 20px;
+}
+.maxHeight {
+  max-height: 500px;
+  overflow-y: auto;
+}
+h3 {
+  margin-bottom: 5px;
+}
+</style>

+ 44 - 0
src/components/Hamburger/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <div style="padding: 0 15px;" @click="toggleClick">
+    <svg
+      :class="{'is-active':isActive}"
+      class="hamburger"
+      viewBox="0 0 1024 1024"
+      xmlns="http://www.w3.org/2000/svg"
+      width="64"
+      height="64"
+    >
+      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Hamburger',
+  props: {
+    isActive: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    toggleClick() {
+      this.$emit('toggleClick')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.hamburger {
+  display: inline-block;
+  vertical-align: middle;
+  width: 20px;
+  height: 20px;
+}
+
+.hamburger.is-active {
+  transform: rotate(180deg);
+}
+</style>

+ 101 - 0
src/components/Pagination/index.vue

@@ -0,0 +1,101 @@
+<template>
+  <div :class="{'hidden':hidden}" class="pagination-container">
+    <el-pagination
+      :background="background"
+      :current-page.sync="currentPage"
+      :page-size.sync="pageSize"
+      :layout="layout"
+      :page-sizes="pageSizes"
+      :total="total"
+      v-bind="$attrs"
+      @size-change="handleSizeChange"
+      @current-change="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import { scrollTo } from '@/utils/scroll-to'
+
+export default {
+  name: 'Pagination',
+  props: {
+    total: {
+      required: true,
+      type: Number
+    },
+    page: {
+      type: Number,
+      default: 1
+    },
+    limit: {
+      type: Number,
+      default: 20
+    },
+    pageSizes: {
+      type: Array,
+      default() {
+        return [5, 10, 20, 30, 50]
+      }
+    },
+    layout: {
+      type: String,
+      default: 'total, sizes, prev, pager, next, jumper'
+    },
+    background: {
+      type: Boolean,
+      default: true
+    },
+    autoScroll: {
+      type: Boolean,
+      default: true
+    },
+    hidden: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    currentPage: {
+      get() {
+        return this.page
+      },
+      set(val) {
+        this.$emit('update:page', val)
+      }
+    },
+    pageSize: {
+      get() {
+        return this.limit
+      },
+      set(val) {
+        this.$emit('update:limit', val)
+      }
+    }
+  },
+  methods: {
+    handleSizeChange(val) {
+      this.$emit('pagination', { page: this.currentPage, limit: val })
+      if (this.autoScroll) {
+        scrollTo(0, 800)
+      }
+    },
+    handleCurrentChange(val) {
+      this.$emit('pagination', { page: val, limit: this.pageSize })
+      if (this.autoScroll) {
+        scrollTo(0, 800)
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.pagination-container {
+  background: #fff;
+  padding: 32px 16px;
+}
+.pagination-container.hidden {
+  display: none;
+}
+</style>

+ 60 - 0
src/components/Screenfull/index.vue

@@ -0,0 +1,60 @@
+<template>
+  <div>
+    <svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" />
+  </div>
+</template>
+
+<script>
+  import screenfull from 'screenfull'
+
+  export default {
+    name: 'Screenfull',
+    data() {
+      return {
+        isFullscreen: false
+      }
+    },
+    mounted() {
+      this.init()
+    },
+    beforeDestroy() {
+      this.destroy()
+    },
+    methods: {
+      click() {
+        if (!screenfull.enabled) {
+          this.$message({
+            message: 'you browser can not work',
+            type: 'warning'
+          })
+          return false
+        }
+        screenfull.toggle()
+      },
+      change() {
+        this.isFullscreen = screenfull.isFullscreen
+      },
+      init() {
+        if (screenfull.enabled) {
+          screenfull.on('change', this.change)
+        }
+      },
+      destroy() {
+        if (screenfull.enabled) {
+          screenfull.off('change', this.change)
+        }
+      }
+    }
+  }
+</script>
+
+<style scoped>
+  .screenfull-svg {
+    display: inline-block;
+    cursor: pointer;
+    fill: #5a5e66;;
+    width: 20px;
+    height: 20px;
+    vertical-align: 10px;
+  }
+</style>

+ 62 - 0
src/components/SvgIcon/index.vue

@@ -0,0 +1,62 @@
+<template>
+  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
+  <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
+    <use :xlink:href="iconName" />
+  </svg>
+</template>
+
+<script>
+// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
+import { isExternal } from '@/utils/validate'
+
+export default {
+  name: 'SvgIcon',
+  props: {
+    iconClass: {
+      type: String,
+      required: true
+    },
+    className: {
+      type: String,
+      default: ''
+    }
+  },
+  computed: {
+    isExternal() {
+      return isExternal(this.iconClass)
+    },
+    iconName() {
+      return `#icon-${this.iconClass}`
+    },
+    svgClass() {
+      if (this.className) {
+        return 'svg-icon ' + this.className
+      } else {
+        return 'svg-icon'
+      }
+    },
+    styleExternalIcon() {
+      return {
+        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
+        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.svg-icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+
+.svg-external-icon {
+  background-color: currentColor;
+  mask-size: cover!important;
+  display: inline-block;
+}
+</style>

BIN
src/icons/images/avatar.jpg


Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
src/icons/images/avatar.js


BIN
src/icons/images/logo.png


+ 9 - 0
src/icons/index.js

@@ -0,0 +1,9 @@
+import Vue from 'vue'
+import SvgIcon from '@/components/SvgIcon'// svg component
+
+// register globally
+Vue.component('svg-icon', SvgIcon)
+
+const req = require.context('./svg', false, /\.svg$/)
+const requireAll = requireContext => requireContext.keys().map(requireContext)
+requireAll(req)

BIN
src/icons/index/bg.png


BIN
src/icons/index/bg1.jpg


BIN
src/icons/index/dp.png


BIN
src/icons/index/dp2.png


BIN
src/icons/index/dp3.png


BIN
src/icons/index/dp4.png


BIN
src/icons/index/hm.png


BIN
src/icons/index/hm2.png


BIN
src/icons/index/hmmj.png


BIN
src/icons/index/hmmj2.png


BIN
src/icons/index/hs.png


BIN
src/icons/index/icon.png


BIN
src/icons/index/jkmwz.png


BIN
src/icons/index/line.png


BIN
src/icons/index/lm.png


BIN
src/icons/index/underLine.png


BIN
src/icons/index/wd.png


BIN
src/icons/index/wdzc.png


BIN
src/icons/index/yc.png


BIN
src/icons/index/ym.png


BIN
src/icons/index/ymwjz.png


BIN
src/icons/index/zj.png


BIN
src/icons/index2/bg.png


BIN
src/icons/index2/blue.png


BIN
src/icons/index2/left_bottom.png


BIN
src/icons/index2/left_top.png


BIN
src/icons/index2/left_top_line.png


BIN
src/icons/index2/red.png


BIN
src/icons/index2/school_logo.png


BIN
src/icons/index2/screen.png


BIN
src/icons/index2/title_line.png


BIN
src/icons/index2/yellow.png


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
src/icons/svg/dashboard.svg


+ 1 - 0
src/icons/svg/example.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

+ 1 - 0
src/icons/svg/exit-fullscreen.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg>

+ 1 - 0
src/icons/svg/eye-open.svg

@@ -0,0 +1 @@
+<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

+ 1 - 0
src/icons/svg/eye.svg

@@ -0,0 +1 @@
+<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
src/icons/svg/form.svg


+ 1 - 0
src/icons/svg/fullscreen.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg>

+ 1 - 0
src/icons/svg/link.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
src/icons/svg/map.svg


+ 1 - 0
src/icons/svg/nested.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

+ 1 - 0
src/icons/svg/password.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

Неке датотеке нису приказане због велике количине промена