Browse Source

init: web3-0210427

林财明 10 tháng trước cách đây
mục cha
commit
01603df9c5
54 tập tin đã thay đổi với 1387 bổ sung637 xóa
  1. 71 4
      CraftsMart-angular/angular.json
  2. 274 215
      CraftsMart-angular/package-lock.json
  3. 6 1
      CraftsMart-angular/package.json
  4. 2 1
      CraftsMart-angular/src/app/app-routing.module.ts
  5. 1 0
      CraftsMart-angular/src/app/app.component.html
  6. 1 2
      CraftsMart-angular/src/app/app.component.ts
  7. 16 5
      CraftsMart-angular/src/app/app.module.ts
  8. BIN
      CraftsMart-angular/src/assets/image/bcg1.jpg
  9. BIN
      CraftsMart-angular/src/assets/image/cp1.jpg
  10. BIN
      CraftsMart-angular/src/assets/image/discover.jpg
  11. BIN
      CraftsMart-angular/src/assets/image/head.jpg
  12. BIN
      CraftsMart-angular/src/assets/image/home.jpg
  13. BIN
      CraftsMart-angular/src/assets/image/jic1.jpg
  14. BIN
      CraftsMart-angular/src/assets/image/jic2.png
  15. BIN
      CraftsMart-angular/src/assets/image/mine.jpg
  16. 3 2
      CraftsMart-angular/src/modules/craftsmart/craftsmart-routing.module.ts
  17. 10 7
      CraftsMart-angular/src/modules/craftsmart/craftsmart.module.ts
  18. 40 24
      CraftsMart-angular/src/modules/craftsmart/home/home.component.html
  19. 109 290
      CraftsMart-angular/src/modules/craftsmart/home/home.component.scss
  20. 51 66
      CraftsMart-angular/src/modules/craftsmart/home/home.component.ts
  21. 2 1
      CraftsMart-angular/src/modules/craftsmart/nav-tabs/nav-tabs.component.scss
  22. 5 4
      CraftsMart-angular/src/modules/craftsmart/nav-tabs/nav-tabs.component.ts
  23. 44 1
      CraftsMart-angular/src/modules/craftsmart/page-cart/page-cart.component.html
  24. 133 3
      CraftsMart-angular/src/modules/craftsmart/page-cart/page-cart.component.scss
  25. 59 2
      CraftsMart-angular/src/modules/craftsmart/page-cart/page-cart.component.ts
  26. 29 1
      CraftsMart-angular/src/modules/craftsmart/page-discover/page-discover.component.html
  27. 47 0
      CraftsMart-angular/src/modules/craftsmart/page-discover/page-discover.component.scss
  28. 21 1
      CraftsMart-angular/src/modules/craftsmart/page-item-detail/page-item-detail.component.html
  29. 56 0
      CraftsMart-angular/src/modules/craftsmart/page-item-detail/page-item-detail.component.scss
  30. 25 2
      CraftsMart-angular/src/modules/craftsmart/page-item-detail/page-item-detail.component.ts
  31. 56 1
      CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.html
  32. 33 0
      CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.scss
  33. 7 4
      CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.spec.ts
  34. 30 0
      CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.ts
  35. 17 0
      CraftsMart-angular/src/modules/user/auth.guard.spec.ts
  36. 15 0
      CraftsMart-angular/src/modules/user/auth.guard.ts
  37. 1 0
      CraftsMart-angular/src/modules/user/page-info/page-info.component.html
  38. 0 0
      CraftsMart-angular/src/modules/user/page-info/page-info.component.scss
  39. 21 0
      CraftsMart-angular/src/modules/user/page-info/page-info.component.spec.ts
  40. 10 0
      CraftsMart-angular/src/modules/user/page-info/page-info.component.ts
  41. 20 0
      CraftsMart-angular/src/modules/user/page-login/page-login.component.html
  42. 0 0
      CraftsMart-angular/src/modules/user/page-login/page-login.component.scss
  43. 21 0
      CraftsMart-angular/src/modules/user/page-login/page-login.component.spec.ts
  44. 29 0
      CraftsMart-angular/src/modules/user/page-login/page-login.component.ts
  45. 1 0
      CraftsMart-angular/src/modules/user/page-register/page-register.component.html
  46. 0 0
      CraftsMart-angular/src/modules/user/page-register/page-register.component.scss
  47. 21 0
      CraftsMart-angular/src/modules/user/page-register/page-register.component.spec.ts
  48. 10 0
      CraftsMart-angular/src/modules/user/page-register/page-register.component.ts
  49. 10 0
      CraftsMart-angular/src/modules/user/user-routing.module.ts
  50. 23 0
      CraftsMart-angular/src/modules/user/user.module.ts
  51. 16 0
      CraftsMart-angular/src/modules/user/user.service.spec.ts
  52. 34 0
      CraftsMart-angular/src/modules/user/user.service.ts
  53. 6 0
      CraftsMart-angular/src/theme/variables.css
  54. 1 0
      CraftsMart-angular/tsconfig.json

+ 71 - 4
CraftsMart-angular/angular.json

@@ -27,10 +27,48 @@
             "inlineStyleLanguage": "scss",
             "assets": [
               "src/favicon.ico",
-              "src/assets"
+              "src/assets",
+              {
+                "glob": "**/*.svg",
+                "input": "node_modules/ionicons/dist/ionicons/svg",
+                "output": "./svg"
+              }
             ],
             "styles": [
-              "src/styles.scss"
+              "src/styles.scss",
+              {
+                "input": "node_modules/@ionic/angular/css/core.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/normalize.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/structure.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/typography.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/display.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/padding.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/float-elements.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/text-alignment.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/text-transformation.css"
+              },
+              {
+                "input": "node_modules/@ionic/angular/css/flex-utils.css"
+              },
+              {
+                "input": "src/theme/variables.css"
+              }
             ],
             "scripts": []
           },
@@ -90,13 +128,42 @@
             "inlineStyleLanguage": "scss",
             "assets": [
               "src/favicon.ico",
-              "src/assets"
+              "src/assets",
+              {
+                "glob": "**/*.svg",
+                "input": "node_modules/ionicons/dist/ionicons/svg",
+                "output": "./svg"
+              }
             ],
             "styles": [
               "src/styles.scss"
             ],
             "scripts": []
           }
+        },
+        "ionic-cordova-serve": {
+          "builder": "@ionic/angular-toolkit:cordova-serve",
+          "options": {
+            "cordovaBuildTarget": "CraftsMart-angular:ionic-cordova-build",
+            "devServerTarget": "CraftsMart-angular:serve"
+          },
+          "configurations": {
+            "production": {
+              "cordovaBuildTarget": "CraftsMart-angular:ionic-cordova-build:production",
+              "devServerTarget": "CraftsMart-angular:serve:production"
+            }
+          }
+        },
+        "ionic-cordova-build": {
+          "builder": "@ionic/angular-toolkit:cordova-build",
+          "options": {
+            "browserTarget": "CraftsMart-angular:build"
+          },
+          "configurations": {
+            "production": {
+              "browserTarget": "CraftsMart-angular:build:production"
+            }
+          }
         }
       }
     }
@@ -104,4 +171,4 @@
   "cli": {
     "analytics": "79472871-679b-4872-a9ce-1884006e16dc"
   }
-}
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 274 - 215
CraftsMart-angular/package-lock.json


+ 6 - 1
CraftsMart-angular/package.json

@@ -14,11 +14,14 @@
     "@angular/common": "^16.2.0",
     "@angular/compiler": "^16.2.0",
     "@angular/core": "^16.2.0",
-    "@angular/forms": "^16.2.0",
+    "@angular/forms": "^16.2.12",
     "@angular/platform-browser": "^16.2.0",
     "@angular/platform-browser-dynamic": "^16.2.0",
     "@angular/router": "^16.2.0",
+    "@ionic/angular": "^7.5.6",
+    "@types/parse": "^3.0.8",
     "babylonjs": "^6.27.1",
+    "parse": "^4.3.1",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",
     "zone.js": "~0.13.0"
@@ -27,6 +30,8 @@
     "@angular-devkit/build-angular": "^16.2.2",
     "@angular/cli": "~16.2.2",
     "@angular/compiler-cli": "^16.2.0",
+    "@compodoc/compodoc": "^1.1.23",
+    "@ionic/angular-toolkit": "latest",
     "@types/jasmine": "~4.3.0",
     "jasmine-core": "~4.6.0",
     "karma": "~6.4.0",

+ 2 - 1
CraftsMart-angular/src/app/app-routing.module.ts

@@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router';
 import { HomeComponent } from 'src/modules/craftsmart/home/home.component';
 import { NavTabsComponent } from 'src/modules/craftsmart/nav-tabs/nav-tabs.component';
 import { PageCartComponent } from 'src/modules/craftsmart/page-cart/page-cart.component';
+import { PageItemDetailComponent } from 'src/modules/craftsmart/page-item-detail/page-item-detail.component';
 import { PageMineComponent } from 'src/modules/craftsmart/page-mine/page-mine.component';
 
 const routes: Routes = [
@@ -12,7 +13,7 @@ const routes: Routes = [
    { path: 'nav-tabs', component: NavTabsComponent },
    { path: 'page-cart', component: PageCartComponent },
    { path: 'page-mine', component: PageMineComponent },
-
+   {path:'page-item-detail/:name',component:PageItemDetailComponent},
 ];
 
 @NgModule({

+ 1 - 0
CraftsMart-angular/src/app/app.component.html

@@ -1,4 +1,5 @@
 
+<app-nav-tabs></app-nav-tabs> <!-- 添加底部导航栏 -->
 
 <router-outlet></router-outlet>
 

+ 1 - 2
CraftsMart-angular/src/app/app.component.ts

@@ -6,6 +6,5 @@ import { Component } from '@angular/core';
   styleUrls: ['./app.component.scss']
 })
 export class AppComponent {
-  // TypeScript代码
-  title = 'CraftsMart'; // 添加了title属性
+  title = 'CraftsMart';
 }

+ 16 - 5
CraftsMart-angular/src/app/app.module.ts

@@ -1,30 +1,41 @@
-import { NgModule } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
 import { AppRoutingModule } from './app-routing.module';
 import { RouterModule, Routes } from '@angular/router'; // 导入 RouterModule 和 Routes
-
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';
+import { IonicModule } from '@ionic/angular';
 
 import { AppComponent } from './app.component';
 import { HomeComponent } from 'src/modules/craftsmart/home/home.component';
 import { PageCartComponent } from 'src/modules/craftsmart/page-cart/page-cart.component';
 import { PageMineComponent } from 'src/modules/craftsmart/page-mine/page-mine.component';
+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';
 
 const routes: Routes = [
   { path: 'home', component: HomeComponent },
   { path: 'cart', component: PageCartComponent },
+  {path:'discover',component:PageDiscoverComponent},
   { path: 'mine', component: PageMineComponent },
 ];
 
 @NgModule({
   declarations: [
-    AppComponent
+    AppComponent,
+    NavTabsComponent
   ],
   imports: [
     BrowserModule,
     AppRoutingModule,
-    RouterModule.forRoot(routes) // 在这里配置根路由
+    FormsModule,
+    CommonModule,
+    RouterModule.forRoot(routes),
+    IonicModule.forRoot() // 在这里配置根路由
   ],
   providers: [],
-  bootstrap: [AppComponent]
+  bootstrap: [AppComponent],
+  schemas: [CUSTOM_ELEMENTS_SCHEMA] // 添加 CUSTOM_ELEMENTS_SCHEMA
+
 })
 export class AppModule { }

BIN
CraftsMart-angular/src/assets/image/bcg1.jpg


BIN
CraftsMart-angular/src/assets/image/cp1.jpg


BIN
CraftsMart-angular/src/assets/image/discover.jpg


BIN
CraftsMart-angular/src/assets/image/head.jpg


BIN
CraftsMart-angular/src/assets/image/home.jpg


BIN
CraftsMart-angular/src/assets/image/jic1.jpg


BIN
CraftsMart-angular/src/assets/image/jic2.png


BIN
CraftsMart-angular/src/assets/image/mine.jpg


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

@@ -6,11 +6,11 @@ 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';
 
 const routes: Routes = [
   {
-    path:"",
-    component:NavTabsComponent,
+    path:"",component:NavTabsComponent,
     children:[
       { path:"home", component:HomeComponent },
       { path:"page-cart", component:PageCartComponent },
@@ -19,6 +19,7 @@ const routes: Routes = [
       { path:"page-item-detail/:name", component:PageItemDetailComponent }
     ]
   },
+  { path: 'detail', component: PageItemDetailComponent, canActivate: [authGuard] },
   { path: '**', redirectTo: 'home', pathMatch: 'full' }
 ];
 

+ 10 - 7
CraftsMart-angular/src/modules/craftsmart/craftsmart.module.ts

@@ -1,28 +1,31 @@
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
-import { NavTabsComponent } from './nav-tabs/nav-tabs.component';
-import { PageMineComponent } from './page-mine/page-mine.component';
 import { PageCartComponent } from './page-cart/page-cart.component';
 import { RouterModule } from '@angular/router';
 import { CraftsmartRoutingModule } from './craftsmart-routing.module';
 import { PageDiscoverComponent } from './page-discover/page-discover.component';
 import { PageItemDetailComponent } from './page-item-detail/page-item-detail.component';
+import { IonicModule } from '@ionic/angular';
+import { PageMineComponent } from './page-mine/page-mine.component';
+import { HomeComponent } from './home/home.component';
+
 
 @NgModule({
   declarations: [
-    NavTabsComponent,
-    PageMineComponent,
     PageCartComponent,
     PageDiscoverComponent,
-    PageItemDetailComponent
+    PageItemDetailComponent,
+    PageMineComponent,
+    HomeComponent,
+    
   ],
   imports: [
     CommonModule,
     RouterModule,
-    CraftsmartRoutingModule
+    CraftsmartRoutingModule,
+    IonicModule,
   ],
   exports:[
-    NavTabsComponent,
     PageCartComponent,
     PageMineComponent
   ]

+ 40 - 24
CraftsMart-angular/src/modules/craftsmart/home/home.component.html

@@ -8,33 +8,49 @@
     </svg>
   </div>
   <!-- 购物区域 -->
-  <div class="shopping-area">
-    <div class="filter-tags">
-      <!-- 筛选标签 -->
-      <div class="filter-tag" >
-            <button (click)="showItemList('热门')">热门</button>
-      </div>
-      <div class="filter-tag" >
-            <button (click)="showItemList('推荐')">推荐</button>
-      </div>
-      <div class="filter-tag" >
-            <button (click)="showItemList('活动')">活动</button>
-      </div>
+  <!-- 购物区域 -->
+<div class="shopping-area">
+  <div class="filter-tags">
+    <!-- 筛选标签 -->
+    <div class="filter-tag">
+      <button (click)="showContent('module-one')">热门</button>
+    </div>
+    <div class="filter-tag">
+      <button (click)="showContent('module-two')">推荐</button>
+    </div>
+    <div class="filter-tag">
+      <button (click)="showContent('module-three')">3D全息</button>
+    </div>
+  </div>
+  <!-- 显示数据 -->
+  <div *ngIf="currentContent === 'module-one'" class="imageurl" >
+    <div *ngFor="let item of items">
+      <div  (click)="selectItem(item)">
+        <img [src]="item.imgUrl" alt="Item Image" />
+      <h3>{{ item.name }}</h3>
     </div>
-    <ul class="image-grid">
-  <li *ngFor="let homeObj of itemList">
-    <div class="image-item" (click)="goToItemDetail(homeObj.name)">
-      <img [src]="sanitizer.bypassSecurityTrustUrl('/assets/image/cp1.jpg')" alt="Digital Collectible">
-      <p>{{ homeObj.description }}</p>
-      <p >{{ homeObj.name }}</p> <!-- 添加点击事件绑定 -->
     </div>
+  </div>
 
-    <div class="image-item2" (click)="goToItemDetail(homeObj.name)">
-      <img [src]="sanitizer.bypassSecurityTrustUrl('./assets/image/cp1.jpg')" alt="Digital Collectible">
-      <p>{{ homeObj.description }}</p>
-      <p >{{ homeObj.name }}</p> <!-- 添加点击事件绑定 -->
+  <div *ngIf="currentContent === 'module-two'" class="imageurl">
+    <!-- 在这里显示 module-two 的内容 -->
+    <div *ngFor="let item of items">
+      <div (click)="selectItem(item)">
+        <img [src]="item.imgUrl" alt="Item Image" />
+      <h3>{{ item.name }}</h3>
+      </div>
     </div>
-  </li>
-</ul>
   </div>
+
+  <div *ngIf="currentContent === 'module-three'" class="imageurl">
+    <!-- 在这里显示 module-three 的内容 -->
+    <div *ngFor="let item of items">
+      <div (click)="selectItem(item)">
+        <img [src]="item.imgUrl" alt="Item Image" />
+      <h3>{{ item.name }}</h3>
+      </div>
+    </div>
+  </div>
+</div>
+
 </div>

+ 109 - 290
CraftsMart-angular/src/modules/craftsmart/home/home.component.scss

@@ -1,309 +1,128 @@
-.page {
-  display: flex;
-  flex-direction: column;
-  min-height: 100vh;
-  padding-bottom: 20px; /* 底部导航栏的高度 */
+html,body{
+  height: 100%;
 }
-
-.search-area {
+.page {
   display: flex;
-  height: 30px; /* 将搜索框的高度设为30px */
-  align-items: center;
-  padding: 10px;
-  position: relative;
-  border: 1px solid #00aa86; /* 添加钝角边框 */
-  border-radius: 14px; /* 设置边框的钝角半径 */
-  margin-bottom: 8px; /* 添加底部间距 */
-}
-
-.search-area input[type="text"] {
-  background-color: #f0f0f0;
-  flex: 1;
-  padding: 12px;
-  border: none;
-  border-radius: 2px;
-  font-size: 16px;
-  text-align: left;
-  box-sizing: border-box;
-}
-
-.search-area input[type="text"]:focus {
-  outline: none; /* 去除默认的聚焦边框 */
-  transition: border-bottom 0.3s ease; /* 添加过渡效果 */
-}
-
-.search-area .search-icon {
-  width: auto; /* 设置搜索icon宽度为自适应 */
-  height: 30px; /* 将搜索框的高度设为60px */
-  margin-left: 5px; /* 调整搜索icon与搜索框的间距 */
-  transform-origin: center; /* 设置变换原点为中心 */
-  transition: transform 0.3s ease, border-color 0.3s ease; /* 添加过渡效果 */
-  cursor: pointer;
-}
-
-.search-area .search-icon:hover {
-  transform: scale(1.1); /* 放大图标 */
-  border-color: #00aa86; /* 边框颜色变为绿色 */
-}
-
-.search-button {
-  background-color: #ccc;
-  padding: 5px;
-  border: none;
-  border-radius: 5px;
-  margin-left: 10px;
-}
-
-.shopping-area {
   flex: 1;
- //border: 1px solid pink;
-  flex-wrap: wrap;
-  .filter-tags {
+  flex-direction: column;
+  overflow: auto;
+  padding-bottom: 20px;
+  
+  .search-area {
+    flex: 0 1 auto;
+    margin-top: 15px;
     display: flex;
-    flex-wrap: wrap;
-    //border: 1px solid purple;
-    .filter-tag {
-      color: rgb(37, 36, 36);
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      width: calc(33.33% - 10px); /* 保留了间距 */
-      height: 40px;
-      //border: 1px solid red;
-      border-radius: 5px;
-      margin-right: 10px;
-      &:last-child {
-        margin-right: 0;
-      }
-    }
-  }
-  .image-grid {
-    margin-top: 0px;
-   //border: 1px solid black; /* 添加了边框样式 */
-    margin-bottom: 40px;
-    padding: 0;
-    li {
-      display: flex;
-      justify-content: space-between;
-      margin-top: 8px;
-      .image-item {
-        border: 1px solid blue; /* 添加了边框样式 */
-        flex: 1;
-        margin-right: 8px;
-
-        img {
-          border: 1px solid green; /* 添加了边框样式 */
-          max-width: 100%;
-          height: auto;
-        }
-      }
-      .image-item2 {
-        border: 1px solid blue; /* 添加了边框样式 */
-        flex: 1;
+    height: 30px;
+    align-items: center;
+    padding: 10px;
+    position: relative;
+    border: 1px solid #ffffff;
+    border-radius: 14px;
+    margin-bottom: 8px;
+    
+    
+    input[type="text"] {
+      background-color: #f0f0f0;
+      flex: 1;
+      padding: 12px;
+      border: none;
+      border-radius: 2px;
+      font-size: 16px;
+      text-align: left;
+      box-sizing: border-box;
+      
+      &:focus {
+        outline: none;
+        transition: border-bottom 0.3s ease;
       }
     }
-  }
-}
-.bottom-navigation {
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  background-color: #ffffff;
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  height: 60px;
-  border: none;
-}
-.tab-button {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  height: 50px;
-  background-color: transparent;
-  border: none;
-  font-size: 4px !important;
-}
-
-// 新增的样式
-以下是完整的修改后的 SCSS 代码:
-
-scss
-复制代码
-.page {
-  display: flex;
-  flex-direction: column;
-  min-height: 100vh;
-  padding-bottom: 20px; /* 底部导航栏的高度 */
-}
-
-.search-area {
-  display: flex;
-  height: 30px; /* 将搜索框的高度设为30px */
-  align-items: center;
-  padding: 10px;
-  position: relative;
-  border: 1px solid #00aa86; /* 添加钝角边框 */
-  border-radius: 14px; /* 设置边框的钝角半径 */
-  margin-bottom: 8px; /* 添加底部间距 */
-}
-
-.search-area input[type="text"] {
-  background-color: #f0f0f0;
-  flex: 1;
-  padding: 12px;
-  border: none;
-  border-radius: 2px;
-  font-size: 16px;
-  text-align: left;
-  box-sizing: border-box;
-}
-
-.search-area input[type="text"]:focus {
-  outline: none; /* 去除默认的聚焦边框 */
-  transition: border-bottom 0.3s ease; /* 添加过渡效果 */
-}
-
-.search-area .search-icon {
-  width: auto; /* 设置搜索icon宽度为自适应 */
-  height: 30px; /* 将搜索框的高度设为60px */
-  margin-left: 5px; /* 调整搜索icon与搜索框的间距 */
-  transform-origin: center; /* 设置变换原点为中心 */
-  transition: transform 0.3s ease, border-color 0.3s ease; /* 添加过渡效果 */
-  cursor: pointer;
-}
-
-.search-area .search-icon:hover {
-  transform: scale(1.1); /* 放大图标 */
-  border-color: #00aa86; /* 边框颜色变为绿色 */
-}
-
-.search-button {
-  background-color: #ccc;
-  padding: 5px;
-  border: none;
-  border-radius: 5px;
-  margin-left: 10px;
-}
-
-.shopping-area {
-  flex: 1;
-  //border: 1px solid pink;
-  flex-wrap: wrap;
-  .filter-tags {
-    display: flex;
-    flex-wrap: wrap;
-    //border: 1px solid purple;
-    .filter-tag {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      width: calc(33.33% - 10px); /* 保留了间距 */
-      height: 40px;
-      //border: 1px solid red;
-      border-radius: 5px;
-      margin-right: 10px;
-      &:last-child {
-        margin-right: 0;
+    
+    .search-icon {
+      width: auto;
+      height: 30px;
+      margin-left: 5px;
+      transform-origin: center;
+      transition: transform 0.3s ease, border-color 0.3s ease;
+      cursor: pointer;
+      
+      &:hover {
+        transform: scale(1.1);
+        border-color: #00aa86;
       }
     }
   }
-
-  .image-grid {
-    margin-top: 0px;
-    //border: 1px solid black; /* 添加了边框样式 */
-    margin-bottom: 40px;
-    padding: 0;
-    li {
+  
+  .shopping-area {
+    flex: 1;
+    overflow: auto;
+    width:100vw;
+height:100vh;
+overflow:scroll;
+    .filter-tags {
       display: flex;
-      justify: space-between;
-      margin-top: 8px;
-      .image-item {
-        border: 1px solid blue; /* 添加了边框样式 */
-        flex: 1;
-        margin-right: 8px;
-
-        img {
-          border: 1px solid green; /* 添加了边框样式 */
-          max-width: 100%;
-          height: auto;
+      flex-wrap: wrap;
+      
+      .filter-tag {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: calc(33.33% - 10px);
+        height: 40px;
+        border-radius: 5px;
+        margin-right: 10px;
+        
+        &:last-child {
+          margin-right: 0;
+        }
+        
+        button {
+          border: none;
+          color: rgb(98, 101, 98);
+          background: none;
+          font-weight: normal;
+          font-size: 16px;
+          margin-right: 10px;
+          cursor: pointer;
+          text-decoration: none;
+          position: relative;
+          transition: all 0.2s ease;
+          
+          &:after {
+            content: "";
+            position: absolute;
+            bottom: -2px;
+            left: 0;
+            width: 100%;
+            height: 2px;
+            background-color: green;
+            opacity: 0;
+            transition: opacity 0.3s ease;
+          }
+          
+          &:hover {
+            color: black;
+          }
         }
-      }
-      .image-item2 {
-        border: 1px solid blue; /* 添加了边框样式 */
-        flex: 1;
       }
     }
-  }
-}
-.bottom-navigation {
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  background-color: #ffffff;
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  height: 60px;
-  border: none;
-}
-.tab-button {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  height: 50px;
-  background-color: transparent;
-  border: none;
-  font-size: 4px !important;
-}
-
-/* 新增的样式 */
-.filter-tags {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: flex-start;
-  margin-bottom: 10px;
-  
-  button {
-    border: none;
-    color: rgb(98, 101, 98);
-    background: none;
-    font-weight: normal;
-    font-size: 16px;
-    margin-right: 10px;
-    cursor: pointer;
-    text-decoration: none;
-    position: relative;
-    transition: all 0.2s ease;
     
-    &:after {
-      content: "";
-      position: absolute;
-      bottom: -2px;
-      left: 0;
+    .imageurl{
+      width:100vw;
+      height:100vh;
+      overflow:scroll;
+      
+      img{
+       height: 100%; 
       width: 100%;
-      height: 2px;
-      background-color: green;
-      opacity: 0;
-      transition: opacity 0.3s ease;
-    }
-    &:hover {
-      color: black; /* 文字变为黑色 */
-    }
+      }
+
+      h3{
+      padding: 0 0 10px 15px;   
+   }
+      height:calc( 100vh - 200px )
+
+     }
   }
 }
-.filter-tags .filter-tag:hover{
-  transform: scale(1.1);
-  color:black;
-}
 
-img {
-  max-width: 100%;
-  height: auto;
-}
 
-li {
-  list-style-type: none;
-}

+ 51 - 66
CraftsMart-angular/src/modules/craftsmart/home/home.component.ts

@@ -1,83 +1,68 @@
-import { Component, NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import * as Parse from 'parse';
 
-
-//detail跳转
-import { Router, ActivatedRoute } from '@angular/router';
-
-interface Home {
+interface Item {
   name: string;
   description: string;
-  imageUrl: string;
+  imgUrl: string;
+ detailId: string;
 }
 
 @Component({
   selector: 'app-home',
   templateUrl: './home.component.html',
-  styleUrls: ['./home.component.scss']  // 添加样式文件
+  styleUrls: ['./home.component.scss']
 })
-export class HomeComponent {
-  homes: Home[] = [
-    {
-      name: 'Digital Collectible 1',
-      description: 'This is the first digital collectible.',
-      imageUrl: 'https://example.com/digital-collectible1.jpg'
-    },
-    {
-      name: 'Digital Collectible 2',
-      description: 'This is the second digital collectible.',
-      imageUrl: 'https://example.com/digital-collectible-2.jpg'
-    },
-    {
-      name: 'Digital Collectible 3',
-      description: 'This is the third digital collectible.',
-      imageUrl: 'https://example.com/digital-collectible-3.jpg'
-    },
-    // 添加更多的数字藏品数据...
-  ];
-  itemList: Home[] = []; // 初始化物品列表为空
-  sanitizer: DomSanitizer;
+export class HomeComponent implements OnInit {
+  items: Item[] = [];
+  currentContent: string = 'module-one';
 
-  constructor(private _sanitizer: DomSanitizer, private router: Router, private route: ActivatedRoute) {
-    this.sanitizer = _sanitizer as DomSanitizer;
-    this.showItemList('推荐'); // 默认显示推荐物品列表
-  }
+  constructor(private router: Router) {}
 
-  getSafeImageUrl(url: string): SafeResourceUrl {
-    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
+  ngOnInit() {
+    this.getData();
   }
 
-  showItemList(type: string) {
-    if (type === '热门') {
-      // 通过你的自定义逻辑获取热门物品列表
-      this.itemList = this.homes.filter(home => {
-        // 这里可以根据需要筛选出对应类型的物品
-        return home.name === 'Digital Collectible 1' || home.name === 'Digital Collectible 2';
-      });
-    } else if (type === '推荐') {
-      // 通过你的自定义逻辑获取推荐物品列表
-      this.itemList = this.homes.filter(home => {
-        // 这里可以根据需要筛选出对应类型的物品
-        return home.name === 'Digital Collectible 1' || home.name === 'Digital Collectible 3';
-      });
-    } else if (type === '活动') {
-      // 通过你的自定义逻辑获取活动物品列表
-      this.itemList = this.homes.filter(home => {
-        // 这里可以根据需要筛选出对应类型的物品
-        return home.name === 'Digital Collectible 2' || home.name === 'Digital Collectible 3';
-      });
+  getData() {
+    (Parse as any).serverURL = 'https://web2023.fmode.cn/parse';
+    Parse.initialize('dev');
+
+    let query: Parse.Query;
+    if (this.currentContent === 'module-one') {
+      query = new Parse.Query('LcmModuleOne');
+    } else if (this.currentContent === 'module-two') {
+      query = new Parse.Query('LcmModuleTwo');
+    } else if (this.currentContent === 'module-three') {
+      query = new Parse.Query('LcmModuleThree');
+    } else {
+      return; // 如果没有匹配的模块,退出方法
     }
+
+    query.find()
+      .then((results) => {
+        this.items = results.map((result) => ({
+          name: result.get('name'),
+          description: result.get('description'),
+          imgUrl: result.get('imgUrl'),
+         detailId: result.get('detailId')
+        }));
+        console.log(this.items);
+      })
+      .catch((error) => {
+        console.error('Error retrieving data from Parse:', error);
+      });
   }
-  goToItemDetail(name: string) {
-    // 实现你的方法逻辑
-    this.router.navigate(['../page-item-detail', name], { relativeTo: this.route });
+
+  selectItem(item: Item) {
+    localStorage.setItem('selectedItem', JSON.stringify(item)); // 存储选定的项目到localStorage
+    console.log(this.selectItem);
+    this.router.navigate(['/page-item-detail', item.detailId]); // 导航到详情页,并传递选定的项目ID作为参数
+  console.log(this.router.navigate)
   }
-}
 
-@NgModule({
-  imports: [CommonModule],
-  declarations: [HomeComponent],
-  exports: [HomeComponent]
-})
-export class HomeModule { }
+  showContent(content: string) {
+    this.currentContent = content;
+    this.getData();
+  }
+}

+ 2 - 1
CraftsMart-angular/src/modules/craftsmart/nav-tabs/nav-tabs.component.scss

@@ -37,7 +37,8 @@
       }
 
       .active{
-        color: aqua;
+        color: rgb(92, 91, 91);
+        transform: scale(1.1);
         font-weight: bold;
       }
      

+ 5 - 4
CraftsMart-angular/src/modules/craftsmart/nav-tabs/nav-tabs.component.ts

@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
 
 @Component({
@@ -7,13 +7,14 @@ import { ActivatedRoute, Router } from '@angular/router';
   styleUrls: ['./nav-tabs.component.scss'],
 })
 export class NavTabsComponent implements OnInit {
+  @Input() showNavTabs: boolean = false;
 
   public path = '';
 
-  constructor(private route: ActivatedRoute, private router: Router) { }
+  constructor(private route: ActivatedRoute, private router: Router) {}
 
   ngOnInit() {
-    this.route.queryParams.subscribe(params => {
+    this.route.queryParams.subscribe((params) => {
       this.path = this.router.url;
     });
   }
@@ -22,4 +23,4 @@ export class NavTabsComponent implements OnInit {
     this.path = path;
     this.router.navigate([path]);
   }
-}
+}

+ 44 - 1
CraftsMart-angular/src/modules/craftsmart/page-cart/page-cart.component.html

@@ -1 +1,44 @@
-<p>page-cart works!</p>
+<ion-searchbar show-cancel-button="focus" placeholder="欢迎来到手艺之窗购物" cancel-button-text="取消" (ionInput)="handleInput($event)"></ion-searchbar>
+
+<div class="buttons-row">
+   <div class="button-tag">
+     <button (click)="showContent('cart-one')">推荐</button>
+   </div>
+   <div class="button-tag">
+    <button  (click)="showContent('cart-two')">手工艺品</button>
+   </div>
+   <div  class="button-tag">
+    <button (click)="showContent('cart-three')">数字藏品</button>
+   </div>
+</div>
+
+<div class="content-wrapper">
+  <div class="item-container">
+    <div *ngFor="let item of items" class="image-container">
+      <div *ngIf="item.choice === 1" class="left-column">
+        <div class="image-item">
+          <img [src]="item.imgUrl" alt="item image">
+          <div class="image-details">
+            <h3>{{ item.name }}</h3>
+          </div>
+          <div class="price-container">
+            <p>价格:{{ item.price }}</p>
+            <p>销量:{{ item.sales }}</p>
+          </div>
+        </div>
+      </div>
+      <div *ngIf="item.choice === 2" class="right-column">
+        <div class="image-item">
+          <img [src]="item.imgUrl" alt="item image">
+          <div class="image-details">
+            <h3>{{ item.name }}</h3>
+          </div>
+          <div class="price-container">
+            <p>价格:{{ item.price }}</p>
+            <p>销量:{{ item.sales }}</p>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 133 - 3
CraftsMart-angular/src/modules/craftsmart/page-cart/page-cart.component.scss

@@ -1,4 +1,134 @@
+.buttons-row {
+  display: flex;
+  justify-content: space-between;
+  height: 40px;
+
+  .button-tag{
+    flex: 1;
+    background-color: #ffffff;
+    padding: 0 30px 0 30px;
+    button{
+      background-color: #ffffff;
+    }
+  }
+  
+}
+
 .active {
-    background-color: yellow;
-    color: white;
-  }
+  padding-bottom: 3px;
+  color: black;
+  transform: scale(1.1);
+  border-bottom: 2px solid black;
+}
+
+.content-wrapper{
+  width:100vw;
+  height:100vh;
+  overflow:scroll;
+  height:calc( 100vh - 200px );
+
+  .item-container {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+
+    .image-container {
+      width: 49.9%;
+      margin-bottom: 2px;
+      
+       .left-column {
+         flex: 1;
+
+         .image-item {
+          display: flex;
+          flex-direction: column;
+          border: 2px solid #d7dee2;
+          border-radius: 4px;
+          .image-item img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+          }
+          .image-details {
+            margin-top: 10px;
+          
+            h3 {
+              font-size: 18px;
+              margin: 0 0 5px 10px;
+            }
+          }
+          .price-container {
+            display: flex;
+            justify-content: space-between;
+          
+            .price{
+              color: rgb(255, 65, 65);
+              margin: 0 0 5px 10px;
+              font-size: 18px;
+            }
+            .sales{
+              margin:0 10px 5px 0 ;
+              padding-top: 6px;
+              color: #787878;
+              font-size: 14px;
+            }
+          }
+        }
+        
+
+       }
+
+       
+       .right-column {
+         flex: 1;
+         .image-item {
+          display: flex;
+          flex-direction: column;
+          border: 2px solid #d7dee2;
+          border-radius: 4px;
+          .image-item img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+          }
+          .image-details {
+            margin-top: 10px;
+          
+            h3 {
+              font-size: 18px;
+              margin: 0 0 5px 10px;
+            }
+          }
+          .price-container {
+            display: flex;
+            justify-content: space-between;
+          
+            .price{
+              color: rgb(255, 65, 65);
+              margin: 0 0 5px 10px;
+              font-size: 18px;
+            }
+            .sales{
+              margin:0 10px 5px 0 ;
+              padding-top: 6px;
+              color: #787878;
+              font-size: 14px;
+            }
+          }
+        }
+
+       }
+    }
+    
+
+  }
+  
+  
+}
+
+
+.image-details p {
+  margin: 0;
+}
+
+

+ 59 - 2
CraftsMart-angular/src/modules/craftsmart/page-cart/page-cart.component.ts

@@ -1,12 +1,69 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import * as Parse from 'parse';
+
+
+interface Item {
+  name: string;
+  imgUrl:string;
+  price: number;
+  sales: number;
+  choice:number;
+ detailId: string;
+}
 
 @Component({
   selector: 'app-page-cart',
   templateUrl: './page-cart.component.html',
   styleUrls: ['./page-cart.component.scss']
 })
+export class PageCartComponent implements OnInit {
+  items: Item[] = [];
+  currentContent: string = 'cart-one';
+
+  constructor(private router: Router) {}
+
+  ngOnInit() {
+    this.getData();
+  }
+
+  getData() {
+    (Parse as any).serverURL = 'https://web2023.fmode.cn/parse';
+    Parse.initialize('dev');
 
+    let query: Parse.Query;
+    if (this.currentContent === 'cart-one') {
+      query = new Parse.Query('LcmCartOne');
+    } else if (this.currentContent === 'cart-two') {
+      query = new Parse.Query('LcmCartTwo');
+    } else if (this.currentContent === 'cart-three') {
+      query = new Parse.Query('LcmCartThree');
+    } else {
+      return; // 如果没有匹配的模块,退出方法
+    }
 
-export class PageCartComponent {
+    query.find()
+      .then((results) => {
+        this.items = results.map((result) => ({
+          imgUrl:result.get('imgUrl'),
+          name: result.get('name'),
+          price: result.get('price'),
+          sales: result.get('sales'),
+          choice:result.get('choice'),
+         detailId: result.get('detailId')
+        }));
+        console.log(this.items);
+      })
+      .catch((error) => {
+        console.error('Error retrieving data from Parse:', error);
+      });
+  }
 
+  showContent(content: string) {
+    this.currentContent = content;
+    this.getData();
+  }
+  handleInput(event: any) {
+    // 处理输入事件的逻辑
+  }
 }

+ 29 - 1
CraftsMart-angular/src/modules/craftsmart/page-discover/page-discover.component.html

@@ -1 +1,29 @@
-<p>page-discover works!</p>
+<div class="logos">
+    <div class="logo">CraftsMart</div>
+</div>
+<div class="box">
+    <div class="list">
+            <p>消息中心</p>
+            <div class="lists"><svg t="1699961826176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3157" width="128" height="128"><path d="M345.642667 822.592c12.629333 12.544 33.130667 12.544 45.76 0L678.613333 536.384c6.741333-6.698667 9.6-15.573333 9.173333-24.384 0.448-8.768-2.410667-17.664-9.173333-24.384L391.402667 201.429333c-12.629333-12.565333-33.130667-12.565333-45.76 0s-12.629333 32.981333 0 45.546667L611.648 512 345.642667 777.045333C333.013333 789.632 333.013333 810.005333 345.642667 822.592z" p-id="3158" fill="#2c2c2c"></path></svg></div>
+        </div>
+    <div class="list" >
+            <p>AI咨询</p>
+            <div class="lists"><svg t="1699961826176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3157" width="128" height="128"><path d="M345.642667 822.592c12.629333 12.544 33.130667 12.544 45.76 0L678.613333 536.384c6.741333-6.698667 9.6-15.573333 9.173333-24.384 0.448-8.768-2.410667-17.664-9.173333-24.384L391.402667 201.429333c-12.629333-12.565333-33.130667-12.565333-45.76 0s-12.629333 32.981333 0 45.546667L611.648 512 345.642667 777.045333C333.013333 789.632 333.013333 810.005333 345.642667 822.592z" p-id="3158" fill="#2c2c2c"></path></svg></div>
+        </div>
+    <div class="list">
+            <p>创作中心</p>
+            <div class="lists"><svg t="1699961826176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3157" width="128" height="128"><path d="M345.642667 822.592c12.629333 12.544 33.130667 12.544 45.76 0L678.613333 536.384c6.741333-6.698667 9.6-15.573333 9.173333-24.384 0.448-8.768-2.410667-17.664-9.173333-24.384L391.402667 201.429333c-12.629333-12.565333-33.130667-12.565333-45.76 0s-12.629333 32.981333 0 45.546667L611.648 512 345.642667 777.045333C333.013333 789.632 333.013333 810.005333 345.642667 822.592z" p-id="3158" fill="#2c2c2c"></path></svg></div>
+        </div>
+    <div class="list">
+            <p>自由寄售</p>
+            <div class="lists"><svg t="1699961826176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3157" width="128" height="128"><path d="M345.642667 822.592c12.629333 12.544 33.130667 12.544 45.76 0L678.613333 536.384c6.741333-6.698667 9.6-15.573333 9.173333-24.384 0.448-8.768-2.410667-17.664-9.173333-24.384L391.402667 201.429333c-12.629333-12.565333-33.130667-12.565333-45.76 0s-12.629333 32.981333 0 45.546667L611.648 512 345.642667 777.045333C333.013333 789.632 333.013333 810.005333 345.642667 822.592z" p-id="3158" fill="#2c2c2c"></path></svg></div>
+        </div>
+    <div class="list">
+            <p>商家中心</p>
+            <div class="lists"><svg t="1699961826176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3157" width="128" height="128"><path d="M345.642667 822.592c12.629333 12.544 33.130667 12.544 45.76 0L678.613333 536.384c6.741333-6.698667 9.6-15.573333 9.173333-24.384 0.448-8.768-2.410667-17.664-9.173333-24.384L391.402667 201.429333c-12.629333-12.565333-33.130667-12.565333-45.76 0s-12.629333 32.981333 0 45.546667L611.648 512 345.642667 777.045333C333.013333 789.632 333.013333 810.005333 345.642667 822.592z" p-id="3158" fill="#2c2c2c"></path></svg></div>
+        </div>
+    <div class="list">
+            <p>物流信息</p>
+           <div class="lists"><svg t="1699961826176" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3157" width="128" height="128"><path d="M345.642667 822.592c12.629333 12.544 33.130667 12.544 45.76 0L678.613333 536.384c6.741333-6.698667 9.6-15.573333 9.173333-24.384 0.448-8.768-2.410667-17.664-9.173333-24.384L391.402667 201.429333c-12.629333-12.565333-33.130667-12.565333-45.76 0s-12.629333 32.981333 0 45.546667L611.648 512 345.642667 777.045333C333.013333 789.632 333.013333 810.005333 345.642667 822.592z" p-id="3158" fill="#2c2c2c"></path></svg></div>
+        </div>
+</div>

+ 47 - 0
CraftsMart-angular/src/modules/craftsmart/page-discover/page-discover.component.scss

@@ -0,0 +1,47 @@
+.logos {
+    padding: 10px 5px;
+    background-color: #ffffff;
+    margin: 5px;
+    display: flex;
+    align-items: center;
+    height: 60px;
+  }
+  
+  .logo {
+    font-size: 26px;
+    margin: 20px 0 0 0;
+    font-family: "Trebuchet MS", Verdana, fantasy;
+    font-style: italic;
+  }
+ 
+  
+  .box {
+    background-color: #f5f4f9;
+    height: 1000px;
+  }
+  
+  .list {
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    height: 70px;
+    background-color: #ffffff;
+    margin: 5px;
+  
+    p {
+      padding: 10px 10px 10px 16px;
+      margin-right: auto;
+    }
+  
+    .lists {
+      margin-left: 20px;
+      margin-right: 10px;
+    }
+  
+    .lists svg {
+      width: 30px;
+      height: 30px;
+      padding-left: 10px;
+    }
+  }
+  

+ 21 - 1
CraftsMart-angular/src/modules/craftsmart/page-item-detail/page-item-detail.component.html

@@ -1 +1,21 @@
-<p>page-item-detail works!</p>
+<div class="navigation-bar">
+    <div>
+        <button class="back-button" (click)="backIconClicked()">
+            <svg t="1699446776660" class="back-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2306" width="128" height="128"><path d="M532.526499 904.817574L139.506311 511.797385 532.526499 118.777197c12.258185-12.258185 12.432147-32.892131-0.187265-45.51052-12.707416-12.707416-32.995485-12.703323-45.511543-0.187265L75.166957 484.739123c-7.120165 7.120165-10.163477 17.065677-8.990768 26.624381-1.500167 9.755178 1.5104 20.010753 8.990768 27.491121l411.660734 411.660734c12.258185 12.258185 32.892131 12.432147 45.511543-0.187265 12.707416-12.707416 12.7023-32.995485 0.187265-45.51052z" p-id="2307" fill="#2c2c2c"></path></svg>
+         </button>
+         <button class="share-button">
+            <svg t="1699446835212" class="share-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3541" width="128" height="128"><path d="M874.9 459.4c-18.8 0-34 15.2-34 34v355.7c0 18.6-15.5 33.7-34.5 33.7H181.5c-19 0-34.5-15.1-34.5-33.7V232.3c0-18.6 15.5-33.7 34.5-33.7H541c18.8 0 34-15.2 34-34s-15.2-34-34-34H181.5C125 130.6 79 176.2 79 232.3v616.8c0 56 46 101.7 102.5 101.7h624.9c56.5 0 102.5-45.6 102.5-101.7V493.4c0-18.8-15.2-34-34-34z" fill="#2c2c2c" p-id="3542"></path><path d="M885.5 82.7H657.1c-18.8 0-34 15.2-34 34s15.2 34 34 34h169.7L358.5 619.1c-13.3 13.3-13.3 34.8 0 48.1 6.6 6.6 15.3 10 24 10s17.4-3.3 24-10l470-470v169.7c0 18.8 15.2 34 34 34s34-15.2 34-34V141.5c0.1-32.4-26.4-58.8-59-58.8z" fill="#2c2c2c" p-id="3543"></path></svg>
+         </button>
+    </div>
+</div>
+
+<div *ngIf="selectedItem" class="image-detail">
+    <img [src]="selectedItem.imgUrl" alt="Item Image" />
+    <div class="detail-p">
+        <h3>{{ selectedItem.name }}</h3>
+        <p>{{ selectedItem.description }}</p>
+    </div>
+  </div>
+  
+  
+

+ 56 - 0
CraftsMart-angular/src/modules/craftsmart/page-item-detail/page-item-detail.component.scss

@@ -0,0 +1,56 @@
+.navigation-bar {
+  align-items: center;
+  height: 50px;
+  padding: 10px;
+  justify-content: space-between; /* 使用 space-between 实现按钮左右对齐 */
+
+  button.back-button {
+    width: 30px;
+    height: 30px;
+    padding: 4px 0 4px 4px;
+    border: none;
+    background-color: transparent;
+    cursor: pointer;
+
+    .back-icon {
+      width: auto;
+      height: 20px;
+      transform-origin: center;
+      transition: transform 0.3s ease, border-color 0.3s ease;
+    }
+  }
+
+  button.share-button {
+    width: 30px;
+    float:right;
+    height: 30px;
+    padding: 4px 0 4px 0;
+    border: none;
+    background-color: transparent;
+    cursor: pointer;
+
+    .share-icon {
+      width: auto;
+      height: 20px;
+      transform-origin: center;
+    }
+  }
+}
+
+
+.image-detail {
+  margin-top: 5px;
+  flex: 1;
+  margin-right: 8px;
+
+
+  img {
+    height: 100%; 
+    width: 100%;
+    
+  }
+  .detail-p{
+    padding: 0 0 10px 15px;   
+
+  }
+}

+ 25 - 2
CraftsMart-angular/src/modules/craftsmart/page-item-detail/page-item-detail.component.ts

@@ -1,10 +1,33 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
+import { Router, ActivatedRoute } from '@angular/router';
+
+interface Item {
+  imgUrl: string;
+  name: string;
+  description: string;
+}
 
 @Component({
   selector: 'app-page-item-detail',
   templateUrl: './page-item-detail.component.html',
   styleUrls: ['./page-item-detail.component.scss']
 })
-export class PageItemDetailComponent {
+export class PageItemDetailComponent implements OnInit {
+  selectedItem: Item | null = null;
+
+  constructor(private router: Router, private route: ActivatedRoute) { }
+
+  ngOnInit() {
+    const selectedItemString = localStorage.getItem('selectedItem');
+    if (selectedItemString) {
+      this.selectedItem = JSON.parse(selectedItemString);
+    } else {
+      // 如果没有选定的项目,导航回首页
+      this.router.navigate(['/home']);
+    }
+  }
 
+  backIconClicked() {
+    this.router.navigate(['/home']);
+  }
 }

+ 56 - 1
CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.html

@@ -1 +1,56 @@
-<p>page-mine works!</p>
+
+<ion-content fullscreen="true" class="mine">
+  <img class="item1" alt="Silhouette of mountains" src="../../../assets/image/bcg1.jpg" />
+  <ion-item>
+    <ion-avatar aria-hidden="true" slot="start">
+      <img alt="" src="../../../assets/image/head.jpg" />
+    </ion-avatar>
+    <ion-label>Fooie</ion-label>
+  </ion-item>
+
+  <ion-list [inset]="true">
+    <!-- 其他代码 -->
+  </ion-list>
+
+  
+  <ion-list [inset]="true"  class="zoom-list">
+    <ion-item [button]="true">
+      <ion-icon color="danger" slot="start" name="list-circle" size="large"></ion-icon>
+      <ion-label>订单</ion-label>
+      <ion-note slot="end">6</ion-note>
+    </ion-item>
+    <ion-item [button]="true">
+      <ion-icon color="tertiary" slot="start" name="list-circle" size="large"></ion-icon>
+      <ion-label>收藏</ion-label>
+      <ion-note slot="end">15</ion-note>
+    </ion-item>
+    <ion-item [button]="true">
+      <ion-icon color="success" slot="start" name="list-circle" size="large"></ion-icon>
+      <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-fab >
+  <ion-fab-button (click)="goToHome()">
+    <ion-icon name="exit-outline"></ion-icon>
+  </ion-fab-button>
+</ion-fab>
+  </ion-content>
+

+ 33 - 0
CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.scss

@@ -0,0 +1,33 @@
+.mine{
+  height: 800px;
+}
+.item1 {
+    height: 265px;
+    width: 100%;
+    background-image: url('../../../assets/image/bcg1.jpg');
+    background-repeat: no-repeat;
+    background-size: cover;
+    background-position: center;
+    
+  }
+  
+  .item2 {
+    height: 80px;
+    width: auto;
+    margin-top: 220px; 
+  }
+  .zoom-list {
+    transform: scale(1.09);
+    
+  }
+  .center-container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 25vh;
+  }
+  
+  .center-list{
+width: 150px;
+}

+ 7 - 4
CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.spec.ts

@@ -1,15 +1,18 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
-
 import { PageMineComponent } from './page-mine.component';
 
 describe('PageMineComponent', () => {
   let component: PageMineComponent;
   let fixture: ComponentFixture<PageMineComponent>;
 
-  beforeEach(() => {
-    TestBed.configureTestingModule({
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
       declarations: [PageMineComponent]
-    });
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
     fixture = TestBed.createComponent(PageMineComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();

+ 30 - 0
CraftsMart-angular/src/modules/craftsmart/page-mine/page-mine.component.ts

@@ -1,4 +1,6 @@
 import { Component } from '@angular/core';
+import { ToastController } from '@ionic/angular';
+import { Router } from '@angular/router';
 
 @Component({
   selector: 'app-page-mine',
@@ -6,5 +8,33 @@ import { Component } from '@angular/core';
   styleUrls: ['./page-mine.component.scss']
 })
 export class PageMineComponent {
+  // 其他代码...
+  toastButtons = [
+    {
+      text: '关闭',
+      role: 'cancel'
+    }
+  ];
 
+
+  constructor(private toastCtrl: ToastController, private router: Router) {}
+
+  // 其他方法...
+
+  async presentToast(position: 'top' | 'bottom' | 'middle') {
+    const toast = await this.toastCtrl.create({
+      message: '请先登录!',
+      duration: 3000,
+      position: position,
+      buttons: this.toastButtons
+    });
+
+    toast.present();
+  }
+
+
+  
+  goToHome() {
+    this.router.navigate(['/home']);
+  }
 }

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

@@ -0,0 +1,17 @@
+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();
+  });
+});

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

@@ -0,0 +1,15 @@
+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;
+  }
+};

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

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

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


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

@@ -0,0 +1,21 @@
+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();
+  });
+});

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

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

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

@@ -0,0 +1,20 @@
+<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 - 0
CraftsMart-angular/src/modules/user/page-login/page-login.component.scss


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

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

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

@@ -0,0 +1,29 @@
+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)
+    }
+  }
+}

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

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

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


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

@@ -0,0 +1,21 @@
+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();
+  });
+});

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

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

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

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

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

@@ -0,0 +1,23 @@
+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 { }

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

@@ -0,0 +1,16 @@
+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();
+  });
+});

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

@@ -0,0 +1,34 @@
+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
+  }
+}

+ 6 - 0
CraftsMart-angular/src/theme/variables.css

@@ -0,0 +1,6 @@
+/* Ionic Variables and Theming. */
+/* This is just a placeholder file For more info, please see: */
+/* https://ionicframework.com/docs/theming/basics */
+
+/* To quickly generate your own theme, check out the color generator */
+/* https://ionicframework.com/docs/theming/color-generator */

+ 1 - 0
CraftsMart-angular/tsconfig.json

@@ -19,6 +19,7 @@
     "target": "ES2022",
     "module": "ES2022",
     "useDefineForClassFields": false,
+    "allowSyntheticDefaultImports": true,
     "lib": [
       "ES2022",
       "dom"

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác