yann hai 6 meses
pai
achega
5de4ab9678

+ 89 - 0
components/addCartModel/addCartModel.js

@@ -0,0 +1,89 @@
+// components/addCartModel/addCartModel.js
+Component({
+    properties: {
+      visible: {
+        type: Boolean,
+        value: false
+      },
+      product: {
+        type: Object,
+        value: {}
+      }
+    },
+  
+    data: {
+      selectedSpecs: [], // 选择的规格索引 [0,1]表示第一个规格的第0个选项,第二个规格的第1个选项
+      quantity: 1
+    },
+  
+    observers: {
+      'product': function(specs) {
+        console.log("888888888888",specs);
+      }
+    },
+  
+    methods: {
+      handleClose() {
+        this.triggerEvent('close');
+      },
+      
+      selectSpec(e) {
+        const { specIndex, optionIndex } = e.currentTarget.dataset;
+        const { selectedSpecs } = this.data;
+        
+        selectedSpecs[specIndex] = optionIndex;
+        this.setData({ selectedSpecs });
+      },
+      
+      isSpecSelected(specIndex, optionIndex) {
+        return this.data.selectedSpecs[specIndex] === optionIndex;
+      },
+      
+      increaseQuantity() {
+        const { quantity, product } = this.data;
+        if (quantity < product.stock) {
+          this.setData({ quantity: quantity + 1 });
+        }
+      },
+      
+      decreaseQuantity() {
+        const { quantity } = this.data;
+        if (quantity > 1) {
+          this.setData({ quantity: quantity - 1 });
+        }
+      },
+      
+      handleAddToCart() {
+        const { product, selectedSpecs, quantity } = this.data;
+        
+        // 获取选中的规格文本
+        const selectedSpecText = product.specs.map((spec, index) => {
+          return spec.options[selectedSpecs[index]];
+        }).join(',');
+        
+        // 组装添加到购物车的数据
+        const cartItem = {
+          productId: product.id,
+          image: product.image,
+          name: product.name,
+          price: product.price,
+          quantity,
+          selectedSpecs: selectedSpecText,
+          stock: product.stock
+        };
+        
+        this.triggerEvent('add', { item: cartItem });
+      }
+    },
+    
+    computed: {
+      selectedSpecText() {
+        const { product, selectedSpecs } = this.data;
+        if (!product.specs || product.specs.length === 0) return '';
+        
+        return product.specs.map((spec, index) => {
+          return spec.options[selectedSpecs[index]];
+        }).join(',');
+      }
+    }
+  });

+ 3 - 0
components/addCartModel/addCartModel.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 56 - 0
components/addCartModel/addCartModel.wxml

@@ -0,0 +1,56 @@
+<!--components/addCartModel/addCartModel.wxml-->
+<view class="modal-container {{visible ? 'modal-show' : ''}}">
+  <view class="modal-mask" bindtap="handleClose"></view>
+  <view class="modal-content">
+    <!-- 头部关闭按钮 -->
+    <view class="modal-header">
+      <text class="title">选择规格</text>
+      <text class="close-btn" bindtap="handleClose">×</text>
+    </view>
+    
+    <!-- 商品信息 -->
+    <view class="product-info">
+      <image class="product-image" src="{{product.prodPicList[0].picUrl}}" mode="aspectFill"></image>
+      <view class="product-detail">
+        <view class="prodName">{{product.prodName}}</view>
+        <view class="product-attr">
+            <text class="price">¥{{product.price || 100}}</text>
+            <text class="stock">剩余:{{product.stock || 100}}</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 数量选择 -->
+    <view class="quantity-section">
+      <view class="quantity-title">购买数量</view>
+      <view class="quantity-control">
+        <text class="btn-minus" bindtap="decreaseQuantity" disabled="{{quantity <= 1}}">-</text>
+        <input class="quantity-input" type="number" value="{{quantity}}" disabled />
+        <text class="btn-plus" bindtap="increaseQuantity" disabled="{{quantity >= product.stock}}">+</text>
+      </view>
+    </view>
+    
+    <!-- 规格选择 -->
+    <view class="spec-section" wx:for="{{product.prodAttrList}}" wx:key="name">
+      <view class="spec-title">{{item.prodName}}</view>
+      <view class="spec-options">
+        <view 
+          class="spec-option {{isSpecSelected(index, optionIndex) ? 'selected' : ''}}"
+          wx:for="{{item.options}}"
+          wx:key="value"
+          bindtap="selectSpec"
+          data-spec-index="{{index}}"
+          data-option-index="{{optionIndex}}"
+        >
+          {{item}}
+        </view>
+      </view>
+    </view>
+    
+    
+    <!-- 底部按钮 -->
+    <view class="footer">
+      <button class="add-btn" bindtap="handleAddToCart">加入购物车</button>
+    </view>
+  </view>
+</view>

+ 189 - 0
components/addCartModel/addCartModel.wxss

@@ -0,0 +1,189 @@
+/* components/addCartModel/addCartModel.wxss */
+.modal-container {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    z-index: 999;
+    visibility: hidden;
+    opacity: 0;
+    transition: all 0.3s ease;
+  }
+  
+  .modal-container.modal-show {
+    visibility: visible;
+    opacity: 1;
+  }
+  
+  .modal-mask {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(0, 0, 0, 0.5);
+  }
+  
+  .modal-content {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    max-height: 70vh;
+    background: #fff;
+    border-radius: 24rpx 24rpx 0 0;
+    box-sizing: border-box;
+    padding: 32rpx;
+    transform: translateY(100%);
+    transition: transform 0.3s ease;
+  }
+  
+  .modal-show .modal-content {
+    transform: translateY(0);
+  }
+  
+  .modal-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 32rpx;
+  }
+  
+  .modal-header .title {
+    font-size: 32rpx;
+    font-weight: bold;
+  }
+  
+  .close-btn {
+    margin: 0;
+    padding: 0;
+    width: 48rpx;
+    height: 48rpx;
+    line-height: 48rpx;
+    font-size: 36rpx;
+    background: transparent;
+    border: none;
+  }
+  
+  .product-info {
+    display: flex;
+    margin-bottom: 32rpx;
+  }
+  
+  .product-image {
+    width: 221rpx;
+    height: 221rpx;
+    border-radius: 30rpx;
+    margin-right: 24rpx;
+  }
+  
+  .product-detail {
+    flex: 1;
+  }
+  
+  .product-attr{
+      display: flex;
+      align-items: flex-end;
+      justify-content: space-between;
+  }
+
+  .price {
+    font-size: 36rpx;
+    color: #ff2e4d;
+    font-weight: bold;
+  }
+  
+  .stock {
+    font-size: 24rpx;
+    color: #000;
+  }
+  
+  .prodName {
+    font-size: 32rpx;
+    color: #000;
+    font-weight: 600;
+    margin-bottom: 130rpx;
+  }
+  
+  .spec-section {
+    margin-bottom: 32rpx;
+  }
+  
+  .spec-title {
+    font-size: 28rpx;
+    margin-bottom: 16rpx;
+  }
+  
+  .spec-options {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 16rpx;
+  }
+  
+  .spec-option {
+    padding: 12rpx 24rpx;
+    border: 1rpx solid #eee;
+    border-radius: 8rpx;
+    font-size: 26rpx;
+  }
+  
+  .spec-option.selected {
+    border-color: #ff2e4d;
+    color: #ff2e4d;
+    background-color: #fff5f6;
+  }
+  
+  .quantity-section {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 48rpx;
+  }
+  
+  .quantity-title {
+    font-size: 28rpx;
+  }
+  
+  .quantity-control {
+    display: flex;
+    align-items: center;
+  }
+  
+  .quantity-input {
+    width: 80rpx;
+    text-align: center;
+    margin: 0 16rpx;
+  }
+  
+  .btn-minus, .btn-plus {
+    width: 60rpx;
+    height: 60rpx;
+    line-height: 60rpx;
+    text-align: center;
+    padding: 0;
+    margin: 0;
+    border: 1rpx solid #eee;
+    background: #f7f7f7;
+    border-radius: 8rpx;
+  }
+  
+  .btn-minus[disabled], .btn-plus[disabled] {
+    opacity: 0.5;
+  }
+  
+  .footer {
+    width: 100%;
+    background: #fff;
+    padding-top: 16rpx;
+  }
+  
+  .add-btn {
+    width: 657rpx !important;
+    background: #89C6BE;
+    color: #fff;
+    border-radius: 20rpx;
+    line-height: 105rpx;
+    font-size: 30rpx;
+    padding: 0;
+  }

+ 15 - 0
components/product-list/product-list.js

@@ -71,6 +71,21 @@ Component({
                 }
             })
         },
+        // 添加购物车
+        addCart(prod){
+            console.log(prod);
+            let prodInfo = prod.currentTarget.dataset.prod;
+            this.triggerEvent('addCart',prodInfo);
+            // let data = {
+            //     mercId:prodInfo.mercId,
+            //     prodId:prodInfo.prodId,
+            //     prodAttrId:prodInfo.prodAttrList[0],
+            //     count:1
+            // }
+            // API.addCart(data).then(res=>{
+            //     console.log(res);
+            // })
+        },
         // 观察滚动触底事件
         onReachBottom(e){
             this.setData({

+ 2 - 2
components/product-list/product-list.wxml

@@ -14,7 +14,7 @@
                     <image src="/images/index/fav.png" class="favorite-icon"></image>
                 </view>
                 <view class="goods-but">
-                    <image class="add-to-cart" src="/images/index/add-cart.png" mode=""/>
+                    <image class="add-to-cart" src="/images/index/add-cart.png" mode="" data-prod="{{item}}" catchtap="addCart"/>
                     <image class="buy-now" src="/images/index/buy-now.png" mode=""/>
                 </view>
             </view>
@@ -24,7 +24,7 @@
                     <view class="favorite">
                         <image src="/images/mall/fav.png" class="favorite-icon"></image>
                     </view>
-                    <image class="shoppingCart" src="/images/mall/cart.png" mode="widthFix"/>
+                    <image class="shoppingCart" src="/images/mall/cart.png" mode="widthFix" data-prod="{{item}}" catchtap="addCart"/>
                 </view>
             </view>
         </view>

+ 30 - 2
pages/index/index.js

@@ -4,7 +4,7 @@ const { API } = require('../../service/api.js');
 const App = getApp();
 
 
-Component({
+Page({
   data: {
     brandList: [
       {
@@ -64,8 +64,36 @@ Component({
         name: "立绘",
       },
     ],
+    showAddCartModal: false,
+    currentProduct: null
+  },
+  // 显示商品属性模态框
+  showAddCartModal(e) {
+    const product = e.detail;
+    this.setData({
+      showAddCartModal: true,
+      currentProduct:product
+    });
+  },
+  // 关闭商品属性模态框
+  handleCloseAddCartModal() {
+    this.setData({ showAddCartModal: false });
+  },
+  // 添加购物车
+  handleAddToCart(e) {
+    const cartItem = e.detail.item;
+    // 这里实现添加到购物车的逻辑
+    console.log('添加到购物车:', cartItem);
+    
+    // 可以显示添加成功的提示
+    wx.showToast({
+      title: '已加入购物车',
+      icon: 'success'
+    });
+    
+    // 关闭弹框
+    this.setData({ showAddCartModal: false });
   },
-
   methods: {
     onLoad: async function (options) {
 

+ 2 - 1
pages/index/index.json

@@ -2,6 +2,7 @@
   "navigationStyle": "custom",
   "usingComponents": {
     "header":"/components/header/header",
-    "product-list":"/components/product-list/product-list"
+    "product-list":"/components/product-list/product-list",
+    "addCartModel":"/components/addCartModel/addCartModel"
   }
 }

+ 5 - 1
pages/index/index.wxml

@@ -38,5 +38,9 @@
   </view>
 
   <!-- 商品列表 -->
-  <product-list position="index"></product-list>
+  <product-list position="index" bindaddCart="showAddCartModal"></product-list>
+
+  <!-- 商品属性模态框 -->
+  <addCartModel visible="{{showAddCartModal}}" product="{{currentProduct}}" bindclose="handleCloseAddCartModal" bindadd="handleAddToCart"></addCartModel>
+
 </view>

+ 4 - 0
service/api.js

@@ -229,5 +229,9 @@ export const API = {
     //  获取购物车商品
     getCartProds: function(){
         return http.get("/api/store/carts/list",{})
+    },
+    // 添加购物车
+    addCart: function(payload){
+        return http.post("/api/store/carts/add",payload)
     }
 }