shaogen1995 %!s(int64=3) %!d(string=hai) anos
pai
achega
7fdf527327

+ 180 - 10
package-lock.json

@@ -8,7 +8,11 @@
       "name": "yunshuju",
       "name": "yunshuju",
       "version": "0.1.0",
       "version": "0.1.0",
       "dependencies": {
       "dependencies": {
+        "axios": "^0.26.1",
+        "Base64": "^1.1.0",
         "core-js": "^3.6.5",
         "core-js": "^3.6.5",
+        "element-ui": "^2.15.8",
+        "js-base64": "^3.7.2",
         "vue": "^2.6.11",
         "vue": "^2.6.11",
         "vue-router": "^3.2.0"
         "vue-router": "^3.2.0"
       },
       },
@@ -3034,6 +3038,14 @@
       "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
       "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
       "dev": true
       "dev": true
     },
     },
+    "node_modules/async-validator": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-1.8.5.tgz",
+      "integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
+      "dependencies": {
+        "babel-runtime": "6.x"
+      }
+    },
     "node_modules/asynckit": {
     "node_modules/asynckit": {
       "version": "0.4.0",
       "version": "0.4.0",
       "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
       "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
@@ -3085,6 +3097,19 @@
       "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
       "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
       "dev": true
       "dev": true
     },
     },
+    "node_modules/axios": {
+      "version": "0.26.1",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz",
+      "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
+      "dependencies": {
+        "follow-redirects": "^1.14.8"
+      }
+    },
+    "node_modules/babel-helper-vue-jsx-merge-props": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+      "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
+    },
     "node_modules/babel-loader": {
     "node_modules/babel-loader": {
       "version": "8.2.5",
       "version": "8.2.5",
       "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz",
       "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz",
@@ -3152,6 +3177,27 @@
         "@babel/core": "^7.0.0-0"
         "@babel/core": "^7.0.0-0"
       }
       }
     },
     },
+    "node_modules/babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmmirror.com/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+      "dependencies": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "node_modules/babel-runtime/node_modules/core-js": {
+      "version": "2.6.12",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-2.6.12.tgz",
+      "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+      "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.",
+      "hasInstallScript": true
+    },
+    "node_modules/babel-runtime/node_modules/regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+    },
     "node_modules/balanced-match": {
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -3188,6 +3234,11 @@
         "node": ">=0.10.0"
         "node": ">=0.10.0"
       }
       }
     },
     },
+    "node_modules/Base64": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/Base64/-/Base64-1.1.0.tgz",
+      "integrity": "sha512-qeacf8dvGpf+XAT27ESHMh7z84uRzj/ua2pQdJg483m3bEXv/kVFtDnMgvf70BQGqzbZhR9t6BmASzKvqfJf3Q=="
+    },
     "node_modules/base64-js": {
     "node_modules/base64-js": {
       "version": "1.5.1",
       "version": "1.5.1",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
@@ -5136,7 +5187,6 @@
       "version": "1.5.2",
       "version": "1.5.2",
       "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-1.5.2.tgz",
       "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-1.5.2.tgz",
       "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
       "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
-      "dev": true,
       "engines": {
       "engines": {
         "node": ">=0.10.0"
         "node": ">=0.10.0"
       }
       }
@@ -5613,6 +5663,22 @@
       "integrity": "sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA==",
       "integrity": "sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA==",
       "dev": true
       "dev": true
     },
     },
+    "node_modules/element-ui": {
+      "version": "2.15.8",
+      "resolved": "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.8.tgz",
+      "integrity": "sha512-N54zxosRFqpYax3APY3GeRmtOZwIls6Z756WM0kdPZ5Q92PIeKHnZgF1StlamIg9bLxP1k+qdhTZvIeQlim09A==",
+      "dependencies": {
+        "async-validator": "~1.8.1",
+        "babel-helper-vue-jsx-merge-props": "^2.0.0",
+        "deepmerge": "^1.2.0",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.0",
+        "throttle-debounce": "^1.0.1"
+      },
+      "peerDependencies": {
+        "vue": "^2.5.17"
+      }
+    },
     "node_modules/elliptic": {
     "node_modules/elliptic": {
       "version": "6.5.4",
       "version": "6.5.4",
       "resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.5.4.tgz",
       "resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.5.4.tgz",
@@ -6440,7 +6506,6 @@
       "version": "1.14.9",
       "version": "1.14.9",
       "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.14.9.tgz",
       "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.14.9.tgz",
       "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
       "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
-      "dev": true,
       "engines": {
       "engines": {
         "node": ">=4.0"
         "node": ">=4.0"
       },
       },
@@ -7975,6 +8040,11 @@
       "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
       "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
       "dev": true
       "dev": true
     },
     },
+    "node_modules/js-base64": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz",
+      "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
+    },
     "node_modules/js-message": {
     "node_modules/js-message": {
       "version": "1.0.7",
       "version": "1.0.7",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
@@ -8953,6 +9023,11 @@
         "node": ">=4"
         "node": ">=4"
       }
       }
     },
     },
+    "node_modules/normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
+    },
     "node_modules/npm-run-path": {
     "node_modules/npm-run-path": {
       "version": "2.0.2",
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-2.0.2.tgz",
       "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -10887,6 +10962,11 @@
       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
       "dev": true
       "dev": true
     },
     },
+    "node_modules/resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
     "node_modules/resolve": {
     "node_modules/resolve": {
       "version": "1.22.0",
       "version": "1.22.0",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.0.tgz",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.0.tgz",
@@ -12415,6 +12495,14 @@
         "node": ">=4.0.0"
         "node": ">=4.0.0"
       }
       }
     },
     },
+    "node_modules/throttle-debounce": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
+      "integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/through2": {
     "node_modules/through2": {
       "version": "2.0.5",
       "version": "2.0.5",
       "resolved": "https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz",
       "resolved": "https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz",
@@ -16009,7 +16097,8 @@
       "version": "4.5.17",
       "version": "4.5.17",
       "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.17.tgz",
       "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.17.tgz",
       "integrity": "sha512-ck/ju2T2dmPKLWK/5QctNJs9SCb+eSZbbmr8neFkMc7GlbXw6qLWw5v3Vpd4KevdQA8QuQOA1pjUmzpCiU/mYQ==",
       "integrity": "sha512-ck/ju2T2dmPKLWK/5QctNJs9SCb+eSZbbmr8neFkMc7GlbXw6qLWw5v3Vpd4KevdQA8QuQOA1pjUmzpCiU/mYQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     },
     "@vue/cli-service": {
     "@vue/cli-service": {
       "version": "4.5.17",
       "version": "4.5.17",
@@ -16146,7 +16235,8 @@
       "version": "1.1.2",
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz",
       "resolved": "https://registry.npmmirror.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz",
       "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==",
       "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     },
     "@vue/web-component-wrapper": {
     "@vue/web-component-wrapper": {
       "version": "1.3.0",
       "version": "1.3.0",
@@ -16385,13 +16475,15 @@
       "version": "1.0.1",
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/ajv-errors/-/ajv-errors-1.0.1.tgz",
       "resolved": "https://registry.npmmirror.com/ajv-errors/-/ajv-errors-1.0.1.tgz",
       "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
       "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     },
     "ajv-keywords": {
     "ajv-keywords": {
       "version": "3.5.2",
       "version": "3.5.2",
       "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
       "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     },
     "alphanum-sort": {
     "alphanum-sort": {
       "version": "1.0.2",
       "version": "1.0.2",
@@ -16597,6 +16689,14 @@
       "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
       "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
       "dev": true
       "dev": true
     },
     },
+    "async-validator": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-1.8.5.tgz",
+      "integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
+      "requires": {
+        "babel-runtime": "6.x"
+      }
+    },
     "asynckit": {
     "asynckit": {
       "version": "0.4.0",
       "version": "0.4.0",
       "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
       "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
@@ -16636,6 +16736,19 @@
       "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
       "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
       "dev": true
       "dev": true
     },
     },
+    "axios": {
+      "version": "0.26.1",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz",
+      "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
+      "requires": {
+        "follow-redirects": "^1.14.8"
+      }
+    },
+    "babel-helper-vue-jsx-merge-props": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+      "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
+    },
     "babel-loader": {
     "babel-loader": {
       "version": "8.2.5",
       "version": "8.2.5",
       "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz",
       "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz",
@@ -16687,6 +16800,27 @@
         "@babel/helper-define-polyfill-provider": "^0.3.1"
         "@babel/helper-define-polyfill-provider": "^0.3.1"
       }
       }
     },
     },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmmirror.com/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.12",
+          "resolved": "https://registry.npmmirror.com/core-js/-/core-js-2.6.12.tgz",
+          "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
+        },
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+        }
+      }
+    },
     "balanced-match": {
     "balanced-match": {
       "version": "1.0.2",
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -16719,6 +16853,11 @@
         }
         }
       }
       }
     },
     },
+    "Base64": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/Base64/-/Base64-1.1.0.tgz",
+      "integrity": "sha512-qeacf8dvGpf+XAT27ESHMh7z84uRzj/ua2pQdJg483m3bEXv/kVFtDnMgvf70BQGqzbZhR9t6BmASzKvqfJf3Q=="
+    },
     "base64-js": {
     "base64-js": {
       "version": "1.5.1",
       "version": "1.5.1",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
@@ -18370,8 +18509,7 @@
     "deepmerge": {
     "deepmerge": {
       "version": "1.5.2",
       "version": "1.5.2",
       "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-1.5.2.tgz",
       "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-1.5.2.tgz",
-      "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
-      "dev": true
+      "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
     },
     },
     "default-gateway": {
     "default-gateway": {
       "version": "5.0.5",
       "version": "5.0.5",
@@ -18767,6 +18905,19 @@
       "integrity": "sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA==",
       "integrity": "sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA==",
       "dev": true
       "dev": true
     },
     },
+    "element-ui": {
+      "version": "2.15.8",
+      "resolved": "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.8.tgz",
+      "integrity": "sha512-N54zxosRFqpYax3APY3GeRmtOZwIls6Z756WM0kdPZ5Q92PIeKHnZgF1StlamIg9bLxP1k+qdhTZvIeQlim09A==",
+      "requires": {
+        "async-validator": "~1.8.1",
+        "babel-helper-vue-jsx-merge-props": "^2.0.0",
+        "deepmerge": "^1.2.0",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.0",
+        "throttle-debounce": "^1.0.1"
+      }
+    },
     "elliptic": {
     "elliptic": {
       "version": "6.5.4",
       "version": "6.5.4",
       "resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.5.4.tgz",
       "resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.5.4.tgz",
@@ -19458,8 +19609,7 @@
     "follow-redirects": {
     "follow-redirects": {
       "version": "1.14.9",
       "version": "1.14.9",
       "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.14.9.tgz",
       "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.14.9.tgz",
-      "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
-      "dev": true
+      "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
     },
     },
     "for-in": {
     "for-in": {
       "version": "1.0.2",
       "version": "1.0.2",
@@ -20684,6 +20834,11 @@
       "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
       "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
       "dev": true
       "dev": true
     },
     },
+    "js-base64": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz",
+      "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
+    },
     "js-message": {
     "js-message": {
       "version": "1.0.7",
       "version": "1.0.7",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
       "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
@@ -21506,6 +21661,11 @@
         "sort-keys": "^1.0.0"
         "sort-keys": "^1.0.0"
       }
       }
     },
     },
+    "normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
+    },
     "npm-run-path": {
     "npm-run-path": {
       "version": "2.0.2",
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-2.0.2.tgz",
       "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-2.0.2.tgz",
@@ -23145,6 +23305,11 @@
       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
       "dev": true
       "dev": true
     },
     },
+    "resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
     "resolve": {
     "resolve": {
       "version": "1.22.0",
       "version": "1.22.0",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.0.tgz",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.0.tgz",
@@ -24442,6 +24607,11 @@
         }
         }
       }
       }
     },
     },
+    "throttle-debounce": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
+      "integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg=="
+    },
     "through2": {
     "through2": {
       "version": "2.0.5",
       "version": "2.0.5",
       "resolved": "https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz",
       "resolved": "https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz",

+ 4 - 0
package.json

@@ -7,7 +7,11 @@
     "build": "vue-cli-service build"
     "build": "vue-cli-service build"
   },
   },
   "dependencies": {
   "dependencies": {
+    "axios": "^0.26.1",
+    "Base64": "^1.1.0",
     "core-js": "^3.6.5",
     "core-js": "^3.6.5",
+    "element-ui": "^2.15.8",
+    "js-base64": "^3.7.2",
     "vue": "^2.6.11",
     "vue": "^2.6.11",
     "vue-router": "^3.2.0"
     "vue-router": "^3.2.0"
   },
   },

+ 3 - 0
src/assets/base.css

@@ -2,4 +2,7 @@
   margin: 0;
   margin: 0;
   padding: 0;
   padding: 0;
   box-sizing: border-box;
   box-sizing: border-box;
+}
+body{
+  background-color: #f6f8f9;
 }
 }

BIN=BIN
src/assets/img/logo.png


BIN=BIN
src/assets/img/user.jpg


+ 3 - 1
src/main.js

@@ -1,7 +1,9 @@
 import Vue from 'vue'
 import Vue from 'vue'
 import App from './App.vue'
 import App from './App.vue'
 import router from './router'
 import router from './router'
-
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+Vue.use(ElementUI);
 Vue.config.productionTip = false
 Vue.config.productionTip = false
 import './assets/base.css'
 import './assets/base.css'
 new Vue({
 new Vue({

+ 28 - 0
src/router/index.js

@@ -9,6 +9,20 @@ const routes = [
     name: 'Login',
     name: 'Login',
     component: () => import('../views/Login.vue')
     component: () => import('../views/Login.vue')
   },
   },
+  {
+    path: '/Layout',
+    name: 'Layout',
+    component: () => import('../views/Layout.vue'),
+    redirect: { name: 'tab1' },
+    children: [
+      {
+        path: '/Layout/tab1',
+        name: 'tab1',
+        meta: { myInd: 1 },
+        component: () => import('../views/Tab1/index.vue')
+      },
+    ]
+  },
 ]
 ]
 
 
 const router = new VueRouter({
 const router = new VueRouter({
@@ -17,4 +31,18 @@ const router = new VueRouter({
   routes
   routes
 })
 })
 
 
+router.beforeEach((to, from, next) => {
+  // 如果是去登录页,不需要验证,直接下一步
+  if (to.name === 'Login') next()
+  // 否则要有token值才能下一步,不然就返回登录页
+  else {
+    const token = localStorage.getItem('Yun_token')
+    if (token) next()
+    else {
+      Message.warning('登录失效,请重新登录')
+      next({ name: 'Login' })
+    }
+  }
+})
+
 export default router
 export default router

+ 25 - 0
src/utils/api.js

@@ -0,0 +1,25 @@
+import axios from './request'
+// 用户登录接口
+export const userLogin = (data) => {
+  return axios({
+    method: 'post',
+    url: '/admin/login',
+    data
+  })
+}
+// 获取表相关列表
+export const getBList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/db/table/getList',
+    data
+  })
+}
+// 新增表
+export const addTable = (data) => {
+  return axios({
+    method: 'post',
+    url: '/db/table/createTable',
+    data
+  })
+}

+ 105 - 0
src/utils/pass.js

@@ -0,0 +1,105 @@
+function NoToChinese(num) {  
+  num = String(num)
+  var chnNumChar = ["零","一","二","三","四","五","六","七","八","九","十"];
+  if(num == 0){  
+    return chnNumChar[0];  
+  }     
+  let tmp = ''
+  for (let i = 0; i < num.length; i++) {
+    let ele = num.charAt(i)
+    tmp += chnNumChar[ele]
+  }
+   
+  return tmp;  
+}  
+
+function randomWord (randomFlag, min, max) {
+  let str = ''
+  let range = min
+  let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
+  // 随机产生
+  if (randomFlag) {
+    range = Math.round(Math.random() * (max - min)) + min
+  }
+  for (var i = 0; i < range; i++) {
+    let pos = Math.round(Math.random() * (arr.length - 1))
+    str += arr[pos]
+  }
+  return str
+}
+
+module.exports = {
+  formatDate: function(time) {
+    var weekArr = ["日", "一", "二", "三", "四", "五", "六"];
+    var date = new Date(time);
+    var year = date.getFullYear();
+    var month = date.getMonth() + 1;
+    var day = date.getDate();
+    var week = "星期" + weekArr[date.getDay()];
+    if (window.innerWidth < 1700) {
+      return (
+        year +
+        "年" +
+        (String(month).length > 1 ? month : "0" + month) +
+        "月" +
+        (String(day).length > 1 ? day : "0" + day) +
+        "日" +
+        "<br/>" +
+        week
+      );
+    }
+    return (
+      year +
+      "年" +
+      (String(month).length > 1 ? month : "0" + month) +
+      "月" +
+      (String(day).length > 1 ? day : "0" + day) +
+      "日" +
+      " " +
+      week
+    );
+  },
+  smoothscrollpos: function(domName) {
+    if (domName == "/") {
+      return window.scrollTo(0, 0);
+    }
+    let smoothscroll = () => {
+      let dom = document.getElementById(domName);
+      // window.scrollTo({
+      //   top:dom.offsetTop - 100,
+      //   left:0,
+      //   behavior: "smooth"
+      // })
+      dom && window.scrollTo(0, dom.offsetTop - 120);
+    };
+    smoothscroll();
+  },
+  
+  formatTime: function(time, fan = false) {
+    let t1 = time.split(" ")[0].split("-");
+    if (fan) {
+      t1 = t1.map((item) => {
+        let t = NoToChinese(item);
+        return t;
+      });
+    }
+    return t1;
+  },
+  encodeStr: function (str, strv = '') {
+    const NUM = 2
+    const front = randomWord(false, 8)
+    const middle = randomWord(false, 8)
+    const end = randomWord(false, 8)
+
+    let str1 = str.substring(0, NUM)
+    let str2 = str.substring(NUM)
+
+    if (strv) {
+      let strv1 = strv.substring(0, NUM)
+      let strv2 = strv.substring(NUM)
+      return [front + str2 + middle + str1 + end, front + strv2 + middle + strv1 + end]
+    }
+
+    return front + str2 + middle + str1 + end
+  }
+};

+ 38 - 0
src/utils/request.js

@@ -0,0 +1,38 @@
+import axios from 'axios'
+const service = axios.create({
+  baseURL: 'http://192.168.0.135:8001/', // 本地调试
+  // baseURL: '', // 显示调试
+  // baseURL: '', // build
+  timeout: 5000
+})
+// 请求拦截器
+service.interceptors.request.use(function (config) {
+  // console.log('触发拦截器')
+  // 在发送请求之前做些什么:看看有没有token,如果有通过请求头的方式传递token
+  const token = localStorage.getItem('Yun_token')
+  if (token) { // 判断是否有token,有,则
+    // config.headers['Authorization'] = token
+    config.headers.token = token
+  }
+
+  return config
+}, function (error) {
+  // 对请求错误做些什么
+  return Promise.reject(error)
+})
+
+// 添加响应拦截器
+service.interceptors.response.use(function (response) {
+  // console.log('触发相应拦截器', response)
+  // 对响应数据做点什么--response就是发送每个请求的返回值
+  if (response.data.code === 5001 || response.data.code === 5002) {
+    // Toast.fail('未登录,请先登录')
+    localStorage.removeItem('Yun_token')
+  }
+  return response.data
+}, function (error) {
+  // 对响应错误做点什么
+  return Promise.reject(error)
+})
+
+export default service

+ 161 - 0
src/views/Layout.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="Layout">
+    <div class="top">
+      <div class="left">
+        <!-- <img src="../assets/img/logo.png" alt="" /> -->
+        <h3>自定义云数据库</h3>
+      </div>
+      <div class="right">
+        <img src="../assets/img/user.jpg" alt="" />
+        <p>{{ userName }}</p>
+        <div class="outLogin" @click="outLogin">退出登录</div>
+      </div>
+    </div>
+    <div class="main">
+      <div class="left">
+        <div
+          class="row"
+          v-for="item in tabData"
+          :key="item.id"
+          :class="{ active: $route.meta.myInd === item.id }"
+        >
+          {{ item.name }}
+        </div>
+      </div>
+      <div class="right">
+        <Router-view />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "Layout",
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      userName: "",
+      tabData: [
+        {
+          id: 1,
+          name: "表相关",
+          path: "/Layout/tab1",
+        },
+        {
+          id: 2,
+          name: "...",
+          path: "",
+        },
+      ],
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    outLogin() {
+      this.$confirm("确定退出吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          localStorage.clear("Yun_token");
+          localStorage.clear("Yun_Name");
+          this.$router.push("/");
+          this.$message.success("退出成功!");
+        })
+        .catch(() => {
+          this.$message.info("已取消");
+        });
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    // 获取用户信息
+    this.userName = localStorage.getItem("Yun_Name");
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.Layout {
+  width: 100vw;
+  height: 100vh;
+  min-width: 1800px;
+  min-height: 900px;
+  .top {
+    color: #fff;
+    display: flex;
+    justify-content: space-between;
+    padding: 0 30px;
+    box-shadow: 1px 3px 3px 3px #ccc;
+    height: 70px;
+    background-color: #409eff;
+    .left {
+      display: flex;
+      align-items: center;
+      & > img {
+        width: 50px;
+        margin-right: 30px;
+      }
+    }
+    .right {
+      display: flex;
+      align-items: center;
+      & > img {
+        width: 40px;
+        border-radius: 50%;
+      }
+      & > p {
+        margin: 0 30px 0 5px;
+      }
+      .outLogin {
+        cursor: pointer;
+      }
+    }
+  }
+  .main {
+    padding: 30px 30px 0;
+    width: 100%;
+    height: calc(100% - 70px);
+    display: flex;
+    .left {
+      padding: 30px 10px 0;
+      background-color: #fff;
+      box-shadow: 0px 0px 4px 0px;
+      margin-right: 30px;
+      width: 220px;
+      height: 100%;
+      .row {
+        cursor: pointer;
+        width: 100%;
+        text-align: center;
+        height: 50px;
+        line-height: 50px;
+      }
+      .active {
+        color: #b9412e;
+      }
+    }
+    .right{
+      padding: 30px 20px 0;
+      flex: 1;
+      background-color: #fff;
+      box-shadow: 0px 0px 4px 0px;
+    }
+  }
+}
+</style>

+ 104 - 1
src/views/Login.vue

@@ -1,5 +1,108 @@
 <template>
 <template>
   <div class="Login">
   <div class="Login">
-    <h1>This is an about page</h1>
+    <div class="main">
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="用户名" prop="userName">
+          <el-input
+            v-model="ruleForm.userName"
+            prefix-icon="el-icon-user-solid"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="密码" prop="password">
+          <el-input
+            v-model="ruleForm.password"
+            show-password
+            prefix-icon="el-icon-s-tools"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <!-- 登录按钮 -->
+      <div class="btn">
+        <el-button type="primary" @click="login">登录</el-button>
+      </div>
+    </div>
   </div>
   </div>
 </template>
 </template>
+
+<script>
+import { encodeStr } from "../utils/pass";
+import { Base64 } from "js-base64";
+import { userLogin } from "../utils/api";
+export default {
+  name: "Login",
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      ruleForm: {
+        userName: "",
+        password: "",
+      },
+      rules: {
+        userName: [{ required: true, message: "不能为空", trigger: "blur" }],
+        password: [{ required: true, message: "不能为空", trigger: "blur" }],
+      },
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    async login() {
+      if (this.ruleForm.userName.trim() === "")
+        return this.$message.warning("账号不能为空");
+      if (this.ruleForm.password.trim() === "")
+        return this.$message.warning("密码不能为空");
+      let obj = {
+        userName: this.ruleForm.userName,
+        password: encodeStr(Base64.encode(this.ruleForm.password)),
+      };
+      let res = await userLogin(obj);
+      if (res.code === 0) {
+        localStorage.setItem("Yun_token", res.data.token);
+        localStorage.setItem("Yun_Name", res.data.user.realName);
+        this.$router.push("/Layout");
+        this.$message.success("登录成功");
+      } else this.$message.warning(res.msg);
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.Login {
+  position: relative;
+  width: 100vw;
+  height: 100vh;
+  min-width: 1800px;
+  min-height: 900px;
+  .main {
+    position: absolute;
+    top: 40%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    width: 500px;
+  }
+  .btn {
+    padding-left: 100px;
+  }
+}
+</style>

+ 88 - 0
src/views/Tab1/Dialog.vue

@@ -0,0 +1,88 @@
+<template>
+  <el-dialog title="新增表" :visible.sync="dialogVisible">
+    <el-form
+      :model="ruleForm"
+      :rules="rules"
+      ref="ruleForm"
+      label-width="100px"
+      class="demo-ruleForm"
+    >
+      <el-form-item label="表名" prop="name">
+        <el-input v-model="ruleForm.name"></el-input>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input v-model="ruleForm.remark"></el-input>
+      </el-form-item>
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="btnX">取 消</el-button>
+      <el-button type="primary" @click="btnOk">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { addTable } from "@/utils/api";
+export default {
+  name: "tab1Dialog",
+  props: {
+    dialogVisible: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  components: {},
+  data() {
+    //这里存放数据
+    return {
+      ruleForm: {
+        appId: 1,
+        name: "",
+        remark: "",
+      },
+      rules: {
+        name: [{ required: true, message: "不能为空", trigger: "blur" }],
+        remark: [{ required: true, message: "不能为空", trigger: "blur" }],
+      },
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 点击取消
+    btnX() {
+      this.$refs.ruleForm.resetFields();
+      this.$emit("update:dialogVisible", false);
+    },
+    async btnOk() {
+      try {
+        await this.$refs.ruleForm.validate();
+        let res = await addTable(this.ruleForm);
+        if (res.code === 0) {
+          this.$emit('clickSon')
+          this.btnX();
+        } else this.$message.warning(res.msg);
+      } catch (error) {
+        console.log(error);
+      }
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+//@import url(); 引入公共css类
+</style>

+ 153 - 0
src/views/Tab1/index.vue

@@ -0,0 +1,153 @@
+<template>
+  <div class="tab1">
+    <div class="search">
+      <div class="left">
+        <el-input
+          style="width: 380px"
+          v-model="pageData.searchKey"
+          placeholder="请输入表名"
+        ></el-input>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          @click="getBList(pageData)"
+          >搜索</el-button
+        >
+      </div>
+      <div class="right">
+        <el-button type="danger" :disabled="selecArr.length === 0"
+          >删除</el-button
+        >
+        <el-button type="success" @click="dialogVisible = true"
+          >新增表</el-button
+        >
+      </div>
+    </div>
+    <div class="table">
+      <el-table
+        :data="tableData"
+        style="width: 100%"
+        @selection-change="selecChange"
+      >
+        <el-table-column type="selection" width="55"> </el-table-column>
+        <el-table-column label="序号" width="80">
+          <template slot-scope="scope">
+            {{ scope.$index + (pageData.pageNum - 1) * pageData.pageSize + 1 }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="name" label="表名"> </el-table-column>
+        <el-table-column prop="remark" label="备注"> </el-table-column>
+        <el-table-column label="操作">
+          <el-button type="text">编辑</el-button>
+          <el-button type="text">字段</el-button>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页器 -->
+    <div class="paging">
+      <el-pagination
+        :current-page='pageData.pageNum'
+        @current-change="currentChange"
+        @size-change="sizeChange"
+        layout="prev, pager, next,sizes,jumper"
+        :total="total"
+      >
+      </el-pagination>
+    </div>
+    <!-- 点击新增和编辑出现的弹窗 -->
+    <Dialog
+      :dialogVisible.sync="dialogVisible"
+      @clickSon="getBList(pageData)"
+    />
+  </div>
+</template>
+
+<script>
+import Dialog from "./Dialog";
+import { getBList } from "@/utils/api";
+export default {
+  name: "tab1",
+  components: { Dialog },
+  data() {
+    //这里存放数据
+    return {
+      total: 0,
+      dialogVisible: false,
+      tableData: [],
+      pageData: {
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: "",
+      },
+      selecArr: [],
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {},
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    // 分页器
+    currentChange(val) {
+      this.pageData.pageNum=val
+      this.getBList(this.pageData);
+    },
+    sizeChange(val) {
+      this.pageData.pageNum=1
+      this.pageData.pageSize=val
+      this.getBList(this.pageData);
+    },
+    selecChange(val) {
+      this.selecArr = val;
+    },
+    // 封装一个获取表列表的方法
+    async getBList(data) {
+      let res = await getBList(data);
+      this.total=res.data.total
+      this.tableData = res.data.records;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.getBList(this.pageData);
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {},
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='less' scoped>
+.tab1 {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .search {
+    display: flex;
+    justify-content: space-between;
+    .left {
+      justify-content: space-between;
+      display: flex;
+      width: 500px;
+    }
+  }
+  .table {
+    /deep/.el-table__body-wrapper {
+      width: 1570px;
+      height: 585px;
+      overflow-y: auto;
+    }
+  }
+  .paging{
+    position: absolute;
+    right: 20px;
+    bottom: 40px;
+  }
+}
+</style>