Jelajahi Sumber

page-login;page-mine ;登录部分实现

林财明 5 bulan lalu
induk
melakukan
cc61136203
33 mengubah file dengan 976 tambahan dan 305 penghapusan
  1. 22 20
      CraftsMart-angular/README.md
  2. 637 5
      CraftsMart-angular/package-lock.json
  3. 1 1
      CraftsMart-angular/package.json
  4. 3 0
      CraftsMart-angular/src/app/app-routing.module.ts
  5. 7 0
      CraftsMart-angular/src/app/app.component.ts
  6. 9 0
      CraftsMart-angular/src/app/app.module.ts
  7. 4 2
      CraftsMart-angular/src/modules/craftsmart/craftsmart-routing.module.ts
  8. 3 0
      CraftsMart-angular/src/modules/craftsmart/craftsmart.module.ts
  9. 6 3
      CraftsMart-angular/src/modules/craftsmart/page-chat-panel/page-chat-panel.component.html
  10. 40 0
      CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.html
  11. 0 0
      CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.scss
  12. 0 0
      CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.spec.ts
  13. 125 0
      CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.ts
  14. 18 21
      CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.html
  15. 32 25
      CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.ts
  16. 0 17
      CraftsMart-angular/src/modules/user/auth.guard.spec.ts
  17. 0 15
      CraftsMart-angular/src/modules/user/auth.guard.ts
  18. 0 1
      CraftsMart-angular/src/modules/user/page-info/page-info.component.html
  19. 0 0
      CraftsMart-angular/src/modules/user/page-info/page-info.component.scss
  20. 0 21
      CraftsMart-angular/src/modules/user/page-info/page-info.component.spec.ts
  21. 0 10
      CraftsMart-angular/src/modules/user/page-info/page-info.component.ts
  22. 0 20
      CraftsMart-angular/src/modules/user/page-login/page-login.component.html
  23. 0 29
      CraftsMart-angular/src/modules/user/page-login/page-login.component.ts
  24. 0 1
      CraftsMart-angular/src/modules/user/page-register/page-register.component.html
  25. 0 0
      CraftsMart-angular/src/modules/user/page-register/page-register.component.scss
  26. 0 21
      CraftsMart-angular/src/modules/user/page-register/page-register.component.spec.ts
  27. 0 10
      CraftsMart-angular/src/modules/user/page-register/page-register.component.ts
  28. 0 10
      CraftsMart-angular/src/modules/user/user-routing.module.ts
  29. 0 23
      CraftsMart-angular/src/modules/user/user.module.ts
  30. 0 16
      CraftsMart-angular/src/modules/user/user.service.spec.ts
  31. 0 34
      CraftsMart-angular/src/modules/user/user.service.ts
  32. 31 0
      CraftsMart-angular/src/parse.js
  33. 38 0
      CraftsMart-angular/test.js

+ 22 - 20
CraftsMart-angular/README.md

@@ -1,27 +1,29 @@
-# CraftsMartAngular
+项目概述;项目概述:
+本项目旨在打造一个手工艺品展示平台,突出手工艺品的匠心精神和非物质文化遗产的价值。通过网页端展示,用户可以浏览热门手工艺品、冈藏品列表,并深入了解每个冈藏品的详情和3D展示。平台还提供多语言的故事讲解和AI问答功能,以增加用户的互动体验。此外,平台将根据用户的偏好和喜好进行内容推荐,并定期举办特别活动。手工艺品按照分类(手工艺、非遗、数藏)进行归类,并支持根据风格和喜好进行搜索。平台还提供作者认证和作品发布功能,以促进手工艺品创作者的参与。
 
-This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 16.2.2.
+产品价值:
+1. 传承非物质文化遗产:通过展示手工艺品,平台将非物质文化遗产传承给更多的人,保护和弘扬传统工艺技艺。
+2. 匠心精神的展示:平台突出手工艺品的匠心精神,让用户深入了解手工艺品背后的故事和制作工艺。
+3. 互动体验:用户可以通过故事讲解和AI问答功能与手工艺品进行互动,提出问题并获得专业的回答,增强用户的参与感。
+4. 个性化推荐:根据用户的偏好和喜好,平台提供个性化的内容推荐,帮助用户发现更多符合其兴趣的手工艺品。
+5. 创作者参与:平台提供作者认证和作品发布功能,鼓励手工艺品创作者积极参与平台,展示自己的作品并与用户互动。
 
-## Development server
+技术可行性:
+项目中使用AI生成冈藏品的故事和整理提示词,以及AI互动的藏品讲解功能。同时,网页端展示3D模型需要使用渲染引擎,如Babylon.js、Three.js或Cocos 3D。这些技术在实现上是可行的,并且已经有成熟的工具和框架可供使用。
 
-Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
 
-## Code scaffolding
+系统名称:手艺之窗App
+所属行业:文创手工艺品电商平台
 
-Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
+手艺之窗App是一款专注于本地特色手工艺品和非物质文化遗产的电商平台。我们致力于提供一个较低门槛的购物平台,让用户能够方便地购买到景德镇手工陶瓷等限量销售的手工艺品。
 
-## Build
+主要功能和内容:
+1. 首页:展示热门手工艺品和特别活动,为用户提供最新的推荐内容。
+2. 藏品列表和详情:展示各类手工艺品的详细信息,包括名称、类别、作者、朝代、地理位置等,让用户了解每个藏品的背后故事。
+3. 3D展示区域:通过虚拟现实技术,让用户可以全方位地欣赏手工艺品的细节和美感。
+4. 藏品介绍:提供多语言的藏品讲解,让用户更深入地了解每个手工艺品的文化背景和制作工艺。
+5. AI问答:通过人工智能技术,回答用户关于手工艺品制作工艺、生产流程和非遗文化等方面的问题。
+6. 探索:提供分类浏览功能,用户可以根据手工艺、非遗和数藏等分类进行浏览,也可以根据风格、喜好等进行搜索。
+7. 我的:用户可以收藏和关注自己喜爱的手工艺品,同时也可以进行作者认证和作品发布。
 
-Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
-
-## Running unit tests
-
-Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
-
-## Running end-to-end tests
-
-Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
-
-## Further help
-
-To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
+手艺之窗App的主要价值在于传承和推广本地特色手工艺品和非物质文化遗产,让更多人了解和欣赏到这些匠心独具的艺术品。通过AI生成的藏品故事和互动讲解,用户可以更深入地了解每个手工艺品的背后故事和文化内涵。我们希望通过这个平台,让手工艺品得到更广泛的认可和传承,同时也为用户提供一个便捷的购物体验。

+ 637 - 5
CraftsMart-angular/package-lock.json

@@ -7,6 +7,7 @@
     "": {
       "name": "crafts-mart-angular",
       "version": "0.0.0",
+      "license": "ISC",
       "dependencies": {
         "@angular/animations": "^16.2.0",
         "@angular/common": "^16.2.0",
@@ -16,8 +17,9 @@
         "@angular/platform-browser": "^16.2.0",
         "@angular/platform-browser-dynamic": "^16.2.0",
         "@angular/router": "^16.2.0",
+        "@capacitor/android": "^5.6.0",
+        "@capacitor/core": "^5.6.0",
         "@ionic/angular": "^7.5.6",
-        "@types/parse": "^3.0.8",
         "babylonjs": "^6.27.1",
         "parse": "^4.3.1",
         "rxjs": "~7.8.0",
@@ -28,9 +30,11 @@
         "@angular-devkit/build-angular": "^16.2.2",
         "@angular/cli": "~16.2.2",
         "@angular/compiler-cli": "^16.2.0",
+        "@capacitor/cli": "^5.6.0",
         "@compodoc/compodoc": "^1.1.23",
         "@ionic/angular-toolkit": "latest",
         "@types/jasmine": "~4.3.0",
+        "@types/parse": "^3.0.9",
         "jasmine-core": "~4.6.0",
         "karma": "~6.4.0",
         "karma-chrome-launcher": "~3.2.0",
@@ -2372,6 +2376,132 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@capacitor/android": {
+      "version": "5.7.6",
+      "resolved": "https://registry.npmmirror.com/@capacitor/android/-/android-5.7.6.tgz",
+      "integrity": "sha512-oOavLrvdB5JcMMrvV7a086/4gpDuCTkesUlcw/JOA6ByMuZGEVZ5jFkXtGNIS+nw+b+FAj5SbordtkMW3ghhBQ==",
+      "peerDependencies": {
+        "@capacitor/core": "^5.7.0"
+      }
+    },
+    "node_modules/@capacitor/cli": {
+      "version": "5.7.6",
+      "resolved": "https://registry.npmmirror.com/@capacitor/cli/-/cli-5.7.6.tgz",
+      "integrity": "sha512-CDDcBF7wHm5v/j0dA2bls0vK954XlD1JCjMuTgLtjZMvWrIlTJAkwCQLkiqRhS2P63AXqfqQqkb/qs2RHc1zDQ==",
+      "dev": true,
+      "dependencies": {
+        "@ionic/cli-framework-output": "^2.2.5",
+        "@ionic/utils-fs": "^3.1.6",
+        "@ionic/utils-subprocess": "^2.1.11",
+        "@ionic/utils-terminal": "^2.3.3",
+        "commander": "^9.3.0",
+        "debug": "^4.3.4",
+        "env-paths": "^2.2.0",
+        "kleur": "^4.1.4",
+        "native-run": "^2.0.0",
+        "open": "^8.4.0",
+        "plist": "^3.0.5",
+        "prompts": "^2.4.2",
+        "rimraf": "^4.4.1",
+        "semver": "^7.3.7",
+        "tar": "^6.1.11",
+        "tslib": "^2.4.0",
+        "xml2js": "^0.5.0"
+      },
+      "bin": {
+        "cap": "bin/capacitor",
+        "capacitor": "bin/capacitor"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@capacitor/cli/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@capacitor/cli/node_modules/commander": {
+      "version": "9.5.0",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-9.5.0.tgz",
+      "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+      "dev": true,
+      "engines": {
+        "node": "^12.20.0 || >=14"
+      }
+    },
+    "node_modules/@capacitor/cli/node_modules/glob": {
+      "version": "9.3.5",
+      "resolved": "https://registry.npmmirror.com/glob/-/glob-9.3.5.tgz",
+      "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "minimatch": "^8.0.2",
+        "minipass": "^4.2.4",
+        "path-scurry": "^1.6.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@capacitor/cli/node_modules/minimatch": {
+      "version": "8.0.4",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-8.0.4.tgz",
+      "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@capacitor/cli/node_modules/minipass": {
+      "version": "4.2.8",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-4.2.8.tgz",
+      "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@capacitor/cli/node_modules/rimraf": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-4.4.1.tgz",
+      "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^9.2.0"
+      },
+      "bin": {
+        "rimraf": "dist/cjs/src/bin.js"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@capacitor/core": {
+      "version": "5.7.6",
+      "resolved": "https://registry.npmmirror.com/@capacitor/core/-/core-5.7.6.tgz",
+      "integrity": "sha512-YVCNegFg04Pm6Rfc6KbZT2wnxAUzhcyi3b+MWFj+FwUOOFNmnGkzxCFo4tQakXFblfOK6pU0Va5XuiNs1+Fnow==",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
     "node_modules/@colors/colors": {
       "version": "1.5.0",
       "resolved": "https://registry.npmmirror.com/@colors/colors/-/colors-1.5.0.tgz",
@@ -3456,6 +3586,20 @@
         "@schematics/angular": "^16.0.0"
       }
     },
+    "node_modules/@ionic/cli-framework-output": {
+      "version": "2.2.8",
+      "resolved": "https://registry.npmmirror.com/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz",
+      "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==",
+      "dev": true,
+      "dependencies": {
+        "@ionic/utils-terminal": "2.3.5",
+        "debug": "^4.0.0",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
     "node_modules/@ionic/core": {
       "version": "7.5.6",
       "resolved": "https://registry.npmmirror.com/@ionic/core/-/core-7.5.6.tgz",
@@ -3466,6 +3610,192 @@
         "tslib": "^2.1.0"
       }
     },
+    "node_modules/@ionic/utils-array": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-array/-/utils-array-2.1.6.tgz",
+      "integrity": "sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.0.0",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-fs": {
+      "version": "3.1.7",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-fs/-/utils-fs-3.1.7.tgz",
+      "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==",
+      "dev": true,
+      "dependencies": {
+        "@types/fs-extra": "^8.0.0",
+        "debug": "^4.0.0",
+        "fs-extra": "^9.0.0",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-fs/node_modules/fs-extra": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "dev": true,
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@ionic/utils-fs/node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/@ionic/utils-fs/node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-object": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-object/-/utils-object-2.1.6.tgz",
+      "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.0.0",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-process": {
+      "version": "2.1.11",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-process/-/utils-process-2.1.11.tgz",
+      "integrity": "sha512-Uavxn+x8j3rDlZEk1X7YnaN6wCgbCwYQOeIjv/m94i1dzslqWhqIHEqxEyeE8HsT5Negboagg7GtQiABy+BLbA==",
+      "dev": true,
+      "dependencies": {
+        "@ionic/utils-object": "2.1.6",
+        "@ionic/utils-terminal": "2.3.4",
+        "debug": "^4.0.0",
+        "signal-exit": "^3.0.3",
+        "tree-kill": "^1.2.2",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-process/node_modules/@ionic/utils-terminal": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-terminal/-/utils-terminal-2.3.4.tgz",
+      "integrity": "sha512-cEiMFl3jklE0sW60r8JHH3ijFTwh/jkdEKWbylSyExQwZ8pPuwoXz7gpkWoJRLuoRHHSvg+wzNYyPJazIHfoJA==",
+      "dev": true,
+      "dependencies": {
+        "@types/slice-ansi": "^4.0.0",
+        "debug": "^4.0.0",
+        "signal-exit": "^3.0.3",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "tslib": "^2.0.1",
+        "untildify": "^4.0.0",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-stream": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-stream/-/utils-stream-3.1.6.tgz",
+      "integrity": "sha512-4+Kitey1lTA1yGtnigeYNhV/0tggI3lWBMjC7tBs1K9GXa/q7q4CtOISppdh8QgtOhrhAXS2Igp8rbko/Cj+lA==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.0.0",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-subprocess": {
+      "version": "2.1.14",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-subprocess/-/utils-subprocess-2.1.14.tgz",
+      "integrity": "sha512-nGYvyGVjU0kjPUcSRFr4ROTraT3w/7r502f5QJEsMRKTqa4eEzCshtwRk+/mpASm0kgBN5rrjYA5A/OZg8ahqg==",
+      "dev": true,
+      "dependencies": {
+        "@ionic/utils-array": "2.1.6",
+        "@ionic/utils-fs": "3.1.7",
+        "@ionic/utils-process": "2.1.11",
+        "@ionic/utils-stream": "3.1.6",
+        "@ionic/utils-terminal": "2.3.4",
+        "cross-spawn": "^7.0.3",
+        "debug": "^4.0.0",
+        "tslib": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-subprocess/node_modules/@ionic/utils-terminal": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-terminal/-/utils-terminal-2.3.4.tgz",
+      "integrity": "sha512-cEiMFl3jklE0sW60r8JHH3ijFTwh/jkdEKWbylSyExQwZ8pPuwoXz7gpkWoJRLuoRHHSvg+wzNYyPJazIHfoJA==",
+      "dev": true,
+      "dependencies": {
+        "@types/slice-ansi": "^4.0.0",
+        "debug": "^4.0.0",
+        "signal-exit": "^3.0.3",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "tslib": "^2.0.1",
+        "untildify": "^4.0.0",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/@ionic/utils-terminal": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmmirror.com/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz",
+      "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==",
+      "dev": true,
+      "dependencies": {
+        "@types/slice-ansi": "^4.0.0",
+        "debug": "^4.0.0",
+        "signal-exit": "^3.0.3",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "tslib": "^2.0.1",
+        "untildify": "^4.0.0",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
     "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
       "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -4137,6 +4467,15 @@
         "@types/send": "*"
       }
     },
+    "node_modules/@types/fs-extra": {
+      "version": "8.1.5",
+      "resolved": "https://registry.npmmirror.com/@types/fs-extra/-/fs-extra-8.1.5.tgz",
+      "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/http-errors": {
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.2.tgz",
@@ -4174,14 +4513,16 @@
       "version": "20.8.4",
       "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.8.4.tgz",
       "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==",
+      "dev": true,
       "dependencies": {
         "undici-types": "~5.25.1"
       }
     },
     "node_modules/@types/parse": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmmirror.com/@types/parse/-/parse-3.0.8.tgz",
-      "integrity": "sha512-yjrykSxZZ8iBXFlyXv2zZnvoZSDJUOe1B1qudXm89eJaLD4d6rfOPe/oz9sf7bdLh9VBdXPVgRAmmgzNqorW8Q==",
+      "version": "3.0.9",
+      "resolved": "https://registry.npmmirror.com/@types/parse/-/parse-3.0.9.tgz",
+      "integrity": "sha512-DGTHygc7krgmNAK8h42giwmAofCd9uv2++RD+zw6OmWI7AEnlTYZwEuWsx22SA2CSMQrZW8P2INHLpQbnQFUng==",
+      "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
@@ -4234,6 +4575,12 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/slice-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/@types/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==",
+      "dev": true
+    },
     "node_modules/@types/sockjs": {
       "version": "0.3.34",
       "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.34.tgz",
@@ -4493,6 +4840,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/@xmldom/xmldom": {
+      "version": "0.8.10",
+      "resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+      "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
     "node_modules/@xtuc/ieee754": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -4939,12 +5295,30 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/astral-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
       "dev": true
     },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
     "node_modules/autoprefixer": {
       "version": "10.4.14",
       "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz",
@@ -5106,6 +5480,15 @@
       "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==",
       "dev": true
     },
+    "node_modules/big-integer": {
+      "version": "1.6.52",
+      "resolved": "https://registry.npmmirror.com/big-integer/-/big-integer-1.6.52.tgz",
+      "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
     "node_modules/big.js": {
       "version": "5.2.2",
       "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
@@ -5206,6 +5589,18 @@
         "pnpm": ">=8.6.0"
       }
     },
+    "node_modules/bplist-parser": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/bplist-parser/-/bplist-parser-0.3.2.tgz",
+      "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==",
+      "dev": true,
+      "dependencies": {
+        "big-integer": "1.6.x"
+      },
+      "engines": {
+        "node": ">= 5.10.0"
+      }
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -5312,6 +5707,15 @@
         "ieee754": "^1.1.13"
       }
     },
+    "node_modules/buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmmirror.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/buffer-equal": {
       "version": "0.0.1",
       "resolved": "https://registry.npmmirror.com/buffer-equal/-/buffer-equal-0.0.1.tgz",
@@ -6604,6 +7008,24 @@
       "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==",
       "dev": true
     },
+    "node_modules/elementtree": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmmirror.com/elementtree/-/elementtree-0.1.7.tgz",
+      "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==",
+      "dev": true,
+      "dependencies": {
+        "sax": "1.1.4"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/elementtree/node_modules/sax": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.1.4.tgz",
+      "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==",
+      "dev": true
+    },
     "node_modules/emitter-component": {
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/emitter-component/-/emitter-component-1.1.2.tgz",
@@ -7363,6 +7785,15 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/fd-slicer": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/fd-slicer/-/fd-slicer-1.1.0.tgz",
+      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+      "dev": true,
+      "dependencies": {
+        "pend": "~1.2.0"
+      }
+    },
     "node_modules/figures": {
       "version": "3.2.0",
       "resolved": "https://registry.npmmirror.com/figures/-/figures-3.2.0.tgz",
@@ -9158,6 +9589,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/kleur": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmmirror.com/kleur/-/kleur-4.1.5.tgz",
+      "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/klona": {
       "version": "2.0.6",
       "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",
@@ -10063,6 +10503,40 @@
         "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
       }
     },
+    "node_modules/native-run": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/native-run/-/native-run-2.0.1.tgz",
+      "integrity": "sha512-XfG1FBZLM50J10xH9361whJRC9SHZ0Bub4iNRhhI61C8Jv0e1ud19muex6sNKB51ibQNUJNuYn25MuYET/rE6w==",
+      "dev": true,
+      "dependencies": {
+        "@ionic/utils-fs": "^3.1.7",
+        "@ionic/utils-terminal": "^2.3.4",
+        "bplist-parser": "^0.3.2",
+        "debug": "^4.3.4",
+        "elementtree": "^0.1.7",
+        "ini": "^4.1.1",
+        "plist": "^3.1.0",
+        "split2": "^4.2.0",
+        "through2": "^4.0.2",
+        "tslib": "^2.6.2",
+        "yauzl": "^2.10.0"
+      },
+      "bin": {
+        "native-run": "bin/native-run"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/native-run/node_modules/through2": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz",
+      "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "3"
+      }
+    },
     "node_modules/needle": {
       "version": "3.2.0",
       "resolved": "https://registry.npmmirror.com/needle/-/needle-3.2.0.tgz",
@@ -11023,6 +11497,12 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+      "dev": true
+    },
     "node_modules/picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
@@ -11132,6 +11612,20 @@
         "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       }
     },
+    "node_modules/plist": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/plist/-/plist-3.1.0.tgz",
+      "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
+      "dev": true,
+      "dependencies": {
+        "@xmldom/xmldom": "^0.8.8",
+        "base64-js": "^1.5.1",
+        "xmlbuilder": "^15.1.1"
+      },
+      "engines": {
+        "node": ">=10.4.0"
+      }
+    },
     "node_modules/png-js": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/png-js/-/png-js-1.0.0.tgz",
@@ -11309,6 +11803,28 @@
         "node": ">=10"
       }
     },
+    "node_modules/prompts": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz",
+      "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+      "dev": true,
+      "dependencies": {
+        "kleur": "^3.0.3",
+        "sisteransi": "^1.0.5"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/prompts/node_modules/kleur": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz",
+      "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/propagating-hammerjs": {
       "version": "1.5.0",
       "resolved": "https://registry.npmmirror.com/propagating-hammerjs/-/propagating-hammerjs-1.5.0.tgz",
@@ -12280,6 +12796,12 @@
         "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
+    "node_modules/sisteransi": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz",
+      "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+      "dev": true
+    },
     "node_modules/slash": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz",
@@ -12289,6 +12811,56 @@
         "node": ">=12"
       }
     },
+    "node_modules/slice-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
     "node_modules/smart-buffer": {
       "version": "4.2.0",
       "resolved": "https://registry.npmmirror.com/smart-buffer/-/smart-buffer-4.2.0.tgz",
@@ -12546,6 +13118,15 @@
         "node": "*"
       }
     },
+    "node_modules/split2": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz",
+      "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.x"
+      }
+    },
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -13325,7 +13906,8 @@
     "node_modules/undici-types": {
       "version": "5.25.3",
       "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.25.3.tgz",
-      "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
+      "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
+      "dev": true
     },
     "node_modules/unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
@@ -13441,6 +14023,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/untildify": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/untildify/-/untildify-4.0.0.tgz",
+      "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/update-browserslist-db": {
       "version": "1.0.13",
       "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
@@ -14183,6 +14774,37 @@
       "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
       "dev": true
     },
+    "node_modules/xml2js": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.5.0.tgz",
+      "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+      "dev": true,
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/xml2js/node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/xmlbuilder": {
+      "version": "15.1.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
     "node_modules/xmlchars": {
       "version": "2.2.0",
       "resolved": "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz",
@@ -14257,6 +14879,16 @@
         "node": ">=12"
       }
     },
+    "node_modules/yauzl": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+      "dev": true,
+      "dependencies": {
+        "buffer-crc32": "~0.2.3",
+        "fd-slicer": "~1.1.0"
+      }
+    },
     "node_modules/yocto-queue": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-1.0.0.tgz",

+ 1 - 1
CraftsMart-angular/package.json

@@ -21,7 +21,6 @@
     "@capacitor/android": "^5.6.0",
     "@capacitor/core": "^5.6.0",
     "@ionic/angular": "^7.5.6",
-    "@types/parse": "^3.0.8",
     "babylonjs": "^6.27.1",
     "parse": "^4.3.1",
     "rxjs": "~7.8.0",
@@ -36,6 +35,7 @@
     "@compodoc/compodoc": "^1.1.23",
     "@ionic/angular-toolkit": "latest",
     "@types/jasmine": "~4.3.0",
+    "@types/parse": "^3.0.9",
     "jasmine-core": "~4.6.0",
     "karma": "~6.4.0",
     "karma-chrome-launcher": "~3.2.0",

+ 3 - 0
CraftsMart-angular/src/app/app-routing.module.ts

@@ -5,8 +5,10 @@ import { NavTabsComponent } from 'src/modules/craftsmart/nav-tabs/nav-tabs.compo
 import { PageCartComponent } from 'src/modules/craftsmart/page-cart/page-cart.component';
 import { PageChatPanelComponent } from 'src/modules/craftsmart/page-chat-panel/page-chat-panel.component';
 import { PageItemDetailComponent } from 'src/modules/craftsmart/page-item-detail/page-item-detail.component';
+import { PageLoginComponent } from 'src/modules/craftsmart/page-login/page-login.component';
 import { PageMineComponent } from 'src/modules/craftsmart/page-mine/page-mine.component';
 
+
 const routes: Routes = [
    {path:"",redirectTo:"/craftsmart/home",pathMatch:"full" },
    {path:'craftsmart', loadChildren:() => import('../modules/craftsmart/craftsmart.module').then(m => m.CraftsmartModule)},
@@ -14,6 +16,7 @@ const routes: Routes = [
    { path: 'nav-tabs', component: NavTabsComponent },
    { path: 'page-cart', component: PageCartComponent },
    { path: 'page-mine', component: PageMineComponent },
+   { path: 'page-login', component: PageLoginComponent },
    {path:'page-item-detail/:name',component:PageItemDetailComponent},
    {path:'page-chat-panel',component:PageChatPanelComponent}
 ];

+ 7 - 0
CraftsMart-angular/src/app/app.component.ts

@@ -1,4 +1,7 @@
 import { Component } from '@angular/core';
+import Parse from 'parse';
+Parse.initialize("dev");
+Parse.serverURL = 'http://web2023.fmode.cn:9999/parse';
 
 @Component({
   selector: 'app-root',
@@ -7,4 +10,8 @@ import { Component } from '@angular/core';
 })
 export class AppComponent {
   title = 'CraftsMart';
+  constructor() {
+
+
+  }
 }

+ 9 - 0
CraftsMart-angular/src/app/app.module.ts

@@ -12,6 +12,9 @@ import { PageMineComponent } from 'src/modules/craftsmart/page-mine/page-mine.co
 import { NavTabsComponent } from 'src/modules/craftsmart/nav-tabs/nav-tabs.component';
 import { NgModule ,CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
 import { PageDiscoverComponent } from 'src/modules/craftsmart/page-discover/page-discover.component';
+import { PageLoginComponent } from 'src/modules/craftsmart/page-login/page-login.component';
+// import { PageLoginComponent } from 'src/modules/user/page-login/page-login.component';
+
 
 
 const routes: Routes = [
@@ -19,6 +22,12 @@ const routes: Routes = [
   { path: 'cart', component: PageCartComponent },
   {path:'discover',component:PageDiscoverComponent},
   { path: 'mine', component: PageMineComponent },
+  { path: 'login', component: PageLoginComponent },
+
+
+  // { path: 'login', component: PageLoginComponent },
+
+
 ];
 
 @NgModule({

+ 4 - 2
CraftsMart-angular/src/modules/craftsmart/craftsmart-routing.module.ts

@@ -6,8 +6,9 @@ import { PageMineComponent } from './page-mine/page-mine.component';
 import { NavTabsComponent } from './nav-tabs/nav-tabs.component';
 import { PageDiscoverComponent } from './page-discover/page-discover.component';
 import { PageItemDetailComponent } from './page-item-detail/page-item-detail.component';
-import { authGuard } from '../user/auth.guard';
 import { PageChatPanelComponent } from './page-chat-panel/page-chat-panel.component';
+import { PageLoginComponent } from './page-login/page-login.component';
+
 
 const routes: Routes = [
   {
@@ -16,12 +17,13 @@ const routes: Routes = [
       { path:"home", component:HomeComponent },
       { path:"page-cart", component:PageCartComponent },
       { path:"page-mine", component:PageMineComponent },
+      { path:"page-login", component:PageLoginComponent },
       { path:"page-discover", component:PageDiscoverComponent },
       { path:"page-item-detail/:name", component:PageItemDetailComponent },
       {path:"page-chat-panel",component:PageChatPanelComponent},
     ]
   },
-  { path: 'detail', component: PageItemDetailComponent, canActivate: [authGuard] },
+  { path: 'detail', component: PageItemDetailComponent },
   { path: '**', redirectTo: 'home', pathMatch: 'full' }
 ];
 

+ 3 - 0
CraftsMart-angular/src/modules/craftsmart/craftsmart.module.ts

@@ -10,6 +10,8 @@ import { PageMineComponent } from './page-mine/page-mine.component';
 import { HomeComponent } from './home/home.component';
 import { PageChatPanelComponent } from './page-chat-panel/page-chat-panel.component';
 import { FormsModule } from '@angular/forms';
+import { PageLoginComponent } from './page-login/page-login.component';
+
 
 @NgModule({
   declarations: [
@@ -19,6 +21,7 @@ import { FormsModule } from '@angular/forms';
     PageMineComponent,
     HomeComponent,
     PageChatPanelComponent,
+    PageLoginComponent,
     
   ],
   imports: [

+ 6 - 3
CraftsMart-angular/src/modules/craftsmart/page-chat-panel/page-chat-panel.component.html

@@ -39,12 +39,15 @@
         </div>
         <!-- 底部:用户输入 -->
         <div class="footer">
-            <ion-item>
+            <ion-list>
+                <ion-item>
                 <ion-textarea  [(ngModel)]="userInput"
-                 labelPlacement="floating"
-                 label="请输入:" placeholder="提示词"></ion-textarea>
+                labelPlacement="fixed"
+                 placeholder="请输入详细提示词"></ion-textarea>
                  <ion-button (click)="send()">发送</ion-button>
             </ion-item>
+        </ion-list>
+            
         </div>
     </div>
 </div>

+ 40 - 0
CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.html

@@ -0,0 +1,40 @@
+<ion-content>
+  <ion-header [translucent]="true">
+    <ion-toolbar>
+      <ion-title>登录/注册</ion-title>
+    </ion-toolbar>
+  </ion-header>
+  
+  <ion-content [fullscreen]="true">
+    <ion-header collapse="condense">
+      <ion-toolbar>
+        <ion-title size="large">登录/注册</ion-title>
+      </ion-toolbar>
+    </ion-header>
+  
+    <ion-card>
+      <ion-card-header>
+        <ion-card-title>登录/注册</ion-card-title>
+      </ion-card-header>
+    
+      <ion-card-content>
+  
+        <ion-list [inset]="true">
+          <ion-item>
+            <ion-input [(ngModel)]="userName" label="账号" placeholder="请输入用户名"></ion-input>
+          </ion-item>
+          <ion-item>
+            <ion-input [(ngModel)]="password" label="密码" type="password" placeholder="请输入密码"></ion-input>
+          </ion-item>
+        </ion-list>
+       
+      </ion-card-content>
+    
+      <ion-button (click)="login()" fill="clear">登录</ion-button>
+      <ion-button (click)="register()" fill="clear">注册</ion-button>
+    </ion-card>
+  
+    <!-- 新增路由返回逻辑,执行back函数 -->
+    <ion-button expand="block" (click)="back()">返回</ion-button>
+  </ion-content>
+  

+ 0 - 0
CraftsMart-angular/src/modules/user/page-login/page-login.component.scss → CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.scss


+ 0 - 0
CraftsMart-angular/src/modules/user/page-login/page-login.component.spec.ts → CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.spec.ts


+ 125 - 0
CraftsMart-angular/src/modules/craftsmart/page-login/page-login.component.ts

@@ -0,0 +1,125 @@
+import { Component } from '@angular/core';
+import { AlertController, NavController } from '@ionic/angular';
+import Parse from 'parse';
+Parse.initialize("dev");
+Parse.serverURL = 'http://web2023.fmode.cn:9999/parse';
+
+@Component({
+  selector: 'app-page-login',
+  templateUrl: './page-login.component.html',
+  styleUrls: ['./page-login.component.scss']
+})
+export class PageLoginComponent {
+
+  userName: string = "";
+  password: string = "";
+
+  constructor(
+    private navCtrl: NavController,
+    private alertController: AlertController
+  ) { }
+
+  async login() {
+    let user1;
+    try {
+
+      // user1 = await Parse.User.logIn(this.userName,this.password)
+      const query = new Parse.Query('LcmUser');
+      query.equalTo('username', this.userName);
+      query.equalTo('password', this.password);
+      user1 = await query.first();
+
+      // 登录成功后保存用户信息到本地存储
+    if (user1) {
+      localStorage.setItem('currentUser', JSON.stringify(user1.toJSON()));
+    }
+
+    } catch (error: any) {
+      let message: string = "";
+      // 新增提示词详情,根据查询错误信息设置不同的中文提示信息
+      if (error?.message.indexOf("is required") > -1) {
+        message = "必须输入账号或邮箱";
+      }
+      if (error?.message.indexOf("Invalid username") > -1) {
+        message = "账号或密码错误,请检查";
+      }
+      this.presentAlert({
+        header: "登录失败",
+        subHeader: "状态码:" + error.code,
+        message: message || error.message
+      });
+    }
+
+    console.log(user1);
+    if (user1?.id) {
+      this.navCtrl.back();
+
+    }
+  }
+
+  // async login() {
+  //   let user;
+  //   try {
+  //       const query = new Parse.Query('LcmUser');
+  //       query.equalTo('username', this.userName);
+  //       query.equalTo('password', this.password);
+  //       user = await query.first();
+  //   } catch (error: any) {
+  //       let message: string = "";
+  //       if (error?.message.indexOf("is required") > -1) {
+  //           message = "必须输入账号或邮箱";
+  //       }
+  //       if (error?.message.indexOf("Invalid username") > -1) {
+  //           message = "账号或密码错误,请检查";
+  //       }
+  //       this.presentAlert({
+  //           header: "登录失败",
+  //           subHeader: "状态码:" + error.code,
+  //           message: message || error.message
+  //       });
+  //   }
+
+  //   console.log(user);
+  //   if (user?.id) {
+  //       this.navCtrl.back();
+  //   }
+  // }
+
+  async register() {
+    let LcmUser = Parse.Object.extend("LcmUser");
+    let user = new LcmUser();
+    user.set("username", this.userName);
+    user.set("password", this.password);
+
+    try {
+      let result = await user.save();
+      console.log(result);
+      if (result.id) {
+        this.navCtrl.back();
+      }
+    } catch (error: any) {
+      let message: string = "注册失败,请重试";
+      this.presentAlert({
+        header: "注册失败",
+        subHeader: "错误信息",
+        message: message
+      });
+    }
+  }
+
+  async presentAlert(options: { header: string, subHeader: string, message: string }) {
+    const alert = await this.alertController.create({
+      header: options?.header,
+      subHeader: options?.subHeader,
+      message: options?.message,
+      buttons: ['好的'],
+    });
+
+    await alert.present();
+  }
+
+  back() {
+    this.navCtrl.back();
+  }
+
+}

+ 18 - 21
CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.html

@@ -5,7 +5,7 @@
     <ion-avatar aria-hidden="true" slot="start">
       <img alt="" src="../../../assets/image/head.jpg" />
     </ion-avatar>
-    <ion-label>Fooie</ion-label>
+    <ion-label>{{user1?.get("username") || '未登录'}}</ion-label>
   </ion-item>
 
   <ion-list [inset]="true">
@@ -13,6 +13,10 @@
   </ion-list>
   
   <ion-list [inset]="true"  class="zoom-list">
+    <ion-item [button]="true">
+      <ion-icon color="warning" slot="start" name="list-circle" size="large"></ion-icon>
+      <ion-label>钱包</ion-label>
+    </ion-item>
     <ion-item [button]="true">
       <ion-icon color="danger" slot="start" name="list-circle" size="large"></ion-icon>
       <ion-label>订单</ion-label>
@@ -28,28 +32,21 @@
       <ion-label>足迹</ion-label>
       <ion-note slot="end">3</ion-note>
     </ion-item>
-    <ion-item [button]="true">
-      <ion-icon color="warning" slot="start" name="list-circle" size="large"></ion-icon>
-      <ion-label>钱包</ion-label>
-    </ion-item>
   </ion-list>
 
-  
- <div class="center-container">
-  <ion-button id="open-toast" (click)="presentToast('top')" class="center-list">登  入</ion-button>
-  <ion-toast
-    trigger="登入"
-    [duration]="3000"
-    message="请先登录!"
-    class="custom-toast"
-    [buttons]="toastButtons" 
-  ></ion-toast>
- </div>
+<ion-card>
+  <ion-card-header>
+    <ion-card-title>{{user1?.get("username") || '未登录'}}</ion-card-title>
+    <ion-card-subtitle *ngIf="!user1?.id">请您登陆后继续使用</ion-card-subtitle>
+    <ion-card-subtitle *ngIf="user1?.id">{{user1?.get("username")}}-{{user1?.get("gender")}}</ion-card-subtitle>
+  </ion-card-header>
+
+  <!-- 新增:根据用户状态,显示登录/登出按钮,执行跳转或登出函数 -->
+  <ion-button *ngIf="!user1?.id" fill="clear" routerLink="/craftsmart/page-login">登录</ion-button>
+  <ion-button *ngIf="user1?.id" fill="clear" routerLink="/user/edit/info">编辑资料</ion-button>
+ <ion-button *ngIf="user1?.id" fill="clear" (click)="logout()">登出</ion-button>
+</ion-card>
+
 
- <ion-fab >
-  <ion-fab-button (click)="goToHome()">
-    <ion-icon name="exit-outline"></ion-icon>
-  </ion-fab-button>
-</ion-fab>
   </ion-content>
 

+ 32 - 25
CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.ts

@@ -1,40 +1,47 @@
-import { Component } from '@angular/core';
-import { ToastController } from '@ionic/angular';
-import { Router } from '@angular/router';
+import { Component, OnInit } from '@angular/core';
+import { AlertController, NavController } from '@ionic/angular';
+import Parse from 'parse';
+
+Parse.initialize("dev");
+Parse.serverURL = 'http://web2023.fmode.cn:9999/parse';
 
 @Component({
   selector: 'app-page-mine',
   templateUrl: './page-mine.component.html',
   styleUrls: ['./page-mine.component.scss']
 })
-export class PageMineComponent {
-  // 其他代码...
-  toastButtons = [
-    {
-      text: '关闭',
-      role: 'cancel'
-    }
-  ];
+export class PageMineComponent implements OnInit {
 
+  private _user1: Parse.User | undefined;
 
-  constructor(private toastCtrl: ToastController, private router: Router) {}
-
-  // 其他方法...
+  constructor() {
+    this.updateUserInfo();
+  }
 
-  async presentToast(position: 'top' | 'bottom' | 'middle') {
-    const toast = await this.toastCtrl.create({
-      message: '请先登录!',
-      duration: 3000,
-      position: position,
-      buttons: this.toastButtons
-    });
+  get user1(): Parse.User | undefined {
+    return this._user1;
+  }
 
-    toast.present();
+  updateUserInfo() {
+    const currentUserString = localStorage.getItem('currentUser');
+    console.log('Current user string:', currentUserString);
+    if (currentUserString) {
+      const currentUser = JSON.parse(currentUserString);
+      console.log('Parsed current user:', currentUser);
+      this._user1 = new Parse.User(currentUser);
+      console.log('Updated user1:', this._user1);
+    }
   }
 
+  ngOnInit() {
+  }
 
-  
-  goToHome() {
-    this.router.navigate(['/home']);
+  async logout() {
+    console.log('Logging out...');
+    await Parse.User.logOut();
+    console.log('User logged out');
+    localStorage.removeItem('currentUser');
+    console.log('Local storage removed');
+    this.updateUserInfo();
   }
 }

+ 0 - 17
CraftsMart-angular/src/modules/user/auth.guard.spec.ts

@@ -1,17 +0,0 @@
-import { TestBed } from '@angular/core/testing';
-import { CanActivateFn } from '@angular/router';
-
-import { authGuard } from './auth.guard';
-
-describe('authGuard', () => {
-  const executeGuard: CanActivateFn = (...guardParameters) => 
-      TestBed.runInInjectionContext(() => authGuard(...guardParameters));
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({});
-  });
-
-  it('should be created', () => {
-    expect(executeGuard).toBeTruthy();
-  });
-});

+ 0 - 15
CraftsMart-angular/src/modules/user/auth.guard.ts

@@ -1,15 +0,0 @@
-import { CanActivateFn } from '@angular/router';
-
-export const authGuard: CanActivateFn = (route, state) => {
-  // 检查当前本地存储中,是否有用户验证信息
-  let userAuth = localStorage.getItem("USER_AUTH")
-  if(userAuth){
-    return true;
-  }else{
-    // 暂时存储登陆前用户所在页面
-    let REDIRECT_URL = location.pathname;
-    localStorage.setItem("REDIRECT_URL",REDIRECT_URL);
-    location.href = "/user/login"
-    return false;
-  }
-};

+ 0 - 1
CraftsMart-angular/src/modules/user/page-info/page-info.component.html

@@ -1 +0,0 @@
-<p>page-info works!</p>

+ 0 - 0
CraftsMart-angular/src/modules/user/page-info/page-info.component.scss


+ 0 - 21
CraftsMart-angular/src/modules/user/page-info/page-info.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { PageInfoComponent } from './page-info.component';
-
-describe('PageInfoComponent', () => {
-  let component: PageInfoComponent;
-  let fixture: ComponentFixture<PageInfoComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [PageInfoComponent]
-    });
-    fixture = TestBed.createComponent(PageInfoComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 10
CraftsMart-angular/src/modules/user/page-info/page-info.component.ts

@@ -1,10 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
-  selector: 'app-page-info',
-  templateUrl: './page-info.component.html',
-  styleUrls: ['./page-info.component.scss']
-})
-export class PageInfoComponent {
-
-}

+ 0 - 20
CraftsMart-angular/src/modules/user/page-login/page-login.component.html

@@ -1,20 +0,0 @@
-<ion-card>
-    <ion-card-header>
-      登录
-    </ion-card-header>
-  
-    <ion-card-content>
-      <ion-item>
-        <ion-label position="floating">用户名</ion-label>
-        <ion-input [(ngModel)]="userData.username" type="text"></ion-input>
-      </ion-item>
-  
-      <ion-item>
-        <ion-label position="floating">密码</ion-label>
-        <ion-input [(ngModel)]="userData.password" type="password"></ion-input>
-      </ion-item>
-  
-      <ion-button expand="full" (click)="login()">登录</ion-button>
-    </ion-card-content>
-  </ion-card>
-  

+ 0 - 29
CraftsMart-angular/src/modules/user/page-login/page-login.component.ts

@@ -1,29 +0,0 @@
-import { Component } from '@angular/core';
-import { Router } from '@angular/router';
-import { UserService } from '../user.service';
-@Component({
-  selector: 'app-page-login',
-  templateUrl: './page-login.component.html',
-  styleUrls: ['./page-login.component.scss']
-})
-export class PageLoginComponent {
-
-  constructor(private userServ:UserService,private router:Router){}
-  userData:any = {
-    username:"",
-    password:""
-  }
-
-  login(){
-    console.log(this.userData)
-    try{
-      let isLogin = this.userServ.checkUserPassword(this.userData)
-      if(isLogin){
-        let path = localStorage.getItem("REDIRECT_URL") || "/lesson/home"
-        this.router.navigate([path])
-      }
-    }catch(err){
-      alert(err)
-    }
-  }
-}

+ 0 - 1
CraftsMart-angular/src/modules/user/page-register/page-register.component.html

@@ -1 +0,0 @@
-<p>page-register works!</p>

+ 0 - 0
CraftsMart-angular/src/modules/user/page-register/page-register.component.scss


+ 0 - 21
CraftsMart-angular/src/modules/user/page-register/page-register.component.spec.ts

@@ -1,21 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { PageRegisterComponent } from './page-register.component';
-
-describe('PageRegisterComponent', () => {
-  let component: PageRegisterComponent;
-  let fixture: ComponentFixture<PageRegisterComponent>;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      declarations: [PageRegisterComponent]
-    });
-    fixture = TestBed.createComponent(PageRegisterComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});

+ 0 - 10
CraftsMart-angular/src/modules/user/page-register/page-register.component.ts

@@ -1,10 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
-  selector: 'app-page-register',
-  templateUrl: './page-register.component.html',
-  styleUrls: ['./page-register.component.scss']
-})
-export class PageRegisterComponent {
-
-}

+ 0 - 10
CraftsMart-angular/src/modules/user/user-routing.module.ts

@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { RouterModule, Routes } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
-  imports: [RouterModule.forChild(routes)],
-  exports: [RouterModule]
-})
-export class UserRoutingModule { }

+ 0 - 23
CraftsMart-angular/src/modules/user/user.module.ts

@@ -1,23 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { UserRoutingModule } from './user-routing.module';
-import { PageLoginComponent } from './page-login/page-login.component';
-import { PageRegisterComponent } from './page-register/page-register.component';
-import { PageInfoComponent } from './page-info/page-info.component';
-import { FormsModule } from '@angular/forms';
-import { IonicModule } from '@ionic/angular';
-
-@NgModule({
-  declarations: [
-    PageLoginComponent,
-    PageRegisterComponent,
-    PageInfoComponent
-  ],
-  imports: [
-    CommonModule,
-    UserRoutingModule,
-    FormsModule,
-    IonicModule
-  ]
-})
-export class UserModule { }

+ 0 - 16
CraftsMart-angular/src/modules/user/user.service.spec.ts

@@ -1,16 +0,0 @@
-import { TestBed } from '@angular/core/testing';
-
-import { UserService } from './user.service';
-
-describe('UserService', () => {
-  let service: UserService;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({});
-    service = TestBed.inject(UserService);
-  });
-
-  it('should be created', () => {
-    expect(service).toBeTruthy();
-  });
-});

+ 0 - 34
CraftsMart-angular/src/modules/user/user.service.ts

@@ -1,34 +0,0 @@
-import { Injectable } from '@angular/core';
-
-@Injectable({
-  providedIn: 'root'
-})
-export class UserService {
-
-  constructor() { }
-
-  UserList = [
-    {username:"123",password:"123"},
-    {username:"qian",password:"duoduo"},
-  ]
-  /**
-   * 检查用户密码是否正确
-   */
-  checkUserPassword(user:{
-    username:string
-    password:string
-  }){
-    // 根据username查询用户信息
-    let exists = this.UserList.find(item=>item.username == user.username)
-    if(!exists){
-      throw "该用户不存在"
-    }
-    // 验证该用户密码是否正确
-    if(exists.password != user.password){
-      throw "用户密码错误"
-    }
-
-    localStorage.setItem("USER_AUTH",JSON.stringify(exists))
-    return true
-  }
-}

+ 31 - 0
CraftsMart-angular/src/parse.js

@@ -0,0 +1,31 @@
+const Parse = require("parse/node")
+Parse.initialize("dev")
+Parse.serverURL = 'http://web2023.fmode.cn:9999/parse'
+
+
+async function main(){
+    let LcmUser = Parse.Object.extend("LcmUser")
+
+    // //创建数据有效
+
+    // let user1 = new LcmUser();
+    // user1.set("userName","小明")
+    // user1.set("userId",123123)
+    // user1.set("password","123456678")
+    // user1.set("stuno","027")
+
+    // let result = await user1.save();
+    // console.log(result)
+
+    //修改用户有效
+    let query = new Parse.Query(LcmUser)
+    query.equalTo("objectId","cHIzeBP8R3") // 注意这里是使用正确的方法名 equalTo 查询 objectId
+    let user1 = await query.first();
+    console.log(user1.toJSON())
+    user1.set("stuno","127")
+    let result =await user1.save();
+    console.log(result.toJSON())
+
+}
+
+main()

+ 38 - 0
CraftsMart-angular/test.js

@@ -0,0 +1,38 @@
+async function getStudentByNo(stuno){
+    let whereCondition = ``
+    if(stuno){
+        whereCondition = `\"where\":{\"stuno\":\"${stuno}\"},`
+    }
+    let response = await fetch("http://web2023.fmode.cn:9999/parse/classes/LcmUser", {
+    "headers": {
+        "accept": "*/*",
+        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
+        "content-type": "text/plain"
+    },
+    "referrer": "http://localhost:4040/",
+    "referrerPolicy": "strict-origin-when-cross-origin",
+    "body": `{`+whereCondition+`\"limit\":200,\"order\":\"createdAt\",\"_method\":\"GET\",\"_ApplicationId\":\"dev\",\"_ClientVersion\":\"js3.4.2\",\"_MasterKey\":\"devmk\",\"_InstallationId\":\"6ea3aea6-b781-4fba-b709-5de81c8a0fda\"}`,
+    "method": "POST",
+    "mode": "cors",
+    "credentials": "omit"
+    });
+    let result = await response.json();
+    if(stuno){
+        return result?.results?.[0]
+    }else{
+        return result?.results
+    }
+}
+module.exports.getStudentByNo = getStudentByNo
+
+async function main() {
+    let student = await getStudentByNo("007");
+    console.log(student)
+    console.log(student?.objectId)
+    let studentList = await getStudentByNo();
+    console.log(studentList)
+}
+
+main()
+
+module.exports.getStudentByNo = getStudentByNo