asd123a20 před 4 roky
rodič
revize
13df5b0e78
100 změnil soubory, kde provedl 14124 přidání a 0 odebrání
  1. 3 0
      .browserslistrc
  2. 5 0
      .editorconfig
  3. 11 0
      .env
  4. 29 0
      .eslintrc.js
  5. 23 0
      .gitignore
  6. 5 0
      babel.config.js
  7. 1 0
      client/css/app.d9cb9654.css
  8. 1 0
      client/css/chunk-22754bfe.479c90a4.css
  9. 1 0
      client/css/chunk-3813fef6.967ae014.css
  10. 1 0
      client/css/chunk-40fb139e.245504ca.css
  11. 1 0
      client/css/chunk-57458d7a.c3c7050e.css
  12. 1 0
      client/css/chunk-6acf5018.7f01c06c.css
  13. 1 0
      client/css/chunk-7030f5aa.352f0d2b.css
  14. 1 0
      client/css/chunk-79924bbd.a4fe5c3f.css
  15. 1 0
      client/css/chunk-a6f5a958.16e983d9.css
  16. 1 0
      client/css/chunk-acafa550.aa0af357.css
  17. 1 0
      client/css/chunk-f43862f0.4e08efc6.css
  18. 1 0
      client/css/chunk-vendors.84bb20f7.css
  19. binární
      client/favicon.ico
  20. binární
      client/fonts/element-icons.535877f5.woff
  21. binární
      client/fonts/element-icons.732389de.ttf
  22. binární
      client/img/bg2.4f6e6589.jpg
  23. binární
      client/img/home.a18367d8.png
  24. 1 0
      client/img/logo1.191c3d70.svg
  25. 1 0
      client/index.html
  26. 1 0
      client/js/app.c758adf1.js
  27. 1 0
      client/js/chunk-22754bfe.0d2e19df.js
  28. 1 0
      client/js/chunk-3813fef6.364de217.js
  29. 1 0
      client/js/chunk-40fb139e.a5847eda.js
  30. 1 0
      client/js/chunk-57458d7a.2ab46242.js
  31. 1 0
      client/js/chunk-6acf5018.9ad9af69.js
  32. 1 0
      client/js/chunk-7030f5aa.d693ddfa.js
  33. 1 0
      client/js/chunk-79924bbd.e5128c73.js
  34. 1 0
      client/js/chunk-a6f5a958.8bddea6c.js
  35. 1 0
      client/js/chunk-acafa550.4d220377.js
  36. 1 0
      client/js/chunk-f43862f0.2a0b159f.js
  37. 33 0
      client/js/chunk-vendors.2addda4d.js
  38. 52 0
      lib/plug/axios.js
  39. 15 0
      lib/plug/deepTree.js
  40. 9 0
      lib/plug/dict.js
  41. 5 0
      lib/plug/element.js
  42. 68 0
      lib/style/index.less
  43. 69 0
      naf/data/deep-tree.vue
  44. 24 0
      naf/data/dialog -drawer.md
  45. 68 0
      naf/data/dialog -drawer.vue
  46. 0 0
      naf/data/export-file.vue
  47. 19 0
      naf/data/form.md
  48. 54 0
      naf/data/form.vue
  49. 56 0
      naf/data/tables/grid.md
  50. 74 0
      naf/data/tables/naf-grid.vue
  51. 47 0
      naf/data/tables/pagination .vue
  52. 70 0
      naf/data/tables/search.vue
  53. 61 0
      naf/data/tables/table.vue
  54. 0 0
      naf/data/upload.vue
  55. 54 0
      naf/layout/breadcrumb.vue
  56. 34 0
      naf/layout/menu-item.vue
  57. 69 0
      naf/layout/menu.vue
  58. 97 0
      naf/layout/user.vue
  59. 82 0
      naf/menu.js
  60. 12826 0
      package-lock.json
  61. 37 0
      package.json
  62. binární
      public/favicon.ico
  63. 17 0
      public/index.html
  64. 1 0
      server/css/app.d9cb9654.css
  65. 1 0
      server/css/chunk-22754bfe.479c90a4.css
  66. 1 0
      server/css/chunk-3813fef6.967ae014.css
  67. 1 0
      server/css/chunk-40fb139e.245504ca.css
  68. 1 0
      server/css/chunk-57458d7a.c3c7050e.css
  69. 1 0
      server/css/chunk-6acf5018.7f01c06c.css
  70. 1 0
      server/css/chunk-7030f5aa.352f0d2b.css
  71. 1 0
      server/css/chunk-79924bbd.a4fe5c3f.css
  72. 1 0
      server/css/chunk-a6f5a958.16e983d9.css
  73. 1 0
      server/css/chunk-acafa550.aa0af357.css
  74. 1 0
      server/css/chunk-f43862f0.4e08efc6.css
  75. 1 0
      server/css/chunk-vendors.84bb20f7.css
  76. binární
      server/favicon.ico
  77. binární
      server/fonts/element-icons.535877f5.woff
  78. binární
      server/fonts/element-icons.732389de.ttf
  79. binární
      server/img/bg2.4f6e6589.jpg
  80. binární
      server/img/home.a18367d8.png
  81. 1 0
      server/img/logo1.191c3d70.svg
  82. 1 0
      server/index.html
  83. 1 0
      server/js/app.1f57ff9d.js
  84. 1 0
      server/js/chunk-22754bfe.8fd0de4e.js
  85. 1 0
      server/js/chunk-3813fef6.364de217.js
  86. 1 0
      server/js/chunk-40fb139e.a5847eda.js
  87. 1 0
      server/js/chunk-57458d7a.2ced3c85.js
  88. 1 0
      server/js/chunk-6acf5018.9ad9af69.js
  89. 1 0
      server/js/chunk-7030f5aa.d693ddfa.js
  90. 1 0
      server/js/chunk-79924bbd.e5128c73.js
  91. 1 0
      server/js/chunk-a6f5a958.8bddea6c.js
  92. 1 0
      server/js/chunk-acafa550.4d220377.js
  93. 1 0
      server/js/chunk-f43862f0.ea0a1136.js
  94. 33 0
      server/js/chunk-vendors.2addda4d.js
  95. 7 0
      src/App.vue
  96. binární
      src/assets/bg2.jpg
  97. binární
      src/assets/home.png
  98. 1 0
      src/assets/logo1.svg
  99. 17 0
      src/main.js
  100. 0 0
      src/router/gaf.js

+ 3 - 0
.browserslistrc

@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead

+ 5 - 0
.editorconfig

@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true

+ 11 - 0
.env

@@ -0,0 +1,11 @@
+VUE_APP_ROOT_URL=/admin/
+VUE_APP_HEIGHT=937px
+VUE_APP_WIDTH=1920px
+VUE_APP_MENU_WIDTH=270PX
+VUE_APP_MENU_BACKGROUNDCOLOR=#083e96
+VUE_APP_MENU_TEXTCOLOR=#FFF
+VUE_APP_MENU_ACTIVETEXTCOLOR=#ffd04b
+VUE_APP_MENU_TITLE=VPN客户端管理系统
+VUE_APP_HOME_TITLEE=VPN客户端管理系统
+VUE_APP_HOME_DESCRIPTION=这是一段系统描述信息
+VUE_APP_TABS=false

+ 29 - 0
.eslintrc.js

@@ -0,0 +1,29 @@
+module.exports = {
+  root: true,
+  env: {
+    node: true
+  },
+  extends: [
+    'plugin:vue/essential',
+    '@vue/standard'
+  ],
+  plugins: ['vue'],
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  rules: {
+    'max-len': [
+      'warn',
+      {
+        code: 250
+      }
+    ],
+    'no-unused-vars': 'off',
+    'no-console': 'off',
+    singleQuote: 0,
+    trailingComma: 0,
+    bracketSpacing: 0,
+    jsxBracketSameLine: 0,
+    printWidth: 0
+  }
+}

+ 23 - 0
.gitignore

@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 5 - 0
babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/css/app.d9cb9654.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/css/chunk-22754bfe.479c90a4.css


+ 1 - 0
client/css/chunk-3813fef6.967ae014.css

@@ -0,0 +1 @@
+.gafBox[data-v-4a482c51]{height:90vh;overflow:hidden}.el-card[data-v-4a482c51]{height:100%}.el-card[data-v-4a482c51] .el-card__body{height:90%;overflow:auto}.el-card[data-v-4a482c51] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-4a482c51]{width:100%}.el-switch[data-v-4a482c51]{width:90%;margin:0 auto;display:block;text-indent:1.7em;margin-bottom:20px}

+ 1 - 0
client/css/chunk-40fb139e.245504ca.css

@@ -0,0 +1 @@
+.gafBox[data-v-2c011487]{height:90vh;overflow:hidden}.el-card[data-v-2c011487]{height:100%}.el-card[data-v-2c011487] .el-card__body{height:90%;overflow:auto}.el-card[data-v-2c011487] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-2c011487]{width:100%}.el-switch[data-v-2c011487]{width:90%;margin:0 auto;display:block;text-indent:1.7em;margin-bottom:20px}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/css/chunk-57458d7a.c3c7050e.css


+ 1 - 0
client/css/chunk-6acf5018.7f01c06c.css

@@ -0,0 +1 @@
+.gafBox[data-v-79a9981a]{height:90vh;overflow:hidden}.el-card[data-v-79a9981a]{height:100%}.el-card[data-v-79a9981a] .el-card__body{height:90%;overflow:auto}.el-card[data-v-79a9981a] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-79a9981a]{width:100%}

+ 1 - 0
client/css/chunk-7030f5aa.352f0d2b.css

@@ -0,0 +1 @@
+.el-card[data-v-32acac71],.gafBox[data-v-32acac71]{height:100%}.el-card .el-main[data-v-32acac71]{display:flex}.el-card .el-main .el-card[data-v-32acac71]{width:45%;margin:0 3%;height:75vh}

+ 1 - 0
client/css/chunk-79924bbd.a4fe5c3f.css

@@ -0,0 +1 @@
+.gafBox[data-v-6d8012e4]{height:90vh;overflow:hidden}.el-card[data-v-6d8012e4]{height:100%}.el-card[data-v-6d8012e4] .el-card__body{height:90%;overflow:auto}.el-card[data-v-6d8012e4] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-6d8012e4]{width:100%}

+ 1 - 0
client/css/chunk-a6f5a958.16e983d9.css

@@ -0,0 +1 @@
+.gafBox[data-v-64fd400e]{height:100%}.upload-demo[data-v-64fd400e]{float:right;margin:0 5px}.el-card[data-v-64fd400e]{height:100%}.el-card .el-main .grid[data-v-64fd400e],.el-card .el-main[data-v-64fd400e]{width:100%}

+ 1 - 0
client/css/chunk-acafa550.aa0af357.css

@@ -0,0 +1 @@
+.demo-form-inline[data-v-72f3a11a]{margin-left:1%;margin-top:10px}.prepend.el-select[data-v-72f3a11a]{width:100px}.table[data-v-16cb7e1c]{width:98%;margin:0 auto;max-height:60vh;overflow-y:auto}.pagination[data-v-f44c3072]{margin-left:1%;margin-top:20px}.gafBox[data-v-634f8c04]{height:100%}.upload-demo[data-v-634f8c04]{float:right;margin:0 5px}.el-card[data-v-634f8c04]{height:100%}.el-card .el-main .grid[data-v-634f8c04],.el-card .el-main[data-v-634f8c04]{width:100%}

+ 1 - 0
client/css/chunk-f43862f0.4e08efc6.css

@@ -0,0 +1 @@
+.wrapper[data-v-71b651fc]{height:100%;width:100%;position:relative;background-position:50%;background-repeat:o-repeat;background-size:cover;background-image:url(../img/home.a18367d8.png)}.titleWrapper[data-v-71b651fc]{text-align:center;top:40%;width:100%;position:absolute;color:#1d87b4}.title[data-v-71b651fc]{font-size:32px;letter-spacing:1.94px;line-height:2em;text-align:center}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/css/chunk-vendors.84bb20f7.css


binární
client/favicon.ico


binární
client/fonts/element-icons.535877f5.woff


binární
client/fonts/element-icons.732389de.ttf


binární
client/img/bg2.4f6e6589.jpg


binární
client/img/home.a18367d8.png


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/img/logo1.191c3d70.svg


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/index.html


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/app.c758adf1.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-22754bfe.0d2e19df.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-3813fef6.364de217.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-40fb139e.a5847eda.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-57458d7a.2ab46242.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-6acf5018.9ad9af69.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-7030f5aa.d693ddfa.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-79924bbd.e5128c73.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-a6f5a958.8bddea6c.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-acafa550.4d220377.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
client/js/chunk-f43862f0.2a0b159f.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 33 - 0
client/js/chunk-vendors.2addda4d.js


+ 52 - 0
lib/plug/axios.js

@@ -0,0 +1,52 @@
+/* eslint-disable no-const-assign */
+import axios from 'axios'
+import router from '../../src/router/index'
+import { Message } from 'element-ui'
+// 构建axios实例
+axios.create({
+  baseURL: process.env.BASE_API,
+  timeout: 10000
+})
+axios.interceptors.request.use(config => {
+  const token = sessionStorage.getItem('token')
+  if (token) {
+    config.headers.Authorization = 'Bearer ' + token
+  }
+  return config
+},
+err => {
+  return Promise.reject(err)
+})
+axios.interceptors.response.use(
+  response => {
+    if (response.data.errcode !== 0 || response.data.errcode === 403) {
+      if (response.data.errmsg.cmd) {
+        Message.error(response.data.errmsg.cmd)
+        return false
+      }
+      Message.error(response.data.errmsg)
+      return false
+    }
+    return response
+  },
+  error => {
+    const { status, data } = error.response
+    if (status === 401) {
+      Message.error('请重新登录')
+      router.push('/login')
+      return false
+    }
+    if (status === 500) {
+      if (data.cmd) {
+        Message.error(data.cmd)
+        return false
+      }
+      if (data.errmsg) {
+        Message.error(data.errmsg)
+        return false
+      }
+    }
+    return data
+  }
+)
+export default axios

+ 15 - 0
lib/plug/deepTree.js

@@ -0,0 +1,15 @@
+const deepTree = {
+  install (vue) {
+    vue.prototype.$deepTree = menus => {
+      if (!menus || menus.length <= 0) return
+      let root = menus.filter(p => p.parentId === '' || p.parentId === null)
+      const childrens = (item) => {
+        const children = menus.filter(p => item.id === p.parentId).map(p => childrens(p))
+        return { ...item, children }
+      }
+      root = root.map(p => childrens(p))
+      return root
+    }
+  }
+}
+export default deepTree

+ 9 - 0
lib/plug/dict.js

@@ -0,0 +1,9 @@
+const dict = {
+  install (vue) {
+    vue.prototype.$dict = function (item) {
+      const dict = this.$store.state.dict
+      return dict[item]
+    }
+  }
+}
+export default dict

+ 5 - 0
lib/plug/element.js

@@ -0,0 +1,5 @@
+import Vue from 'vue'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+// Vue.use(ElementUI)
+export default ElementUI

+ 68 - 0
lib/style/index.less

@@ -0,0 +1,68 @@
+html, body, #app{
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  background: #fff;
+}
+*,
+*::before,
+*::after {
+  box-sizing: border-box;
+}
+[class*=" el-icon-naf"], [class^=el-icon-naf] {
+  font-family: naf-icons!important;
+}
+::-webkit-scrollbar {/*滚动条整体样式*/
+  width: 8px;     /*高宽分别对应横竖滚动条的尺寸*/
+  height: 8px;
+}
+::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
+  box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
+  border-radius: 5px;
+  background: hsla(220,4%,58%,.3)
+}
+::-webkit-scrollbar-track {/*滚动条里面轨道*/
+  box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
+  background: #EDEDED;
+}
+.el-menu-item [class^=naf-icon],.el-submenu [class^=naf-icon] {
+  vertical-align: middle;
+  margin-right: 5px;
+  width: 24px;
+  text-align: center;
+  font-size: 18px;
+}
+.flex.el-tabs {
+  display: flex;
+  flex-direction: column;
+  .el-tabs__content {
+    flex: 1;
+  }
+}
+.el-message {
+  z-index: 9999 !important;
+}
+.el-transfer.compact {
+  .el-transfer-panel {
+    width: 160px;
+  }
+  .el-transfer__buttons {
+    padding: 0 10px;
+  }
+  .el-transfer__buttons > .el-transfer__button {
+    padding: 9px 5px;
+  }
+  .el-transfer__button + .el-transfer__button {
+    margin-left: 5px;
+  }
+  .el-transfer-panel__item {
+    width: 100%;
+  }
+}
+.el-tooltip__popper.is-dark {
+  opacity: 0.8;
+}
+.large-icon {
+  font-size: 2em;
+}

+ 69 - 0
naf/data/deep-tree.vue

