laosan2382995021@163.com hace 4 años
padre
commit
3dc60e73eb
Se han modificado 100 ficheros con 4038 adiciones y 79 borrados
  1. 13 0
      babel.config.js
  2. 47 32
      package-lock.json
  3. 2 1
      package.json
  4. 0 0
      public/dll/vue-d24cf6156ad424d3d2bc.dll.js
  5. 52 0
      public/font/font.css
  6. BIN
      public/font/iconfont.ttf
  7. 3 2
      public/index.html
  8. 13 0
      src/App.vue
  9. 0 0
      src/assets/dll/vue-d24cf6156ad424d3d2bc.dll.js
  10. 23 1
      src/assets/scss/entry/global.scss
  11. 3 1
      src/assets/scss/variable/color.scss
  12. 3 0
      src/components/button/index.ts
  13. 64 0
      src/components/button/mixins/handle.ts
  14. 5 0
      src/components/button/mixins/index.ts
  15. 39 0
      src/components/button/mixins/size.ts
  16. 59 0
      src/components/button/props.ts
  17. 98 0
      src/components/button/src/main.vue
  18. 60 0
      src/components/button/style.scss
  19. 3 0
      src/components/icon/index.ts
  20. 9 0
      src/components/icon/props.ts
  21. 15 0
      src/components/icon/src/main.vue
  22. 3 0
      src/components/icon/style.scss
  23. 7 1
      src/components/index.ts
  24. 3 0
      src/components/popup/index.ts
  25. 20 0
      src/components/popup/props.ts
  26. 51 0
      src/components/popup/src/main.vue
  27. 10 0
      src/components/popup/style.scss
  28. 1 0
      src/components/scroll-view/api/scroll.ts
  29. 2 2
      src/components/scroll-view/mixins/config.ts
  30. 1 1
      src/components/scroll-view/mixins/on.ts
  31. 1 1
      src/components/v-image/api/image.ts
  32. 2 2
      src/config/config.ts
  33. 12 0
      src/config/user.ts
  34. 1 1
      src/layout/layout-entry/data/about.ts
  35. 1 0
      src/layout/layout-entry/src/main.vue
  36. 5 1
      src/main.ts
  37. 13 0
      src/mixins/status/const/status.ts
  38. 85 0
      src/mixins/status/index.ts
  39. 91 0
      src/mixins/time.ts
  40. 19 26
      src/pages/home/src/main.vue
  41. 6 0
      src/popup/popup-export/components.ts
  42. 22 0
      src/popup/popup-export/global.js
  43. 30 0
      src/popup/popup-export/global.ts
  44. 61 0
      src/popup/popup-export/src/main.vue
  45. 0 0
      src/popup/popup-export/style.scss
  46. 43 0
      src/popup/popup-export/types/lib.popup-export.d.ts
  47. 20 0
      src/popup/popup-login/components/login/data/input.ts
  48. 3 0
      src/popup/popup-login/components/login/index.ts
  49. 102 0
      src/popup/popup-login/components/login/src/main.vue
  50. 76 0
      src/popup/popup-login/components/login/style.scss
  51. 45 0
      src/popup/popup-login/components/register/data/input.ts
  52. 3 0
      src/popup/popup-login/components/register/index.ts
  53. 3 0
      src/popup/popup-login/components/register/mixins/index.ts
  54. 115 0
      src/popup/popup-login/components/register/src/main.vue
  55. 9 0
      src/popup/popup-login/components/register/style.scss
  56. BIN
      src/popup/popup-login/images/background.png
  57. 3 0
      src/popup/popup-login/index.ts
  58. 65 0
      src/popup/popup-login/mixins/handle.ts
  59. 3 0
      src/popup/popup-login/mixins/index.ts
  60. 14 0
      src/popup/popup-login/props.ts
  61. 62 0
      src/popup/popup-login/src/main.vue
  62. 48 0
      src/popup/popup-login/style.scss
  63. 3 0
      src/popup/popup-toast/index.ts
  64. 15 0
      src/popup/popup-toast/mixins/handle.ts
  65. 3 0
      src/popup/popup-toast/mixins/index.ts
  66. 15 0
      src/popup/popup-toast/props.ts
  67. 52 0
      src/popup/popup-toast/src/main.vue
  68. 19 0
      src/popup/popup-toast/style.scss
  69. 2 0
      src/router/index.ts
  70. 39 0
      src/store/modules/user.ts
  71. 7 0
      src/types/lib.data.d.ts
  72. 14 0
      src/types/lib.fetch.d.ts
  73. 21 6
      src/types/lib.mixins.d.ts
  74. 1 0
      src/utils/animate/animate.ts
  75. 20 0
      src/utils/encryption/ase.js
  76. 104 0
      src/utils/encryption/encryption.js
  77. 683 0
      src/utils/encryption/md5.js
  78. 111 0
      src/utils/request/cache/cache.ts
  79. 90 0
      src/utils/request/cache/index.ts
  80. 18 0
      src/utils/request/config.ts
  81. 12 0
      src/utils/request/const/index.ts
  82. 47 0
      src/utils/request/const/request.ts
  83. 7 0
      src/utils/request/format/index.ts
  84. 50 0
      src/utils/request/index.ts
  85. 7 0
      src/utils/request/instructions/index.ts
  86. 227 0
      src/utils/request/instructions/instructions.ts
  87. 37 0
      src/utils/request/instructions/plugins/config.ts
  88. 138 0
      src/utils/request/instructions/plugins/control.ts
  89. 6 0
      src/utils/request/instructions/plugins/create.ts
  90. 154 0
      src/utils/request/instructions/plugins/instructions.ts
  91. 160 0
      src/utils/request/types/lib.request.d.ts
  92. 81 0
      src/utils/request/types/lib.request.options.d.ts
  93. 30 0
      src/utils/request/types/request.config.d.ts
  94. 19 0
      src/utils/tool/popup.ts
  95. 83 0
      src/utils/tool/storage.ts
  96. 13 0
      src/utils/tool/type.ts
  97. 1 1
      src/utils/tool/url.ts
  98. 10 0
      src/utils/verification/config.ts
  99. 12 0
      src/utils/verification/const/index.ts
  100. 155 0
      src/utils/verification/index.ts

+ 13 - 0
babel.config.js

@@ -3,3 +3,16 @@ module.exports = {
     '@vue/cli-plugin-babel/preset'
   ]
 }
+// module.exports = {
+//   presets: [
+//     '@vue/app',
+//     "@babel/preset-typescript"
+//   ],
+//
+//   plugins: [
+//
+//     "@babel/plugin-transform-typescript"
+//
+//   ]
+//
+// }

+ 47 - 32
package-lock.json

@@ -7,6 +7,7 @@
     "": {
       "version": "0.1.0",
       "dependencies": {
+        "axios": "^0.21.1",
         "core-js": "^3.6.5",
         "swiper": "^6.6.2",
         "vue": "^3.0.0",
@@ -24,7 +25,7 @@
         "postcss-pxtorem": "^5.1.1",
         "sass": "^1.26.5",
         "sass-loader": "^8.0.2",
-        "typescript": "~4.1.5"
+        "typescript": "^4.3.2"
       }
     },
     "node_modules/@babel/code-frame": {
@@ -114,16 +115,16 @@
       }
     },
     "node_modules/@babel/helper-create-class-features-plugin": {
-      "version": "7.14.3",
-      "resolved": "https://registry.nlark.com/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.14.3.tgz?cache=0&sync_timestamp=1621285504031&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.14.3.tgz",
-      "integrity": "sha1-gyERvPT1fKV6TFsaAA/BJavGVUo=",
+      "version": "7.14.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz",
+      "integrity": "sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.12.13",
         "@babel/helper-function-name": "^7.14.2",
         "@babel/helper-member-expression-to-functions": "^7.13.12",
         "@babel/helper-optimise-call-expression": "^7.12.13",
-        "@babel/helper-replace-supers": "^7.14.3",
+        "@babel/helper-replace-supers": "^7.14.4",
         "@babel/helper-split-export-declaration": "^7.12.13"
       },
       "peerDependencies": {
@@ -262,15 +263,15 @@
       }
     },
     "node_modules/@babel/helper-replace-supers": {
-      "version": "7.14.3",
-      "resolved": "https://registry.nlark.com/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.14.3.tgz",
-      "integrity": "sha1-yhezGLhZ0Qfw6bci1YzxLZRDZgA=",
+      "version": "7.14.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz",
+      "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-member-expression-to-functions": "^7.13.12",
         "@babel/helper-optimise-call-expression": "^7.12.13",
         "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.2"
+        "@babel/types": "^7.14.4"
       }
     },
     "node_modules/@babel/helper-simple-access": {
@@ -1344,9 +1345,9 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.14.2",
-      "resolved": "https://registry.nlark.com/@babel/types/download/@babel/types-7.14.2.tgz?cache=0&sync_timestamp=1620839476067&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.14.2.tgz",
-      "integrity": "sha1-QgiuADEH74oFfqgzPlbrZNL2osM=",
+      "version": "7.14.4",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
+      "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
       "dependencies": {
         "@babel/helper-validator-identifier": "^7.14.0",
         "to-fast-properties": "^2.0.0"
@@ -2951,6 +2952,14 @@
       "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
       "dev": true
     },
+    "node_modules/axios": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+      "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+      "dependencies": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
     "node_modules/babel-code-frame": {
       "version": "6.26.0",
       "resolved": "https://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.26.0.tgz",
@@ -6403,7 +6412,6 @@
       "version": "1.14.1",
       "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.1.tgz?cache=0&sync_timestamp=1620555246888&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.1.tgz",
       "integrity": "sha1-2RFN7Qoc/dM04WTmZirQK/2R/0M=",
-      "dev": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -14325,9 +14333,9 @@
       "dev": true
     },
     "node_modules/typescript": {
-      "version": "4.1.5",
-      "resolved": "https://registry.nlark.com/typescript/download/typescript-4.1.5.tgz?cache=0&sync_timestamp=1621495395375&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftypescript%2Fdownload%2Ftypescript-4.1.5.tgz",
-      "integrity": "sha1-Ejo7IUqv874ykm8Njx9ucE64mnI=",
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz",
+      "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -16314,16 +16322,16 @@
       }
     },
     "@babel/helper-create-class-features-plugin": {
-      "version": "7.14.3",
-      "resolved": "https://registry.nlark.com/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.14.3.tgz?cache=0&sync_timestamp=1621285504031&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-create-class-features-plugin%2Fdownload%2F%40babel%2Fhelper-create-class-features-plugin-7.14.3.tgz",
-      "integrity": "sha1-gyERvPT1fKV6TFsaAA/BJavGVUo=",
+      "version": "7.14.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz",
+      "integrity": "sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw==",
       "dev": true,
       "requires": {
         "@babel/helper-annotate-as-pure": "^7.12.13",
         "@babel/helper-function-name": "^7.14.2",
         "@babel/helper-member-expression-to-functions": "^7.13.12",
         "@babel/helper-optimise-call-expression": "^7.12.13",
-        "@babel/helper-replace-supers": "^7.14.3",
+        "@babel/helper-replace-supers": "^7.14.4",
         "@babel/helper-split-export-declaration": "^7.12.13"
       }
     },
@@ -16453,15 +16461,15 @@
       }
     },
     "@babel/helper-replace-supers": {
-      "version": "7.14.3",
-      "resolved": "https://registry.nlark.com/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.14.3.tgz",
-      "integrity": "sha1-yhezGLhZ0Qfw6bci1YzxLZRDZgA=",
+      "version": "7.14.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz",
+      "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==",
       "dev": true,
       "requires": {
         "@babel/helper-member-expression-to-functions": "^7.13.12",
         "@babel/helper-optimise-call-expression": "^7.12.13",
         "@babel/traverse": "^7.14.2",
-        "@babel/types": "^7.14.2"
+        "@babel/types": "^7.14.4"
       }
     },
     "@babel/helper-simple-access": {
@@ -17322,9 +17330,9 @@
       }
     },
     "@babel/types": {
-      "version": "7.14.2",
-      "resolved": "https://registry.nlark.com/@babel/types/download/@babel/types-7.14.2.tgz?cache=0&sync_timestamp=1620839476067&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.14.2.tgz",
-      "integrity": "sha1-QgiuADEH74oFfqgzPlbrZNL2osM=",
+      "version": "7.14.4",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
+      "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
       "requires": {
         "@babel/helper-validator-identifier": "^7.14.0",
         "to-fast-properties": "^2.0.0"
@@ -18717,6 +18725,14 @@
       "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
       "dev": true
     },
+    "axios": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+      "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+      "requires": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
     "babel-code-frame": {
       "version": "6.26.0",
       "resolved": "https://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.26.0.tgz",
@@ -21599,8 +21615,7 @@
     "follow-redirects": {
       "version": "1.14.1",
       "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.1.tgz?cache=0&sync_timestamp=1620555246888&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.1.tgz",
-      "integrity": "sha1-2RFN7Qoc/dM04WTmZirQK/2R/0M=",
-      "dev": true
+      "integrity": "sha1-2RFN7Qoc/dM04WTmZirQK/2R/0M="
     },
     "for-in": {
       "version": "1.0.2",
@@ -27978,9 +27993,9 @@
       "dev": true
     },
     "typescript": {
-      "version": "4.1.5",
-      "resolved": "https://registry.nlark.com/typescript/download/typescript-4.1.5.tgz?cache=0&sync_timestamp=1621495395375&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftypescript%2Fdownload%2Ftypescript-4.1.5.tgz",
-      "integrity": "sha1-Ejo7IUqv874ykm8Njx9ucE64mnI=",
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz",
+      "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==",
       "dev": true
     },
     "uglify-js": {

+ 2 - 1
package.json

@@ -7,6 +7,7 @@
     "build": "vue-cli-service build"
   },
   "dependencies": {
+    "axios": "^0.21.1",
     "core-js": "^3.6.5",
     "swiper": "^6.6.2",
     "vue": "^3.0.0",
@@ -24,6 +25,6 @@
     "postcss-pxtorem": "^5.1.1",
     "sass": "^1.26.5",
     "sass-loader": "^8.0.2",
-    "typescript": "~4.1.5"
+    "typescript": "^4.3.2"
   }
 }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
public/dll/vue-d24cf6156ad424d3d2bc.dll.js


+ 52 - 0
public/font/font.css

@@ -0,0 +1,52 @@
+@font-face {
+  font-family: "iconfont"; /* Project id  */
+  src: url('iconfont.ttf?t=1622012365563') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-search:before {
+  content: "\e607";
+}
+
+.icon-add:before {
+  content: "\e620";
+}
+
+.icon-iconfontxingxing:before {
+  content: "\e6b0";
+}
+
+.icon-jian:before {
+  content: "\e621";
+}
+
+.icon-down:before {
+  content: "\e63c";
+}
+
+.icon-xihuan:before {
+  content: "\e630";
+}
+
+.icon-close:before {
+  content: "\e608";
+}
+
+.icon-more:before {
+  content: "\e633";
+}
+
+.icon-nan:before {
+  content: "\e8b3";
+}
+
+.icon-nv:before {
+  content: "\e67b";
+}
+

BIN
public/font/iconfont.ttf


+ 3 - 2
public/index.html

@@ -5,6 +5,7 @@
     <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">
+    <link rel="stylesheet" type="text/css" href="./font/font.css" />
     <title><%= htmlWebpackPlugin.options.title %></title>
       <script>
           var inputContent = {
@@ -59,11 +60,11 @@
           })(window,document);
       </script>
   </head>
-  <body>
+  <body ondragstart="window.event.returnValue=false;return false;" oncontextmenu="window.event.returnValue=false;return false;" onselectstart="event.returnValue=false;return false;">
     <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>
+</html>

+ 13 - 0
src/App.vue

@@ -1,6 +1,19 @@
 <template>
+    <layout-entry>
+      <router-view></router-view>
+    </layout-entry>
     <router-view/>
 </template>
+<script>
+import {layoutEntry} from '$layout';
+export default {
+
+  components:{
+    layoutEntry
+  }
+
+}
+</script>
 <style lang="scss">
   @import "assets/scss/entry/index";
 </style>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/dll/vue-d24cf6156ad424d3d2bc.dll.js


+ 23 - 1
src/assets/scss/entry/global.scss

@@ -18,9 +18,31 @@
 .button-active{
   transition: opacity .5s;
 }
-.button-active:active{
+
+.button{
+  background: $main-linear;
+  height: 44px;
+  border-radius: 22px;
+  font-size: 16px;
+  font-weight: 500;
+  color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: row;
+  cursor: pointer;
+  transition: opacity .3s;
+}
+
+.button:active,.button-active:active,.button-disabled{
   opacity: 0.7;
 }
+.button-disabled,.button-disabled-active{
+  cursor:default;
+}
+.button-disabled-active {
+  opacity: 1 !important;
+}
 
 .cursor-pointer {
   cursor: pointer;

+ 3 - 1
src/assets/scss/variable/color.scss

@@ -1,4 +1,6 @@
 /* 主题色 */
 $main: #AA9BD4;
 
-$main-linear: linear-gradient(90deg, #629CFF, #7870F1);
+$main-text:#788DFF;
+
+$main-linear: linear-gradient(90deg, #629CFF, #7870F1);

+ 3 - 0
src/components/button/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 64 - 0
src/components/button/mixins/handle.ts

@@ -0,0 +1,64 @@
+import Status from '$mixins/status/const/status';
+
+export default <LibMixins>{
+
+    data(){
+      return {
+          status_fetch_key:'submit',
+          exit:false
+      }
+    },
+
+    computed:{
+
+        buttonStatus(){
+            // 如果不允许进入加载状态设置为无状态
+            if (this.status === Status.loading && !this.intoLoading || this.status === Status.success && !this.success) {
+                return Status.none
+            } else {
+                return this.status;
+            }
+        }
+
+    },
+
+    methods:{
+
+        trigger(){
+            if (this.disabled || this._status === Status.success || this._status === Status.loading) return;
+
+            if (this.$attrs.onClick) {
+                return this.$emit('click');
+            }
+
+            if (this.$attrs.onSubmitVerify) {
+                return this.$emit('submit-verify',(data:any)=> this.statusFetch(false,data));
+            }
+
+            if (this.$attrs.onSubmit) {
+                return this.statusFetch();
+            }
+
+        },
+
+        triggerChangeStatus(status:Status){
+            clearTimeout(this._timeChangeStats);
+            if (this.success && status === Status.success) {
+                this._timeChangeStats = setTimeout(()=> {
+                    if (this._status === Status.success) {
+                        this.exit = true;
+
+                        this.$emit('change-success');
+
+                        setTimeout(()=>{
+                            this.exit = false;
+                            this.setStatus(Status.none);
+                        },600);
+                    }
+                },this.asyncSuccess);
+            }
+        }
+
+    }
+
+}

+ 5 - 0
src/components/button/mixins/index.ts

@@ -0,0 +1,5 @@
+import status from '$mixins/status';
+import size from './size';
+import handle from './handle';
+
+export default [status,size,handle];

+ 39 - 0
src/components/button/mixins/size.ts

@@ -0,0 +1,39 @@
+import Status from '$mixins/status/const/status';
+export default <LibMixins>{
+
+    data(){
+        return {
+            buttonSize:{}
+        }
+    },
+
+    computed:{
+      size(){
+          return {
+              width: this.buttonSize.width || 0,
+              height: this.buttonSize.height || 0
+          }
+      },
+      width(){
+          if (this.buttonStatus === Status.loading && this.loadingSize) {
+              return this.size.height + 'px';
+          } else {
+              return this.size.width ?this.size.width+'px':'';
+          }
+      }
+    },
+
+    methods:{
+        setSize(){
+            this.buttonSize = {
+                width: this.$refs.button.offsetWidth,
+                height: this.$refs.button.offsetHeight
+            };
+        }
+    },
+
+    mounted() {
+        this.setSize();
+    },
+
+}

+ 59 - 0
src/components/button/props.ts

@@ -0,0 +1,59 @@
+export default {
+
+
+    // 是否存在成功状态
+    success:{
+        type:Boolean,
+        default:true
+    },
+
+    // 加载成功的文本
+    successText:{
+      type:String,
+      default:'成功'
+    },
+
+    // 成功的颜色
+    successColor:{
+      type:String,
+      default:'#00D5AF'
+    },
+
+    // 失败状态的文本
+    failText:{
+      type:String,
+      default:'服务繁忙,点击重试'
+    },
+
+    // 失败的颜色
+    failColor:{
+      type:String,
+      default:'#ff3a29'
+    },
+
+    // 成功状态后的延迟
+    asyncSuccess:{
+        type:Number,
+        default:3000
+    },
+
+    // 是否可以进入加载状态
+    intoLoading:{
+        type:Boolean,
+        default: true
+    },
+
+    // 加载状态是否改变size
+    loadingSize:{
+        type:Boolean,
+        default: true
+    },
+
+    // 禁用按钮
+    disabled:{
+        type:Boolean,
+        default:false
+    }
+
+
+}

+ 98 - 0
src/components/button/src/main.vue

@@ -0,0 +1,98 @@
+<template>
+  <div ref="button" class="button v-button relative"
+       :class="{
+          'button-disabled': disabled || buttonStatus === constStatus.loading,
+          'button-disabled-active': buttonStatus === constStatus.success
+       }"
+    :style="{width: width}"
+    @click="trigger"
+  >
+    <!--  加载状态   -->
+    <div class="v-button-loading screen center"
+         v-if="buttonStatus === constStatus.loading"
+    >
+      <slot name="loading">
+        <svg class="screen" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
+            <path fill="#fff" d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50">
+              <animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="1s" from="0 50 50" to="360 50 50" repeatCount="indefinite"></animateTransform>
+          </path>
+        </svg>
+      </slot>
+    </div>
+
+    <!--  常规状态  -->
+    <div
+        v-else
+        class="screen center"
+    >
+      <slot>
+        按钮
+      </slot>
+    </div>
+
+    <!--  成功状态  -->
+    <div
+      v-if="buttonStatus === constStatus.success"
+      class="absolute v-button-success screen center"
+    >
+      <slot name="success">
+        <div
+            class="center v-button-target"
+            :style="{background:successColor}"
+            :class="['v-button-success-'+(!loadingSize?'animate':'default'),exit?'v-button-success-out':'']"
+        >{{successText}}</div>
+      </slot>
+    </div>
+
+    <!--  失败状态  -->
+    <div
+        v-else-if="buttonStatus === constStatus.fail"
+        class="absolute v-button-success screen center"
+    >
+      <slot name="fail">
+        <div
+            class="center v-button-target"
+            :style="{background:failColor}"
+            :class="['v-button-success-'+(!loadingSize?'animate':'default'),exit?'v-button-success-out':'']"
+        >{{failText}}</div>
+      </slot>
+    </div>
+
+
+
+  </div>
+</template>
+
+<script>
+import mixins from '../mixins';
+import props from '../props';
+export default {
+  name: "v-button",
+
+  data(){
+    return {
+      buttonSize:{}
+    }
+  },
+
+  methods:{
+    setSize(){
+      this.buttonSize = {
+        width: this.$refs.button.offsetWidth,
+        height: this.$refs.button.offsetHeight
+      };
+    }
+  },
+
+  mounted() {
+    this.setSize();
+  },
+
+  mixins,
+
+  props
+
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 60 - 0
src/components/button/style.scss

@@ -0,0 +1,60 @@
+/* 外部状态 */
+.v-button {
+  transition: .3s;
+  overflow: hidden;
+  white-space: nowrap;
+}
+/* 外部状态 */
+
+/* 加载状态 */
+.v-button-loading-warp{
+  position: relative;
+}
+.v-button-loading-warp:before{
+  content: '';
+  padding-left: 100%;
+  height: 100%;
+  width: 0;
+  display: block;
+}
+//.v-button-loading{
+//  padding-top: 100%;
+//}
+/* 加载状态 */
+
+/* 加载成功 */
+.v-button-target{
+  height: 100%;
+}
+.v-button-success{
+  top: 0;
+  bottom: 0;
+  right: 0;
+  left: 0;
+  z-index: 99;
+  overflow: hidden;
+}
+.v-button-success-animate {
+  animation: animateSuccess .6s forwards;
+}
+.v-button-success-out{
+  animation: animateSuccess .6s forwards reverse;
+}
+.v-button-success-default{
+  width: 100%;
+}
+@keyframes animateSuccess {
+  0%{
+    width: 0;
+    opacity: 0;
+  }
+  100%{
+    width: 100%;
+    opacity: 1;
+  }
+}
+/* 加载成功 */
+
+/* 加载失败 */
+
+/* 加载失败 */

+ 3 - 0
src/components/icon/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 9 - 0
src/components/icon/props.ts

@@ -0,0 +1,9 @@
+export default {
+
+    // 类型
+    type:{
+        type:String,
+        default:''
+    }
+
+}

+ 15 - 0
src/components/icon/src/main.vue

@@ -0,0 +1,15 @@
+<template>
+  <i class="iconfont icon-default"
+    :class="['icon-'+type]"
+  ></i>
+</template>
+
+<script>
+import props from '../props';
+export default {
+  name: "icon",
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 3 - 0
src/components/icon/style.scss

@@ -0,0 +1,3 @@
+.icon-default{
+  font-size: 16px;
+}

+ 7 - 1
src/components/index.ts

@@ -6,4 +6,10 @@ export { default as scrollView } from './scroll-view';
 
 export { default as swiper } from './swiper';
 
-export { default as swiperItem } from './swiper-item';
+export { default as swiperItem } from './swiper-item';
+
+export { default as Popup } from './popup';
+
+export { default as icon } from './icon';
+
+export { default as vButton } from './button';

+ 3 - 0
src/components/popup/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 20 - 0
src/components/popup/props.ts

@@ -0,0 +1,20 @@
+export default {
+
+    value:{
+        type:Boolean,
+        default: false
+    },
+
+    // 点击其他位置隐藏
+    trigger:{
+        type:Boolean,
+        default: true
+    },
+
+    // 是否启用居中
+    center:{
+        type:Boolean,
+        default: true
+    }
+
+}

+ 51 - 0
src/components/popup/src/main.vue

@@ -0,0 +1,51 @@
+<template>
+  <section v-show="vValue" class="absolute popup-screen center"
+           @click="trigger && changeValue"
+           :class="{'center':center}"
+  >
+    <section @click.stop>
+      <slot></slot>
+    </section>
+  </section>
+</template>
+
+<script lang="ts">
+import props from '../props';
+export default <LibMixins>{
+  name: "popup",
+
+  data(){
+    return {
+      vValue:false
+    }
+  },
+
+  watch:{
+    value:{
+      handler:function (this:any) {
+        this.changeValue(this.value);
+      },
+      immediate:true
+    }
+  },
+
+  methods:{
+
+    // 发生变更
+    changeValue(value:boolean=false):any{
+      if (this.vValue !== value) {
+        this.vValue = value;
+        this.$emit(value ? 'open' :'close');
+        if (this.value !== value) {
+          return this.$emit('update:value',value);
+        }
+      }
+    }
+
+  },
+
+  props
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 10 - 0
src/components/popup/style.scss

@@ -0,0 +1,10 @@
+/* 弹窗 */
+.popup-screen{
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: 999;
+  background-color: rgba(0,0,0,0.3);
+}
+/* 弹窗 */

+ 1 - 0
src/components/scroll-view/api/scroll.ts

@@ -70,6 +70,7 @@ export default class ScrollApi {
         poolIndex++;
         if (poolIndex <= poolCount) {
             if (this.look) {
+                // @ts-ignore
                 this.look.time = setTimeout(()=> this.animateToPool(params,poolCount,poolIndex,config),16.66);
             }
         } else {

+ 2 - 2
src/components/scroll-view/mixins/config.ts

@@ -184,7 +184,7 @@ export default <LibMixins>{
         },
 
         // 添加监听
-        addEventListener<T extends EventTypes>(el:HTMLElement,event:T,target:ListenerEventTarget){
+        addEventListener:function <T extends EventTypes>(this:any,el:HTMLElement,event:T,target:ListenerEventTarget){
             // 如果没有监听器对象创建
             if (this._listeners === undefined) {
                 this._listeners = {};
@@ -209,7 +209,7 @@ export default <LibMixins>{
         },
 
         // 移除兼容
-        removeEventListener<K extends EventTypes>(el:HTMLElement,event:K,unique:string){
+        removeEventListener<K extends EventTypes>(this:any,el:HTMLElement,event:K,unique:string){
             if (this._listeners !== undefined && this._listeners[unique] !== undefined) {
                 if (window.removeEventListener !== undefined) {
                     el.removeEventListener(event, this._listeners[unique]);

+ 1 - 1
src/components/scroll-view/mixins/on.ts

@@ -19,7 +19,7 @@ export default <LibMixins>{
                 scrollParams.y =  scrollParams.y - this._scrollConfig.y.y;
             }
 
-            return this._scrollApi?.animateTo(scrollParams as scrollRunningParams);
+            return this._scrollApi.animateTo(scrollParams as scrollRunningParams);
 
         },
 

+ 1 - 1
src/components/v-image/api/image.ts

@@ -5,7 +5,7 @@ export default <ImageApi>{
     /*
     * 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
     * */
-    scaleToFill:function(params:ImageParams):ImageExport{
+    scaleToFill:function():ImageExport{
         return {
             width: '100%',
             height: '100%',

+ 2 - 2
src/config/config.ts

@@ -1,7 +1,7 @@
 export default <Config>{
 
-    baseApiURL:'',
+    baseApiURL:'/api',
 
-    baseURL:'',
+    baseURL:'http://newqiaoyu.com/',
 
 }

+ 12 - 0
src/config/user.ts

@@ -0,0 +1,12 @@
+export default {
+
+    // 默认缓存多久
+    storageTime: -1,
+
+    // 用户信息
+    user:undefined,
+
+    // 缓存的key
+    storageKey:'user'
+
+}

+ 1 - 1
src/layout/layout-entry/data/about.ts

@@ -2,7 +2,7 @@ export default {
 
     data:<LibDataArray>[
         {
-            label: '关于我们'
+            label:'关于我们',
         },
         {
             label:'用户协议',

+ 1 - 0
src/layout/layout-entry/src/main.vue

@@ -5,6 +5,7 @@
         <section class="absolute user-absolute-screen">
           <slot></slot>
         </section>
+        <div id="popup"></div>
       </section>
       <footer class="footer-container absolute">
         <aside class="row center">

+ 5 - 1
src/main.ts

@@ -2,5 +2,9 @@ import { createApp } from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
+import popup from '$popup/popup-export/global';
+import request from "$utils/request";
+
+createApp(App).use(store).use(router).use(popup).use(request).mount('#app')
+
 
-createApp(App).use(store).use(router).mount('#app')

+ 13 - 0
src/mixins/status/const/status.ts

@@ -0,0 +1,13 @@
+enum Status {
+
+    loading='loading',
+
+    success='success',
+
+    fail='fail',
+
+    none='none'
+
+}
+
+export default Status;

+ 85 - 0
src/mixins/status/index.ts

@@ -0,0 +1,85 @@
+import Status from './const/status';
+export default <LibMixins>{
+
+    data(){
+      return {
+          // 当前状态
+          status: Status.none,
+          // 使用延迟key
+          status_async_key:'statusAsync',
+          // 是否使用唯一值
+          status_unique: true,
+          // 请求的名称
+          status_fetch_key:'fetch',
+          // 常量
+          constStatus: Status
+      }
+    },
+
+    methods:{
+
+        // 设置状态变更
+        setStatus(status){
+            if (status !== this._status) {
+                if (this[this.status_async_key]) clearTimeout(this._statusTime);
+                this._status = status;
+                if (this[this.status_async_key] && status === Status.loading) {
+                    this._statusTime = setTimeout(()=>{
+                        this.status = this._status;
+                    },this[this.status_async_key]);
+                } else {
+                    this.status = status;
+                }
+
+                this.triggerChangeStatus && this.triggerChangeStatus(status);
+            }
+        },
+
+        // 开启请求
+        statusFetch:function (must:boolean=false,data:any) {
+            // 如果当前状态为请求中就结束本次请求
+            if (this._status === Status.loading && !must) return;
+
+            let unique = '';
+            if (this.status_unique) {
+                unique = new Date().getTime() + '-' + Math.floor(Math.random() * 10000);
+                this._statusUseUnique = unique;
+            }
+
+            this.setStatus(Status.loading);
+
+
+            return this.$emit(this.status_fetch_key,{
+               success:()=> {
+                   if (!this.status_unique || unique === this._statusUseUnique) {
+                       return this.setStatus(Status.success);
+                   }
+                   // @ts-ignore
+                   unique = null;
+               },
+               fail:()=> {
+                   if (!this.status_unique || unique === this._statusUseUnique) {
+                       return this.setStatus(Status.fail);
+                   }
+                   // @ts-ignore
+                   unique = null;
+               },
+               none:()=>{
+                    if (!this.status_unique || unique === this._statusUseUnique) {
+                        return this.setStatus(Status.none);
+                    }
+                    // @ts-ignore
+                    unique = null;
+                },
+               unique,
+               data
+            });
+
+        }
+
+    },
+    created(){
+        this._status = Status.none;
+    }
+
+}

+ 91 - 0
src/mixins/time.ts

@@ -0,0 +1,91 @@
+import verification from '$utils/verification';
+
+import { InstructionsMessageType } from '$utils/request';
+
+export default <LibMixins>{
+
+    data(){
+        return {
+            timeConfig:{
+                default:'获取验证码',
+                format:'还剩',
+                afterFormat:'s',
+                time:60
+            },
+            timeFormat:''
+        }
+    },
+
+    methods:{
+
+        // 获取验证码
+        triggerTimeDate(item:LibData,data:LibDataArray){
+
+            if (this.timeFormat) return;
+
+            let resultData:LibData = undefined;
+            for (let i=0,count=data.length;i<count;i++) {
+                if (item.code === data[i].key) {
+                    resultData = {
+                        ...data[i]
+                    };
+                    break;
+                }
+            }
+
+            if (resultData) {
+                resultData.key = 'mobile';
+                verification.verificationPromise(resultData,true).then((data)=>{
+
+                    data.type = item.codeType;
+
+                    this.$request({
+                        url:'login/send_sms',
+                        data,
+                        message:InstructionsMessageType.other,
+                        failMessage:true
+                    }).catch(()=>{
+                        // 如果发生错误触发
+                        this.endTimeDate = 0
+                    });
+
+                    return this.triggerTimeType();
+                });
+
+
+            }
+
+        },
+
+        // 触发倒计时
+        triggerTimeType(){
+
+            clearTimeout(this._time_format);
+
+            if (this.endTimeDate === undefined) {
+                this.endTimeDate = this.getTimeDate() + this.timeConfig.time;
+            }
+
+            let diff = this.endTimeDate - this.getTimeDate();
+
+            if (diff <= 0) {
+                this.timeFormat = '';
+                this.endTimeDate = undefined;
+            } else {
+                this.timeFormat = this.timeConfig.format + diff + this.timeConfig.afterFormat;
+
+                this._time_format = setTimeout(()=> this.triggerTimeType(),1000);
+            }
+
+        },
+
+        // 获取时间
+        getTimeDate(){
+            return Math.ceil(new Date().getTime() / 1000);
+        }
+
+    },
+    beforeUnmount() {
+        clearTimeout(this._time_format);
+    }
+}

+ 19 - 26
src/pages/home/src/main.vue

@@ -1,36 +1,30 @@
 <template>
-  <layout-entry>
-    <section class="screen flex">
-      <view-header></view-header>
-      <section class="flex-1 row container">
-        <article class="flex-1 content-container">
-          <tab :data="tabData">
-            <template
-                v-for="(item,index) in tabData"
-                v-slot:[item.slot]
-            >
-              <component
-                  :key="'tab-component-'+index"
-                  :is="item.component"
-              ></component>
-            </template>
+  <section class="screen flex">
+    <view-header></view-header>
+    <section class="flex-1 row container">
+      <article class="flex-1 content-container">
+        <tab :data="tabData">
+          <template
+              v-for="(item,index) in tabData"
+              v-slot:[item.slot]
+          >
+            <component
+                :key="'tab-component-'+index"
+                :is="item.component"
+            ></component>
+          </template>
 
-          </tab>
-        </article>
-        <view-menu></view-menu>
+        </tab>
+      </article>
+      <view-menu></view-menu>
 
-      </section>
-      <view-footer></view-footer>
     </section>
-
-  </layout-entry>
+    <view-footer></view-footer>
+  </section>
 </template>
 
 <script>
 import {
-  layoutEntry
-} from '$layout';
-import {
   tab
 } from '$components';
 import {
@@ -50,7 +44,6 @@ export default {
     }
   },
   components:{
-    layoutEntry,
     viewHeader,
     viewFooter,
     tab,

+ 6 - 0
src/popup/popup-export/components.ts

@@ -0,0 +1,6 @@
+import { defineAsyncComponent } from 'vue';
+
+export default {
+    popupLogin:defineAsyncComponent(()=> import('$popup/popup-login')),
+    toast:defineAsyncComponent(()=> import('$popup/popup-toast'))
+}

+ 22 - 0
src/popup/popup-export/global.js

@@ -0,0 +1,22 @@
+/// <reference path="./types/lib.popup-export.d.ts"/>
+console.log("popup-login" /* login */);
+// import main from './src/main.vue';
+//
+// import {nextTick,createApp} from 'vue';
+//
+// export default {
+//
+//     install(Vue:any){
+//
+//         nextTick(()=>{
+//
+//             // @ts-ignore
+//             const popup:PopupComponent = createApp(main).mount('#popup');
+//
+//             popup.open(PopupExportComponent.login);
+//
+//         });
+//
+//     }
+//
+// }

+ 30 - 0
src/popup/popup-export/global.ts

@@ -0,0 +1,30 @@
+import main from './src/main.vue';
+
+import {nextTick,createApp} from 'vue';
+
+import popup from "$utils/tool/popup";
+
+import request from "$utils/request";
+
+export default {
+
+    install(app:any){
+
+        nextTick(()=>{
+
+            // @ts-ignore
+            popup.$popup = createApp(main).use(request).mount('#popup');
+
+            for (let key in popup) {
+                if (popup.hasOwnProperty(key)) {
+                    app.config.globalProperties[key] = popup[key];
+                }
+            }
+
+            (popup.$popup as PopupComponent).open('popup-login');
+
+        });
+
+    }
+
+}

+ 61 - 0
src/popup/popup-export/src/main.vue

@@ -0,0 +1,61 @@
+<template>
+  <component
+    v-for="(item,key) in components"
+    v-bind="item.options"
+    :is="item.name"
+    :unique="key"
+    :key="key"
+    @destroy-popup="close(key)"
+  ></component>
+</template>
+
+<script lang="ts">
+import components from "../components";
+export default <LibMixins>{
+  name: "popup-export",
+  data() {
+    return {
+      components: {} as PopupExportComponents
+    };
+  },
+  noUniqueOptions: {},
+  provide(): any {
+    return {
+      destroyPopup: (name: string) => {
+        this.close(name);
+      }
+    };
+  },
+  methods: {
+    // 打开弹窗
+    open:function (name: PopupExportComponent, options?: Record<string, any>): string {
+
+      let useId: string;
+      // 鉴定是否唯一
+      if (!this.$options.noUniqueOptions[name]) {
+        useId = name;
+      } else {
+        useId = name + '-' + new Date().getTime() + '-' + Math.ceil(Math.random() * 10000);
+      }
+      if (this.components[useId]) {
+        this.components[useId].options = options;
+      } else {
+        this.components[useId] = {
+          name,
+          options
+        };
+      }
+      return useId;
+    },
+    // 关闭弹窗
+    close(name: string) {
+      if (this.components[name]) {
+        delete this.components[name];
+      }
+    }
+  },
+  components
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 0 - 0
src/popup/popup-export/style.scss


+ 43 - 0
src/popup/popup-export/types/lib.popup-export.d.ts

@@ -0,0 +1,43 @@
+interface PopupExportComponents {
+    [propName:string]:PopupExportOptions
+}
+
+interface PopupExportOptions {
+    options: Record<string, any>,
+    name: PopupExportComponent
+}
+
+declare const enum PopupExportComponent {
+    
+    // 登录弹窗
+    login='popup-login',
+
+    // 提示框
+    toast='toast'
+    
+}
+
+
+declare const enum LibDataComponents {
+    text,
+    input,
+    date,
+    address,
+    textarea,
+    upload,
+    radio,
+    picker
+}
+
+interface PopupComponent {
+    open:(name:PopupExportComponent | string,options?:Record<string, any>)=>string;
+    close:(name:string)=>void
+}
+
+interface PopupToastOption {
+    title:string,
+    duration?:number
+}
+
+
+type PopupToastOptions = string | PopupToastOption;

+ 20 - 0
src/popup/popup-login/components/login/data/input.ts

@@ -0,0 +1,20 @@
+import { VerificationType } from '$utils/verification';
+
+export default function(){
+    return [
+        {
+            placeholder:'请输入手机号',
+            key:'user_login',
+            rules:{
+                [VerificationType.empty]:'',
+                [VerificationType.mobile]:'手机号格式不正确'
+            }
+        },
+        {
+            placeholder:'请输入密码',
+            type:'password',
+            key:'password',
+            rules:''
+        },
+    ] as LibDataArray
+}

+ 3 - 0
src/popup/popup-login/components/login/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 102 - 0
src/popup/popup-login/components/login/src/main.vue

@@ -0,0 +1,102 @@
+<template>
+  <aside class="screen overflow">
+    <div class="login-icon-container overflow">
+      <div @click="$emit('close')" class="cursor-pointer login-close">
+        <icon type="close" class="login-close-icon"></icon>
+      </div>
+    </div>
+
+    <article class="login-content-padding">
+      <!--  标题内容介绍  -->
+      <header class="login-header">
+        <div class="login-header-title">欢迎登录</div>
+        <div class="login-header-info">还没有账号?<span @click="openModal('register')">立即注册</span></div>
+      </header>
+
+      <!--  输入内容  -->
+      <section class="login-section">
+        <aside
+            v-for="(item,index) in inputData"
+            :key="'login-input-'+index"
+            class="login-input rowACenter"
+        >
+          <div class="flex-1 overflow">
+            <input :type="item.type || 'text'"
+                   :placeholder="item.placeholder"
+                   class="screen login-input-target"
+                   v-model="item.value"
+            />
+          </div>
+        </aside>
+      </section>
+
+      <!--  按钮  -->
+      <v-button class="login-button"
+        @submit-verify="submitVerify"
+        @submit="submit"
+      >同意协议并登录</v-button>
+
+      <!--  协议  -->
+      <div class="login-agreement">已阅读并同意以下协议<span>《用户协议》</span>和<span>《隐私政策》</span></div>
+
+    </article>
+
+
+  </aside>
+</template>
+
+<script>
+import {
+  icon,
+  vButton
+} from '$components';
+import inputData from '../data/input';
+
+import verification from '$utils/verification';
+
+import { InstructionsMessageType } from '$utils/request';
+
+export default {
+  name: "login",
+  data(){
+    return {
+      inputData:inputData()
+    }
+  },
+
+  inject:['openModal'],
+
+  methods:{
+    submitVerify:function (callback) {
+      return verification.verificationPromise(this.inputData,true).then(callback);
+    },
+    submit:function (obj) {
+      return this.$request({
+        url:'login/user_login',
+        data:obj.data,
+        message: InstructionsMessageType.other
+      }).then((data)=>{
+        return data.isSuccess ? obj.success() : obj.none();
+      }).catch(obj.fail);
+    },
+    setLoginParams:function (data){
+
+      if (data) {
+        this.inputData.map((item)=>{
+          if (item.value !== data[item.key]) {
+            item.value = data[item.key];
+          }
+        });
+      }
+
+    }
+  },
+
+  components:{
+    icon,
+    vButton
+  }
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 76 - 0
src/popup/popup-login/components/login/style.scss

@@ -0,0 +1,76 @@
+/* 登录内容模块 */
+.login-content-padding{
+  padding: 0 46px;
+}
+.login-icon-container{
+  margin: 20px 20px 0 0;
+}
+.login-close {
+  color:#C1BED5;
+  transition: .5s;
+  float: right;
+}
+.login-close:hover {
+  transform: rotate(180deg);
+}
+.login-close-icon{
+  font-weight: bold;
+  font-size: 16px;
+}
+.login-header{
+  font-size: 14px;
+  color: #666;
+  line-height: 18px;
+  font-weight: 400;
+
+}
+.login-header-title{
+  font-size: 26px;
+  color: #333;
+  font-weight: bold;
+  line-height: 30px;
+  margin: 10px 0;
+}
+.login-section{
+  margin-top: 50px;
+}
+.login-input{
+  height: 40px;
+  margin-top: 15px;
+  border-bottom: 1px solid #EEEEEE;
+}
+.login-input-target{
+  font-size: 16px;
+  color: #333;
+  font-weight: 400;
+}
+.login-input-target::placeholder{
+  color: #999999;
+}
+.login-code{
+  font-size: 16px;
+  color: $main-text;
+  font-weight: 400;
+  line-height: 30px;
+  margin-left: 10px;
+}
+.login-button{
+  width: 240px;
+  margin: 125px auto 0;
+}
+.login-agreement{
+  text-align: center;
+  font-size: 14px;
+  line-height: 20px;
+  margin-top: 28px;
+  color: #999999;
+  font-weight: 400;
+}
+.login-agreement span,.login-header-info span{
+  color: $main-text;
+  cursor: pointer;
+}
+.login-code-disabled{
+  opacity: 0.7;
+}
+/* 登录内容模块 */

+ 45 - 0
src/popup/popup-login/components/register/data/input.ts

@@ -0,0 +1,45 @@
+import { VerificationType } from '$utils/verification';
+
+export default function(){
+
+    let password = {
+            placeholder:'请输入密码',
+            key:'password',
+            type:'password',
+            rules:{
+                [VerificationType.empty]:'',
+                [VerificationType.password]:'密码必须6-16位字母或者数字组成'
+            }
+    };
+
+    return [
+        {
+            placeholder:'请输入手机号',
+            key:'user_login',
+            rules:{
+                [VerificationType.empty]:'',
+                [VerificationType.mobile]:'手机号格式不正确'
+            }
+        },
+        {
+            placeholder:'请输入手机验证码',
+            code:'user_login',
+            codeType:'2',
+            key:'sms_code',
+            rules:'',
+        },
+        password,
+        {
+            placeholder:'请输入确认密码',
+            key:'password',
+            type:'password',
+            rules:{
+                [VerificationType.empty]:'',
+                [VerificationType.eq]:'两次密码不相符',
+            },
+            rulesOption:{
+              data: password
+            }
+        }
+    ] as LibDataArray
+}

+ 3 - 0
src/popup/popup-login/components/register/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 3 - 0
src/popup/popup-login/components/register/mixins/index.ts

@@ -0,0 +1,3 @@
+import time from '$mixins/time';
+
+export default [time];

+ 115 - 0
src/popup/popup-login/components/register/src/main.vue

@@ -0,0 +1,115 @@
+<template>
+  <aside class="screen overflow">
+    <div class="login-icon-container overflow">
+      <div @click="$emit('close')" class="cursor-pointer login-close">
+        <icon type="close" class="login-close-icon"></icon>
+      </div>
+    </div>
+
+    <article class="login-content-padding">
+      <!--  标题内容介绍  -->
+      <header class="login-header">
+        <div class="login-header-title">欢迎注册</div>
+        <div class="login-header-info">已有账号?<span @click="openModal('login')">立即登录</span></div>
+      </header>
+
+
+      <!--  输入内容  -->
+      <section class="login-section register-section">
+        <aside
+            v-for="(item,index) in inputData"
+            :key="'login-input-'+index"
+            class="login-input rowACenter"
+        >
+          <div class="flex-1 overflow">
+            <input :type="item.value ?  item.type : '' || 'text'"
+                   :placeholder="item.placeholder"
+                   class="screen login-input-target"
+                   v-model="item.value"
+                   autocomplete="off"
+                   disableautocomplete
+            />
+          </div>
+          <div v-if="item.code"
+               class="login-code cursor-pointer"
+               :class="{
+                    'button-active' : !timeFormat,
+                    'login-code-disabled': timeFormat
+                   }"
+               @click="triggerTimeDate(item,inputData)"
+          >{{ timeFormat || timeConfig.default }}</div>
+        </aside>
+      </section>
+
+      <!--  按钮  -->
+      <v-button class="login-button register-button"
+          @submit-verify="submitVerify"
+          @submit="submit"
+          @change-success="toLogin"
+          success-text="注册成功"
+      >同意协议并注册</v-button>
+
+      <!--  协议  -->
+      <div class="login-agreement">已阅读并同意以下协议<span>《用户协议》</span>和<span>《隐私政策》</span></div>
+
+    </article>
+
+
+  </aside>
+</template>
+
+<script>
+import {
+  icon,
+  vButton
+} from '$components';
+import inputData from '../data/input';
+import mixins from '../mixins';
+import verification from "$utils/verification";
+import {InstructionsMessageType} from "$utils/request";
+
+export default {
+  name: "register",
+  data(){
+    return {
+      inputData: inputData()
+    }
+  },
+
+  inject:['openModal','setLoginParams'],
+
+  methods:{
+    submitVerify:function (callback) {
+      return verification.verificationPromise(this.inputData,true).then(callback);
+    },
+    submit:function (obj) {
+
+      this.storageData = obj.data;
+      setTimeout(()=> obj.success(),1000);
+
+      // return this.$request({
+      //   url:'login/user_reg',
+      //   data:obj.data,
+      //   message: InstructionsMessageType.other
+      // }).then((data)=>{
+      //   return data.isSuccess ? obj.success() : obj.none();
+      // }).catch(obj.fail);
+    },
+    //跳转登录
+    toLogin(){
+
+      this.storageData && this.setLoginParams(this.storageData);
+
+      // 跳转 login 同时释放自身
+      return this.openModal('login',false);
+    }
+  },
+  components:{
+    icon,
+    vButton
+  },
+  mixins
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 9 - 0
src/popup/popup-login/components/register/style.scss

@@ -0,0 +1,9 @@
+@import "../login/style.scss";
+
+.register-button{
+  margin-top: 30px;
+}
+
+.register-section{
+  margin-top: 40px;
+}

BIN
src/popup/popup-login/images/background.png


+ 3 - 0
src/popup/popup-login/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 65 - 0
src/popup/popup-login/mixins/handle.ts

@@ -0,0 +1,65 @@
+export default <LibMixins>{
+
+    data(){
+        return {
+            value:true,
+            useModal:'',
+            animate:false,
+            drawModal:{},
+            useModals:['login','register'],
+        }
+    },
+
+    watch:{
+        modal:{
+            handler:function () {
+                if (this.modal) {
+                    return this.openModal(this.modal);
+                }
+            },
+            immediate:true
+        },
+
+    },
+
+    provide(){
+        return {
+            openModal:(name,draw?:boolean)=> this.openModal(name,draw),
+            setLoginParams:(data:Record<string, any>)=> this.$refs.$login && this.$refs.$login.setLoginParams(data)
+        }
+    },
+
+    methods:{
+
+        close(){
+            if (this.value) {
+                this.value = false;
+            }
+        },
+
+        openModal(name:string,draw:boolean=true){
+
+            let animate:boolean = this.useModal !== '';
+
+            if (name !== this.useModal) {
+
+                if (draw !== this.drawModal[this.useModal]) {
+                    this.drawModal[this.useModal] = draw;
+                }
+
+                if (this.drawModal[name] !== true) {
+                    this.drawModal[name] = true;
+                }
+
+                this.useModal = name;
+
+                if (this.animate !== animate) {
+                    this.animate = animate;
+                }
+            }
+
+        }
+
+    }
+
+}

+ 3 - 0
src/popup/popup-login/mixins/index.ts

@@ -0,0 +1,3 @@
+import handle from './handle';
+
+export default [handle];

+ 14 - 0
src/popup/popup-login/props.ts

@@ -0,0 +1,14 @@
+export default {
+
+    unique:{
+        type:String,
+        default:''
+    },
+
+    // 打开的modal
+    modal:{
+        type: String,
+        default:'login'
+    }
+
+}

+ 62 - 0
src/popup/popup-login/src/main.vue

@@ -0,0 +1,62 @@
+<template>
+  <popup v-model:value="value" @close="$emit('destroy-popup')">
+    <section class="login-container overflow row">
+      <img
+        src="../images/background.png"
+        class="login-background"
+      />
+      <!--  登录内容模块  -->
+      <aside class="login-content overflow relative">
+        <transition-group
+          name="transition"
+        >
+          <template
+              v-for="(item,index) in useModals"
+              :key="'modal-'+index"
+          >
+            <component
+                :is="item"
+                v-if="drawModal[item]"
+                v-show="useModal===item"
+                :ref="'$'+item"
+                :key="item"
+                @close="close"
+            ></component>
+          </template>
+        </transition-group>
+
+
+      </aside>
+    </section>
+  </popup>
+</template>
+
+<script>
+import {
+  Popup
+} from '$components';
+
+import props from '../props';
+
+import mixins from '../mixins';
+
+import login from '../components/login';
+
+import register from '../components/register';
+
+export default {
+  name: "popup-login",
+
+  mixins,
+
+  props,
+
+  components:{
+    Popup,
+    login,
+    register
+  }
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 48 - 0
src/popup/popup-login/style.scss

@@ -0,0 +1,48 @@
+/* 容器 */
+.login-container{
+  background-color: #fff;
+  height: 550px;
+  border-radius: 10px;
+}
+/* 容器 */
+
+/* 背景图 */
+.login-background{
+  width: 400px;
+  height: 100%;
+  background-size: 100% !important;
+}
+/* 背景图 */
+
+/* content */
+.login-content{
+  width: 454px;
+  height: 100%;
+}
+
+.transition-entry-active{
+  animation: .5s transitionEntry forwards;
+  z-index: 9;
+}
+.transition-entry-active,.transition-leave-active{
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  right: 0;
+  left: 0;
+  background-color: #fff;
+}
+.transition-leave-active{
+  animation: .5s transitionEntry forwards reverse;
+  z-index: 8;
+}
+
+@keyframes transitionEntry {
+  0%{
+    transform: translateX(-100%) rotate(90deg);
+  }
+  100%{
+    transform: translateX(0) rotate(0);
+  }
+}
+/* content */

+ 3 - 0
src/popup/popup-toast/index.ts

@@ -0,0 +1,3 @@
+import main from './src/main.vue';
+
+export default main;

+ 15 - 0
src/popup/popup-toast/mixins/handle.ts

@@ -0,0 +1,15 @@
+export default <LibMixins>{
+
+    data(){
+        return {
+            value:true
+        }
+    },
+
+    methods:{
+
+
+
+    }
+
+}

+ 3 - 0
src/popup/popup-toast/mixins/index.ts

@@ -0,0 +1,3 @@
+import handle from './handle';
+
+export default [handle];

+ 15 - 0
src/popup/popup-toast/props.ts

@@ -0,0 +1,15 @@
+export default {
+
+    // 显示标题
+    title:{
+        type:String,
+        default:''
+    },
+
+    // 显示最大时长
+    duration:{
+        type:Number,
+        default: 3000
+    }
+
+}

+ 52 - 0
src/popup/popup-toast/src/main.vue

@@ -0,0 +1,52 @@
+<template>
+  <aside v-if="toastTitle" class="absolute toast center">{{toastTitle}}</aside>
+</template>
+
+<script>
+import props from '../props';
+export default {
+  name: "popup-toast",
+
+  watch:{
+
+    title:{
+      handler:function () {
+        if (this.title) {
+          return this.open();
+        }
+      },
+      immediate:true
+    }
+
+  },
+
+  methods:{
+    open:function () {
+
+      if (this.title) {
+        clearTimeout(this.time);
+
+        this.toastTitle = this.title;
+
+        this.time = setTimeout(()=> this.close(),this.duration || 3000);
+      }
+
+    },
+    close(){
+      clearTimeout(this.time);
+      this.$emit('destroy-popup');
+    }
+  },
+
+  data(){
+    return {
+      toastTitle:''
+    }
+  },
+
+  props
+
+}
+</script>
+
+<style scoped lang="scss" src="../style.scss"></style>

+ 19 - 0
src/popup/popup-toast/style.scss

@@ -0,0 +1,19 @@
+
+/* toast */
+.toast{
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%,-50%);
+  font-size: 18px;
+  color: #fff;
+  line-height: 24px;
+  height: 50px;
+  padding: 0 20px;
+  background-color: rgba(0,0,0,0.5);
+  border-radius: 5px;
+  letter-spacing: 1px;
+  opacity: 1 !important;
+  pointer-events: all;
+  z-index: 99999;
+}
+/* toast */

+ 2 - 0
src/router/index.ts

@@ -13,6 +13,7 @@ const pagesContText = require.context('../pages',true,/page.ts$/);
 
 
 
+
 pagesContText.keys().map((item:string)=>{
 
   // 获取模块
@@ -56,6 +57,7 @@ function getPathName(path:string){
 }
 
 
+
 const router = createRouter({
   history: createWebHashHistory(),
   routes

+ 39 - 0
src/store/modules/user.ts

@@ -0,0 +1,39 @@
+import {StoreOptions} from "vuex";
+
+import userConfig from '$config/user';
+
+import storage from '$utils/tool/storage';
+
+export default <StoreOptions>{
+
+    state:{
+        user:{}
+    },
+
+    mutations:{
+
+        initializationUser(state){
+            let userData = storage.getItem(userConfig.storageKey);
+            if (userData) {
+                userConfig.user = userData;
+                state.user = userData;
+            }
+        },
+
+        // 设置缓存
+        setUserInfo(state,user){
+
+            if (user) {
+
+                userConfig.user = userData;
+                state.user = user;
+
+                return storage.setItem(userConfig.storageKey,user,userConfig.storageTime);
+
+            }
+
+        }
+
+    }
+
+}

+ 7 - 0
src/types/lib.data.d.ts

@@ -30,9 +30,16 @@ interface LibData extends TriggerData{
     // 规则
     rules?: LibDataRules | string,
 
+    placeholder?: string,
+
     // 组件
     component?:string,
 
+    // 校验规则配置
+    rulesOption?:{
+        data: LibData
+    },
+
     [propName:string]:any
 
 }

+ 14 - 0
src/types/lib.fetch.d.ts

@@ -0,0 +1,14 @@
+interface LibFetch {
+
+    success(...params):void,
+
+    fail(...params):void,
+
+    // 本次请求的唯一标识
+    unique?:string,
+
+}
+
+interface LibFetchCallback {
+    (options:LibFetch):void
+}

+ 21 - 6
src/types/lib.mixins.d.ts

@@ -1,13 +1,28 @@
-interface LibMixins {
+type LibMixins = LibMixin & Record<string, any>;
 
-    computed?:{
-        [propName:string]:Record<string, any> | LibMixinsComputed
-    };
+interface LibMixin {
 
-    [propName:string]: any
+    computed?:Record<string,  Record<string, any> | LibMixinsComputed>;
+
+    methods?:Record<string, LibMixinsMethod>;
 
 }
 
 interface LibMixinsComputed {
-    (this:any):any
+    (this:LibVueOptions):any | void
+}
+
+
+interface LibMixinsMethod {
+    (this:LibVueOptions,...rest:any):any | void
+}
+
+type LibVueOptions = Record<string, any> & LibVueOption;
+
+interface LibVueOption  {
+
+    $popup:PopupComponent,
+
+    $toast:(option:PopupToastOptions)=>string
+
 }

+ 1 - 0
src/utils/animate/animate.ts

@@ -17,6 +17,7 @@ type animate = {
     [key in animateType]:animateFunction
 }
 
+
 export default <animate>{
     linear:function(x, t, b, c, d){
         return c * (t/d) + b;

+ 20 - 0
src/utils/encryption/ase.js

@@ -0,0 +1,20 @@
+import CryptoJS from 'crypto-js';
+export default {
+
+	key : CryptoJS.enc.Utf8.parse("1234123412ABCDEF"),  //十六位十六进制数作为密钥
+    iv :  CryptoJS.enc.Utf8.parse('8105548186756005'),   //十六位十六进制数作为密钥偏移量
+
+	decode:function(word) {
+		let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
+		let decrypt = CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(encryptedHexStr), this.key, { iv: this.iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
+		let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
+		return decryptedStr.toString();
+	},
+
+	//加密方法
+	encode:function(word) {
+		let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(word), this.key, { iv: this.iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
+		return encrypted.ciphertext.toString().toUpperCase();
+	}
+
+}

+ 104 - 0
src/utils/encryption/encryption.js

@@ -0,0 +1,104 @@
+export default new function () {
+
+  // private property
+  let _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+  // public method for encoding
+  this.encode = function (input) {
+    var output = "";
+    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
+    var i = 0;
+    input = _utf8_encode(input);
+    while (i < input.length) {
+      chr1 = input.charCodeAt(i++);
+      chr2 = input.charCodeAt(i++);
+      chr3 = input.charCodeAt(i++);
+      enc1 = chr1 >> 2;
+      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+      enc4 = chr3 & 63;
+      if (isNaN(chr2)) {
+        enc3 = enc4 = 64;
+      } else if (isNaN(chr3)) {
+        enc4 = 64;
+      }
+      output = output +
+        _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
+        _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
+    }
+    return output;
+  }
+
+  // public method for decoding
+  this.decode = function (input) {
+    var output = "";
+    var chr1, chr2, chr3;
+    var enc1, enc2, enc3, enc4;
+    var i = 0;
+    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+    while (i < input.length) {
+      enc1 = _keyStr.indexOf(input.charAt(i++));
+      enc2 = _keyStr.indexOf(input.charAt(i++));
+      enc3 = _keyStr.indexOf(input.charAt(i++));
+      enc4 = _keyStr.indexOf(input.charAt(i++));
+      chr1 = (enc1 << 2) | (enc2 >> 4);
+      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+      chr3 = ((enc3 & 3) << 6) | enc4;
+      output = output + String.fromCharCode(chr1);
+      if (enc3 != 64) {
+        output = output + String.fromCharCode(chr2);
+      }
+      if (enc4 != 64) {
+        output = output + String.fromCharCode(chr3);
+      }
+    }
+    output = _utf8_decode(output);
+    return output;
+  }
+
+  // private method for UTF-8 encoding
+  let _utf8_encode = function (string) {
+    string = string.replace(/\r\n/g,"\n");
+    var utftext = "";
+    for (var n = 0; n < string.length; n++) {
+      var c = string.charCodeAt(n);
+      if (c < 128) {
+        utftext += String.fromCharCode(c);
+      } else if((c > 127) && (c < 2048)) {
+        utftext += String.fromCharCode((c >> 6) | 192);
+        utftext += String.fromCharCode((c & 63) | 128);
+      } else {
+        utftext += String.fromCharCode((c >> 12) | 224);
+        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+        utftext += String.fromCharCode((c & 63) | 128);
+      }
+
+    }
+    return utftext;
+  }
+
+  // private method for UTF-8 decoding
+  let _utf8_decode = function (utftext) {
+    var string = "";
+    var i = 0;
+    let c,c1,c2,c3;
+    c = c1 = c2 = 0;
+    while ( i < utftext.length ) {
+      c = utftext.charCodeAt(i);
+      if (c < 128) {
+        string += String.fromCharCode(c);
+        i++;
+      } else if((c > 191) && (c < 224)) {
+        c2 = utftext.charCodeAt(i+1);
+        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
+        i += 2;
+      } else {
+        c2 = utftext.charCodeAt(i+1);
+        c3 = utftext.charCodeAt(i+2);
+        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+        i += 3;
+      }
+    }
+    return string;
+  }
+}

+ 683 - 0
src/utils/encryption/md5.js

@@ -0,0 +1,683 @@
+/**
+ * [js-md5]{@link https://github.com/emn178/js-md5}
+ *
+ * @namespace md5
+ * @version 0.7.3
+ * @author Chen, Yi-Cyuan [emn178@gmail.com]
+ * @copyright Chen, Yi-Cyuan 2014-2017
+ * @license MIT
+ */
+(function () {
+	'use strict';
+
+	var ERROR = 'input is invalid type';
+	var WINDOW = typeof window === 'object';
+	var root = WINDOW ? window : {};
+	if (root.JS_MD5_NO_WINDOW) {
+		WINDOW = false;
+	}
+	var WEB_WORKER = !WINDOW && typeof self === 'object';
+	var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
+	if (NODE_JS) {
+		root = global;
+	} else if (WEB_WORKER) {
+		root = self;
+	}
+	var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;
+	var AMD = typeof define === 'function' && define.amd;
+	var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
+	var HEX_CHARS = '0123456789abcdef'.split('');
+	var EXTRA = [128, 32768, 8388608, -2147483648];
+	var SHIFT = [0, 8, 16, 24];
+	var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];
+	var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
+
+	var blocks = [], buffer8;
+	if (ARRAY_BUFFER) {
+		var buffer = new ArrayBuffer(68);
+		buffer8 = new Uint8Array(buffer);
+		blocks = new Uint32Array(buffer);
+	}
+
+	if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {
+		Array.isArray = function (obj) {
+			return Object.prototype.toString.call(obj) === '[object Array]';
+		};
+	}
+
+	if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
+		ArrayBuffer.isView = function (obj) {
+			return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
+		};
+	}
+
+	/**
+	 * @method hex
+	 * @memberof md5
+	 * @description Output hash as hex string
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {String} Hex string
+	 * @example
+	 * md5.hex('The quick brown fox jumps over the lazy dog');
+	 * // equal to
+	 * md5('The quick brown fox jumps over the lazy dog');
+	 */
+	/**
+	 * @method digest
+	 * @memberof md5
+	 * @description Output hash as bytes array
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {Array} Bytes array
+	 * @example
+	 * md5.digest('The quick brown fox jumps over the lazy dog');
+	 */
+	/**
+	 * @method array
+	 * @memberof md5
+	 * @description Output hash as bytes array
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {Array} Bytes array
+	 * @example
+	 * md5.array('The quick brown fox jumps over the lazy dog');
+	 */
+	/**
+	 * @method arrayBuffer
+	 * @memberof md5
+	 * @description Output hash as ArrayBuffer
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {ArrayBuffer} ArrayBuffer
+	 * @example
+	 * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');
+	 */
+	/**
+	 * @method buffer
+	 * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
+	 * @memberof md5
+	 * @description Output hash as ArrayBuffer
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {ArrayBuffer} ArrayBuffer
+	 * @example
+	 * md5.buffer('The quick brown fox jumps over the lazy dog');
+	 */
+	/**
+	 * @method base64
+	 * @memberof md5
+	 * @description Output hash as base64 string
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {String} base64 string
+	 * @example
+	 * md5.base64('The quick brown fox jumps over the lazy dog');
+	 */
+	var createOutputMethod = function (outputType) {
+		return function (message) {
+			return new Md5(true).update(message)[outputType]();
+		};
+	};
+
+	/**
+	 * @method create
+	 * @memberof md5
+	 * @description Create Md5 object
+	 * @returns {Md5} Md5 object.
+	 * @example
+	 * var hash = md5.create();
+	 */
+	/**
+	 * @method update
+	 * @memberof md5
+	 * @description Create and update Md5 object
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {Md5} Md5 object.
+	 * @example
+	 * var hash = md5.update('The quick brown fox jumps over the lazy dog');
+	 * // equal to
+	 * var hash = md5.create();
+	 * hash.update('The quick brown fox jumps over the lazy dog');
+	 */
+	var createMethod = function () {
+		var method = createOutputMethod('hex');
+		if (NODE_JS) {
+			method = nodeWrap(method);
+		}
+		method.create = function () {
+			return new Md5();
+		};
+		method.update = function (message) {
+			return method.create().update(message);
+		};
+		for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
+			var type = OUTPUT_TYPES[i];
+			method[type] = createOutputMethod(type);
+		}
+		return method;
+	};
+
+	var nodeWrap = function (method) {
+		var crypto = eval("require('crypto')");
+		var Buffer = eval("require('buffer').Buffer");
+		var nodeMethod = function (message) {
+			if (typeof message === 'string') {
+				return crypto.createHash('md5').update(message, 'utf8').digest('hex');
+			} else {
+				if (message === null || message === undefined) {
+					throw ERROR;
+				} else if (message.constructor === ArrayBuffer) {
+					message = new Uint8Array(message);
+				}
+			}
+			if (Array.isArray(message) || ArrayBuffer.isView(message) ||
+				message.constructor === Buffer) {
+				return crypto.createHash('md5').update(new Buffer(message)).digest('hex');
+			} else {
+				return method(message);
+			}
+		};
+		return nodeMethod;
+	};
+
+	/**
+	 * Md5 class
+	 * @class Md5
+	 * @description This is internal class.
+	 * @see {@link md5.create}
+	 */
+	function Md5(sharedMemory) {
+		if (sharedMemory) {
+			blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
+				blocks[4] = blocks[5] = blocks[6] = blocks[7] =
+					blocks[8] = blocks[9] = blocks[10] = blocks[11] =
+						blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
+			this.blocks = blocks;
+			this.buffer8 = buffer8;
+		} else {
+			if (ARRAY_BUFFER) {
+				var buffer = new ArrayBuffer(68);
+				this.buffer8 = new Uint8Array(buffer);
+				this.blocks = new Uint32Array(buffer);
+			} else {
+				this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+			}
+		}
+		this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;
+		this.finalized = this.hashed = false;
+		this.first = true;
+	}
+
+	/**
+	 * @method update
+	 * @memberof Md5
+	 * @instance
+	 * @description Update hash
+	 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+	 * @returns {Md5} Md5 object.
+	 * @see {@link md5.update}
+	 */
+	Md5.prototype.update = function (message) {
+		if (this.finalized) {
+			return;
+		}
+
+		var notString, type = typeof message;
+		if (type !== 'string') {
+			if (type === 'object') {
+				if (message === null) {
+					throw ERROR;
+				} else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
+					message = new Uint8Array(message);
+				} else if (!Array.isArray(message)) {
+					if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
+						throw ERROR;
+					}
+				}
+			} else {
+				throw ERROR;
+			}
+			notString = true;
+		}
+		var code, index = 0, i, length = message.length, blocks = this.blocks;
+		var buffer8 = this.buffer8;
+
+		while (index < length) {
+			if (this.hashed) {
+				this.hashed = false;
+				blocks[0] = blocks[16];
+				blocks[16] = blocks[1] = blocks[2] = blocks[3] =
+					blocks[4] = blocks[5] = blocks[6] = blocks[7] =
+						blocks[8] = blocks[9] = blocks[10] = blocks[11] =
+							blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
+			}
+
+			if (notString) {
+				if (ARRAY_BUFFER) {
+					for (i = this.start; index < length && i < 64; ++index) {
+						buffer8[i++] = message[index];
+					}
+				} else {
+					for (i = this.start; index < length && i < 64; ++index) {
+						blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
+					}
+				}
+			} else {
+				if (ARRAY_BUFFER) {
+					for (i = this.start; index < length && i < 64; ++index) {
+						code = message.charCodeAt(index);
+						if (code < 0x80) {
+							buffer8[i++] = code;
+						} else if (code < 0x800) {
+							buffer8[i++] = 0xc0 | (code >> 6);
+							buffer8[i++] = 0x80 | (code & 0x3f);
+						} else if (code < 0xd800 || code >= 0xe000) {
+							buffer8[i++] = 0xe0 | (code >> 12);
+							buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);
+							buffer8[i++] = 0x80 | (code & 0x3f);
+						} else {
+							code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
+							buffer8[i++] = 0xf0 | (code >> 18);
+							buffer8[i++] = 0x80 | ((code >> 12) & 0x3f);
+							buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);
+							buffer8[i++] = 0x80 | (code & 0x3f);
+						}
+					}
+				} else {
+					for (i = this.start; index < length && i < 64; ++index) {
+						code = message.charCodeAt(index);
+						if (code < 0x80) {
+							blocks[i >> 2] |= code << SHIFT[i++ & 3];
+						} else if (code < 0x800) {
+							blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
+							blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
+						} else if (code < 0xd800 || code >= 0xe000) {
+							blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
+							blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
+							blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
+						} else {
+							code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
+							blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
+							blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
+							blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
+							blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
+						}
+					}
+				}
+			}
+			this.lastByteIndex = i;
+			this.bytes += i - this.start;
+			if (i >= 64) {
+				this.start = i - 64;
+				this.hash();
+				this.hashed = true;
+			} else {
+				this.start = i;
+			}
+		}
+		if (this.bytes > 4294967295) {
+			this.hBytes += this.bytes / 4294967296 << 0;
+			this.bytes = this.bytes % 4294967296;
+		}
+		return this;
+	};
+
+	Md5.prototype.finalize = function () {
+		if (this.finalized) {
+			return;
+		}
+		this.finalized = true;
+		var blocks = this.blocks, i = this.lastByteIndex;
+		blocks[i >> 2] |= EXTRA[i & 3];
+		if (i >= 56) {
+			if (!this.hashed) {
+				this.hash();
+			}
+			blocks[0] = blocks[16];
+			blocks[16] = blocks[1] = blocks[2] = blocks[3] =
+				blocks[4] = blocks[5] = blocks[6] = blocks[7] =
+					blocks[8] = blocks[9] = blocks[10] = blocks[11] =
+						blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
+		}
+		blocks[14] = this.bytes << 3;
+		blocks[15] = this.hBytes << 3 | this.bytes >>> 29;
+		this.hash();
+	};
+
+	Md5.prototype.hash = function () {
+		var a, b, c, d, bc, da, blocks = this.blocks;
+
+		if (this.first) {
+			a = blocks[0] - 680876937;
+			a = (a << 7 | a >>> 25) - 271733879 << 0;
+			d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;
+			d = (d << 12 | d >>> 20) + a << 0;
+			c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2] - 1126478375;
+			c = (c << 17 | c >>> 15) + d << 0;
+			b = (a ^ (c & (d ^ a))) + blocks[3] - 1316259209;
+			b = (b << 22 | b >>> 10) + c << 0;
+		} else {
+			a = this.h0;
+			b = this.h1;
+			c = this.h2;
+			d = this.h3;
+			a += (d ^ (b & (c ^ d))) + blocks[0] - 680876936;
+			a = (a << 7 | a >>> 25) + b << 0;
+			d += (c ^ (a & (b ^ c))) + blocks[1] - 389564586;
+			d = (d << 12 | d >>> 20) + a << 0;
+			c += (b ^ (d & (a ^ b))) + blocks[2] + 606105819;
+			c = (c << 17 | c >>> 15) + d << 0;
+			b += (a ^ (c & (d ^ a))) + blocks[3] - 1044525330;
+			b = (b << 22 | b >>> 10) + c << 0;
+		}
+
+		a += (d ^ (b & (c ^ d))) + blocks[4] - 176418897;
+		a = (a << 7 | a >>> 25) + b << 0;
+		d += (c ^ (a & (b ^ c))) + blocks[5] + 1200080426;
+		d = (d << 12 | d >>> 20) + a << 0;
+		c += (b ^ (d & (a ^ b))) + blocks[6] - 1473231341;
+		c = (c << 17 | c >>> 15) + d << 0;
+		b += (a ^ (c & (d ^ a))) + blocks[7] - 45705983;
+		b = (b << 22 | b >>> 10) + c << 0;
+		a += (d ^ (b & (c ^ d))) + blocks[8] + 1770035416;
+		a = (a << 7 | a >>> 25) + b << 0;
+		d += (c ^ (a & (b ^ c))) + blocks[9] - 1958414417;
+		d = (d << 12 | d >>> 20) + a << 0;
+		c += (b ^ (d & (a ^ b))) + blocks[10] - 42063;
+		c = (c << 17 | c >>> 15) + d << 0;
+		b += (a ^ (c & (d ^ a))) + blocks[11] - 1990404162;
+		b = (b << 22 | b >>> 10) + c << 0;
+		a += (d ^ (b & (c ^ d))) + blocks[12] + 1804603682;
+		a = (a << 7 | a >>> 25) + b << 0;
+		d += (c ^ (a & (b ^ c))) + blocks[13] - 40341101;
+		d = (d << 12 | d >>> 20) + a << 0;
+		c += (b ^ (d & (a ^ b))) + blocks[14] - 1502002290;
+		c = (c << 17 | c >>> 15) + d << 0;
+		b += (a ^ (c & (d ^ a))) + blocks[15] + 1236535329;
+		b = (b << 22 | b >>> 10) + c << 0;
+		a += (c ^ (d & (b ^ c))) + blocks[1] - 165796510;
+		a = (a << 5 | a >>> 27) + b << 0;
+		d += (b ^ (c & (a ^ b))) + blocks[6] - 1069501632;
+		d = (d << 9 | d >>> 23) + a << 0;
+		c += (a ^ (b & (d ^ a))) + blocks[11] + 643717713;
+		c = (c << 14 | c >>> 18) + d << 0;
+		b += (d ^ (a & (c ^ d))) + blocks[0] - 373897302;
+		b = (b << 20 | b >>> 12) + c << 0;
+		a += (c ^ (d & (b ^ c))) + blocks[5] - 701558691;
+		a = (a << 5 | a >>> 27) + b << 0;
+		d += (b ^ (c & (a ^ b))) + blocks[10] + 38016083;
+		d = (d << 9 | d >>> 23) + a << 0;
+		c += (a ^ (b & (d ^ a))) + blocks[15] - 660478335;
+		c = (c << 14 | c >>> 18) + d << 0;
+		b += (d ^ (a & (c ^ d))) + blocks[4] - 405537848;
+		b = (b << 20 | b >>> 12) + c << 0;
+		a += (c ^ (d & (b ^ c))) + blocks[9] + 568446438;
+		a = (a << 5 | a >>> 27) + b << 0;
+		d += (b ^ (c & (a ^ b))) + blocks[14] - 1019803690;
+		d = (d << 9 | d >>> 23) + a << 0;
+		c += (a ^ (b & (d ^ a))) + blocks[3] - 187363961;
+		c = (c << 14 | c >>> 18) + d << 0;
+		b += (d ^ (a & (c ^ d))) + blocks[8] + 1163531501;
+		b = (b << 20 | b >>> 12) + c << 0;
+		a += (c ^ (d & (b ^ c))) + blocks[13] - 1444681467;
+		a = (a << 5 | a >>> 27) + b << 0;
+		d += (b ^ (c & (a ^ b))) + blocks[2] - 51403784;
+		d = (d << 9 | d >>> 23) + a << 0;
+		c += (a ^ (b & (d ^ a))) + blocks[7] + 1735328473;
+		c = (c << 14 | c >>> 18) + d << 0;
+		b += (d ^ (a & (c ^ d))) + blocks[12] - 1926607734;
+		b = (b << 20 | b >>> 12) + c << 0;
+		bc = b ^ c;
+		a += (bc ^ d) + blocks[5] - 378558;
+		a = (a << 4 | a >>> 28) + b << 0;
+		d += (bc ^ a) + blocks[8] - 2022574463;
+		d = (d << 11 | d >>> 21) + a << 0;
+		da = d ^ a;
+		c += (da ^ b) + blocks[11] + 1839030562;
+		c = (c << 16 | c >>> 16) + d << 0;
+		b += (da ^ c) + blocks[14] - 35309556;
+		b = (b << 23 | b >>> 9) + c << 0;
+		bc = b ^ c;
+		a += (bc ^ d) + blocks[1] - 1530992060;
+		a = (a << 4 | a >>> 28) + b << 0;
+		d += (bc ^ a) + blocks[4] + 1272893353;
+		d = (d << 11 | d >>> 21) + a << 0;
+		da = d ^ a;
+		c += (da ^ b) + blocks[7] - 155497632;
+		c = (c << 16 | c >>> 16) + d << 0;
+		b += (da ^ c) + blocks[10] - 1094730640;
+		b = (b << 23 | b >>> 9) + c << 0;
+		bc = b ^ c;
+		a += (bc ^ d) + blocks[13] + 681279174;
+		a = (a << 4 | a >>> 28) + b << 0;
+		d += (bc ^ a) + blocks[0] - 358537222;
+		d = (d << 11 | d >>> 21) + a << 0;
+		da = d ^ a;
+		c += (da ^ b) + blocks[3] - 722521979;
+		c = (c << 16 | c >>> 16) + d << 0;
+		b += (da ^ c) + blocks[6] + 76029189;
+		b = (b << 23 | b >>> 9) + c << 0;
+		bc = b ^ c;
+		a += (bc ^ d) + blocks[9] - 640364487;
+		a = (a << 4 | a >>> 28) + b << 0;
+		d += (bc ^ a) + blocks[12] - 421815835;
+		d = (d << 11 | d >>> 21) + a << 0;
+		da = d ^ a;
+		c += (da ^ b) + blocks[15] + 530742520;
+		c = (c << 16 | c >>> 16) + d << 0;
+		b += (da ^ c) + blocks[2] - 995338651;
+		b = (b << 23 | b >>> 9) + c << 0;
+		a += (c ^ (b | ~d)) + blocks[0] - 198630844;
+		a = (a << 6 | a >>> 26) + b << 0;
+		d += (b ^ (a | ~c)) + blocks[7] + 1126891415;
+		d = (d << 10 | d >>> 22) + a << 0;
+		c += (a ^ (d | ~b)) + blocks[14] - 1416354905;
+		c = (c << 15 | c >>> 17) + d << 0;
+		b += (d ^ (c | ~a)) + blocks[5] - 57434055;
+		b = (b << 21 | b >>> 11) + c << 0;
+		a += (c ^ (b | ~d)) + blocks[12] + 1700485571;
+		a = (a << 6 | a >>> 26) + b << 0;
+		d += (b ^ (a | ~c)) + blocks[3] - 1894986606;
+		d = (d << 10 | d >>> 22) + a << 0;
+		c += (a ^ (d | ~b)) + blocks[10] - 1051523;
+		c = (c << 15 | c >>> 17) + d << 0;
+		b += (d ^ (c | ~a)) + blocks[1] - 2054922799;
+		b = (b << 21 | b >>> 11) + c << 0;
+		a += (c ^ (b | ~d)) + blocks[8] + 1873313359;
+		a = (a << 6 | a >>> 26) + b << 0;
+		d += (b ^ (a | ~c)) + blocks[15] - 30611744;
+		d = (d << 10 | d >>> 22) + a << 0;
+		c += (a ^ (d | ~b)) + blocks[6] - 1560198380;
+		c = (c << 15 | c >>> 17) + d << 0;
+		b += (d ^ (c | ~a)) + blocks[13] + 1309151649;
+		b = (b << 21 | b >>> 11) + c << 0;
+		a += (c ^ (b | ~d)) + blocks[4] - 145523070;
+		a = (a << 6 | a >>> 26) + b << 0;
+		d += (b ^ (a | ~c)) + blocks[11] - 1120210379;
+		d = (d << 10 | d >>> 22) + a << 0;
+		c += (a ^ (d | ~b)) + blocks[2] + 718787259;
+		c = (c << 15 | c >>> 17) + d << 0;
+		b += (d ^ (c | ~a)) + blocks[9] - 343485551;
+		b = (b << 21 | b >>> 11) + c << 0;
+
+		if (this.first) {
+			this.h0 = a + 1732584193 << 0;
+			this.h1 = b - 271733879 << 0;
+			this.h2 = c - 1732584194 << 0;
+			this.h3 = d + 271733878 << 0;
+			this.first = false;
+		} else {
+			this.h0 = this.h0 + a << 0;
+			this.h1 = this.h1 + b << 0;
+			this.h2 = this.h2 + c << 0;
+			this.h3 = this.h3 + d << 0;
+		}
+	};
+
+	/**
+	 * @method hex
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as hex string
+	 * @returns {String} Hex string
+	 * @see {@link md5.hex}
+	 * @example
+	 * hash.hex();
+	 */
+	Md5.prototype.hex = function () {
+		this.finalize();
+
+		var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;
+
+		return HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
+			HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
+			HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
+			HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
+			HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
+			HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
+			HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
+			HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
+			HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
+			HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
+			HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
+			HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
+			HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
+			HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
+			HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
+			HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F];
+	};
+
+	/**
+	 * @method toString
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as hex string
+	 * @returns {String} Hex string
+	 * @see {@link md5.hex}
+	 * @example
+	 * hash.toString();
+	 */
+	Md5.prototype.toString = Md5.prototype.hex;
+
+	/**
+	 * @method digest
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as bytes array
+	 * @returns {Array} Bytes array
+	 * @see {@link md5.digest}
+	 * @example
+	 * hash.digest();
+	 */
+	Md5.prototype.digest = function () {
+		this.finalize();
+
+		var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;
+		return [
+			h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 24) & 0xFF,
+			h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 24) & 0xFF,
+			h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 24) & 0xFF,
+			h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 24) & 0xFF
+		];
+	};
+
+	/**
+	 * @method array
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as bytes array
+	 * @returns {Array} Bytes array
+	 * @see {@link md5.array}
+	 * @example
+	 * hash.array();
+	 */
+	Md5.prototype.array = Md5.prototype.digest;
+
+	/**
+	 * @method arrayBuffer
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as ArrayBuffer
+	 * @returns {ArrayBuffer} ArrayBuffer
+	 * @see {@link md5.arrayBuffer}
+	 * @example
+	 * hash.arrayBuffer();
+	 */
+	Md5.prototype.arrayBuffer = function () {
+		this.finalize();
+
+		var buffer = new ArrayBuffer(16);
+		var blocks = new Uint32Array(buffer);
+		blocks[0] = this.h0;
+		blocks[1] = this.h1;
+		blocks[2] = this.h2;
+		blocks[3] = this.h3;
+		return buffer;
+	};
+
+	/**
+	 * @method buffer
+	 * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as ArrayBuffer
+	 * @returns {ArrayBuffer} ArrayBuffer
+	 * @see {@link md5.buffer}
+	 * @example
+	 * hash.buffer();
+	 */
+	Md5.prototype.buffer = Md5.prototype.arrayBuffer;
+
+	/**
+	 * @method base64
+	 * @memberof Md5
+	 * @instance
+	 * @description Output hash as base64 string
+	 * @returns {String} base64 string
+	 * @see {@link md5.base64}
+	 * @example
+	 * hash.base64();
+	 */
+	Md5.prototype.base64 = function () {
+		var v1, v2, v3, base64Str = '', bytes = this.array();
+		for (var i = 0; i < 15;) {
+			v1 = bytes[i++];
+			v2 = bytes[i++];
+			v3 = bytes[i++];
+			base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +
+				BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] +
+				BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] +
+				BASE64_ENCODE_CHAR[v3 & 63];
+		}
+		v1 = bytes[i];
+		base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +
+			BASE64_ENCODE_CHAR[(v1 << 4) & 63] +
+			'==';
+		return base64Str;
+	};
+
+	var exports = createMethod();
+
+	if (COMMON_JS) {
+		module.exports = exports;
+	} else {
+		/**
+		 * @method md5
+		 * @description Md5 hash function, export to global in browsers.
+		 * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
+		 * @returns {String} md5 hashes
+		 * @example
+		 * md5(''); // d41d8cd98f00b204e9800998ecf8427e
+		 * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6
+		 * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0
+		 *
+		 * // It also supports UTF-8 encoding
+		 * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07
+		 *
+		 * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`
+		 * md5([]); // d41d8cd98f00b204e9800998ecf8427e
+		 * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e
+		 */
+		root.md5 = exports;
+		if (AMD) {
+			define(function () {
+				return exports;
+			});
+		}
+	}
+})();

+ 111 - 0
src/utils/request/cache/cache.ts

@@ -0,0 +1,111 @@
+
+// @ts-ignore
+import md5 from '../../encryption/md5';
+
+import storage from "$utils/tool/storage";
+
+import { InstructionsCacheType } from '$utils/request/const/request';
+
+export default  class Cache {
+
+	static key:string='cache:'
+
+	// 缓存的数据
+	caches:Record<string, InstructionsCache> = {};
+
+	static sign(requestData:LibRequestOptions) {
+
+		let keys = Object.keys(requestData.data || {}).sort();
+
+		let sign:string = '';
+
+		// 执行 建立 数据记录 合集
+		for (let i = 0, count = keys.length; i < count; i++) {
+			// @ts-ignore
+			let value = requestData.data[keys[i]];
+			if (value === undefined) value = '';
+			sign += keys[i]+':'+value;
+		}
+
+		// 构造唯一值
+		// @ts-ignore
+		return md5(requestData.url +'-'+ sign);
+	}
+
+	// 获取缓存
+	getCache(sign:string,expire:boolean = true):InstructionsCache | undefined{
+
+		// 查看内存是否存在且可以使用
+		if (this.caches[sign]) {
+
+			if (expire && Cache.isExpire(this.caches[sign])) {
+				return this.caches[sign];
+			} else {
+				return this.caches[sign];
+			}
+
+		}
+		// 否则查询缓存
+		else {
+
+			let data:InstructionsCache = storage.getItem(Cache.key+':'+sign);
+
+			if (data) {
+
+				data.first = undefined;
+
+				return this.setCache(sign,data);
+			}
+
+		}
+
+		return undefined;
+
+	}
+
+	// 设置缓存
+	setCache(sign:string,cache:InstructionsCache):InstructionsCache{
+
+		let resultCache:InstructionsCache;
+		if (typeof cache === 'boolean') {
+			resultCache = {};
+		} else {
+			resultCache = {...cache};
+		}
+
+		// 设置过期时间
+		resultCache.expireTime = !resultCache.expireTime || resultCache.expireTime<=0 ? resultCache.expireTime : Cache.getNowTime() + resultCache.expireTime;
+
+		if (this.caches[sign]) {
+			resultCache.first = this.caches[sign].first;
+		}
+		// 设置是否为第一次
+		resultCache.first = resultCache.first === undefined;
+
+		this.caches[sign] = resultCache;
+
+		// 设置缓存
+		if (
+			resultCache.type === undefined || resultCache.type === InstructionsCacheType.storage
+
+		) {
+			if (resultCache.expireTime != null) {
+				storage.setItem(Cache.key + ':' + sign, resultCache, resultCache.expireTime);
+			}
+		}
+
+		return resultCache;
+	}
+
+	// 验证是否过期
+	static isExpire(data:InstructionsCache):boolean {
+		return !data.expireTime || data.expireTime <=0 || Cache.getNowTime() < data.expireTime;
+
+	}
+
+	// 获取当前时间
+	static getNowTime(){
+		return parseInt((new Date().getTime() / 1000).toString());
+	}
+
+}

+ 90 - 0
src/utils/request/cache/index.ts

@@ -0,0 +1,90 @@
+import Cache from './cache';
+
+import instructions from '../instructions/index';
+
+const cache = new Cache();
+
+import {
+    InstructionsWhere,
+    InstructionsTypes,
+    LibRequestStatus,
+} from '../const/request';
+
+instructions.push('cache',{
+    trigger:function (data: LibRequestContext) {
+
+        let sign:string = data.sign ? data.sign : Cache.sign(data.requestData);
+
+        if (!data.sign) {
+            data.sign = sign;
+        }
+
+        // 如果为请求触发
+        if (data.status === LibRequestStatus.loading || data.status === LibRequestStatus.fail) {
+
+            let resultData = cache.getCache(sign);
+
+            if (resultData !== undefined && resultData.data) {
+                data.responseData = JSON.parse(JSON.stringify(resultData.data));
+                // 设置本次属于缓存
+                // @ts-ignore
+                data.responseData.data.isCache = true;
+
+                data.status = LibRequestStatus.success;
+
+                let storageCache = data.requestData.cache;
+
+                delete data.requestData.cache;
+
+                instructions.trigger(data,InstructionsTypes.end);
+
+                if (
+                    data.status === LibRequestStatus.fail
+                    ||
+                    !(
+                        // @ts-ignore
+                        resultData.first && (typeof storageCache === 'boolean' || storageCache.sync === InstructionsCacheSync.first )
+                        ||
+                        // @ts-ignore
+                        typeof storageCache!== 'boolean' && typeof storageCache.sync=== 'function' && storageCache.sync(resultData,data)
+                    )
+                ) {
+
+                    // 退出本次执行
+                    // @ts-ignore
+                    return  data.exit('cache',false);
+                } else {
+                    data.requestData.cache = storageCache;
+                }
+
+            }
+
+        } else{
+
+            let resultData:InstructionsCache;
+            if (typeof data.requestData.cache === 'boolean') {
+                resultData = {};
+            } else {
+                resultData = {...data.requestData.cache};
+            }
+
+            // @ts-ignore
+            if (resultData.where === undefined && data.responseData.data.isSuccess || typeof resultData.where === 'function' && resultData.where(resultData,data)) {
+                // 存储必要参数
+                resultData.data = {
+                    // @ts-ignore
+                    statusCode: data.responseData.statusCode,
+                    // @ts-ignore
+                    data: JSON.parse(JSON.stringify(data.responseData.data))
+                };
+
+                return cache.setCache(sign,resultData);
+            }
+
+        }
+
+    },
+    triggerType:InstructionsTypes.all,
+    zIndex:-8,
+    where:InstructionsWhere.has
+});

+ 18 - 0
src/utils/request/config.ts

@@ -0,0 +1,18 @@
+import config from '$config/config';
+
+import constName from './const';
+
+export default <LibRequestConfig>{
+
+    [constName.mode.default] :{
+        // baseURL:config.baseURL + config.baseApiURL,
+        baseURL: config.baseApiURL,
+
+        method:'POST',
+
+        // header:{
+        //     'content-type':'application/x-www-form-urlencoded; charset=UTF-8'
+        // },
+    }
+
+}

+ 12 - 0
src/utils/request/const/index.ts

@@ -0,0 +1,12 @@
+enum Mode {
+    default,
+    main
+}
+
+export default {
+
+    mode:Mode
+
+}
+
+export {Mode};

+ 47 - 0
src/utils/request/const/request.ts

@@ -0,0 +1,47 @@
+enum InstructionsWhere {
+    has='has',
+    skip='skip',
+    custom='custom',
+    hasCustom='hasCustom'
+}
+
+enum InstructionsCacheSync {
+    first
+}
+
+enum LibRequestStatus {
+    loading,
+    success,
+    fail
+}
+
+enum InstructionsTypes {
+    start='start',
+    end='end',
+    all='all'
+}
+
+enum InstructionsCacheType {
+    storage,
+    memory,
+    all
+}
+
+enum InstructionsMessageType {
+    // 自适应
+    auto,
+    // 仅提示成功
+    success,
+    // 仅提示其他
+    other
+
+}
+
+export {
+    LibRequestStatus,
+    InstructionsTypes,
+    InstructionsWhere,
+    InstructionsCacheSync,
+    InstructionsCacheType,
+    InstructionsMessageType
+}

+ 7 - 0
src/utils/request/format/index.ts

@@ -0,0 +1,7 @@
+
+
+const format = <Record<string, InstructionsFormat>>{
+
+}
+
+export default format;

+ 50 - 0
src/utils/request/index.ts

@@ -0,0 +1,50 @@
+import instructions,{Instructions} from './instructions/index';
+
+import config from "./config";
+
+import constName from './const';
+
+import axios from "axios";
+
+import './cache/index';
+import {LibRequestStatus} from "$utils/request/const/request";
+
+export { LibRequestStatus,InstructionsMessageType,InstructionsCacheType,InstructionsTypes } from "$utils/request/const/request";
+
+// 创建实例化工具
+const requestContent = axios.create(config[constName.mode.default]);
+
+const request = function (data:LibRequestOptions) {
+    return new Promise<ResponseData>(function (resolve, reject) {
+
+        // 创建请求上下文
+
+        let requestContext =Instructions.createRequestContext({
+            requestData: data,
+            reject,
+            resolve,
+            status:LibRequestStatus.loading
+        });
+
+        // 如果前期校验通过触发
+        if (instructions.trigger(requestContext)) {
+            return requestContent(requestContext.requestData).then(function (data){
+                return requestContext.success(data);
+            }).catch(function (fail){
+                return requestContext.fail(fail);
+            });
+        } else {
+            // 否则释放上下文
+            // @ts-ignore
+            requestContext = null;
+        }
+
+    });
+
+}
+
+request.install = function (app:any) {
+    app.config.globalProperties.$request = request;
+};
+
+export default request;

+ 7 - 0
src/utils/request/instructions/index.ts

@@ -0,0 +1,7 @@
+import './plugins/instructions';
+import './plugins/control';
+import instructions,{Instructions} from './plugins/create';
+
+export default instructions;
+
+export {Instructions};

+ 227 - 0
src/utils/request/instructions/instructions.ts

@@ -0,0 +1,227 @@
+import { InstructionsWhere,InstructionsTypes } from '../const/request';
+
+export default class Instructions {
+
+    static options:Array<LibRequestOptionsKeyOf> = ['triggerType','where','zIndex'];
+
+    static defaultOptions:Pick<LibRequestInstructionsObject,LibRequestOptionsKeyOf> = {
+      triggerType: InstructionsTypes.start,
+      where: InstructionsWhere.has,
+      zIndex:0
+    };
+
+    static defaultUnshift:{ [key in InstructionsWhere]?:boolean } = {
+        [InstructionsWhere.skip]:true
+    }
+
+    static NotHas:{ [key in InstructionsWhere]?:boolean } = {
+        [InstructionsWhere.custom]:true
+    }
+
+    // 配置文件表
+    config:{ [key in InstructionsTypes]?:InstructionsTypeConfig} = {
+        [InstructionsTypes.start]:{},
+        [InstructionsTypes.end]:{}
+    };
+
+    constructor(configs?:Record<string, LibRequestInstructions>,options?:LibRequestInstructionsObject) {
+        configs && this.pushConfig(configs,options);
+    }
+
+    // 执行函数列表
+    triggers:Record<string, LibRequestInstructionsObject> = {};
+
+    // 增加添加配置文件
+    pushConfig(data:Record<string, LibRequestInstructions>,options?:LibRequestInstructionsObject):Instructions{
+
+        for (let key in data) {
+            if (data.hasOwnProperty(key)) {
+                this.push(key,data[key],options);
+            }
+        }
+
+        return this;
+    }
+
+    push(name:string,data:LibRequestInstructions,options?:LibRequestInstructionsObject){
+
+        if (this.triggers[name]) return;
+
+        let resultData:LibRequestInstructionsObject;
+
+        if (typeof data === 'function') {
+            resultData = {
+                trigger: data
+            };
+        } else {
+            resultData = data as LibRequestInstructionsObject;
+        }
+
+        for (let i=0,count = Instructions.options.length;i<count;i++) {
+            if (resultData[Instructions.options[i]] === undefined) {
+                // @ts-ignore
+                resultData[Instructions.options[i]] = options && options[Instructions.options[i]] ? options[Instructions.options[i]] : Instructions.defaultOptions[Instructions.options[i]];
+            }
+        }
+
+        let where:InstructionsWhere = resultData.where === undefined && typeof resultData.whereTrigger === 'function' ? InstructionsWhere.hasCustom : resultData.where as InstructionsWhere;
+
+        if (resultData.triggerType === InstructionsTypes.start || resultData.triggerType === InstructionsTypes.all) {
+            this.setTypeWhere(<InstructionsTypeConfig>this.config[InstructionsTypes.start],name,resultData,where);
+        }
+
+        if (resultData.triggerType === InstructionsTypes.end || resultData.triggerType === InstructionsTypes.all) {
+            this.setTypeWhere(<InstructionsTypeConfig>this.config[InstructionsTypes.end],name,resultData,where);
+        }
+
+        this.triggers[name] = resultData;
+    }
+
+    setTypeWhere(data:InstructionsTypeConfig,name:string,resultData:LibRequestInstructionsObject,where:InstructionsWhere){
+
+        if (data.orderObject === undefined) {
+            data.orderObject = {};
+        }
+
+        if (Instructions.defaultUnshift[where]) {
+
+            if (data.unshiftObject === undefined) {
+                data.unshiftObject = {};
+            }
+
+            data.unshiftObject[name] = resultData.zIndex || 999;
+            data.orderObject[name] =  data.unshiftObject[name];
+
+        } else if (resultData.zIndex != null){
+           data.orderObject[name] = resultData.zIndex;
+        }
+
+        if (Instructions.NotHas[where]) {
+            if (data.notHas === undefined) {
+                data.notHas = [name];
+            } else {
+                data.notHas.push(name);
+            }
+        }
+
+
+
+    }
+
+    static createRequestContext(data:LibRequestContext){
+        // 创建执行环境
+        data.execContext = true;
+        // 创建退出函数
+        data.exit = function (name:string,fail:boolean = true) {
+            // 是否提示fail
+            fail && data.reject(<InstructionsExitStatus>{
+                status:-200,
+                msg:name + ':exit',
+                exit:true
+            });
+
+            // 释放所有的事件
+            for (let key in data) {
+                if (data.hasOwnProperty(key)) {
+                    // @ts-ignore
+                    delete data[key];
+                }
+            }
+        }
+
+        return data;
+
+    }
+
+    // 根据配置表 执行配置
+    trigger(data:LibRequestContext,type:InstructionsTypes = InstructionsTypes.start):boolean{
+
+        try {
+            // @ts-ignore
+            let config:InstructionsTypeConfig = this.config[type];
+
+            let resultData:Record<string,number> = {};
+            // 执行前缀合并
+            if (config.unshiftObject) {
+                Object.assign(resultData,config.unshiftObject);
+            }
+            // 执行验证 不需要存在即可执行的定义
+            if (config.notHas) {
+                for (let i=0,count = config.notHas.length;i<count;i++) {
+
+                    if (resultData[config.notHas[i]] === undefined &&
+                        (
+                            // @ts-ignore
+                            this.whereTrigger[this.triggers[config.notHas[i]].where] === undefined
+                            ||
+                            // @ts-ignore
+                            this.whereTrigger[this.triggers[config.notHas[i]].where](config.notHas[i],data,this)
+                        )){
+                        // @ts-ignore
+                        resultData[config.notHas[i]] = config.orderObject[config.notHas[i]];
+                    }
+                }
+            }
+
+            // 构建触发表
+            for (let key in data.requestData) {
+                // @ts-ignore
+                if (data.requestData.hasOwnProperty(key) && resultData[key] === undefined && config.orderObject[key] !== undefined) {
+                    // @ts-ignore
+                    if (!this.whereTrigger[this.triggers[key].where] || this.whereTrigger[this.triggers[key].where](key,data,this)) {
+                        // @ts-ignore
+                        resultData[key] = config.orderObject[key];
+                    }
+                }
+            }
+
+            // 触发data
+            let orderList = Object.keys(resultData).sort(function (a:string,b:string){
+                return resultData[a] > resultData[b] ? -1 : 1;
+            });
+
+            // 执行触发
+            for (let i=0,count=orderList.length;i<count;i++) {
+
+                // 执行
+                // @ts-ignore
+                this.triggers[orderList[i]].trigger(data);
+                if (data.execContext === undefined) return false;
+
+            }
+
+            return data.execContext !== undefined;
+        } catch (e) {
+            console.log(e);
+        }
+
+
+        return  true;
+
+
+
+
+
+    }
+
+    // 触发条件
+    whereTrigger ={
+
+        // 自定义校验
+        [InstructionsWhere.custom]:function(name:string,data:LibRequestContext,config:Instructions){
+
+            if (config.triggers[name] && config.triggers[name].whereTrigger) {
+                // @ts-ignore
+                return config.triggers[name].whereTrigger(data);
+            } else {
+                return false;
+            }
+
+        },
+        // 存在自定义验证
+        [InstructionsWhere.hasCustom]:function(name:string,data:LibRequestContext,config:Instructions){
+            return  this[InstructionsWhere.custom](name,data,config);
+        }
+    }
+
+}

+ 37 - 0
src/utils/request/instructions/plugins/config.ts

@@ -0,0 +1,37 @@
+import constName from '../../const';
+
+export default {
+
+    mode:{
+        [constName.mode.default] :{
+            successCode:[200],
+            pageOption:{
+                page:'page',
+                pageSize:'pageSize'
+            },
+            user:{
+                token:'token'
+            },
+            failMessage:{
+                default: '服务繁忙',
+                timeout: '网络繁忙'
+            }
+        } as RequestConfig,
+        [constName.mode.main]:{
+            successCode: [1]
+        } as RequestConfig
+    },
+
+    // 获取配置
+    getTargetConfig:function (mode:string | undefined,key:keyof RequestConfig) {
+
+        if (mode === undefined) {
+            mode = constName.mode.default as unknown as string;
+        }
+
+        if (this.mode[mode] && this.mode[mode][key]) {
+            return this.mode[mode][key];
+        }
+    }
+
+}

+ 138 - 0
src/utils/request/instructions/plugins/control.ts

@@ -0,0 +1,138 @@
+import instructions from './create';
+
+// import globalConfig from '$config/config';
+
+// import toast from '/tool/toast/index';
+
+import InConfig from './config';
+
+import popup from '$utils/tool/popup';
+
+import {
+    InstructionsWhere,
+    InstructionsTypes,
+    LibRequestStatus,
+    InstructionsMessageType
+} from '../../const/request';
+
+export default instructions.pushConfig({
+
+    failMessage:{
+        trigger:function (data) {
+
+            let {responseData } = data;
+
+            let statusCode:number | string = responseData ? responseData.status : 'timeout';
+
+            // console.log(statusCode);
+
+            let failMessageConfig = InConfig.getTargetConfig(data.requestData.mode,'failMessage');
+
+            return popup.$toast(failMessageConfig[statusCode] || failMessageConfig.default);
+            // return toast.fail(globalConfig.failMessage[statusCode] || globalConfig.failMessage.default);
+        },
+        where:InstructionsWhere.hasCustom,
+        whereTrigger:function (data:LibRequestContext) {
+            return data.status === LibRequestStatus.fail;
+        }
+    },
+
+    format:{
+        trigger:function(data){
+            let {requestData,responseData} = data;
+            let value = requestData.format(responseData.data);
+            if (value !== undefined) {
+                responseData.data = value;
+            }
+        },
+        zIndex:2,
+        where:InstructionsWhere.hasCustom,
+        whereTrigger:function (data) { return data.status === LibRequestStatus.success }
+    },
+
+    successCode:{
+      trigger:function(data){
+
+          let {requestData,responseData} = data;
+
+          let successCode:Array<number> = requestData.successCode || InConfig.getTargetConfig(requestData.mode,'successCode');
+
+          responseData.data.isSuccess = successCode.indexOf(responseData.data.code) >= 0;
+
+      },
+      zIndex:3,
+      where:InstructionsWhere.custom,
+      whereTrigger:function (data) { return data.status === LibRequestStatus.success }
+    },
+
+    message:{
+        trigger:function (data){
+
+            let {requestData,responseData} = data;
+
+            let type:InstructionsMessageType =  typeof requestData.message === 'boolean' ? InstructionsMessageType.auto : requestData.message;
+            let messageType:'success' | 'info';
+
+            if (
+                (type === InstructionsMessageType.auto || type === InstructionsMessageType.success)
+                &&
+                responseData.data.isSuccess
+            ) {
+                messageType = 'success';
+            } else if ((type === InstructionsMessageType.auto || type === InstructionsMessageType.other) && !responseData.data.isSuccess) {
+                messageType = 'info';
+            }
+
+            return messageType && popup.$toast(responseData.data.msg);
+            // return toast[messageType] && toast[messageType](responseData.data.msg);
+        },
+        where: InstructionsWhere.hasCustom,
+        whereTrigger:function (data) { return data.status === LibRequestStatus.success }
+    },
+
+    next:{
+      triggerType:InstructionsTypes.all,
+      trigger:function (data) {
+
+          let {requestData,responseData,status} = data;
+
+          let isSuccess:boolean = false;
+          if (status === LibRequestStatus.success && responseData.data.isSuccess) {
+              isSuccess = true;
+          }
+
+          return requestData.next({
+              status:status === LibRequestStatus.loading,
+              speed:status,
+              isSuccess
+          });
+
+      }
+    },
+
+    successAgent:{
+        trigger(data){
+            return data.resolve(data.responseData.data);
+        },
+        where: InstructionsWhere.custom,
+        whereTrigger:function (data){
+            return data.status === LibRequestStatus.success;
+        },
+        zIndex:-10
+    },
+
+    failAgent:{
+        trigger(data){
+            return data.reject({
+                fail:true,
+                responseData:data.responseData
+            });
+        },
+        where: InstructionsWhere.custom,
+        whereTrigger:function (data){
+            return data.status === LibRequestStatus.fail;
+        },
+        zIndex:-10
+    }
+
+},{triggerType:InstructionsTypes.end})

+ 6 - 0
src/utils/request/instructions/plugins/create.ts

@@ -0,0 +1,6 @@
+import Instructions from '../instructions';
+
+
+export default new Instructions();
+
+export {Instructions};

+ 154 - 0
src/utils/request/instructions/plugins/instructions.ts

@@ -0,0 +1,154 @@
+import instructions from './create';
+
+import config from '../../config';
+
+import InConfig from './config';
+
+// import user from '../../../../user/index';
+
+import {
+    InstructionsWhere,
+    InstructionsTypes,
+    LibRequestStatus
+} from '../../const/request';
+
+import verification from '$utils/verification/index';
+
+import { Mode } from '../../const/index';
+
+export default instructions.pushConfig({
+
+    // 初始化触发
+    default:{
+      where: InstructionsWhere.skip,
+      trigger:function (data){
+
+          if (data.requestData.mode && data.requestData.mode !== Mode.default && config[data.requestData.mode]) {
+
+              let targetConfig:Record<string, any> = config[data.requestData.mode];
+
+              // 执行配置合并
+              data.requestData = {...targetConfig,...data.requestData};
+
+              // 设置 url
+              if (data.requestData.url.indexOf('http') !== 0) {
+                  data.requestData.url = data.requestData.baseURL + data.requestData.url;
+                  delete data.requestData.baseURL;
+              }
+          }
+
+
+      }
+    },
+
+    // 验证
+    verification:{
+        trigger:function (data) {
+
+            let { requestData,exit } = data;
+
+            if (requestData.data) {
+
+                let resultData = verification.verification(requestData.data as LibDataArray,true);
+
+                // 如果验证通过
+                if (resultData.verification) {
+                    // 设置请求 data
+                    requestData.data =  typeof requestData.test === 'function' ? requestData.test(resultData.value) || resultData.value : resultData.value
+
+                } else {
+                    return exit('test fail '+resultData.value);
+                }
+
+            }
+
+        },
+        zIndex:10
+    },
+
+    // 设置token
+    token:function ({requestData}){
+
+        if (requestData.data === undefined) requestData.data = {};
+        requestData.data[InConfig.getTargetConfig(requestData.mode,'user').token ] =  '';
+
+    },
+
+    // 设置分页
+    page:function ({requestData}){
+       if (requestData.data === undefined) requestData.data = {};
+       let pagesOption = InConfig.getTargetConfig(requestData.mode,'pageOption');
+       requestData.data[pagesOption.page] = requestData.page.page;
+       requestData.data[pagesOption.pageSize] = requestData.page.pageSize;
+    },
+
+    // 加载提示
+    // loading:{
+    //   triggerType:InstructionsTypes.all,
+    //   trigger:function ({requestData,status}){
+    //
+    //       console.log(requestData,status);
+    //       // // 首次触发
+    //       // if (status === LibRequestStatus.loading) {
+    //       //
+    //       //     if (typeof requestData.loading === 'string'){
+    //       //         // @ts-ignore
+    //       //         requestData.loading = {title:requestData.loading}
+    //       //     }
+    //       //
+    //       //     let resultLoading:InstructionsLoading = (requestData.loading as InstructionsLoading);
+    //       //
+    //       //     if (resultLoading.delay === undefined || resultLoading.delay > 0){
+    //       //         resultLoading._time = setTimeout( ()=>{
+    //       //             delete resultLoading._time
+    //       //             return this.triggerOpenLoading(resultLoading.title,resultLoading.mask);
+    //       //         },resultLoading.delay || 300);
+    //       //     } else {
+    //       //         return this.triggerOpenLoading(resultLoading.title,resultLoading.mask);
+    //       //     }
+    //       //
+    //       // } else {
+    //       //     let resultLoading:InstructionsLoading = (requestData.loading as InstructionsLoading);
+    //       //     if (resultLoading._time) return clearTimeout(resultLoading._time);
+    //       //     else return  toast.hideLoading();
+    //       // }
+    //
+    //   },
+    //   triggerOpenLoading(title:string,mask:boolean = true){
+    //       // return  toast.loading({
+    //       //     title,
+    //       //     mask
+    //       // });
+    //   },
+    //   zIndex:1
+    // },
+
+    // 结束时触发
+    end:{
+        where:InstructionsWhere.skip,
+        trigger:function (data){
+            /* 配置最终执行代理 */
+            data.success = function (useData:LibRequestResponseData) {
+                data.responseData = useData;
+
+                if (typeof useData.data === 'string') {
+                    try {
+                        useData.data = JSON.parse(useData.data);
+                    } catch (e) {
+
+                    }
+                }
+
+                data.status = useData.status === 200 && typeof useData.data ==='object' ? LibRequestStatus.success : LibRequestStatus.fail;
+                return instructions.trigger(data,InstructionsTypes.end);
+            }
+            data.fail = function (useData:any) {
+                data.responseData = useData;
+                data.status = LibRequestStatus.fail;
+                return instructions.trigger(data,InstructionsTypes.end);
+            }
+        },
+        zIndex:-10
+    }
+
+});

+ 160 - 0
src/utils/request/types/lib.request.d.ts

@@ -0,0 +1,160 @@
+
+interface LibRequestOptions extends LibRequestConfig,LibRequestInstructionsOptions{
+
+    url:string,
+
+    data?:Record<string, any> | LibDataArray,
+
+    formData?:Record<string, any>,
+
+    success?:Function,
+
+    fail?:Function,
+
+    filePath?:string,
+
+    name?:string,
+
+    header?:Record<string, string>,
+
+    merge?:LibRequestMerge,
+
+    // 是否代理
+    agent?:boolean,
+
+    // 模式
+    mode?:Mode
+
+}
+
+interface LibRequestMerge {
+    start:number,
+    end:number
+}
+//
+// declare const enum LibRequestMergeType {
+//     start:
+// }
+
+interface LibRequestConfig {
+
+    // 请求前缀
+    baseURL?:string,
+
+    // 请求头配置
+    header?:Record<string, string>,
+
+    // 默认的请求方式
+    method?: 'GET' | 'POST',
+
+    // 超时时间
+    timeout?:number
+
+}
+
+interface LibRequestResponseData {
+    data:ResponseData;
+    status: number;
+    statusText: string;
+    headers: any;
+    config: AxiosRequestConfig;
+    request?: any;
+}
+
+interface LibRequestContext {
+
+    // 请求Data
+    requestData: LibRequestOptions,
+
+    // 响应Data
+    responseData?: LibRequestResponseData,
+
+    // 执行针
+    execContext?:boolean,
+
+    // 退出执行针
+    exit?:(message:string,fail?:boolean)=>void,
+
+    // 设置运行成功
+    resolve:(data?:Record<string, any>)=>void,
+
+    // 设置运行错误
+    reject:(data?:any)=>void,
+
+    // 当前状态
+    status: LibRequestStatus,
+
+    // 本次请求的唯一值
+    sign?: string,
+
+    // 成功
+    success?:(data:LibRequestResponseData)=>any,
+
+    // 失败
+    fail?:(data:any)=>any
+}
+
+interface InstructionsExitStatus {
+    status: number,
+    exit:boolean,
+    msg:string
+}
+
+type LibRequestOptionsKeyOf = 'triggerType' | 'where' | 'zIndex';
+
+interface LibRequestInstructionsFunction {
+    (data:LibRequestContext):void
+    // 自定义配置
+    [propName:string]:any
+}
+
+interface InstructionsWhereFunction {
+    (data: LibRequestContext): boolean
+}
+
+interface LibRequestInstructionsObject {
+    // 执行函数
+    trigger?: LibRequestInstructionsFunction,
+    // 执行类型
+    triggerType?: InstructionsTypes | any,
+    // 执行条件
+    where?: InstructionsWhere | any,
+    // 触发条件
+    whereTrigger?:InstructionsWhereFunction,
+    // 执行顺序
+    zIndex?:number,
+    // 自定义配置
+    [propName:string]:any
+}
+
+type LibRequestInstructions = LibRequestInstructionsObject | LibRequestInstructionsFunction;
+
+type InstructionsTypeConfigWhere = { [key in InstructionsWhere]?:Array<string> };
+
+interface InstructionsTypeConfig {
+    // [propName:number]: InstructionsTypeConfigWhere
+    orderObject?: Record<string, number>,
+    unshiftObject?: Record<string,number>,
+    notHas?:Array<string>,
+}
+
+
+interface ResponseData {
+
+    code:number,
+
+    msg: string,
+
+    time:number,
+
+    data:any,
+
+    // 是否为成功的状态码
+    isSuccess:boolean,
+
+    // 是否属于缓存
+    isCache:boolean,
+
+    [propName:string]:any
+
+}

+ 81 - 0
src/utils/request/types/lib.request.options.d.ts

@@ -0,0 +1,81 @@
+interface LibRequestInstructionsOptions {
+
+    loading?: string | InstructionsLoading,
+
+    token?:boolean,
+
+    page?: InstructionsPage,
+
+    failMessage?:boolean,
+
+    message?: InstructionsMessageType | boolean,
+
+    successCode?:Array<number>,
+
+    next?:(data:InstructionsNextObject)=>any,
+
+    format?:InstructionsFormat,
+
+    cache?: InstructionsCache | boolean,
+
+    test?:boolean | InstructionsTest
+
+}
+
+
+interface InstructionsTest {
+    (data:Record<string, any>):Record<string, any> | void
+}
+
+interface InstructionsCache {
+    // 存储类型
+    type?: InstructionsCacheType,
+    // 过期时间
+    expireTime?: number,
+    // 什么时候去同步一次接口
+    sync?:any | InstructionsCacheSyncWhere,
+    // 存储的数据
+    data?:LibRequestResponseData,
+    // 是否属于第一次
+    first?:boolean,
+    // 存储的条件是什么
+    where?: InstructionsCacheSyncWhere
+}
+
+interface InstructionsCacheSyncWhere {
+    (data:InstructionsCache,useData:LibRequestContext):boolean
+}
+
+
+interface InstructionsFormat {
+    (data:ResponseData): any
+}
+
+interface InstructionsNextObject {
+    status:boolean,
+    speed:LibRequestStatus,
+    isSuccess: boolean
+}
+
+
+interface InstructionsPage {
+    page:number,
+    pageSize:number
+}
+
+interface InstructionsLoading {
+
+    // 加载文本
+    title:string,
+
+    // 延迟显示的时间
+    delay: number,
+
+    // 默认的透明蒙层
+    mask?:boolean,
+
+    // 计时器
+    _time?:number
+
+}
+

+ 30 - 0
src/utils/request/types/request.config.d.ts

@@ -0,0 +1,30 @@
+interface RequestConfig {
+
+    // 成功的状态码
+    successCode:Array<number>,
+
+    // 数据模版
+    dataTemplate?:Record<string, string | RequestConfigTemplate>,
+
+    // 执行url
+    baseURL?:string,
+
+    // 分页标签
+    pageOption?:{
+        page:string,
+        pageSize:string
+    },
+
+    // 用户 配置
+    user?:{
+        token:string
+    },
+
+    // 描述
+    failMessage?:Record<string, string>
+
+}
+
+interface RequestConfigTemplate {
+    (item:any,key:any,data:any):any
+}

+ 19 - 0
src/utils/tool/popup.ts

@@ -0,0 +1,19 @@
+export default <Record<string, LibMixinsMethod | any>>{
+
+    $popup:undefined,
+
+    // 提示弹窗
+    $toast:function (option:PopupToastOptions) {
+
+        let resultOption:PopupToastOptions;
+
+        if (typeof option === 'string') {
+            resultOption={title:option}
+        } else {
+            resultOption=option;
+        }
+
+        return this.$popup && this.$popup.open('toast',resultOption);
+    }
+
+}

+ 83 - 0
src/utils/tool/storage.ts

@@ -0,0 +1,83 @@
+import encryption from '../encryption/encryption';
+export default {
+
+	storage:localStorage,
+
+	setItem:function(key: string, value: any, time: number){
+
+		time = time || -1;
+
+		let data = {
+			data:value,
+			time: time>0?this.get_time() + time:time,
+		};
+
+		//设置 缓存
+		this.storage.setItem(key,this.stringify(data));
+
+	},
+
+	removeItem:function(key: string){
+		this.storage.removeItem(key);
+	},
+
+	getItem:function (key: string) {
+
+		let data = this.storage.getItem(key);
+
+		if (!data) {
+			return null;
+		}else {
+
+			if (typeof data === 'string'){
+				data = this.parse(data);
+			} else {
+				return data;
+			}
+
+			if (!data)  return null;
+
+			// @ts-ignore
+			if (data['time']){
+				// @ts-ignore
+				if (data['time'] < 0){
+					// @ts-ignore
+					return data.data;
+					// @ts-ignore
+				} else if (this.get_time() < data['time']) {
+					// @ts-ignore
+					return data.data;
+				} else {
+					this.removeItem(key);
+					return null;
+				}
+
+			} else {
+				// @ts-ignore
+				return data.data;
+			}
+
+		}
+
+	},
+
+	get_time:function(){
+		// @ts-ignore
+		return Math.floor(Date.parse(new Date())/1000)
+	},
+
+	stringify:function (data: any) {
+		return encryption.encode(JSON.stringify(data));
+	},
+
+	parse:function (data: string) {
+		try {
+			data = encryption.decode(data);
+			data = JSON.parse(data);
+			return data;
+		} catch (e) {
+			return null;
+		}
+	}
+
+}

+ 13 - 0
src/utils/tool/type.ts

@@ -0,0 +1,13 @@
+export default {
+
+    // 判断是否为object
+    isObject(data:any):boolean{
+        return  Object.prototype.toString.call(data) === '[object Object]';
+    },
+
+    // 判断是否为array
+    isArray(data:any):boolean {
+        return  Object.prototype.toString.call(data) === '[object Array]';
+    }
+
+}

+ 1 - 1
src/utils/tool/url.ts

@@ -1,4 +1,4 @@
-import $config from '$config/index.ts';
+import $config from '$config/index';
 export default {
 
     addBaseURL(url:string,baseURL:string=$config.baseURL):string{

+ 10 - 0
src/utils/verification/config.ts

@@ -0,0 +1,10 @@
+export default {
+
+    // 处理
+    trim:function(value:any){
+        value = value || '';
+        if (typeof value !== 'string')  value +='';
+        return value.replace(/^\s*|\s*$/,'');
+    }
+
+}

+ 12 - 0
src/utils/verification/const/index.ts

@@ -0,0 +1,12 @@
+enum VerificationType {
+    // 是否为空
+    empty,
+    // 手机号
+    mobile,
+    // 密码
+    password,
+    // 是否相等
+    eq,
+}
+
+export { VerificationType };

+ 155 - 0
src/utils/verification/index.ts

@@ -0,0 +1,155 @@
+import config from './config';
+
+import type from '$utils/tool/type';
+
+import { VerificationType } from './const';
+
+import popup from '$utils/tool/popup';
+
+export default {
+
+    trigger:{
+
+        [VerificationType.empty]: function(value){
+            if (value === undefined || value===null || value !== value){
+                return false;
+            } else if (typeof value === 'string') {
+
+                value = config.trim(value);
+
+                return value !== '';
+
+            } else {
+                return true;
+            }
+        },
+
+        // 手机号验证
+        [VerificationType.mobile]:function(value:any){
+            if (!value || typeof value === 'object') return false;
+            else value = String(value);
+            return /^1\d{10}$/.test(value);
+        },
+
+        // 是否相等
+        [VerificationType.eq]:function(value:any,item:LibData){
+            if (item.rulesOption && item.rulesOption.data) {
+                return  item.rulesOption.data.value === value;
+            }
+            return false;
+        },
+
+        // 密码
+        [VerificationType.password]:function(value){
+            if (value && typeof  value === 'string') {
+                return /[^\u4E00-\u9FA5]{6,16}/.test(value);
+            }
+            return false;
+        },
+
+
+    } as VerificationTrigger,
+
+    // 校验item
+    verificationItem: function (data: LibData, toast: boolean | string): VerificationResult {
+
+        if (data.rules !== undefined) {
+
+            let resultRules: Record<VerificationType, string>;
+            if (typeof data.rules === 'string') {
+                // @ts-ignore
+                resultRules = {[VerificationType.empty]: data.rules}
+            } else {
+                resultRules = data.rules;
+            }
+
+            for (let key in resultRules) {
+
+                // @ts-ignore
+                if (resultRules.hasOwnProperty(key) && this.trigger[key] && !this.trigger[key](data.value, data)) {
+
+                    // @ts-ignore
+                    let value = resultRules[key] || data.placeholder || data.label;
+
+                    // 如果不通过,是否自动提示
+                    if (toast) {
+                        return popup.$toast(value);
+                        // let rulesToast = typeof toast === 'boolean' ? 'info' : toast;
+                        // if (toastModal[rulesToast]) {
+                        //     toastModal[rulesToast](value);
+                        // }
+                    }
+
+                    return {
+                        verification: false,
+                        value,
+                        type: key as unknown as VerificationType
+                    }
+                }
+            }
+
+            return {
+                verification: true,
+                value: data.value
+            }
+
+
+        }
+
+        return {
+            verification: true,
+            value: data.value
+        }
+
+    },
+
+    // 校验
+    verification(data:LibData | LibDataArray,toast:boolean|string):VerificationResult{
+
+        let resultData:LibDataArray;
+        if (type.isObject(data)) resultData = [data as LibData];
+        else resultData = data as LibDataArray;
+
+        let result:Record<string, any> = {};
+
+        for (let i=0,count=resultData.length;i<count;i++) {
+
+            let useResult:VerificationResult = this.verificationItem(resultData[i],toast);
+
+            if (!useResult.verification) {
+                return useResult;
+            } else {
+
+                let useKey = resultData[i].exportKey || resultData[i].key;
+
+                if (useKey) {
+                    result[useKey] = useResult.value;
+                }
+
+            }
+
+        }
+
+        return {
+            verification:true,
+            value:result
+        }
+
+
+    },
+
+    // 校验返回 Promise
+    verificationPromise(data:LibData | LibDataArray,toast:boolean|string):Promise<Record<string, any>>{
+
+        return  new Promise<Record<string, any>>( (resolve,reject)=>{
+            let result:VerificationResult = this.verification(data,toast);
+            return result.verification ? resolve(result.value) : reject(result.value);
+        });
+
+    },
+
+}
+
+export {
+    VerificationType
+}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio