Browse Source

短信验证码:登录,找回密码

lrf 6 months ago
parent
commit
0471cbec26

+ 355 - 0
package-lock.json

@@ -9,6 +9,7 @@
       "version": "1.0.0",
       "license": "MIT",
       "dependencies": {
+        "@alicloud/dysmsapi20170525": "^3.0.0",
         "@midwayjs/axios": "^3.16.5",
         "@midwayjs/bootstrap": "^3.12.0",
         "@midwayjs/core": "^3.12.0",
@@ -69,6 +70,109 @@
       "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
       "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
     },
+    "node_modules/@alicloud/credentials": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/@alicloud/credentials/-/credentials-2.3.1.tgz",
+      "integrity": "sha512-FK8N1YNVqUGOl7qOFn8h3zTwv2Tj8ON3459XXnJkAa08YBECj8o/V81D/ubxpX0yZub4RVKjknxNSHEbrASc+A==",
+      "dependencies": {
+        "@alicloud/tea-typescript": "^1.5.3",
+        "httpx": "^2.2.0",
+        "ini": "^1.3.5",
+        "kitx": "^2.0.0"
+      }
+    },
+    "node_modules/@alicloud/credentials/node_modules/ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+    },
+    "node_modules/@alicloud/dysmsapi20170525": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/@alicloud/dysmsapi20170525/-/dysmsapi20170525-3.0.0.tgz",
+      "integrity": "sha512-d2Wp5Cxx30As8STvUFys8L6aPTVm2U+xhDLDRMPEB3H5lYFlREixHPn4vu6s8kaTGUNPHuCOD0I940Z9jaApSA==",
+      "dependencies": {
+        "@alicloud/endpoint-util": "^0.0.1",
+        "@alicloud/openapi-client": "^0.4.10",
+        "@alicloud/openapi-util": "^0.3.2",
+        "@alicloud/tea-typescript": "^1.7.1",
+        "@alicloud/tea-util": "^1.4.8"
+      }
+    },
+    "node_modules/@alicloud/endpoint-util": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/@alicloud/endpoint-util/-/endpoint-util-0.0.1.tgz",
+      "integrity": "sha512-+pH7/KEXup84cHzIL6UJAaPqETvln4yXlD9JzlrqioyCSaWxbug5FUobsiI6fuUOpw5WwoB3fWAtGbFnJ1K3Yg==",
+      "dependencies": {
+        "@alicloud/tea-typescript": "^1.5.1",
+        "kitx": "^2.0.0"
+      }
+    },
+    "node_modules/@alicloud/gateway-spi": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmmirror.com/@alicloud/gateway-spi/-/gateway-spi-0.0.8.tgz",
+      "integrity": "sha512-KM7fu5asjxZPmrz9sJGHJeSU+cNQNOxW+SFmgmAIrITui5hXL2LB+KNRuzWmlwPjnuA2X3/keq9h6++S9jcV5g==",
+      "dependencies": {
+        "@alicloud/credentials": "^2",
+        "@alicloud/tea-typescript": "^1.7.1"
+      }
+    },
+    "node_modules/@alicloud/openapi-client": {
+      "version": "0.4.11",
+      "resolved": "https://registry.npmmirror.com/@alicloud/openapi-client/-/openapi-client-0.4.11.tgz",
+      "integrity": "sha512-WEDGbfSx4Lcjj7ij3fv+6HBDua3l0tMGott6jaFO+pI42ctTJlK/y/AcyjFGwrf1UCQneauI2gEo6+5hHbv4Bg==",
+      "dependencies": {
+        "@alicloud/credentials": "^2",
+        "@alicloud/gateway-spi": "^0.0.8",
+        "@alicloud/openapi-util": "^0.3.2",
+        "@alicloud/tea-typescript": "^1.7.1",
+        "@alicloud/tea-util": "^1.4.9",
+        "@alicloud/tea-xml": "0.0.3"
+      }
+    },
+    "node_modules/@alicloud/openapi-util": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/@alicloud/openapi-util/-/openapi-util-0.3.2.tgz",
+      "integrity": "sha512-EC2JvxdcOgMlBAEG0+joOh2IB1um8CPz9EdYuRfTfd1uP8Yc9D8QRUWVGjP6scnj6fWSOaHFlit9H6PrJSyFow==",
+      "dependencies": {
+        "@alicloud/tea-typescript": "^1.7.1",
+        "@alicloud/tea-util": "^1.3.0",
+        "kitx": "^2.1.0",
+        "sm3": "^1.0.3"
+      }
+    },
+    "node_modules/@alicloud/tea-typescript": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmmirror.com/@alicloud/tea-typescript/-/tea-typescript-1.8.0.tgz",
+      "integrity": "sha512-CWXWaquauJf0sW30mgJRVu9aaXyBth5uMBCUc+5vKTK1zlgf3hIqRUjJZbjlwHwQ5y9anwcu18r48nOZb7l2QQ==",
+      "dependencies": {
+        "@types/node": "^12.0.2",
+        "httpx": "^2.2.6"
+      }
+    },
+    "node_modules/@alicloud/tea-typescript/node_modules/@types/node": {
+      "version": "12.20.55",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-12.20.55.tgz",
+      "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
+    },
+    "node_modules/@alicloud/tea-util": {
+      "version": "1.4.9",
+      "resolved": "https://registry.npmmirror.com/@alicloud/tea-util/-/tea-util-1.4.9.tgz",
+      "integrity": "sha512-S0wz76rGtoPKskQtRTGqeuqBHFj8BqUn0Vh+glXKun2/9UpaaaWmuJwcmtImk6bJZfLYEShDF/kxDmDJoNYiTw==",
+      "dependencies": {
+        "@alicloud/tea-typescript": "^1.5.1",
+        "kitx": "^2.0.0"
+      }
+    },
+    "node_modules/@alicloud/tea-xml": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmmirror.com/@alicloud/tea-xml/-/tea-xml-0.0.3.tgz",
+      "integrity": "sha512-+/9GliugjrLglsXVrd1D80EqqKgGpyA0eQ6+1ZdUOYCaRguaSwz44trX3PaxPu/HhIPJg9PsGQQ3cSLXWZjbAA==",
+      "dependencies": {
+        "@alicloud/tea-typescript": "^1",
+        "@types/xml2js": "^0.4.5",
+        "xml2js": "^0.6.0"
+      }
+    },
     "node_modules/@ampproject/remapping": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -1944,6 +2048,14 @@
         "@types/superagent": "*"
       }
     },
+    "node_modules/@types/xml2js": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmmirror.com/@types/xml2js/-/xml2js-0.4.14.tgz",
+      "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/yargs": {
       "version": "17.0.32",
       "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.32.tgz",
@@ -5096,6 +5208,23 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/httpx": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmmirror.com/httpx/-/httpx-2.3.2.tgz",
+      "integrity": "sha512-ZG7QArW/BB/opy+XVp/zSJYdiPD9FTmPb3VfMnPdAknKFJq2OiIXS9D4oBeDJvWnZnJAzXDy9J/JKATXkJ7qlw==",
+      "dependencies": {
+        "@types/node": "^20",
+        "debug": "^4.1.1"
+      }
+    },
+    "node_modules/httpx/node_modules/@types/node": {
+      "version": "20.16.5",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.16.5.tgz",
+      "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
+      "dependencies": {
+        "undici-types": "~6.19.2"
+      }
+    },
     "node_modules/human-signals": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz",
@@ -6352,6 +6481,19 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/kitx": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/kitx/-/kitx-2.1.0.tgz",
+      "integrity": "sha512-C/5v9MtIX7aHGOjwn5BmrrbNkJSf7i0R5mRzmh13GSAdRqQ7bYQo/Su2pTYNylFicqKNTVX3HML9k1u8k51+pQ==",
+      "dependencies": {
+        "@types/node": "^12.0.2"
+      }
+    },
+    "node_modules/kitx/node_modules/@types/node": {
+      "version": "12.20.55",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-12.20.55.tgz",
+      "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
+    },
     "node_modules/kleur": {
       "version": "3.0.3",
       "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz",
@@ -8278,6 +8420,11 @@
       "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
+    "node_modules/sax": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
+      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+    },
     "node_modules/saxes": {
       "version": "5.0.1",
       "resolved": "https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz",
@@ -8432,6 +8579,11 @@
         "url": "https://github.com/chalk/slice-ansi?sponsor=1"
       }
     },
+    "node_modules/sm3": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/sm3/-/sm3-1.0.3.tgz",
+      "integrity": "sha512-KyFkIfr8QBlFG3uc3NaljaXdYcsbRy1KrSfc4tsQV8jW68jAktGeOcifu530Vx/5LC+PULHT0Rv8LiI8Gw+c1g=="
+    },
     "node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
@@ -9257,6 +9409,11 @@
         "node": ">=4.2.0"
       }
     },
+    "node_modules/undici-types": {
+      "version": "6.19.8",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz",
+      "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
+    },
     "node_modules/unique-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/unique-string/-/unique-string-2.0.0.tgz",
@@ -9580,6 +9737,26 @@
         "node": ">=8"
       }
     },
+    "node_modules/xml2js": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.6.2.tgz",
+      "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
     "node_modules/xmlchars": {
       "version": "2.2.0",
       "resolved": "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz",
@@ -9712,6 +9889,113 @@
         }
       }
     },
+    "@alicloud/credentials": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/@alicloud/credentials/-/credentials-2.3.1.tgz",
+      "integrity": "sha512-FK8N1YNVqUGOl7qOFn8h3zTwv2Tj8ON3459XXnJkAa08YBECj8o/V81D/ubxpX0yZub4RVKjknxNSHEbrASc+A==",
+      "requires": {
+        "@alicloud/tea-typescript": "^1.5.3",
+        "httpx": "^2.2.0",
+        "ini": "^1.3.5",
+        "kitx": "^2.0.0"
+      },
+      "dependencies": {
+        "ini": {
+          "version": "1.3.8",
+          "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz",
+          "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+        }
+      }
+    },
+    "@alicloud/dysmsapi20170525": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/@alicloud/dysmsapi20170525/-/dysmsapi20170525-3.0.0.tgz",
+      "integrity": "sha512-d2Wp5Cxx30As8STvUFys8L6aPTVm2U+xhDLDRMPEB3H5lYFlREixHPn4vu6s8kaTGUNPHuCOD0I940Z9jaApSA==",
+      "requires": {
+        "@alicloud/endpoint-util": "^0.0.1",
+        "@alicloud/openapi-client": "^0.4.10",
+        "@alicloud/openapi-util": "^0.3.2",
+        "@alicloud/tea-typescript": "^1.7.1",
+        "@alicloud/tea-util": "^1.4.8"
+      }
+    },
+    "@alicloud/endpoint-util": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/@alicloud/endpoint-util/-/endpoint-util-0.0.1.tgz",
+      "integrity": "sha512-+pH7/KEXup84cHzIL6UJAaPqETvln4yXlD9JzlrqioyCSaWxbug5FUobsiI6fuUOpw5WwoB3fWAtGbFnJ1K3Yg==",
+      "requires": {
+        "@alicloud/tea-typescript": "^1.5.1",
+        "kitx": "^2.0.0"
+      }
+    },
+    "@alicloud/gateway-spi": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmmirror.com/@alicloud/gateway-spi/-/gateway-spi-0.0.8.tgz",
+      "integrity": "sha512-KM7fu5asjxZPmrz9sJGHJeSU+cNQNOxW+SFmgmAIrITui5hXL2LB+KNRuzWmlwPjnuA2X3/keq9h6++S9jcV5g==",
+      "requires": {
+        "@alicloud/credentials": "^2",
+        "@alicloud/tea-typescript": "^1.7.1"
+      }
+    },
+    "@alicloud/openapi-client": {
+      "version": "0.4.11",
+      "resolved": "https://registry.npmmirror.com/@alicloud/openapi-client/-/openapi-client-0.4.11.tgz",
+      "integrity": "sha512-WEDGbfSx4Lcjj7ij3fv+6HBDua3l0tMGott6jaFO+pI42ctTJlK/y/AcyjFGwrf1UCQneauI2gEo6+5hHbv4Bg==",
+      "requires": {
+        "@alicloud/credentials": "^2",
+        "@alicloud/gateway-spi": "^0.0.8",
+        "@alicloud/openapi-util": "^0.3.2",
+        "@alicloud/tea-typescript": "^1.7.1",
+        "@alicloud/tea-util": "^1.4.9",
+        "@alicloud/tea-xml": "0.0.3"
+      }
+    },
+    "@alicloud/openapi-util": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/@alicloud/openapi-util/-/openapi-util-0.3.2.tgz",
+      "integrity": "sha512-EC2JvxdcOgMlBAEG0+joOh2IB1um8CPz9EdYuRfTfd1uP8Yc9D8QRUWVGjP6scnj6fWSOaHFlit9H6PrJSyFow==",
+      "requires": {
+        "@alicloud/tea-typescript": "^1.7.1",
+        "@alicloud/tea-util": "^1.3.0",
+        "kitx": "^2.1.0",
+        "sm3": "^1.0.3"
+      }
+    },
+    "@alicloud/tea-typescript": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmmirror.com/@alicloud/tea-typescript/-/tea-typescript-1.8.0.tgz",
+      "integrity": "sha512-CWXWaquauJf0sW30mgJRVu9aaXyBth5uMBCUc+5vKTK1zlgf3hIqRUjJZbjlwHwQ5y9anwcu18r48nOZb7l2QQ==",
+      "requires": {
+        "@types/node": "^12.0.2",
+        "httpx": "^2.2.6"
+      },
+      "dependencies": {
+        "@types/node": {
+          "version": "12.20.55",
+          "resolved": "https://registry.npmmirror.com/@types/node/-/node-12.20.55.tgz",
+          "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
+        }
+      }
+    },
+    "@alicloud/tea-util": {
+      "version": "1.4.9",
+      "resolved": "https://registry.npmmirror.com/@alicloud/tea-util/-/tea-util-1.4.9.tgz",
+      "integrity": "sha512-S0wz76rGtoPKskQtRTGqeuqBHFj8BqUn0Vh+glXKun2/9UpaaaWmuJwcmtImk6bJZfLYEShDF/kxDmDJoNYiTw==",
+      "requires": {
+        "@alicloud/tea-typescript": "^1.5.1",
+        "kitx": "^2.0.0"
+      }
+    },
+    "@alicloud/tea-xml": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmmirror.com/@alicloud/tea-xml/-/tea-xml-0.0.3.tgz",
+      "integrity": "sha512-+/9GliugjrLglsXVrd1D80EqqKgGpyA0eQ6+1ZdUOYCaRguaSwz44trX3PaxPu/HhIPJg9PsGQQ3cSLXWZjbAA==",
+      "requires": {
+        "@alicloud/tea-typescript": "^1",
+        "@types/xml2js": "^0.4.5",
+        "xml2js": "^0.6.0"
+      }
+    },
     "@ampproject/remapping": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -11228,6 +11512,14 @@
         "@types/superagent": "*"
       }
     },
+    "@types/xml2js": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmmirror.com/@types/xml2js/-/xml2js-0.4.14.tgz",
+      "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/yargs": {
       "version": "17.0.32",
       "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.32.tgz",
@@ -13505,6 +13797,25 @@
         "toidentifier": "1.0.1"
       }
     },
+    "httpx": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmmirror.com/httpx/-/httpx-2.3.2.tgz",
+      "integrity": "sha512-ZG7QArW/BB/opy+XVp/zSJYdiPD9FTmPb3VfMnPdAknKFJq2OiIXS9D4oBeDJvWnZnJAzXDy9J/JKATXkJ7qlw==",
+      "requires": {
+        "@types/node": "^20",
+        "debug": "^4.1.1"
+      },
+      "dependencies": {
+        "@types/node": {
+          "version": "20.16.5",
+          "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.16.5.tgz",
+          "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
+          "requires": {
+            "undici-types": "~6.19.2"
+          }
+        }
+      }
+    },
     "human-signals": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz",
@@ -14457,6 +14768,21 @@
       "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
       "dev": true
     },
+    "kitx": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/kitx/-/kitx-2.1.0.tgz",
+      "integrity": "sha512-C/5v9MtIX7aHGOjwn5BmrrbNkJSf7i0R5mRzmh13GSAdRqQ7bYQo/Su2pTYNylFicqKNTVX3HML9k1u8k51+pQ==",
+      "requires": {
+        "@types/node": "^12.0.2"
+      },
+      "dependencies": {
+        "@types/node": {
+          "version": "12.20.55",
+          "resolved": "https://registry.npmmirror.com/@types/node/-/node-12.20.55.tgz",
+          "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="
+        }
+      }
+    },
     "kleur": {
       "version": "3.0.3",
       "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz",
@@ -15906,6 +16232,11 @@
       "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
+    "sax": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
+      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+    },
     "saxes": {
       "version": "5.0.1",
       "resolved": "https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz",
@@ -16024,6 +16355,11 @@
         "is-fullwidth-code-point": "^3.0.0"
       }
     },
+    "sm3": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/sm3/-/sm3-1.0.3.tgz",
+      "integrity": "sha512-KyFkIfr8QBlFG3uc3NaljaXdYcsbRy1KrSfc4tsQV8jW68jAktGeOcifu530Vx/5LC+PULHT0Rv8LiI8Gw+c1g=="
+    },
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
@@ -16567,6 +16903,11 @@
       "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
       "dev": true
     },
+    "undici-types": {
+      "version": "6.19.8",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz",
+      "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
+    },
     "unique-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/unique-string/-/unique-string-2.0.0.tgz",
@@ -16809,6 +17150,20 @@
       "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
       "dev": true
     },
+    "xml2js": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.6.2.tgz",
+      "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+      "requires": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      }
+    },
+    "xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+    },
     "xmlchars": {
       "version": "2.2.0",
       "resolved": "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz",

+ 1 - 0
package.json

@@ -4,6 +4,7 @@
   "description": "",
   "private": true,
   "dependencies": {
+    "@alicloud/dysmsapi20170525": "^3.0.0",
     "@midwayjs/axios": "^3.16.5",
     "@midwayjs/bootstrap": "^3.12.0",
     "@midwayjs/core": "^3.12.0",

+ 8 - 0
src/config/config.default.ts

@@ -21,4 +21,12 @@ export default {
     path: 'C:\\temp\\cxyy\\',
   },
   showDBSub: false,
+  loginSmsSign: 'LoginSmsSign',
+  pwdSmsSign:'PasswordSmsSign',
+  aliyunSms: {
+    template: 'SMS_275370127', //模板code
+    sign: '吉林省华欣数字科技股份', //签名
+    AccessKey_ID: 'LTAI5tDGzajxW6oDiTBvKB53',
+    AccessKey_Secret: 'woGAW31X6PuzaE2O1fawwFCxfWMsfw',
+  },
 } as MidwayConfig;

+ 6 - 1
src/controller/home.controller.ts

@@ -4,6 +4,7 @@ import { InitSystemDataService } from '../service/initData/initSystemData.servic
 import { ExportConfigService } from '../service/exportConfig.service';
 import { ExportMissionService } from '../service/exportMission.service';
 import { AsyncExportService } from '../service/asyncExport.service';
+import { AliyunSmsService } from '../service/thirdParty/aliyunSms.service';
 @Controller('/')
 export class HomeController {
   @Inject()
@@ -15,11 +16,15 @@ export class HomeController {
   aeService: AsyncExportService;
   Opera = Opera;
 
+  @Inject()
+  smsService: AliyunSmsService;
+
   @Get('/')
   async home(@Query() query: object): Promise<any> {
     // await this.ec.initData()
     // await this.missionService.toSendMq(1);
-    await this.aeService.execute(11)
+    // await this.aeService.execute(11);
+    // await this.smsService.send('13089419810', '2234');
     return 'starting...';
   }
   // @Get('/:method')

+ 70 - 0
src/controller/login.controller.ts

@@ -7,6 +7,8 @@ import { Context } from '@midwayjs/koa';
 const assert = require('assert');
 import get = require('lodash/get');
 import { UtilService } from '../service/util.service';
+import { UserService } from '../service/system/user.service';
+import { ErrorCode, ServiceError } from '../error/service.error';
 
 @ApiTags(['登录服务'])
 @Controller('/login')
@@ -17,12 +19,80 @@ export class LoginController {
   jwtService: JwtService;
   @Inject()
   utilService: UtilService;
+  @Inject()
+  userSerivce: UserService;
   @Config('jwt.secret')
   jwtSecret;
   @Config('jwt.expiresIn')
   jwtExpiresIn;
   @Inject()
   ctx: Context;
+
+  @Post('/pwd/reset', { routerName: '用户忘记密码-重置密码' })
+  async pwdReset(@Body('id') id: number, @Body('password') password: string) {
+    if (!id || !password) throw new ServiceError(ErrorCode.BODY_ERROR);
+    // 检查是否有该用户
+    const user = await this.userSerivce.fetch({ id }, { id: this.userSerivce.Opera.Equal });
+    if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
+    await this.userSerivce.update({ id }, { password });
+  }
+
+  @Post('/pwd/check', { routerName: '用户忘记密码-验证码验证' })
+  async pwdCodeCheck(@Body() body: object) {
+    const type = get(body, 'type');
+    const to = get(body, 'to');
+    const code = get(body, 'checkCode');
+    if (!code) throw new ServiceError(ErrorCode.PWD_NO_CODE); // 缺少密码找回验证码
+    if (!type) throw new ServiceError(ErrorCode.PWD_NO_TYPE); //缺少找回方式
+    else if (type !== 'phone' && type !== 'email') throw new ServiceError(ErrorCode.PWD_ERROR_TYPE); // 找回方式错误
+    if (type === 'phone' && !to) throw new ServiceError(ErrorCode.PWD_NO_PHONE); // 缺少手机号码
+    else if (type === 'email' && !to) throw new ServiceError(ErrorCode.PWD_NO_EMAIL); //缺少邮箱地址
+    await this.loginService.checkPwdCode(type, to, code);
+    // 检查是否有该用户
+    const user = await this.userSerivce.fetch({ [type]: to }, { phone: this.userSerivce.Opera.Equal, email: this.userSerivce.Opera.Equal });
+    if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
+    // 将id返回给前端,直接做修改密码用
+    const id = get(user, 'id');
+    return id;
+  }
+
+  @Post('/pwd/code', { routerName: '用户忘记密码-获取验证码' })
+  async getPwdCode(@Body() body: object) {
+    const type = get(body, 'type');
+    const to = get(body, 'to');
+    if (!type) throw new ServiceError(ErrorCode.PWD_NO_TYPE); //缺少找回方式
+    else if (type !== 'phone' && type !== 'email') throw new ServiceError(ErrorCode.PWD_ERROR_TYPE); // 找回方式错误
+    if (type === 'phone' && !to) throw new ServiceError(ErrorCode.PWD_NO_PHONE); // 缺少手机号码
+    else if (type === 'email' && !to) throw new ServiceError(ErrorCode.PWD_NO_EMAIL); //缺少邮箱地址
+    // 检查是否有该用户
+    const user = await this.userSerivce.fetch({ [type]: to }, { phone: this.userSerivce.Opera.Equal, email: this.userSerivce.Opera.Equal });
+    if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
+    // 有用户再发
+    await this.loginService.sendPwdCode(type, to);
+  }
+
+  @Post('/sms/code', { routerName: '用户登录-获取登录验证码' })
+  async getSmsCode(@Body('phone') phone: string) {
+    // 先用phone找下用户,没有先返回去
+    const user = await this.userSerivce.fetch({ phone }, { phone: this.userSerivce.Opera.Equal });
+    if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
+    await this.loginService.sendSmsLoginCode(phone);
+  }
+
+  @Post('/sms/login', { routerName: '用户登录-通过手机验证码登录' })
+  async smsLogin(@Body() body: object) {
+    await this.loginService.valiSmsCode(body);
+    // 没有中断,就是没有问题,直接通过phone查出来用户然后返回
+    const phone = get(body, 'phone');
+    const user = await this.userSerivce.fetch({ phone }, { phone: this.userSerivce.Opera.Equal });
+    user.role = [LoginType.User];
+    let vo = new LoginVO(user);
+    vo = JSON.parse(JSON.stringify(vo));
+    vo.login_code = await this.loginService.onePointLogin(vo);
+    const token = await this.jwtService.sign(vo, this.jwtSecret);
+    return token;
+  }
+
   /**
    * 账密登录
    * @param data 用户名和密码

+ 12 - 1
src/error/service.error.ts

@@ -17,8 +17,19 @@ export enum ErrorCode {
   SERVICE_END = 'SERVICE_END',
   DUPLICATE_USERS_ACCOUNT = 'DUPLICATE_USERS_ACCOUNT',
   DUPLICATE_USERS_OPENID = 'DUPLICATE_USERS_OPENID',
-
   PHONE_IS_EXISTS = 'PHONE_IS_EXISTS',
+  LOGIN_VALICODE_EXPIRES = 'LOGIN_VALICODE_EXPIRES',
+  LOGIN_VALICODE_ERROR = 'LOGIN_VALICODE_ERROR',
+  PLEASE_INPUT_LOGIN_CODE = 'PLEASE_INPUT_LOGIN_CODE',
+  PLEASE_INPUT_LOGIN_PHONE = 'PLEASE_INPUT_LOGIN_PHONE',
+  LOGIN_VALICODE_IS_EXISTS = 'LOGIN_VALICODE_IS_EXISTS',
+  PWD_NO_TYPE = 'PWD_NO_TYPE',
+  PWD_ERROR_TYPE = 'PWD_ERROR_TYPE',
+  PWD_NO_PHONE = 'PWD_NO_PHONE',
+  PWD_NO_EMAIL = 'PWD_NO_EMAIL',
+  PWD_NO_CODE = 'PWD_NO_CODE',
+  PWD_VALICODE_EXPIRES = 'PWD_VALICODE_EXPIRES',
+  PWD_VALICODE_ERROR = 'PWD_VALICODE_ERROR',
 
   // 参数
   ID_NOT_FOUND = 'ID_NOT_FOUND',

+ 80 - 1
src/service/login.service.ts

@@ -1,5 +1,5 @@
 import { Config, Inject, Provide } from '@midwayjs/core';
-import { get } from 'lodash';
+import { get, random } from 'lodash';
 import { RoleService } from '../service/system/role.service';
 import { RedisService } from '@midwayjs/redis';
 import * as Crypto from 'crypto-js';
@@ -11,6 +11,7 @@ import { LoginDTO, LoginType, UPwdDTO } from '../interface/login.interface';
 import { Admin } from '../entity/system/admin.entity';
 import * as bcrypt from 'bcryptjs';
 import { User } from '../entity/system/user.entity';
+import { AliyunSmsService } from './thirdParty/aliyunSms.service';
 
 @Provide()
 export class LoginService {
@@ -24,14 +25,92 @@ export class LoginService {
   jwtSecret;
   @Config('jwt.expiresIn')
   jwtExpiresIn;
+  @Config('requestTimeLimit')
+  timeLimit;
+  @Config('loginSmsSign')
+  loginSmsSign;
+  @Config('pwdSmsSign')
+  pwdSmsSign;
+
   @Inject()
   redisService: RedisService;
 
+  @Inject()
+  smsService: AliyunSmsService;
+
   @InjectEntityModel(Admin)
   adminModel: Repository<Admin>;
   @InjectEntityModel(User)
   userModel: Repository<User>;
 
+  /**
+   * 验证:找回密码的验证是否正确
+   * @param type 验证方式
+   * @param to 手机号/邮箱地址
+   * @param code 验证码
+   */
+  async checkPwdCode(type, to, code) {
+    const redisKey = `${this.pwdSmsSign}:${type}:${to}`;
+    const redisCode = await this.redisService.get(redisKey);
+    if (!redisCode) throw new ServiceError(ErrorCode.PWD_VALICODE_EXPIRES); // 找回密码验证码已过期
+    if (`${redisCode}` !== `${code}`) throw new ServiceError(ErrorCode.PWD_VALICODE_ERROR); // 找回密码验证码错误
+    await this.redisService.del(redisKey);
+    return true;
+  }
+
+  /**
+   * 发送忘记密码的验证码
+   * @param type 验证方式: phone/email
+   * @param to 向 手机号/邮箱地址 发送
+   */
+  async sendPwdCode(type, to) {
+    const redisKey = `${this.pwdSmsSign}:${type}:${to}`;
+    const code = random(1000, 999999);
+    await this.redisService.set(redisKey, code, 'EX', this.timeLimit);
+    if (type === 'email') {
+      // TODO: 发邮箱
+    } else if (type === 'phone') {
+      // 发短信
+      await this.smsService.send(to, code);
+    }
+  }
+
+  /**
+   * 发送登录验证码
+   * @param phone 手机号
+   * @param code 验证码
+   */
+  async sendSmsLoginCode(phone) {
+    // code
+    const code = random(1000, 999999);
+    const redisKey = `${this.loginSmsSign}:${phone}`;
+    // 如果以验证码超时为下条验证码发送的条件,则放开下2行注释
+    // const hasCode = await this.redisService.get(redisKey);
+    // if (hasCode) throw new ServiceError(ErrorCode.LOGIN_VALICODE_IS_EXISTS);
+    // redis存起来用于验证
+    await this.redisService.set(redisKey, code, 'EX', this.timeLimit);
+    // sms发送短信
+    await this.smsService.send(phone, code);
+  }
+  /**
+   * 验证登录验证码
+   * @param phone 手机号
+   * @param code 验证码
+   * @returns
+   */
+  async valiSmsCode(body) {
+    const code = get(body, 'checkCode');
+    const phone = get(body, 'phone');
+    if (!code) throw new ServiceError(ErrorCode.PLEASE_INPUT_LOGIN_CODE);
+    if (!phone) throw new ServiceError(ErrorCode.PLEASE_INPUT_LOGIN_PHONE);
+    const redisKey = `${this.loginSmsSign}:${phone}`;
+    const redisCode = await this.redisService.get(redisKey);
+    if (!redisCode) throw new ServiceError(ErrorCode.LOGIN_VALICODE_EXPIRES); // 登录验证码已过期
+    if (`${redisCode}` !== `${code}`) throw new ServiceError(ErrorCode.LOGIN_VALICODE_ERROR); // 登录验证码输入错误
+    await this.redisService.del(redisKey);
+    return true;
+  }
+
   async tokenViewGetUserInfo(role: Array<string>, id: number) {
     const hasAdminRole = role.find(f => f === LoginType.Admin);
     let model;

+ 33 - 0
src/service/thirdParty/aliyunSms.service.ts

@@ -0,0 +1,33 @@
+import { Config, Init, Provide } from '@midwayjs/core';
+import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
+import Dysmsapi20170525, * as $Dysmsapi20170525 from '@alicloud/dysmsapi20170525';
+import Util, * as $Util from '@alicloud/tea-util';
+@Provide()
+export class AliyunSmsService {
+  @Config('aliyunSms')
+  aliyunSms;
+
+  client: Dysmsapi20170525;
+  @Init()
+  init() {
+    const config = new $OpenApi.Config({
+      accessKeyId: this.aliyunSms.AccessKey_ID,
+      accessKeySecret: this.aliyunSms.AccessKey_Secret,
+    });
+    config.endpoint = `dysmsapi.aliyuncs.com`;
+    this.client = new Dysmsapi20170525(config);
+  }
+  async send(phone, code) {
+    const smsRequest = new $Dysmsapi20170525.SendSmsRequest({
+      phoneNumbers: phone,
+      signName: this.aliyunSms.sign,
+      templateCode: this.aliyunSms.template,
+      templateParam: JSON.stringify({ code }),
+    });
+    try {
+      await this.client.sendSms(smsRequest);
+    } catch (error) {
+      console.log(error);
+    }
+  }
+}