@@ -0,0 +1,69 @@
+<template>
+  <div class="treeContainer">
+    <el-input size="mini" class="filter" v-if="treeFilter" placeholder="输入关键字进行搜索" v-model="filterText"></el-input>
+    <el-tree
+      :data="datas"
+      default-expand-all
+      :filter-node-method="filterNode"
+      :props="defaultProps"
+      @node-click="treeClick"
+      ref="deeptree"
+    >
+    </el-tree>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    // 形成树的扁平化数据  关联方式parentId
+    data: { type: Array },
+    // 是否启用搜索
+    treeFilter: { type: Boolean, default: true }
+  },
+  data () {
+    return {
+      filterText: '',
+      defaultProps: {
+        children: 'children',
+        label: 'title'
+      }
+    }
+  },
+  computed: {
+    datas () {
+      const data = this.$deepTree(this.data)
+      return data
+    }
+  },
+  methods: {
+    filterNode (value, data) {
+      if (!value) return true
+      return data.title.indexOf(value) !== -1
+    },
+    treeClick (data, node, event) {
+      console.log(data)
+      this.$emit('treeclick', data)
+    }
+  },
+  mounted () {},
+  watch: {
+    filterText (val) {
+      this.$refs.deeptree.filter(val)
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.treeContainer {
+  width: 15%;
+  height: 100%;
+  border-right: 1px solid #dadada;
+  .filter {
+    width: 90%;
+    margin: 20px auto;
+    display: block;
+  }
+}
+</style>

+ 24 - 0
naf/data/dialog -drawer.md

@@ -0,0 +1,24 @@
+### title标题
+title: '这是标题'
+、、、
+### type选择弹出的类型 dialog = 弹窗, drawer = 抽屉(抽屉还是弹窗)默认弹窗
+type:'dialog'
+、、、
+### modal 点击这招是否关闭  默认关闭
+modal: true
+、、、
+### escape 退出键是否关闭  默认关闭
+escape: true
+、、、
+### close 是否显示退出按钮 默认显示
+close: true
+、、、
+### visible 弹窗控制  开启关闭 (必须) 默认开启
+visible: true || false
+、、、
+### width 弹窗宽度 弹窗默认 40% 抽屉默认 25%
+width: '40%'
+、、、
+### 传出事件  close  关闭事件
+@close="visible = false"
+、、、

+ 68 - 0
naf/data/dialog -drawer.vue

@@ -0,0 +1,68 @@
+<template>
+  <div class="ad-aw-box">
+    <el-drawer
+      v-if="type == 'drawer'"
+      :visible.sync="visible"
+      :wrapperClosable="modal"
+      :close-on-press-escape="escape"
+      :show-close="close"
+      :before-close="beforeClose"
+      :size="wd"
+    >
+      <template v-slot:title>
+        <h1>
+          {{ title }}
+        </h1>
+      </template>
+      <slot name="content"></slot>
+    </el-drawer>
+    <el-dialog
+      v-if="type == 'dialog'"
+      :title="title"
+      :close-on-click-modal="modal"
+      :close-on-press-escape="escape"
+      :show-close="close"
+      :visible.sync="visible"
+      :before-close="beforeClose"
+      :width="wd"
+    >
+      <slot name="content"></slot>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    // 标题
+    title: String,
+    type: { type: String, default: 'dialog' },
+    // 是否可以点击遮罩关闭
+    modal: { type: Boolean, default: true },
+    // 是否可以ESC关闭
+    escape: { type: Boolean, default: true },
+    // 是否显示退出按钮
+    close: { type: Boolean, default: true },
+    visible: { type: Boolean, default: true, required: true },
+    width: { type: String }
+  },
+  computed: {
+    wd () {
+      if (this.width) return this.width
+      const width = this.type === 'dialog' ? '40%' : '25%'
+      return width
+    }
+  },
+  data () {
+    return {}
+  },
+  methods: {
+    beforeClose (done) {
+      this.$emit('close')
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped></style>

+ 0 - 0
naf/data/export-file.vue


+ 19 - 0
naf/data/form.md

@@ -0,0 +1,19 @@
+### rules: 规则,对应字段需要的规则
+rules: {
+    name: [
+        { required: true, message: '请输入活动名称', trigger: 'blur' },
+        { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
+    ]
+}
+、、、
+### meta:设置标签的名称及字段
+meta: [
+    字段名         标题          字典(下拉选)     使用插槽
+    { name: 'xb', title: '性别', formatter: 'xb', slots: true }
+]
+、、、
+### data需要显示的数据(如对应字段存在值时传入,修改时使用)
+data: {
+    name: 'xxx'
+}
+、、、

+ 54 - 0
naf/data/form.vue

@@ -0,0 +1,54 @@
+<template>
+  <el-form :model="form" :rules="rules" ref="ruleForm" label-width="100px" size="mini">
+    <el-form-item v-for="(item, index) in meta" :key="index" :label="item.title" :prop="item.name">
+      <slot name="field" v-if="item.slots" v-bind="{ item, form }"></slot>
+      <el-input v-if="!item.formatter && !item.slots" v-model="form[item.name]" :placeholder="item.placeholder || `请输入${item.title}`" :disabled="item.disabled"></el-input>
+      <el-select v-if="item.formatter && !item.slots" v-model="form[item.name]" :placeholder="item.placeholder || `请选择${item.title}`" :disabled="item.disabled">
+        <el-option v-for="(i, idx) in $dict(item.formatter)" :key="idx" :label="i.title" :value="i.value"></el-option>
+      </el-select>
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
+      <el-button @click="resetForm('ruleForm')">重置</el-button>
+    </el-form-item>
+  </el-form>
+</template>
+
+<script>
+export default {
+  components: {},
+  props: {
+    rules: Object,
+    meta: Array,
+    data: Object
+  },
+  data () {
+    return {
+      form: {}
+    }
+  },
+  methods: {
+    reset () {
+      this.form = { ...this.data }
+    },
+    submitForm (formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.$emit('save', this.form)
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    resetForm (formName) {
+      this.$refs[formName].resetFields()
+    }
+  },
+  mounted () {
+    this.reset()
+  }
+}
+</script>
+
+<style lang="less" scoped></style>

+ 56 - 0
naf/data/tables/grid.md

@@ -0,0 +1,56 @@
+naf-grid  参数定义 (naf-grid为  搜索、 列表、 分页、的集合)
+、、、
+### search 是否启用搜索 默认启用
+:search="true"
+、、、
+### pagination 是否启用分页  默认启用
+:pagination="true"
+、、、
+### readonly 是否显示操作列 默认启用
+:readonly="true"
+、、、
+### selection 是否显示多选 默认启用
+:selection="true"
+、、、
+### operation 操作栏数组 默认修改删除
+operation: [
+    { name: 'edit', title: '编辑', icons: 'el-icon-edit' },
+    { name: 'delete', title: '删除', icons: 'el-icon-delete' }
+]
+name: 返回的方法名, title:按钮文字, icons:按钮图标
+、、、
+### meta 定义表格字段
+meta: [
+    { name: 'xb', title: '性别', formatter: 'xb', filter: true, width: '100' },
+]
+name: 字段名, title: 列表标题, formatter: 使用字典得类名, filter:是否使用该字段搜索, width: 该字段列表宽度(默认自适应)
+、、、
+### data列表展示数据 (类型为数组array)
+:data="[]"
+、、、
+### total分页总条数(类型为数字number)默认为0
+:total="100"
+、、、
+
+
+事件定义
+### 双击事件 dblclick  默认参数当前双击行数据
+dblclick(e) {
+    console.log(e)
+}
+、、、
+### 默认修改事件 edit 默认参数当前修改行数据 (事件名可被operation覆盖)
+edit(e) {
+    console.log(e)
+}
+、、、
+### 默认删除事件 delete 默认参数当前删除行数据 (事件名可被operation覆盖)
+delete(e) {
+    console.log(e)
+}
+、、、
+### query 查询事件 当页码条数改变时会调用该事件,当查询条件改变时会调用该事件  参数为{ filter, paging }  filter = 查询条件, paging = 页码/条数
+query({ filter, paging }) {
+    console.log(filter, paging)
+}
+、、、

+ 74 - 0
naf/data/tables/naf-grid.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="container">
+    <naf-search @handlefilter="handleFilter" :filterList="filterList" v-if="search"></naf-search>
+    <naf-table :meta="meta" :selection="selection" @selection="$emit('selection', $event)" :operation="operation" :data="data" :readonly="readonly" @oper="handleOper"></naf-table>
+    <naf-pagination @handlechange="handleChange" :total="total" v-if="pagination"></naf-pagination>
+  </div>
+</template>
+
+<script>
+import nafSearch from '@naf/data/tables/search'
+import nafTable from '@naf/data/tables/table'
+import nafPagination from '@naf/data/tables/pagination '
+export default {
+  components: {
+    nafSearch,
+    nafTable,
+    nafPagination
+  },
+  props: {
+    // 是否启用搜索
+    search: { type: Boolean, default: true },
+    // 是否启用分页
+    pagination: { type: Boolean, default: true },
+    // 是否显示操作列
+    readonly: { type: Boolean, default: true },
+    // 是否显示多选
+    selection: { type: Boolean, default: true },
+    // 操作栏数组
+    operation: {
+      default: () => [
+        { name: 'edit', title: '编辑', icons: 'el-icon-edit' },
+        { name: 'delete', title: '删除', icons: 'el-icon-delete' }
+      ]
+    },
+    // 表格字段参数
+    meta: { type: Array, required: true },
+    // 数据源
+    data: Array,
+    // 总条数
+    total: { type: Number, default: 0 }
+  },
+  data () {
+    return {
+      paging: {},
+      filter: {}
+    }
+  },
+  computed: {
+    filterList () {
+      return this.meta.filter(p => (p.filter && p.filter === true))
+    }
+  },
+  methods: {
+    handleChange ({ page, size }) {
+      this.paging = { page, size }
+      this.query()
+    },
+    handleFilter (filter) {
+      console.log(filter)
+      this.filter = filter
+      this.query()
+    },
+    query () {
+      this.$emit('query', { filter: this.filter, paging: this.paging })
+    },
+    handleOper ({ event, data }) {
+      this.$emit(event, data)
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped></style>

+ 47 - 0
naf/data/tables/pagination .vue

@@ -0,0 +1,47 @@
+<template>
+ <el-pagination
+    class="pagination"
+    @size-change="handleSizeChange"
+    @current-change="handleCurrentChange"
+    :current-page="page"
+    :page-sizes="[10,20,50,100]"
+    :page-size="size"
+    layout="total, sizes, prev, pager, next, jumper"
+    :total="total">
+  </el-pagination>
+</template>
+
+<script>
+export default {
+  props: {
+    total: { type: Number, default: 0 }
+  },
+  data () {
+    return {
+      page: 0,
+      size: 10
+    }
+  },
+  methods: {
+    handleSizeChange (val) {
+      this.size = val
+      this.handleChange()
+    },
+    handleCurrentChange (val) {
+      this.page = val
+      this.handleChange()
+    },
+    handleChange () {
+      this.$emit('handlechange', { page: this.page, size: this.size })
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped>
+.pagination {
+  margin-left: 1%;
+  margin-top: 20px;
+}
+</style>

+ 70 - 0
naf/data/tables/search.vue

@@ -0,0 +1,70 @@
+<template>
+  <el-form :inline="true" :model="form" class="demo-form-inline" size="mini">
+    <el-form-item v-for="(item, index) in simpleFields" :key="index" :label="item.title">
+      <el-select class="prepend" v-if="item.formatter" v-model="form[item.name]" :placeholder="item.placeholder || '请选择'">
+        <el-option
+          v-for="i in $dict(item.formatter)"
+          :key="i.value"
+          :label="i.title"
+          :value="i.value">
+        </el-option>
+      </el-select>
+      <el-input v-else v-model="form[item.name]" :placeholder="item.placeholder || ''"></el-input>
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" @click="onSubmit">查询</el-button>
+      <el-button type="primary" @click="reset">重置</el-button>
+      <el-button type="primary" v-if="filterList.length > 4" @click="more = !more">{{ !more ? '更多' : '收起' }}</el-button>
+    </el-form-item>
+    <slot v-if="more">
+      <el-form :inline="true" :model="form" size="mini">
+        <el-form-item v-for="(item, index) in moreFields" :key="index" :label="item.title">
+          <el-input v-model="form[item.name]" :placeholder="item.placeholder || ''"></el-input>
+        </el-form-item>
+      </el-form>
+    </slot>
+  </el-form>
+</template>
+
+<script>
+export default {
+  props: {
+    filterList: Array,
+    maxFields: { type: Number, default: 4 }
+  },
+  computed: {
+    simpleFields () {
+      return this.filterList.slice(0, this.maxFields)
+    },
+    moreFields () {
+      return this.filterList.slice(this.maxFields) || []
+    }
+  },
+  data () {
+    return {
+      form: {},
+      more: false
+    }
+  },
+  methods: {
+    onSubmit () {
+      this.$emit('handlefilter', this.form)
+    },
+    reset () {
+      this.form = {}
+      this.$emit('handlefilter', this.form)
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped>
+.demo-form-inline {
+  margin-left: 1%;
+  margin-top: 10px;
+}
+.prepend.el-select {
+  width: 100px;
+}
+</style>

+ 61 - 0
naf/data/tables/table.vue

@@ -0,0 +1,61 @@
+<template>
+  <el-table size="mini" :data="datas" class="table" @selection-change="handleSelectionChange" @row-dblclick="$emit('oper', { event: 'dblclick', data: $event })" border>
+    <el-table-column v-if="selection" type="selection" width="55"></el-table-column>
+    <el-table-column v-for="(item, index) in meta" :key="index" :prop="item.name" :label="item.title" :width="item.width || ''" show-overflow-tooltip></el-table-column>
+    <el-table-column label="操作" v-if="readonly">
+      <template slot-scope="scope">
+        <el-button size="mini" type="text" v-for="(item, index) in operation" :key="index" @click="$emit('oper', { event: item.name, data: scope.row})">
+          <i v-if="item.icons" :class="item.icons"></i>
+          {{ item.title }}
+        </el-button>
+      </template>
+    </el-table-column>
+  </el-table>
+</template>
+
+<script>
+export default {
+  components: {},
+  props: {
+    data: { type: Array, defalut: [] },
+    meta: Array,
+    operation: Array,
+    selection: Boolean,
+    readonly: Boolean
+  },
+  computed: {
+    datas () {
+      const formatter = this.meta.filter(p => p.formatter)
+      const data = [...this.data]
+      formatter.filter(i => {
+        data.map(p => {
+          const dict = this.$dict(i.name) || []
+          const item = dict.filter(z => p[i.name] === z.value)
+          if (item.length > 0) {
+            p[i.name] = item[0].title
+          }
+        })
+      })
+      return data
+    }
+  },
+  data () {
+    return {}
+  },
+  methods: {
+    handleSelectionChange (val) {
+      this.$emit('selection', val)
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped>
+.table {
+  width: 98%;
+  margin: 0 auto;
+  max-height: 60vh;
+  overflow-y: auto;
+}
+</style>

+ 0 - 0
naf/data/upload.vue


+ 54 - 0
naf/layout/breadcrumb.vue

@@ -0,0 +1,54 @@
+<template>
+  <el-breadcrumb class="breadcrumb" separator="/">
+    <el-breadcrumb-item :to="{ path: '/frame' }">首页</el-breadcrumb-item>
+    <el-breadcrumb-item v-for="(item, index) in list" :key="index">{{ item.title }}</el-breadcrumb-item>
+    </el-breadcrumb>
+</template>
+
+<script>
+export default {
+  props: {
+    menuItems: Array
+  },
+  data () {
+    return {
+      routers: []
+    }
+  },
+  computed: {
+    list () {
+      const path = this.$route.path
+      if (path === '/frame') return false
+      const item = this.items(path)
+      return item
+    }
+  },
+  methods: {
+    items (path) {
+      const menuList = []
+      const nemus = (path) => {
+        const list = this.menuItems.filter(p => {
+          if (`/frame${p.path}` === path) {
+            if (p.parentId !== null && p.parentId !== '') {
+              const item = this.menuItems.filter(i => i.id === p.parentId)
+              nemus(`/frame${item[0].path}`)
+            }
+            menuList.push(p)
+          }
+        })
+      }
+      nemus(path)
+      return menuList
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped>
+.breadcrumb {
+  line-height: 2em;
+  text-indent: 0.5em;
+  border-bottom: 1px solid #e6e6e6;
+}
+</style>

+ 34 - 0
naf/layout/menu-item.vue

@@ -0,0 +1,34 @@
+<template>
+  <el-submenu :index="index" v-if="item.children && item.children.length > 0">
+    <template slot="title">
+      <i :class="item.icons"></i>
+      <span slot="title">{{ item.title }}</span>
+    </template>
+    <naf-menu-item v-for="(item, idx) in item.children" :key="idx" :index="item.path" :item="item" @naf-menu-item="$emit('naf-menu-item', $event)"></naf-menu-item>
+  </el-submenu>
+  <el-menu-item :index="index" @click="$emit('naf-menu-item', item)" v-else>
+    <i :class="item.icons"></i>
+    <span slot="title" v-if="item.title.length < 9">{{ item.title }}</span>
+    <el-tooltip slot="title" v-else :content="item.title" placement="top" effect="light">
+      <span>{{ item.title.substr(0, 9) + '...' }}</span>
+    </el-tooltip>
+  </el-menu-item>
+</template>
+
+<script>
+export default {
+  name: 'naf-menu-item',
+  props: {
+    item: Object,
+    index: String
+  },
+  components: {},
+  data () {
+    return {}
+  },
+  methods: {},
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped></style>

+ 69 - 0
naf/layout/menu.vue

@@ -0,0 +1,69 @@
+<template>
+  <el-menu :default-active="active" v-bind="config" class="el-menu-vertical-demo" :collapse="isCollapse">
+    <naf-menu-item @naf-menu-item="menuItem" v-for="(item, index) in menuItems" :key="index" :item="item" :index="item.path"></naf-menu-item>
+  </el-menu>
+</template>
+
+<script>
+import nafMenuItem from './menu-item'
+const config = {
+  backgroundColor: process.env.VUE_APP_MENU_BACKGROUNDCOLOR,
+  textColor: process.env.VUE_APP_MENU_TEXTCOLOR,
+  activeTextColor: process.env.VUE_APP_MENU_ACTIVETEXTCOLOR
+}
+export default {
+  props: {
+    // 菜单折叠
+    isCollapse: { type: Boolean, default: false },
+    // 树形结构菜单数据
+    menuItems: Array
+  },
+  components: {
+    nafMenuItem
+  },
+  computed: {
+    // 按钮选中状态计算树形
+    active () {
+      // 如果是首页返回空
+      if (this.$route.path === '/frame') return ''
+      // 定义当前选中的菜单
+      let active = ''
+      // 自定义函数  参数是当前路由与需要过滤的数组
+      const item = (path, items) => {
+        // 数组过滤
+        items.filter(p => {
+          // 如果数组地址等于传入地址 给当前项赋值
+          if (`/frame${p.path}` === path) active = p.path
+          // 如果存在子级数组 递归调用
+          if (p.children) item(path, p.children)
+        })
+      }
+      // 当前路由
+      const path = this.$route.path
+      // 调用自定义函数
+      item(path, this.menuItems)
+      return active
+    }
+  },
+  data () {
+    return {
+      config
+    }
+  },
+  methods: {
+    // 菜单点击跳转地址
+    menuItem (e) {
+      const url = `/frame${e.path}`
+      if (url === this.$route.path) return
+      this.$router.push(url)
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped>
+.el-menu-vertical-demo {
+  height: 100%;
+}
+</style>

+ 97 - 0
naf/layout/user.vue

@@ -0,0 +1,97 @@
+<template>
+  <div class="container">
+    <el-avatar class="avatar" :size="40" :src="circleUrl" :icon="circleUrl == null ? 'el-icon-user-solid' : ''"></el-avatar>
+    <el-dropdown @command="handleCommand">
+        <span class="el-dropdown-link">
+            {{ name }}
+        </span>
+        <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item>修改密码</el-dropdown-item>
+            <!-- <el-dropdown-item>系统任务</el-dropdown-item>
+            <el-dropdown-item>系统消息</el-dropdown-item>
+            <el-dropdown-item>退出系统</el-dropdown-item> -->
+        </el-dropdown-menu>
+    </el-dropdown>
+    <dialog-drawer type="dialog" :visible="visible" title="修改密码" @close="visible = false">
+      <template v-slot:content>
+        <el-form ref="form" :rules="rules" :model="form" label-width="80px">
+          <el-form-item label="原密码" prop="password">
+            <el-input v-model="form.password"></el-input>
+          </el-form-item>
+          <el-form-item label="新密码" prop="newpassword">
+            <el-input v-model="form.newpassword"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="onSubmit">提交</el-button>
+          </el-form-item>
+        </el-form>
+      </template>
+    </dialog-drawer>
+  </div>
+</template>
+
+<script>
+import dialogDrawer from '@naf/data/dialog -drawer'
+import { mapActions } from 'vuex'
+export default {
+  components: {
+    dialogDrawer
+  },
+  data () {
+    return {
+      circleUrl: null,
+      form: {},
+      visible: false,
+      rules: {
+        password: [
+          { required: true, message: '请输入原密码', trigger: 'blur' }
+        ],
+        newpassword: [
+          { required: true, message: '请输入新密码', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  computed: {
+    name () {
+      const name = sessionStorage.getItem('name') || ''
+      return name
+    }
+  },
+  methods: {
+    ...mapActions(['editPwa']),
+    handleCommand () {
+      this.visible = true
+    },
+    async onSubmit () {
+      const userName = sessionStorage.getItem('userName')
+      const res = await this.editPwa({ ...this.form, userName })
+      if (res.errcode === 0) {
+        this.$message({
+          message: '修改成功',
+          type: 'success'
+        })
+        sessionStorage.clear()
+      } else {
+        this.$message.error(res.errmsg)
+      }
+      this.visible = false
+    }
+  },
+  mounted () {}
+}
+</script>
+
+<style lang="less" scoped>
+.container {
+  display: flex;
+  .avatar {
+    margin-top: 8%;
+    margin-right: 5%;
+  }
+  .el-dropdown-link{
+    color: #fff;
+    line-height: 4em;
+  }
+}
+</style>

+ 82 - 0
naf/menu.js

@@ -0,0 +1,82 @@
+export const menus = [
+  {
+    title: '网络管理',
+    id: '0',
+    icons: 'el-icon-s-tools',
+    parentId: '',
+    path: '0',
+    module: '@wokes'
+  },
+  {
+    title: '网卡设置',
+    id: '0-1',
+    icons: 'el-icon-s-custom',
+    parentId: '0',
+    path: '/wokes/card',
+    module: '@wokes'
+  },
+  {
+    title: '证书管理',
+    id: '2',
+    icons: 'el-icon-user-solid',
+    parentId: '',
+    path: '2',
+    module: '@wokes'
+  },
+  {
+    title: '证书链管理',
+    id: '2-1',
+    icons: 'el-icon-user-solid',
+    parentId: '2',
+    path: '/wokes/chaincerd',
+    module: '@wokes/chaincerd'
+  },
+  {
+    title: '设备证书管理',
+    id: '2-2',
+    icons: 'el-icon-user-solid',
+    parentId: '2',
+    path: '/wokes/devcerd',
+    module: '@wokes'
+  },
+  {
+    title: 'VPN管理',
+    id: '1',
+    icons: 'el-icon-user-solid',
+    parentId: '',
+    path: '1',
+    module: '@wokes'
+  },
+  {
+    title: 'SSLVPN',
+    id: '1-1',
+    icons: 'el-icon-user-solid',
+    parentId: '1',
+    path: '/wokes/sslvpn',
+    module: '@wokes'
+  },
+  {
+    title: 'IPSecVPN',
+    id: '1-2',
+    icons: 'el-icon-user-solid',
+    parentId: '1',
+    path: '/wokes/ipsecvpn',
+    module: '@wokes'
+  }
+  // {
+  //   title: 'SSLVPN',
+  //   id: '1-3',
+  //   icons: 'el-icon-user-solid',
+  //   parentId: '1',
+  //   path: '/wokes/sslservicevpn',
+  //   module: '@wokes'
+  // },
+  // {
+  //   title: 'IPsecVPN',
+  //   id: '1-4',
+  //   icons: 'el-icon-user-solid',
+  //   parentId: '1',
+  //   path: '/wokes/ipsecservicevpn',
+  //   module: '@wokes'
+  // }
+]

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 12826 - 0
package-lock.json


+ 37 - 0
package.json

@@ -0,0 +1,37 @@
+{
+  "name": "admin-frame",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "axios": "^0.21.0",
+    "core-js": "^3.7.0",
+    "element-ui": "^2.14.1",
+    "url-join": "^4.0.1",
+    "vue": "^2.6.12",
+    "vue-router": "^3.4.9",
+    "vuex": "^3.5.1"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.8",
+    "@vue/cli-plugin-eslint": "~4.5.8",
+    "@vue/cli-plugin-router": "~4.5.8",
+    "@vue/cli-plugin-vuex": "~4.5.8",
+    "@vue/cli-service": "~4.5.8",
+    "@vue/eslint-config-standard": "^5.1.2",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^7.13.0",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-standard": "^4.1.0",
+    "eslint-plugin-vue": "^7.1.0",
+    "less": "^3.12.2",
+    "less-loader": "^7.1.0",
+    "vue-template-compiler": "^2.6.12"
+  }
+}

binární
public/favicon.ico


+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> 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>

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/css/app.d9cb9654.css


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/css/chunk-22754bfe.479c90a4.css


+ 1 - 0
server/css/chunk-3813fef6.967ae014.css

@@ -0,0 +1 @@
+.gafBox[data-v-4a482c51]{height:90vh;overflow:hidden}.el-card[data-v-4a482c51]{height:100%}.el-card[data-v-4a482c51] .el-card__body{height:90%;overflow:auto}.el-card[data-v-4a482c51] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-4a482c51]{width:100%}.el-switch[data-v-4a482c51]{width:90%;margin:0 auto;display:block;text-indent:1.7em;margin-bottom:20px}

+ 1 - 0
server/css/chunk-40fb139e.245504ca.css

@@ -0,0 +1 @@
+.gafBox[data-v-2c011487]{height:90vh;overflow:hidden}.el-card[data-v-2c011487]{height:100%}.el-card[data-v-2c011487] .el-card__body{height:90%;overflow:auto}.el-card[data-v-2c011487] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-2c011487]{width:100%}.el-switch[data-v-2c011487]{width:90%;margin:0 auto;display:block;text-indent:1.7em;margin-bottom:20px}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/css/chunk-57458d7a.c3c7050e.css


+ 1 - 0
server/css/chunk-6acf5018.7f01c06c.css

@@ -0,0 +1 @@
+.gafBox[data-v-79a9981a]{height:90vh;overflow:hidden}.el-card[data-v-79a9981a]{height:100%}.el-card[data-v-79a9981a] .el-card__body{height:90%;overflow:auto}.el-card[data-v-79a9981a] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-79a9981a]{width:100%}

+ 1 - 0
server/css/chunk-7030f5aa.352f0d2b.css

@@ -0,0 +1 @@
+.el-card[data-v-32acac71],.gafBox[data-v-32acac71]{height:100%}.el-card .el-main[data-v-32acac71]{display:flex}.el-card .el-main .el-card[data-v-32acac71]{width:45%;margin:0 3%;height:75vh}

+ 1 - 0
server/css/chunk-79924bbd.a4fe5c3f.css

@@ -0,0 +1 @@
+.gafBox[data-v-6d8012e4]{height:90vh;overflow:hidden}.el-card[data-v-6d8012e4]{height:100%}.el-card[data-v-6d8012e4] .el-card__body{height:90%;overflow:auto}.el-card[data-v-6d8012e4] .el-card__body .el-form{width:90%;margin:0 auto}.el-select[data-v-6d8012e4]{width:100%}

+ 1 - 0
server/css/chunk-a6f5a958.16e983d9.css

@@ -0,0 +1 @@
+.gafBox[data-v-64fd400e]{height:100%}.upload-demo[data-v-64fd400e]{float:right;margin:0 5px}.el-card[data-v-64fd400e]{height:100%}.el-card .el-main .grid[data-v-64fd400e],.el-card .el-main[data-v-64fd400e]{width:100%}

+ 1 - 0
server/css/chunk-acafa550.aa0af357.css

@@ -0,0 +1 @@
+.demo-form-inline[data-v-72f3a11a]{margin-left:1%;margin-top:10px}.prepend.el-select[data-v-72f3a11a]{width:100px}.table[data-v-16cb7e1c]{width:98%;margin:0 auto;max-height:60vh;overflow-y:auto}.pagination[data-v-f44c3072]{margin-left:1%;margin-top:20px}.gafBox[data-v-634f8c04]{height:100%}.upload-demo[data-v-634f8c04]{float:right;margin:0 5px}.el-card[data-v-634f8c04]{height:100%}.el-card .el-main .grid[data-v-634f8c04],.el-card .el-main[data-v-634f8c04]{width:100%}

+ 1 - 0
server/css/chunk-f43862f0.4e08efc6.css

@@ -0,0 +1 @@
+.wrapper[data-v-71b651fc]{height:100%;width:100%;position:relative;background-position:50%;background-repeat:o-repeat;background-size:cover;background-image:url(../img/home.a18367d8.png)}.titleWrapper[data-v-71b651fc]{text-align:center;top:40%;width:100%;position:absolute;color:#1d87b4}.title[data-v-71b651fc]{font-size:32px;letter-spacing:1.94px;line-height:2em;text-align:center}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/css/chunk-vendors.84bb20f7.css


binární
server/favicon.ico


binární
server/fonts/element-icons.535877f5.woff


binární
server/fonts/element-icons.732389de.ttf


binární
server/img/bg2.4f6e6589.jpg


binární
server/img/home.a18367d8.png


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/img/logo1.191c3d70.svg


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/index.html


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/app.1f57ff9d.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-22754bfe.8fd0de4e.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-3813fef6.364de217.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-40fb139e.a5847eda.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-57458d7a.2ced3c85.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-6acf5018.9ad9af69.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-7030f5aa.d693ddfa.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-79924bbd.e5128c73.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-a6f5a958.8bddea6c.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-acafa550.4d220377.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
server/js/chunk-f43862f0.ea0a1136.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 33 - 0
server/js/chunk-vendors.2addda4d.js


+ 7 - 0
src/App.vue

@@ -0,0 +1,7 @@
+<template>
+  <div id="app">
+    <router-view/>
+  </div>
+</template>
+
+<style lang="less"></style>

binární
src/assets/bg2.jpg


binární
src/assets/home.png


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 0
src/assets/logo1.svg


+ 17 - 0
src/main.js

@@ -0,0 +1,17 @@
+import Vue from 'vue'
+import App from './App.vue'
+import router from './router'
+import store from './store'
+import ElementUI from '@lib/plug/element'
+import deepTree from '@lib/plug/deepTree'
+import dict from '@lib/plug/dict'
+import '@lib/style/index.less'
+Vue.config.productionTip = false
+Vue.use(ElementUI)
+Vue.use(deepTree)
+Vue.use(dict)
+new Vue({
+  router,
+  store,
+  render: h => h(App)
+}).$mount('#app')

+ 0 - 0
src/router/gaf.js


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů