Browse Source

登录

qiji
nili 5 months ago
parent
commit
500f958027
  1. 12
      build/asset-manifest.json
  2. 2
      build/index.html
  3. 2
      build/static/css/main.31676e70.css
  4. 1
      build/static/css/main.31676e70.css.map
  5. 2
      build/static/css/main.6464b9b7.css
  6. 1
      build/static/css/main.6464b9b7.css.map
  7. 3
      build/static/js/main.d0f8649a.js
  8. 89
      build/static/js/main.d0f8649a.js.LICENSE.txt
  9. 1
      build/static/js/main.d0f8649a.js.map
  10. 3
      build/static/js/main.f7930c69.js
  11. 103
      build/static/js/main.f7930c69.js.LICENSE.txt
  12. 1
      build/static/js/main.f7930c69.js.map
  13. 14365
      package-lock.json
  14. 7
      package.json
  15. 37
      src/App.tsx
  16. 14
      src/PrivateRoute.tsx
  17. 7
      src/api/generated/.openapi-generator/FILES
  18. 3
      src/api/generated/api.ts
  19. 60
      src/api/generated/api/admin-api.ts
  20. 423
      src/api/generated/api/open-controller-api.ts
  21. 120
      src/api/generated/api/user-controller-api.ts
  22. 4
      src/api/generated/model/index.ts
  23. 45
      src/api/generated/model/rstsinfo.ts
  24. 45
      src/api/generated/model/ruser-bo.ts
  25. 66
      src/api/generated/model/stsinfo.ts
  26. 84
      src/api/generated/model/user-bo.ts
  27. 12
      src/api/index.tsx
  28. 1
      src/index.css
  29. 12
      src/index.tsx
  30. 30
      src/page/DownloadPage.tsx
  31. 82
      src/page/MyQRCodePage.tsx
  32. 34
      src/page/RegisterPage.tsx
  33. 95
      src/page/UserPage.tsx
  34. 106
      src/page/login/LoginByCode.tsx
  35. 64
      src/page/login/LoginByPwd.tsx
  36. 98
      src/page/login/LoginPage.tsx
  37. 13
      src/utils/numberUtils.tsx

12
build/asset-manifest.json

@ -1,15 +1,15 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.6464b9b7.css", "main.css": "/static/css/main.31676e70.css",
"main.js": "/static/js/main.d0f8649a.js", "main.js": "/static/js/main.f7930c69.js",
"static/js/453.1d641cba.chunk.js": "/static/js/453.1d641cba.chunk.js", "static/js/453.1d641cba.chunk.js": "/static/js/453.1d641cba.chunk.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.6464b9b7.css.map": "/static/css/main.6464b9b7.css.map", "main.31676e70.css.map": "/static/css/main.31676e70.css.map",
"main.d0f8649a.js.map": "/static/js/main.d0f8649a.js.map", "main.f7930c69.js.map": "/static/js/main.f7930c69.js.map",
"453.1d641cba.chunk.js.map": "/static/js/453.1d641cba.chunk.js.map" "453.1d641cba.chunk.js.map": "/static/js/453.1d641cba.chunk.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.6464b9b7.css", "static/css/main.31676e70.css",
"static/js/main.d0f8649a.js" "static/js/main.f7930c69.js"
] ]
} }

2
build/index.html

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>奇迹畅玩</title><script defer="defer" src="/static/js/main.d0f8649a.js"></script><link href="/static/css/main.6464b9b7.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>奇迹畅玩</title><script defer="defer" src="/static/js/main.f7930c69.js"></script><link href="/static/css/main.31676e70.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

2
build/static/css/main.31676e70.css

File diff suppressed because one or more lines are too long

1
build/static/css/main.31676e70.css.map

File diff suppressed because one or more lines are too long

2
build/static/css/main.6464b9b7.css

File diff suppressed because one or more lines are too long

1
build/static/css/main.6464b9b7.css.map

File diff suppressed because one or more lines are too long

3
build/static/js/main.d0f8649a.js

File diff suppressed because one or more lines are too long

89
build/static/js/main.d0f8649a.js.LICENSE.txt

@ -1,89 +0,0 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* use-sync-external-store-shim.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @remix-run/router v1.16.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router v6.23.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/

1
build/static/js/main.d0f8649a.js.map

File diff suppressed because one or more lines are too long

3
build/static/js/main.f7930c69.js

File diff suppressed because one or more lines are too long

103
build/static/js/main.f7930c69.js.LICENSE.txt

@ -0,0 +1,103 @@
/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* use-sync-external-store-shim.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license qrcode.react
* Copyright (c) Paul O'Shannessy
* SPDX-License-Identifier: ISC
*/
/**
* @remix-run/router v1.16.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**
* React Router v6.23.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/**![alipay](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNTU3LjIgMTI5YTYuNjggNi42OCAwIDAxNi43MiA2LjY1VjI1MC4yaDI0My44YTYuNzQgNi43NCAwIDAxNi42NSA2Ljg0Yy4wMiAyMy45Mi02LjA1IDU0LjY5LTE5Ljg1IDU0LjY5SDU2My45NHY4MS4xaDE2Ni4xOGM3LjY5IDAgMTMuOCA2LjUxIDEzLjI1IDE0LjE4bC0uMTEgMS41MWMtLjcgOTAuMi0zMC42MyAxODAuNjQtNzkuNTIgMjU5LjY1bDguNzEgMy44MmM3Ny4zIDMzLjQ4IDE2Mi4xNSA2MC44NSAyNjcuMTUgNjQuMTRhMjEuMDggMjEuMDggMCAwMTIwLjM4IDIyLjA3bC0uMiAzLjk1Yy0zLjM0IDU5LjU3LTIwIDEzMi44NS03OS44NSAxMzIuODUtOC44IDAtMTcuMjktLjU1LTI1LjQ4LTEuNjEtNzguMDQtOS4yNS0xNTYuMjgtNTcuMDUtMjM2LjMyLTExMC4yN2wtMTcuMzMtMTEuNTctMTMuMTUtOC44M2E0ODAuODMgNDgwLjgzIDAgMDEtNjkuOTkgNTcuMjUgMTkyLjggMTkyLjggMCAwMS0xOS41NyAxMS4wOGMtNjUuNTEgMzkuMTgtMTQyLjIxIDYyLjYtMjI3LjQyIDYyLjYyLTExOC4yIDAtMjA0LjkyLTc3Ljk3LTIwNi42NC0xNzUuOWwtLjAzLTIuOTUuMDMtMS43YzEuNjYtOTguMTIgODQuNzctMTc1LjE4IDIwMy0xNzYuNzJsMy42NC0uMDNjMTAyLjkyIDAgMTg2LjY2IDMzLjU0IDI3MC40OCA3My4xNGwuNDQuMzggMS43LTMuNDdjMjEuMjctNDQuMTQgMzYuNDQtOTQuOTUgNDIuNzQtMTUyLjA2aC0zMjQuOGE2LjY0IDYuNjQgMCAwMS02LjYzLTYuNjJjLS4wNC0yMS44NiA2LTU0LjkxIDE5Ljg1LTU0LjkxaDE2Mi4xdi04MS4xSDE5MS45MmE2LjcxIDYuNzEgMCAwMS02LjY0LTYuODVjLS4wMS0yMi42MSA2LjA2LTU0LjY4IDE5Ljg2LTU0LjY4aDIzMS40di02NC44NWwuMDItMS45OWMuOS0zMC45MyAyMy43Mi01NC4zNiAxMjAuNjQtNTQuMzZNMjU2LjkgNjE5Yy03NC43NyAwLTEzNi41MyAzOS45My0xMzcuODggOTUuNmwtLjAyIDEuMjYuMDggMy4yNGE5Mi41NSA5Mi41NSAwIDAwMS41OCAxMy42NGMyMC4yNiA5Ni41IDIyMC4xNiAxMjkuNzEgMzY0LjM0LTM2LjU5bC04LjAzLTQuNzJDNDA1Ljk1IDY1MC4xMSAzMzIuOTQgNjE5IDI1Ni45IDYxOSIgLz48L3N2Zz4=) */
/**![gift](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4MCAzMTBINzMyLjRjMTMuNi0yMS40IDIxLjYtNDYuOCAyMS42LTc0IDAtNzYuMS02MS45LTEzOC0xMzgtMTM4LTQxLjQgMC03OC43IDE4LjQtMTA0IDQ3LjQtMjUuMy0yOS02Mi42LTQ3LjQtMTA0LTQ3LjQtNzYuMSAwLTEzOCA2MS45LTEzOCAxMzggMCAyNy4yIDcuOSA1Mi42IDIxLjYgNzRIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnYyMDBjMCA0LjQgMy42IDggOCA4aDQwdjM0NGMwIDE3LjcgMTQuMyAzMiAzMiAzMmg2NDBjMTcuNyAwIDMyLTE0LjMgMzItMzJWNTUwaDQwYzQuNCAwIDgtMy42IDgtOFYzNDJjMC0xNy43LTE0LjMtMzItMzItMzJ6bS0zMzQtNzRjMC0zOC42IDMxLjQtNzAgNzAtNzBzNzAgMzEuNCA3MCA3MC0zMS40IDcwLTcwIDcwaC03MHYtNzB6bS0xMzgtNzBjMzguNiAwIDcwIDMxLjQgNzAgNzB2NzBoLTcwYy0zOC42IDAtNzAtMzEuNC03MC03MHMzMS40LTcwIDcwLTcwek0xODAgNDgyVjM3OGgyOTh2MTA0SDE4MHptNDggNjhoMjUwdjMwOEgyMjhWNTUwem01NjggMzA4SDU0NlY1NTBoMjUwdjMwOHptNDgtMzc2SDU0NlYzNzhoMjk4djEwNHoiIC8+PC9zdmc+) */
/**![line-chart](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4OCA3OTJIMjAwVjE2OGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2Njg4YzAgNC40IDMuNiA4IDggOGg3NTJjNC40IDAgOC0zLjYgOC04di01NmMwLTQuNC0zLjYtOC04LTh6TTMwNS44IDYzNy43YzMuMSAzLjEgOC4xIDMuMSAxMS4zIDBsMTM4LjMtMTM3LjZMNTgzIDYyOC41YzMuMSAzLjEgOC4yIDMuMSAxMS4zIDBsMjc1LjQtMjc1LjNjMy4xLTMuMSAzLjEtOC4yIDAtMTEuM2wtMzkuNi0zOS42YTguMDMgOC4wMyAwIDAwLTExLjMgMGwtMjMwIDIyOS45TDQ2MS40IDQwNGE4LjAzIDguMDMgMCAwMC0xMS4zIDBMMjY2LjMgNTg2LjdhOC4wMyA4LjAzIDAgMDAwIDExLjNsMzkuNSAzOS43eiIgLz48L3N2Zz4=) */
/**![team](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTgyNC4yIDY5OS45YTMwMS41NSAzMDEuNTUgMCAwMC04Ni40LTYwLjRDNzgzLjEgNjAyLjggODEyIDU0Ni44IDgxMiA0ODRjMC0xMTAuOC05Mi40LTIwMS43LTIwMy4yLTIwMC0xMDkuMSAxLjctMTk3IDkwLjYtMTk3IDIwMCAwIDYyLjggMjkgMTE4LjggNzQuMiAxNTUuNWEzMDAuOTUgMzAwLjk1IDAgMDAtODYuNCA2MC40QzM0NSA3NTQuNiAzMTQgODI2LjggMzEyIDkwMy44YTggOCAwIDAwOCA4LjJoNTZjNC4zIDAgNy45LTMuNCA4LTcuNyAxLjktNTggMjUuNC0xMTIuMyA2Ni43LTE1My41QTIyNi42MiAyMjYuNjIgMCAwMTYxMiA2ODRjNjAuOSAwIDExOC4yIDIzLjcgMTYxLjMgNjYuOEM4MTQuNSA3OTIgODM4IDg0Ni4zIDg0MCA5MDQuM2MuMSA0LjMgMy43IDcuNyA4IDcuN2g1NmE4IDggMCAwMDgtOC4yYy0yLTc3LTMzLTE0OS4yLTg3LjgtMjAzLjl6TTYxMiA2MTJjLTM0LjIgMC02Ni40LTEzLjMtOTAuNS0zNy41YTEyNi44NiAxMjYuODYgMCAwMS0zNy41LTkxLjhjLjMtMzIuOCAxMy40LTY0LjUgMzYuMy04OCAyNC0yNC42IDU2LjEtMzguMyA5MC40LTM4LjcgMzMuOS0uMyA2Ni44IDEyLjkgOTEgMzYuNiAyNC44IDI0LjMgMzguNCA1Ni44IDM4LjQgOTEuNCAwIDM0LjItMTMuMyA2Ni4zLTM3LjUgOTAuNUExMjcuMyAxMjcuMyAwIDAxNjEyIDYxMnpNMzYxLjUgNTEwLjRjLS45LTguNy0xLjQtMTcuNS0xLjQtMjYuNCAwLTE1LjkgMS41LTMxLjQgNC4zLTQ2LjUuNy0zLjYtMS4yLTcuMy00LjUtOC44LTEzLjYtNi4xLTI2LjEtMTQuNS0zNi45LTI1LjFhMTI3LjU0IDEyNy41NCAwIDAxLTM4LjctOTUuNGMuOS0zMi4xIDEzLjgtNjIuNiAzNi4zLTg1LjYgMjQuNy0yNS4zIDU3LjktMzkuMSA5My4yLTM4LjcgMzEuOS4zIDYyLjcgMTIuNiA4NiAzNC40IDcuOSA3LjQgMTQuNyAxNS42IDIwLjQgMjQuNCAyIDMuMSA1LjkgNC40IDkuMyAzLjIgMTcuNi02LjEgMzYuMi0xMC40IDU1LjMtMTIuNCA1LjYtLjYgOC44LTYuNiA2LjMtMTEuNi0zMi41LTY0LjMtOTguOS0xMDguNy0xNzUuNy0xMDkuOS0xMTAuOS0xLjctMjAzLjMgODkuMi0yMDMuMyAxOTkuOSAwIDYyLjggMjguOSAxMTguOCA3NC4yIDE1NS41LTMxLjggMTQuNy02MS4xIDM1LTg2LjUgNjAuNC01NC44IDU0LjctODUuOCAxMjYuOS04Ny44IDIwNGE4IDggMCAwMDggOC4yaDU2LjFjNC4zIDAgNy45LTMuNCA4LTcuNyAxLjktNTggMjUuNC0xMTIuMyA2Ni43LTE1My41IDI5LjQtMjkuNCA2NS40LTQ5LjggMTA0LjctNTkuNyAzLjktMSA2LjUtNC43IDYtOC43eiIgLz48L3N2Zz4=) */

1
build/static/js/main.f7930c69.js.map

File diff suppressed because one or more lines are too long

14365
package-lock.json

File diff suppressed because it is too large

7
package.json

@ -3,6 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.3.7",
"@testing-library/jest-dom": "^5.17.0", "@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
@ -13,6 +14,8 @@
"antd-mobile": "^5.36.0", "antd-mobile": "^5.36.0",
"antd-mobile-icons": "^0.3.0", "antd-mobile-icons": "^0.3.0",
"axios": "^1.6.8", "axios": "^1.6.8",
"html-to-image": "^1.11.11",
"qrcode.react": "^3.1.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-router-dom": "^6.23.0", "react-router-dom": "^6.23.0",
@ -25,7 +28,7 @@
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"gen:api":"openapi-generator-cli generate -i http://localhost:9001/api/v3/api-docs -g typescript-axios --additional-properties=apiPackage=api,modelPackage=model,withSeparateModelsAndApi=true -o ./src/api/generated --skip-validate-spec" "gen:api": "openapi-generator-cli generate -i http://localhost:9001/api/v3/api-docs -g typescript-axios --additional-properties=apiPackage=api,modelPackage=model,withSeparateModelsAndApi=true -o ./src/api/generated --skip-validate-spec"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
@ -45,7 +48,5 @@
"last 1 safari version" "last 1 safari version"
] ]
}, },
"devDependencies": {
},
"proxy": "http://localhost:9001" "proxy": "http://localhost:9001"
} }

37
src/App.tsx

@ -5,16 +5,45 @@ import {
Route, Route,
Routes, Routes,
} from "react-router-dom"; } from "react-router-dom";
import RegisterPage from "./RegisterPage"; import DownloadPage from "./page/DownloadPage";
import DownloadPage from "./DownloadPage";
import LoginPage from "./page/login/LoginPage";
import RegisterPage from "./page/RegisterPage";
import UserPage from "./page/UserPage";
import PrivateRoute from "./PrivateRoute";
import MyQRCodePage from "./page/MyQRCodePage";
function App() { function App() {
return ( return (
<Router> <Router>
<Routes> <Routes>
<Route path="/register/:inviteCode" element={<RegisterPage />} /> <Route path="/register/:inviteCode" element={<RegisterPage />} />
<Route path="/download/:inviteCode" element={<DownloadPage />} /> <Route path="/login/:appCode" element={<LoginPage />} />
<Route path="*" element={<Navigate to="/register" replace />} /> <Route path="*" element={<Navigate to="/home" replace />} />
<Route
path="/download/:inviteCode"
element={
<PrivateRoute>
<DownloadPage />
</PrivateRoute>
}
/>
<Route
path="/home"
element={
<PrivateRoute>
<UserPage />
</PrivateRoute>
}
/>
<Route
path="/myCode"
element={
<PrivateRoute>
<MyQRCodePage />
</PrivateRoute>
}
/>
{/* 添加其他路由 */} {/* 添加其他路由 */}
</Routes> </Routes>
</Router> </Router>

14
src/PrivateRoute.tsx

@ -0,0 +1,14 @@
import { FC, ReactNode } from "react";
import { Navigate } from "react-router-dom";
interface PrivateRouteProps {
children: ReactNode;
}
const PrivateRoute: FC<PrivateRouteProps> = ({ children }) => {
const isLoggedIn = localStorage.getItem("isLoggedIn"); // 假设登录状态存储在
return isLoggedIn ? <>{children}</> : <Navigate to="/login" replace />;
};
export default PrivateRoute;

7
src/api/generated/.openapi-generator/FILES

@ -6,7 +6,8 @@ api/app-controller-api.ts
api/device-api.ts api/device-api.ts
api/login-controller-api.ts api/login-controller-api.ts
api/matrix-controller-api.ts api/matrix-controller-api.ts
api/register-controller-api.ts api/open-controller-api.ts
api/user-controller-api.ts
base.ts base.ts
common.ts common.ts
configuration.ts configuration.ts
@ -55,5 +56,9 @@ model/roverview-bo.ts
model/rpage-result-matrix-adv-record-bo.ts model/rpage-result-matrix-adv-record-bo.ts
model/rrank-list.ts model/rrank-list.ts
model/rstring.ts model/rstring.ts
model/rstsinfo.ts
model/ruser-bo.ts
model/rvoid.ts model/rvoid.ts
model/stsinfo.ts
model/user-bo.ts
model/user-info.ts model/user-info.ts

3
src/api/generated/api.ts

@ -19,5 +19,6 @@ export * from './api/app-controller-api';
export * from './api/device-api'; export * from './api/device-api';
export * from './api/login-controller-api'; export * from './api/login-controller-api';
export * from './api/matrix-controller-api'; export * from './api/matrix-controller-api';
export * from './api/register-controller-api'; export * from './api/open-controller-api';
export * from './api/user-controller-api';

60
src/api/generated/api/admin-api.ts

@ -48,6 +48,8 @@ import { ROverviewBo } from '../model';
// @ts-ignore // @ts-ignore
import { RPageResultMatrixAdvRecordBo } from '../model'; import { RPageResultMatrixAdvRecordBo } from '../model';
// @ts-ignore // @ts-ignore
import { RSTSInfo } from '../model';
// @ts-ignore
import { RVoid } from '../model'; import { RVoid } from '../model';
/** /**
* AdminApi - axios parameter creator * AdminApi - axios parameter creator
@ -325,6 +327,35 @@ export const AdminApiAxiosParamCreator = function (configuration?: Configuration
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getSTS: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/admin/getSTS`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter); setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
@ -679,6 +710,17 @@ export const AdminApiFp = function(configuration?: Configuration) {
const localVarOperationServerBasePath = operationServerMap['AdminApi.deleteWhiteList']?.[localVarOperationServerIndex]?.url; const localVarOperationServerBasePath = operationServerMap['AdminApi.deleteWhiteList']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getSTS(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RSTSInfo>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getSTS(options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['AdminApi.getSTS']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/** /**
* *
* @param {string} appIds * @param {string} appIds
@ -843,6 +885,14 @@ export const AdminApiFactory = function (configuration?: Configuration, basePath
deleteWhiteList(deviceId: string, options?: any): AxiosPromise<RVoid> { deleteWhiteList(deviceId: string, options?: any): AxiosPromise<RVoid> {
return localVarFp.deleteWhiteList(deviceId, options).then((request) => request(axios, basePath)); return localVarFp.deleteWhiteList(deviceId, options).then((request) => request(axios, basePath));
}, },
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getSTS(options?: any): AxiosPromise<RSTSInfo> {
return localVarFp.getSTS(options).then((request) => request(axios, basePath));
},
/** /**
* *
* @param {string} appIds * @param {string} appIds
@ -1002,6 +1052,16 @@ export class AdminApi extends BaseAPI {
return AdminApiFp(this.configuration).deleteWhiteList(deviceId, options).then((request) => request(this.axios, this.basePath)); return AdminApiFp(this.configuration).deleteWhiteList(deviceId, options).then((request) => request(this.axios, this.basePath));
} }
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AdminApi
*/
public getSTS(options?: RawAxiosRequestConfig) {
return AdminApiFp(this.configuration).getSTS(options).then((request) => request(this.axios, this.basePath));
}
/** /**
* *
* @param {string} appIds * @param {string} appIds

423
src/api/generated/api/open-controller-api.ts

@ -0,0 +1,423 @@
/* tslint:disable */
/* eslint-disable */
/**
* matrix后台
*
*
* The version of the OpenAPI document: v1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios';
// Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';
// @ts-ignore
import { LoginReq } from '../model';
// @ts-ignore
import { RMatrixAppBo } from '../model';
// @ts-ignore
import { RString } from '../model';
// @ts-ignore
import { RVoid } from '../model';
// @ts-ignore
import { RegisterBo } from '../model';
/**
* OpenControllerApi - axios parameter creator
* @export
*/
export const OpenControllerApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @param {string} [inviteCode]
* @param {string} [appCode]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getApp: async (inviteCode?: string, appCode?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/citrus/register/getApp`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
if (inviteCode !== undefined) {
localVarQueryParameter['inviteCode'] = inviteCode;
}
if (appCode !== undefined) {
localVarQueryParameter['appCode'] = appCode;
}
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
loginByCode: async (loginReq: LoginReq, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'loginReq' is not null or undefined
assertParamExists('loginByCode', 'loginReq', loginReq)
const localVarPath = `/api/citrus/loginByCode`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(loginReq, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
loginByPwd: async (loginReq: LoginReq, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'loginReq' is not null or undefined
assertParamExists('loginByPwd', 'loginReq', loginReq)
const localVarPath = `/api/citrus/loginByPwd`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(loginReq, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {string} mobile
* @param {string} scene
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
sendCode: async (mobile: string, scene: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'mobile' is not null or undefined
assertParamExists('sendCode', 'mobile', mobile)
// verify required parameter 'scene' is not null or undefined
assertParamExists('sendCode', 'scene', scene)
const localVarPath = `/api/citrus/register/sendCode`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
if (mobile !== undefined) {
localVarQueryParameter['mobile'] = mobile;
}
if (scene !== undefined) {
localVarQueryParameter['scene'] = scene;
}
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @param {RegisterBo} registerBo
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
submitRegister: async (registerBo: RegisterBo, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'registerBo' is not null or undefined
assertParamExists('submitRegister', 'registerBo', registerBo)
const localVarPath = `/api/citrus/register/submitRegister`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(registerBo, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
}
};
/**
* OpenControllerApi - functional programming interface
* @export
*/
export const OpenControllerApiFp = function(configuration?: Configuration) {
const localVarAxiosParamCreator = OpenControllerApiAxiosParamCreator(configuration)
return {
/**
*
* @param {string} [inviteCode]
* @param {string} [appCode]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getApp(inviteCode?: string, appCode?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RMatrixAppBo>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getApp(inviteCode, appCode, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['OpenControllerApi.getApp']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async loginByCode(loginReq: LoginReq, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RString>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.loginByCode(loginReq, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['OpenControllerApi.loginByCode']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async loginByPwd(loginReq: LoginReq, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RString>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.loginByPwd(loginReq, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['OpenControllerApi.loginByPwd']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
*
* @param {string} mobile
* @param {string} scene
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async sendCode(mobile: string, scene: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RVoid>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.sendCode(mobile, scene, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['OpenControllerApi.sendCode']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/**
*
* @param {RegisterBo} registerBo
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async submitRegister(registerBo: RegisterBo, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RVoid>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.submitRegister(registerBo, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['OpenControllerApi.submitRegister']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
}
};
/**
* OpenControllerApi - factory interface
* @export
*/
export const OpenControllerApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
const localVarFp = OpenControllerApiFp(configuration)
return {
/**
*
* @param {string} [inviteCode]
* @param {string} [appCode]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getApp(inviteCode?: string, appCode?: string, options?: any): AxiosPromise<RMatrixAppBo> {
return localVarFp.getApp(inviteCode, appCode, options).then((request) => request(axios, basePath));
},
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
loginByCode(loginReq: LoginReq, options?: any): AxiosPromise<RString> {
return localVarFp.loginByCode(loginReq, options).then((request) => request(axios, basePath));
},
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
loginByPwd(loginReq: LoginReq, options?: any): AxiosPromise<RString> {
return localVarFp.loginByPwd(loginReq, options).then((request) => request(axios, basePath));
},
/**
*
* @param {string} mobile
* @param {string} scene
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
sendCode(mobile: string, scene: string, options?: any): AxiosPromise<RVoid> {
return localVarFp.sendCode(mobile, scene, options).then((request) => request(axios, basePath));
},
/**
*
* @param {RegisterBo} registerBo
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
submitRegister(registerBo: RegisterBo, options?: any): AxiosPromise<RVoid> {
return localVarFp.submitRegister(registerBo, options).then((request) => request(axios, basePath));
},
};
};
/**
* OpenControllerApi - object-oriented interface
* @export
* @class OpenControllerApi
* @extends {BaseAPI}
*/
export class OpenControllerApi extends BaseAPI {
/**
*
* @param {string} [inviteCode]
* @param {string} [appCode]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof OpenControllerApi
*/
public getApp(inviteCode?: string, appCode?: string, options?: RawAxiosRequestConfig) {
return OpenControllerApiFp(this.configuration).getApp(inviteCode, appCode, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof OpenControllerApi
*/
public loginByCode(loginReq: LoginReq, options?: RawAxiosRequestConfig) {
return OpenControllerApiFp(this.configuration).loginByCode(loginReq, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {LoginReq} loginReq
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof OpenControllerApi
*/
public loginByPwd(loginReq: LoginReq, options?: RawAxiosRequestConfig) {
return OpenControllerApiFp(this.configuration).loginByPwd(loginReq, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {string} mobile
* @param {string} scene
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof OpenControllerApi
*/
public sendCode(mobile: string, scene: string, options?: RawAxiosRequestConfig) {
return OpenControllerApiFp(this.configuration).sendCode(mobile, scene, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @param {RegisterBo} registerBo
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof OpenControllerApi
*/
public submitRegister(registerBo: RegisterBo, options?: RawAxiosRequestConfig) {
return OpenControllerApiFp(this.configuration).submitRegister(registerBo, options).then((request) => request(this.axios, this.basePath));
}
}

120
src/api/generated/api/user-controller-api.ts

@ -0,0 +1,120 @@
/* tslint:disable */
/* eslint-disable */
/**
* matrix后台
*
*
* The version of the OpenAPI document: v1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type { Configuration } from '../configuration';
import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
import globalAxios from 'axios';
// Some imports not used depending on template conditions
// @ts-ignore
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';
// @ts-ignore
import { RUserBo } from '../model';
/**
* UserControllerApi - axios parameter creator
* @export
*/
export const UserControllerApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
currentUser1: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/citrus/user/current`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
}
};
/**
* UserControllerApi - functional programming interface
* @export
*/
export const UserControllerApiFp = function(configuration?: Configuration) {
const localVarAxiosParamCreator = UserControllerApiAxiosParamCreator(configuration)
return {
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async currentUser1(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RUserBo>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.currentUser1(options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['UserControllerApi.currentUser1']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
}
};
/**
* UserControllerApi - factory interface
* @export
*/
export const UserControllerApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
const localVarFp = UserControllerApiFp(configuration)
return {
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
currentUser1(options?: any): AxiosPromise<RUserBo> {
return localVarFp.currentUser1(options).then((request) => request(axios, basePath));
},
};
};
/**
* UserControllerApi - object-oriented interface
* @export
* @class UserControllerApi
* @extends {BaseAPI}
*/
export class UserControllerApi extends BaseAPI {
/**
*
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof UserControllerApi
*/
public currentUser1(options?: RawAxiosRequestConfig) {
return UserControllerApiFp(this.configuration).currentUser1(options).then((request) => request(this.axios, this.basePath));
}
}

4
src/api/generated/model/index.ts

@ -37,8 +37,12 @@ export * from './rmatrix-app-bo';
export * from './roverview-bo'; export * from './roverview-bo';
export * from './rpage-result-matrix-adv-record-bo'; export * from './rpage-result-matrix-adv-record-bo';
export * from './rrank-list'; export * from './rrank-list';
export * from './rstsinfo';
export * from './rstring'; export * from './rstring';
export * from './ruser-bo';
export * from './rvoid'; export * from './rvoid';
export * from './rank-list'; export * from './rank-list';
export * from './register-bo'; export * from './register-bo';
export * from './stsinfo';
export * from './user-bo';
export * from './user-info'; export * from './user-info';

45
src/api/generated/model/rstsinfo.ts

@ -0,0 +1,45 @@
/* tslint:disable */
/* eslint-disable */
/**
* matrix后台
*
*
* The version of the OpenAPI document: v1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
// May contain unused imports in some cases
// @ts-ignore
import { STSInfo } from './stsinfo';
/**
*
* @export
* @interface RSTSInfo
*/
export interface RSTSInfo {
/**
*
* @type {number}
* @memberof RSTSInfo
*/
'code'?: number;
/**
*
* @type {string}
* @memberof RSTSInfo
*/
'message'?: string;
/**
*
* @type {STSInfo}
* @memberof RSTSInfo
*/
'data'?: STSInfo;
}

45
src/api/generated/model/ruser-bo.ts

@ -0,0 +1,45 @@
/* tslint:disable */
/* eslint-disable */
/**
* matrix后台
*
*
* The version of the OpenAPI document: v1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
// May contain unused imports in some cases
// @ts-ignore
import { UserBo } from './user-bo';
/**
*
* @export
* @interface RUserBo
*/
export interface RUserBo {
/**
*
* @type {number}
* @memberof RUserBo
*/
'code'?: number;
/**
*
* @type {string}
* @memberof RUserBo
*/
'message'?: string;
/**
*
* @type {UserBo}
* @memberof RUserBo
*/
'data'?: UserBo;
}

66
src/api/generated/model/stsinfo.ts

@ -0,0 +1,66 @@
/* tslint:disable */
/* eslint-disable */
/**
* matrix后台
*
*
* The version of the OpenAPI document: v1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
*
* @export
* @interface STSInfo
*/
export interface STSInfo {
/**
*
* @type {string}
* @memberof STSInfo
*/
'securityToken'?: string;
/**
*
* @type {string}
* @memberof STSInfo
*/
'expiration'?: string;
/**
*
* @type {string}
* @memberof STSInfo
*/
'accessKeySecret'?: string;
/**
*
* @type {string}
* @memberof STSInfo
*/
'accessKeyId'?: string;
/**
*
* @type {string}
* @memberof STSInfo
*/
'stsRole'?: string;
/**
*
* @type {string}
* @memberof STSInfo
*/
'bucket'?: string;
/**
*
* @type {string}
* @memberof STSInfo
*/
'endpoint'?: string;
}

84
src/api/generated/model/user-bo.ts

@ -0,0 +1,84 @@
/* tslint:disable */
/* eslint-disable */
/**
* matrix后台
*
*
* The version of the OpenAPI document: v1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
*
* @export
* @interface UserBo
*/
export interface UserBo {
/**
*
* @type {number}
* @memberof UserBo
*/
'id'?: number;
/**
*
* @type {string}
* @memberof UserBo
*/
'mobile'?: string;
/**
*
* @type {string}
* @memberof UserBo
*/
'name'?: string;
/**
*
* @type {string}
* @memberof UserBo
*/
'nickname'?: string;
/**
*
* @type {string}
* @memberof UserBo
*/
'avatar'?: string;
/**
*
* @type {number}
* @memberof UserBo
*/
'money'?: number;
/**
*
* @type {string}
* @memberof UserBo
*/
'aliPayAccount'?: string;
/**
*
* @type {number}
* @memberof UserBo
*/
'income'?: number;
/**
*
* @type {string}
* @memberof UserBo
*/
'inviteCode'?: string;
/**
*
* @type {string}
* @memberof UserBo
*/
'inviteUrl'?: string;
}

12
src/api/index.tsx

@ -1,6 +1,14 @@
import { RegisterControllerApi } from "./generated"; import { OpenControllerApi } from "./generated";
import { UserControllerApi } from "./generated/api/user-controller-api";
export const api = new RegisterControllerApi({ export const api = new OpenControllerApi({
basePath: "",
isJsonMime(mime) {
return mime === "application/json";
},
});
export const userApi = new UserControllerApi({
basePath: "", basePath: "",
isJsonMime(mime) { isJsonMime(mime) {
return mime === "application/json"; return mime === "application/json";

1
src/index.css

@ -5,6 +5,7 @@ body {
sans-serif; sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
height: 100%;
} }
code { code {

12
src/index.tsx

@ -1,11 +1,11 @@
import React from 'react'; import React from "react";
import ReactDOM from 'react-dom/client'; import ReactDOM from "react-dom/client";
import './index.css'; import "./index.css";
import App from './App'; import App from "./App";
import reportWebVitals from './reportWebVitals'; import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot( const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement document.getElementById("root") as HTMLElement
); );
root.render( root.render(
<React.StrictMode> <React.StrictMode>

30
src/DownloadPage.tsx → src/page/DownloadPage.tsx

@ -2,29 +2,27 @@
import { Button, Image, Toast } from "antd-mobile"; import { Button, Image, Toast } from "antd-mobile";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { api } from "../api";
import { api } from "./api"; import { MatrixAppBo } from "../api/generated";
import { MatrixAppBo } from "./api/generated/model/matrix-app-bo"; import { isEnvWeixin } from "../utils/uaUtils";
import { isEnvWeixin } from "./utils/uaUtils";
const DownloadPage = () => { const DownloadPage = () => {
const [app, setApp] = React.useState<MatrixAppBo>(); const [app, setApp] = React.useState<MatrixAppBo>();
const { inviteCode } = useParams(); const { inviteCode } = useParams();
const getApp = async () => {
if (!inviteCode) {
return;
}
const res = await api.getApp(inviteCode);
if (res.data.code !== 0) {
return;
}
setApp(res.data.data);
};
useEffect(() => { useEffect(() => {
const getApp = async () => {
if (!inviteCode) {
return;
}
const res = await api.getApp(inviteCode);
if (res.data.code !== 0) {
return;
}
setApp(res.data.data);
};
getApp(); getApp();
}, []); }, [inviteCode]);
return ( return (
<div <div

82
src/page/MyQRCodePage.tsx

@ -0,0 +1,82 @@
import { Avatar, List } from "antd-mobile";
import * as htmlToImage from "html-to-image";
import { QRCodeSVG } from "qrcode.react";
import { useEffect, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import { userApi } from "../api";
import { UserBo } from "../api/generated";
const MyQRCodePage = () => {
const pageRef = useRef<HTMLDivElement>(null);
const [user, setUser] = useState<UserBo>();
const navigate = useNavigate();
// const [imageUrl, setImageUrl] = useState("");
const convertToImage = async () => {
if (pageRef.current) {
const dataUrl = await htmlToImage.toJpeg(pageRef.current, {
quality: 0.95,
backgroundColor: "white",
});
// setImageUrl(dataUrl);
//下载
const link = document.createElement("a");
link.download = "page.jpeg";
link.href = dataUrl;
link.click();
}
};
useEffect(() => {
const getUser = async () => {
const res = await userApi.currentUser1();
if (res.data.code !== 0) {
if (res.data.code === -88888) {
navigate("/home");
return;
}
}
setUser(res.data.data);
};
getUser();
}, [navigate]);
return (
<div>
<div ref={pageRef} style={{ padding: 20 }}>
<List
style={{
border: "none",
marginBottom: 20,
}}
>
<List.Item
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
border: "none",
}}
prefix={<Avatar src={user?.avatar || ""} />}
description="邀请你一起玩"
>
{user?.nickname}
</List.Item>
</List>
<div
style={{ width: "100%", display: "flex", justifyContent: "center" }}
>
<QRCodeSVG value={user?.inviteUrl || ""} />
</div>
</div>
<p style={{ textAlign: "center" }} onClick={convertToImage}>
</p>
</div>
);
};
export default MyQRCodePage;

34
src/RegisterPage.tsx → src/page/RegisterPage.tsx

@ -2,10 +2,8 @@
import { Button, Form, Input, Toast, Image } from "antd-mobile"; import { Button, Form, Input, Toast, Image } from "antd-mobile";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { api } from "../api";
import { api } from "./api"; import { MatrixAppBo, RegisterBo } from "../api/generated";
import { RegisterBo } from "./api/generated/model/register-bo";
import { MatrixAppBo } from "./api/generated/model/matrix-app-bo";
const RegisterPage = () => { const RegisterPage = () => {
const [count, setCount] = React.useState(60); const [count, setCount] = React.useState(60);
@ -44,7 +42,7 @@ const RegisterPage = () => {
}); });
return; return;
} }
const res = await api.sendCode(mobile); const res = await api.sendCode(mobile, "register");
if (res.data.code !== 0) { if (res.data.code !== 0) {
Toast.show({ Toast.show({
content: res.data.message, content: res.data.message,
@ -68,20 +66,22 @@ const RegisterPage = () => {
}, 60000); }, 60000);
}; };
const getApp = async () => {
if (!inviteCode) {
return;
}
const res = await api.getApp(inviteCode);
if (res.data.code !== 0) {
return;
}
setApp(res.data.data);
};
useEffect(() => { useEffect(() => {
const getApp = async () => {
if (!inviteCode) {
return;
}
const res = await api.getApp(inviteCode);
if (res.data.code !== 0) {
Toast.show({
content: res.data.message,
});
return;
}
setApp(res.data.data);
};
getApp(); getApp();
}, []); }, [inviteCode]);
return ( return (
<div style={{ maxWidth: 500, margin: "auto" }}> <div style={{ maxWidth: 500, margin: "auto" }}>

95
src/page/UserPage.tsx

@ -0,0 +1,95 @@
import React, { useEffect } from "react";
import { UserBo } from "../api/generated/model/user-bo";
import { userApi } from "../api";
import { useNavigate } from "react-router-dom";
import { Avatar, List } from "antd-mobile";
import {
PayCircleOutline,
SetOutline,
UnorderedListOutline,
} from "antd-mobile-icons";
import { cent2Yuan, formatIncome } from "../utils/numberUtils";
import {
AlipayOutlined,
GiftOutlined,
LineChartOutlined,
TeamOutlined,
} from "@ant-design/icons";
const UserPage = () => {
const [user, setUser] = React.useState<UserBo>();
const navigate = useNavigate();
useEffect(() => {
const getUser = async () => {
const res = await userApi.currentUser1();
if (res.data.code !== 0) {
if (res.data.code === -88888) {
navigate("/home");
return;
}
}
setUser(res.data.data);
};
getUser();
}, [navigate]);
return (
<div
style={{
height: "100%",
maxWidth: 500,
margin: "auto",
// paddingTop: 20,
}}
>
<List>
<List.Item
prefix={<Avatar src={user?.avatar || ""} />}
description={"uid:" + user?.id}
>
{user?.nickname}
</List.Item>
</List>
<List mode="card" header="提现数据">
<List.Item
prefix={<LineChartOutlined />}
extra={formatIncome(user?.income) + "元"}
>
</List.Item>
<List.Item
prefix={<PayCircleOutline />}
extra={cent2Yuan(user?.money) + "元"}
>
</List.Item>
<List.Item prefix={<UnorderedListOutline />} onClick={() => {}}>
</List.Item>
<List.Item prefix={<AlipayOutlined />} extra="修改" onClick={() => {}}>
</List.Item>
</List>
<List mode="card" header="个人信息">
<List.Item
prefix={<GiftOutlined />}
onClick={() => {
navigate("/myCode");
}}
>
</List.Item>
<List.Item prefix={<TeamOutlined />} onClick={() => {}}>
</List.Item>
<List.Item prefix={<SetOutline />} onClick={() => {}}>
</List.Item>
</List>
</div>
);
};
export default UserPage;

106
src/page/login/LoginByCode.tsx

@ -0,0 +1,106 @@
import { Button, Form, Input, Toast } from "antd-mobile";
import React, { FC } from "react";
import { useParams } from "react-router-dom";
import { api } from "../../api";
import { LoginReq } from "../../api/generated";
interface LoginByCodeProps {
appCode: string;
onSuccess: () => void;
}
const LoginByCode: FC<LoginByCodeProps> = (params: LoginByCodeProps) => {
const [count, setCount] = React.useState(60);
const [form] = Form.useForm();
const { appCode } = useParams();
const onFinish = async (values: LoginReq) => {
const res = await api.loginByCode(values);
if (res.data.code !== 0) {
Toast.show({ content: res.data.message });
return;
}
params.onSuccess();
};
const send = async () => {
const values = form.getFieldsValue();
const mobile: string = values.mobile;
if (!mobile) {
Toast.show({
content: "请输入手机号",
});
return;
}
const res = await api.sendCode(mobile, "login");
if (res.data.code !== 0) {
Toast.show({
content: res.data.message,
});
return;
}
Toast.show({
content: "验证码发送成功:" + mobile,
});
startCountdown();
};
const startCountdown = () => {
setCount(60);
const timer = setInterval(() => {
setCount((count) => count - 1);
}, 1000);
setTimeout(() => {
clearInterval(timer);
setCount(60);
}, 60000);
};
return (
<Form
onFinish={onFinish}
layout="horizontal"
mode="card"
form={form}
initialValues={{ appCode: appCode }}
>
<Form.Item
name="mobile"
label="手机号"
rules={[
{ required: true, message: "请输入手机号" },
{ pattern: /^1\d{10}$/, message: "手机号格式错误" },
]}
>
<Input placeholder="请输入手机号" maxLength={11} />
</Form.Item>
<Form.Item
name="code"
label="短信验证码"
extra={
<Button
size="small"
color="primary"
onClick={send}
disabled={count !== 60}
>
{count === 60 ? "发送验证码" : `${count}s`}
</Button>
}
rules={[{ required: true, message: "请输入短信验证码!" }]}
>
<Input />
</Form.Item>
<Form.Item hidden name="appCode" label="邀请码" disabled>
<Input />
</Form.Item>
<Form.Item>
<Button color="primary" block type="submit">
</Button>
</Form.Item>
</Form>
);
};
export default LoginByCode;

64
src/page/login/LoginByPwd.tsx

@ -0,0 +1,64 @@
import { Button, Form, Input, Toast } from "antd-mobile";
import { FC } from "react";
import { api } from "../../api";
import { LoginReq } from "../../api/generated/model/login-req";
interface LoginByPwdProps {
appCode: string;
onSuccess: () => void;
}
const LoginByPwd: FC<LoginByPwdProps> = (params: LoginByPwdProps) => {
const [form] = Form.useForm();
const { appCode } = params;
const onFinish = async (values: LoginReq) => {
const res = await api.loginByPwd(values);
if (res.data.code !== 0) {
Toast.show({ content: res.data.message });
return;
}
params.onSuccess();
};
return (
<Form
onFinish={onFinish}
layout="horizontal"
mode="card"
form={form}
initialValues={{ appCode: appCode }}
>
<Form.Item
name="mobile"
label="手机号"
rules={[
{ required: true, message: "请输入手机号" },
{ pattern: /^1\d{10}$/, message: "手机号格式错误" },
]}
>
<Input placeholder="请输入手机号" maxLength={11} />
</Form.Item>
<Form.Item
name="pwd"
label="密码"
rules={[{ required: true, message: "请输入密码" }]}
>
<Input type="password" placeholder="请输入密码" />
</Form.Item>
<Form.Item hidden name="appCode" label="appCode" disabled>
<Input />
</Form.Item>
<Form.Item>
<Button color="primary" block type="submit">
</Button>
</Form.Item>
</Form>
);
};
export default LoginByPwd;

98
src/page/login/LoginPage.tsx

@ -0,0 +1,98 @@
import { Image, Swiper, SwiperRef, Tabs, Toast } from "antd-mobile";
import React, { useEffect, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { api } from "../../api";
import { MatrixAppBo } from "../../api/generated";
import LoginByCode from "./LoginByCode";
import LoginByPwd from "./LoginByPwd";
const tabItems = [
{ key: "pwd", title: "密码登录" },
{ key: "code", title: "验证码登录" },
// { key: 'weixin', title: '微信授权' },
];
const LoginPage = () => {
const swiperRef = useRef<SwiperRef>(null);
const [activeIndex, setActiveIndex] = useState(0);
const [app, setApp] = React.useState<MatrixAppBo>();
const isLoggedIn = localStorage.getItem("isLoggedIn"); // 假设登录状态存储在
const navigate = useNavigate();
const { appCode } = useParams();
useEffect(() => {
if (isLoggedIn) {
navigate("/home");
}
const getApp = async () => {
if (!appCode) {
return;
}
const res = await api.getApp(undefined, appCode);
if (res.data.code !== 0) {
Toast.show({
content: res.data.message,
});
return;
}
setApp(res.data.data);
};
getApp();
}, [appCode, isLoggedIn, navigate]);
const onSuccess = () => {
localStorage.setItem("isLoggedIn", "true");
navigate("/home");
};
return (
<>
{app && appCode && (
<div style={{ maxWidth: 500, margin: "auto" }}>
<Image
style={{ margin: "auto", paddingTop: 20 }}
src={app?.img}
width={100}
height={100}
/>
<p style={{ textAlign: "center", fontSize: 20, fontWeight: "bold" }}>
{app?.name}
</p>
<Tabs
activeKey={tabItems[activeIndex].key}
onChange={(key) => {
const index = tabItems.findIndex((item) => item.key === key);
setActiveIndex(index);
swiperRef.current?.swipeTo(index);
}}
>
{tabItems.map((item) => (
<Tabs.Tab title={item.title} key={item.key} />
))}
</Tabs>
<Swiper
direction="horizontal"
loop
indicator={() => null}
ref={swiperRef}
defaultIndex={activeIndex}
onIndexChange={(index) => {
setActiveIndex(index);
}}
>
<Swiper.Item>
<LoginByPwd appCode={appCode} onSuccess={onSuccess} />
</Swiper.Item>
<Swiper.Item>
<LoginByCode appCode={appCode} onSuccess={onSuccess} />
</Swiper.Item>
</Swiper>
</div>
)}
</>
);
};
export default LoginPage;

13
src/utils/numberUtils.tsx

@ -0,0 +1,13 @@
export const formatIncome = (v: number | undefined) => {
if (!v) {
return 0;
}
return parseFloat((v / 1000_00).toFixed(2));
};
export const cent2Yuan = (v: number | undefined) => {
if (!v) {
return 0;
}
return parseFloat((v / 100).toFixed(2));
};
Loading…
Cancel
Save