Jelajahi Sumber

添加商品详情页

0235697 2 hari lalu
induk
melakukan
583574c768

+ 2 - 1
picture-web/angular.json

@@ -30,7 +30,8 @@
               }
             ],
             "styles": [
-              "src/styles.scss"
+              "src/styles.scss",
+                "node_modules/swiper/swiper-bundle.min.css"
             ]
           },
           "configurations": {

+ 2 - 2
picture-web/package-lock.json

@@ -215,7 +215,7 @@
     },
     "node_modules/@angular/cdk": {
       "version": "20.0.4",
-      "resolved": "https://registry.npmmirror.com/@angular/cdk/-/cdk-20.0.4.tgz",
+      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-20.0.4.tgz",
       "integrity": "sha512-NCUuw0qQXwawLsT14JHApNB9or3XGs7D1pWXlOIix/fKqzHVfi4un9xHmpjH2Q1uCiwonuak7fDof8B+IXhbug==",
       "license": "MIT",
       "dependencies": {
@@ -8147,7 +8147,7 @@
     },
     "node_modules/swiper": {
       "version": "11.2.10",
-      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-11.2.10.tgz",
+      "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz",
       "integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==",
       "funding": [
         {

+ 94 - 1
picture-web/src/modules/first-home/image-detail/image-detail.html

@@ -1 +1,94 @@
-<p>image-detail works!</p>
+<!-- 头部导航 -->
+<div class="header">
+  <div class="back-btn" (click)="goBack()">
+    <i class="fas fa-arrow-left"></i>
+  </div>
+  <div class="header-title">精品美食图片</div>
+  <div class="action-icons">
+    <i class="fas" [class.fas]="isFavorite" [class.far]="!isFavorite" 
+       [style.color]="isFavorite ? '#ffeb3b' : 'white'"
+       [style.textShadow]="isFavorite ? '0 0 10px rgba(255, 235, 59, 0.8)' : 'none'"
+       (click)="toggleFavorite()"></i>
+    <i class="fas fa-download" (click)="handleAction('download')"></i>
+  </div>
+</div>
+
+<!-- 图片展示区域 -->
+<div class="image-showcase">
+  <swiper-container [init]="false" [config]="swiperConfig">
+    <swiper-slide *ngFor="let slide of slides">
+      <img [src]="slide.url" [alt]="slide.alt">
+    </swiper-slide>
+    <div class="swiper-pagination" slot="pagination"></div>
+  </swiper-container>
+  
+  <div class="image-actions">
+    <div class="action-btn" title="放大查看" (click)="handleAction('expand')">
+      <i class="fas fa-expand"></i>
+    </div>
+    <div class="action-btn" title="分享图片" (click)="handleAction('share')">
+      <i class="fas fa-share-alt"></i>
+    </div>
+    <div class="action-btn" title="下载原图" (click)="handleAction('download')">
+      <i class="fas fa-download"></i>
+    </div>
+  </div>
+</div>
+
+
+<!-- 图片信息区域 -->
+<div class="image-info">
+  <h2 class="image-title">{{imageDetail.title}}</h2>
+  
+  <div class="image-meta">
+    <div class="meta-item" *ngFor="let item of imageDetail.meta">
+      <i [class]="item.icon"></i>
+      <span>{{item.text}}</span>
+    </div>
+  </div>
+  
+  <div class="image-stats">
+    <div class="stat-item" *ngFor="let stat of imageDetail.stats">
+      <div class="stat-value">{{stat.value}}</div>
+      <div class="stat-label">{{stat.label}}</div>
+    </div>
+  </div>
+  
+  <div class="purchase-section">
+    <div class="price">{{imageDetail.price}}</div>
+    <button class="buy-btn" (click)="buyImage()">
+      <i class="fas fa-shopping-cart"></i>
+      购买图片
+    </button>
+  </div>
+</div>
+
+<!-- 摄影师信息 -->
+<div class="photographer">
+  <div class="avatar">
+    <img [src]="photographer.avatar" alt="摄影师">
+  </div>
+  <div class="photographer-info">
+    <h3>{{photographer.name}}</h3>
+    <p>{{photographer.title}}</p>
+  </div>
+  <button class="follow-btn" (click)="toggleFollow()">
+    {{photographer.isFollowing ? '✓ 已关注' : '+ 关注'}}
+  </button>
+</div>
+
+<!-- 相关推荐 -->
+<div class="related-section">
+  <h2 class="section-title">更多美食图片</h2>
+  <div class="related-items">
+    <div class="related-item" *ngFor="let item of relatedItems">
+      <div class="related-img">
+        <img [src]="item.image" [alt]="item.name">
+      </div>
+      <div class="related-info">
+        <div class="related-name">{{item.name}}</div>
+        <div class="related-price">{{item.price}}</div>
+      </div>
+    </div>
+  </div>
+</div>

+ 432 - 0
picture-web/src/modules/first-home/image-detail/image-detail.scss

@@ -0,0 +1,432 @@
+/* 基础样式 */
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+  font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
+}
+
+body {
+  background: linear-gradient(135deg, #fff8f0, #fff0e6);
+  color: #5a3e36;
+  line-height: 1.6;
+}
+
+.container {
+  max-width: 480px;
+  margin: 0 auto;
+  background: white;
+  min-height: 100vh;
+  position: relative;
+  box-shadow: 0 0 40px rgba(255, 152, 0, 0.1);
+}
+
+/* 头部样式 - 橙色系 */
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20px;
+  background: linear-gradient(to right, #ff9800, #ff5722);
+  color: white;
+  position: sticky;
+  top: 0;
+  z-index: 100;
+  box-shadow: 0 4px 12px rgba(255, 87, 34, 0.2);
+}
+
+.back-btn {
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+  background: rgba(255, 255, 255, 0.2);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 18px;
+  color: white;
+  cursor: pointer;
+  transition: all 0.3s ease;
+
+  &:hover {
+    background: rgba(255, 255, 255, 0.3);
+    transform: scale(1.05);
+  }
+}
+
+.header-title {
+  font-weight: 600;
+  font-size: 20px;
+  letter-spacing: 1px;
+  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.action-icons {
+  display: flex;
+  gap: 20px;
+
+  i {
+    font-size: 20px;
+    color: white;
+    cursor: pointer;
+    transition: all 0.3s;
+    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+
+    &:hover {
+      transform: scale(1.15);
+    }
+  }
+}
+
+/* 图片展示区域 */
+.image-showcase {
+  position: relative;
+  height: 380px;
+  overflow: hidden;
+  background: #333;
+}
+
+/* 图片展示区域 */
+.image-showcase {
+  position: relative;
+  height: 380px;
+  overflow: hidden;
+  background: #333;
+}
+
+swiper-container {
+  width: 100%;
+  height: 100%;
+  
+  // Swiper 11 自定义样式
+  --swiper-pagination-color: #ff9800;
+  --swiper-pagination-bullet-inactive-color: rgba(255, 255, 255, 0.5);
+  --swiper-pagination-bullet-inactive-opacity: 1;
+  --swiper-pagination-bullet-size: 10px;
+  --swiper-pagination-bullet-horizontal-gap: 6px;
+}
+
+swiper-slide {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  overflow: hidden;
+
+  img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+    transition: transform 0.5s;
+  }
+}
+
+.swiper-pagination {
+  bottom: 20px !important;
+}
+
+.swiper-pagination-bullet {
+  width: 10px;
+  height: 10px;
+  background: rgba(255, 255, 255, 0.5);
+  opacity: 1;
+}
+
+.swiper-pagination-bullet-active {
+  background: #ff9800;
+  width: 24px;
+  border-radius: 6px;
+}
+
+.image-actions {
+  position: absolute;
+  bottom: 20px;
+  right: 20px;
+  display: flex;
+  gap: 15px;
+  z-index: 10;
+}
+
+.action-btn {
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+  background: rgba(255, 152, 0, 0.8);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+  font-size: 18px;
+  cursor: pointer;
+  transition: all 0.3s;
+  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
+
+  &:hover {
+    background: rgba(255, 87, 34, 0.9);
+    transform: translateY(-3px);
+  }
+}
+
+/* 图片信息区域 */
+.image-info {
+  padding: 25px;
+  background: white;
+}
+
+.image-title {
+  font-size: 24px;
+  font-weight: 700;
+  color: #ff5722;
+  margin-bottom: 15px;
+  position: relative;
+  display: inline-block;
+
+  &:after {
+    content: '';
+    position: absolute;
+    bottom: -5px;
+    left: 0;
+    width: 50px;
+    height: 3px;
+    background: #ff9800;
+    border-radius: 3px;
+  }
+}
+
+.image-meta {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 25px;
+  font-size: 15px;
+  color: #7d5d54;
+}
+
+.meta-item {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+
+  i {
+    color: #ff9800;
+  }
+}
+
+.image-stats {
+  display: flex;
+  justify-content: space-between;
+  background: #fff8f0;
+  border-radius: 15px;
+  padding: 20px;
+  margin: 25px 0;
+  box-shadow: 0 4px 15px rgba(255, 152, 0, 0.1);
+}
+
+.stat-item {
+  text-align: center;
+}
+
+.stat-value {
+  font-size: 24px;
+  font-weight: 700;
+  color: #ff5722;
+  margin-bottom: 5px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #7d5d54;
+}
+
+.purchase-section {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 20px;
+}
+
+.price {
+  font-size: 28px;
+  font-weight: 800;
+  color: #ff5722;
+}
+
+.buy-btn {
+  background: linear-gradient(135deg, #ff9800, #ff5722);
+  color: white;
+  border: none;
+  padding: 15px 35px;
+  border-radius: 30px;
+  font-size: 18px;
+  font-weight: 600;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  transition: all 0.3s ease;
+  box-shadow: 0 6px 20px rgba(255, 87, 34, 0.3);
+
+  &:hover {
+    transform: translateY(-3px);
+    box-shadow: 0 8px 25px rgba(255, 87, 34, 0.4);
+  }
+
+  &.purchased {
+    background: linear-gradient(135deg, #4CAF50, #66BB6A);
+    box-shadow: 0 6px 20px rgba(76, 175, 80, 0.3);
+  }
+}
+
+/* 摄影师信息 */
+.photographer {
+  display: flex;
+  align-items: center;
+  gap: 15px;
+  padding: 20px;
+  background: #fffaf5;
+  border-top: 1px solid #ffedd8;
+  margin-top: 30px;
+}
+
+.avatar {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  overflow: hidden;
+  border: 3px solid #ff9800;
+
+  img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+  }
+}
+
+.photographer-info h3 {
+  font-size: 18px;
+  color: #ff5722;
+  margin-bottom: 5px;
+}
+
+.photographer-info p {
+  color: #7d5d54;
+  font-size: 14px;
+}
+
+.follow-btn {
+  background: transparent;
+  border: 2px solid #ff9800;
+  color: #ff5722;
+  padding: 8px 15px;
+  border-radius: 20px;
+  font-weight: 600;
+  cursor: pointer;
+  transition: all 0.3s;
+  margin-left: auto;
+
+  &:hover {
+    background: #ff9800;
+    color: white;
+  }
+}
+
+/* 相关推荐 */
+.related-section {
+  padding: 0 20px 30px;
+}
+
+.section-title {
+  font-size: 20px;
+  font-weight: 700;
+  margin-bottom: 20px;
+  color: #ff5722;
+  display: flex;
+  align-items: center;
+  gap: 10px;
+
+  &:before {
+    content: '';
+    width: 6px;
+    height: 24px;
+    background: #ff9800;
+    border-radius: 3px;
+  }
+}
+
+.related-items {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 20px;
+}
+
+.related-item {
+  border-radius: 15px;
+  overflow: hidden;
+  box-shadow: 0 8px 20px rgba(255, 152, 0, 0.15);
+  transition: all 0.3s;
+  background: white;
+
+  &:hover {
+    transform: translateY(-8px);
+    box-shadow: 0 12px 25px rgba(255, 152, 0, 0.25);
+  }
+}
+
+.related-img {
+  height: 140px;
+  overflow: hidden;
+
+  img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+    transition: transform 0.5s;
+  }
+}
+
+.related-item:hover .related-img img {
+  transform: scale(1.1);
+}
+
+.related-info {
+  padding: 15px;
+}
+
+.related-name {
+  font-weight: 600;
+  margin-bottom: 8px;
+  color: #5a3e36;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.related-price {
+  color: #ff5722;
+  font-weight: 700;
+  font-size: 18px;
+}
+
+/* 动画效果 */
+@keyframes pulse {
+  0% { transform: scale(1); }
+  50% { transform: scale(1.05); }
+  100% { transform: scale(1); }
+}
+
+.pulse {
+  animation: pulse 0.5s ease-in-out;
+}
+
+/* 响应式调整 */
+@media (max-width: 480px) {
+  .image-showcase {
+    height: 340px;
+  }
+  
+  .image-info {
+    padding: 20px;
+  }
+  
+  .related-items {
+    grid-template-columns: 1fr;
+  }
+}

+ 151 - 5
picture-web/src/modules/first-home/image-detail/image-detail.ts

@@ -1,11 +1,157 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+// 导入 Swiper 11 相关模块
+import { register } from 'swiper/element/bundle';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
 
 @Component({
   selector: 'app-image-detail',
-  imports: [],
+  standalone: true,
+  imports: [CommonModule, FormsModule],
   templateUrl: './image-detail.html',
-  styleUrl: './image-detail.scss'
+  styleUrls: ['./image-detail.scss'],
+  schemas: [CUSTOM_ELEMENTS_SCHEMA] // 允许使用自定义元素
 })
-export class ImageDetail {
+export class ImageDetailComponent implements OnInit {
+   // 轮播图配置
+  swiperConfig = JSON.stringify({
+    pagination: {
+      clickable: true,
+      type: 'bullets',
+    },
+    loop: true,
+    autoplay: {
+      delay: 5000,
+      disableOnInteraction: false
+    },
+    effect: 'fade',
+    fadeEffect: {
+      crossFade: true
+    }
+  });
+
+  // 轮播图数据
+  slides = [
+    {
+      url: 'https://images.unsplash.com/photo-1565299624946-b28f40a0ae38?auto=format&fit=crop&w=800&q=80',
+      alt: '美味披萨'
+    },
+    {
+      url: 'https://images.unsplash.com/photo-1565958011703-44f9829ba187?auto=format&fit=crop&w=800&q=80',
+      alt: '披萨制作过程'
+    },
+    {
+      url: 'https://images.unsplash.com/photo-1513104890138-7c749659a591?auto=format&fit=crop&w=800&q=80',
+      alt: '披萨特写'
+    }
+  ];
+
+  // 图片详情数据
+  imageDetail = {
+    title: '意式玛格丽特披萨',
+    meta: [
+      { icon: 'fas fa-camera', text: '专业美食摄影' },
+      { icon: 'fas fa-image', text: '高分辨率 (4000×3000)' },
+      { icon: 'fas fa-tags', text: '意大利料理, 披萨' }
+    ],
+    stats: [
+      { value: '1,258', label: '下载量' },
+      { value: '4.9', label: '用户评分' },
+      { value: '96%', label: '推荐度' }
+    ],
+    price: '¥ 38.00'
+  };
+
+  // 摄影师数据
+  photographer = {
+    name: '张明轩',
+    title: '专业美食摄影师 | 8年经验',
+    avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=200&q=80',
+    isFollowing: false
+  };
+
+  // 相关推荐数据
+  relatedItems = [
+    {
+      image: 'https://images.unsplash.com/photo-1552539618-7eec9b4d1796?auto=format&fit=crop&w=400&q=80',
+      name: '番茄肉酱意面',
+      price: '¥ 32.00'
+    },
+    {
+      image: 'https://images.unsplash.com/photo-1606491956689-2ea866880c84?auto=format&fit=crop&w=400&q=80',
+      name: '凯撒沙拉',
+      price: '¥ 28.00'
+    },
+    {
+      image: 'https://images.unsplash.com/photo-1551183053-bf91a1d81141?auto=format&fit=crop&w=400&q=80',
+      name: '提拉米苏',
+      price: '¥ 25.00'
+    },
+    {
+      image: 'https://images.unsplash.com/photo-1513104890138-7c749659a591?auto=format&fit=crop&w=400&q=80',
+      name: '四芝士披萨',
+      price: '¥ 42.00'
+    }
+  ];
+
+  isFavorite = false;
+
+  ngOnInit(): void {
+    // 初始化代码可以放在这里
+  }
+
+  // 图片操作功能
+  handleAction(iconType: string): void {
+    let message = '';
+    
+    switch(iconType) {
+      case 'expand':
+        message = '图片已全屏展示';
+        break;
+      case 'share':
+        message = '分享功能已激活';
+        break;
+      case 'download':
+        message = '开始下载高清图片';
+        break;
+    }
+    
+    if (message) {
+      alert(message);
+    }
+  }
+
+  // 收藏功能
+  toggleFavorite(): void {
+    this.isFavorite = !this.isFavorite;
+    alert(this.isFavorite ? '已添加到收藏' : '已取消收藏');
+  }
+
+  // 关注功能
+  toggleFollow(): void {
+    this.photographer.isFollowing = !this.photographer.isFollowing;
+  }
+
+  // 购买功能
+  buyImage(): void {
+    const buyBtn = document.querySelector('.buy-btn');
+    if (buyBtn) {
+      const originalText = buyBtn.innerHTML;
+      buyBtn.innerHTML = '<i class="fas fa-check"></i> 已添加到购物车';
+      buyBtn.classList.add('purchased');
+      
+      setTimeout(() => {
+        buyBtn.innerHTML = originalText;
+        buyBtn.classList.remove('purchased');
+      }, 2000);
+    }
+  }
 
-}
+  // 返回功能
+  goBack(): void {
+    alert('返回首页');
+    // 实际项目中这里应该是路由跳转
+  }
+}

+ 1 - 1
picture-web/src/modules/picture/mobile.routes.ts

@@ -43,7 +43,7 @@ export const MOBILE_ROUTES: Routes = [
   },
   {
     path: 'image-detail',
-    loadComponent: () => import('../first-home/image-detail/image-detail').then(m => m.ImageDetail)}
+    loadComponent: () => import('../first-home/image-detail/image-detail').then(m => m.ImageDetailComponent)}
 ];