Bläddra i källkod

完善产品页静态布局

sfmind 2 år sedan
förälder
incheckning
3b266c4a0e
1 ändrade filer med 375 tillägg och 97 borttagningar
  1. 375 97
      yudao-ui-app/pages/product/product.vue

+ 375 - 97
yudao-ui-app/pages/product/product.vue

@@ -1,6 +1,6 @@
 <template>
   <view class="container">
-    <u-swiper :list="product.images" @change="e => currentNum = e.current" :autoplay="false" height="750rpx" radius="0" indicatorStyle="right: 20px">
+    <u-swiper :list="product.images" @change="e => (currentNum = e.current)" :autoplay="false" height="750rpx" radius="0" indicatorStyle="right: 20px">
       <view slot="indicator" class="indicator-num">
         <text class="indicator-num__text">{{ currentNum + 1 }}/{{ product.images.length }}</text>
       </view>
@@ -14,49 +14,125 @@
           <u--text :lines="3" size="12px" color="#939393" :text="product.desc"></u--text>
         </view>
         <view class="price-and-cart">
-          <u--text-price color="red" size="16" intSize="26" :text="product.price"></u--text-price>
+          <custom-text-price color="red" size="16" intSize="26" :price="product.price"></custom-text-price>
         </view>
       </view>
       <view class="prod-favor">
         <u-icon name="star" color="#2979ff" size="28"></u-icon>
       </view>
-
     </view>
 
     <u-gap height="8" bgColor="#f3f3f3"></u-gap>
-    <view class="info-box">
-      <text class="info-title">配送</text>
-<!--      <text>快递配送</text>
-      <text>到店自提</text>-->
+    <view class="row-box">
+      <view class="row-left">规格</view>
+      <view class="row-right" @click="skuPopup = true">
+        <view class="row-content">
+          <view class="sku-box">
+            <view v-if="product.sku.length > 0" class="sku-item">
+              <view class="sku-desc">{{ product.sku[currentSkuIndex].desc }}</view>
+            </view>
+          </view>
+        </view>
+        <view class="row-more">
+          <u-icon name="more-dot-fill" color="#939393" size="14"></u-icon>
+        </view>
+      </view>
     </view>
 
-    <u-gap height="8" bgColor="#f3f3f3"></u-gap>
-    <view class="info-box" @click="showPromPopup">
-      <text class="info-title">促销</text>
-    </view>
+    <!-- 商品SKU选择弹窗 -->
+    <u-popup :show="skuPopup" :round="10" :closeable="true" :closeOnClickOverlay="false" @close="skuPopup = false">
+      <view class="sku-popup-slot">
+        <view class="current-sku-info">
+          <u--image class="current-sku-img" :showLoading="true" :src="product.sku[currentSkuIndex].image" width="120rpx" height="120rpx"></u--image>
+          <view class="current-sku-desc">
+            <view class="name">{{ product.sku[currentSkuIndex].desc }}</view>
+            <custom-text-price color="red" size="12" intSize="18" :price="product.sku[currentSkuIndex].price"></custom-text-price>
+            <view class="current-sku-stock">库存: {{ 1 }}</view>
+          </view>
+        </view>
+        <view class="sku-selection">
+          <view class="sku-item" :class="{ active: currentSkuIndex === index }" v-for="(item, index) in product.sku" :key="item.id" @click="handleSkuItemClick(index)">{{ item.desc }}</view>
+        </view>
+        <view class="sku-num-box">
+          <view class="text">选择数量</view>
+          <u-number-box integer></u-number-box>
+        </view>
+        <view class="sku-btn-group">
+          <view class="btn-item-main">
+            <u-button type="warning" shape="circle" size="small" text="加入购物车"></u-button>
+          </view>
+          <view class="btn-item-main">
+            <u-button type="error" shape="circle" size="small" text="立即购买"></u-button>
+          </view>
+        </view>
+      </view>
+    </u-popup>
 
-    <view>
-      <u-popup :show="promotionPopup" :round="10" :closeable="true" :closeOnClickOverlay="false" @close="closePromPopup">
-        <view class="prom-popup-slot">
-          <view class="prom-title">促销信息</view>
-          <view class="prom-list">
-            <view class="prom-item">全场满500减100</view>
-            <view class="prom-item">全场满300减50</view>
-            <view class="prom-item">全场满200减20</view>
-            <view class="prom-item">全场满100减5</view>
+    <u-gap height="8" bgColor="#f3f3f3"></u-gap>
+    <view class="row-box">
+      <view class="row-left">配送</view>
+      <view class="row-right">
+        <view class="row-content">
+          <view class="delivery-box">
+            <view class="delivery-item" v-for="(item, index) in deliveryType" :key="item.id">
+              <u-icon name="checkmark-circle" color="#2979ff" size="16"></u-icon>
+              <text class="delivery-name">{{ item.name }}</text>
+            </view>
           </view>
         </view>
-      </u-popup>
+        <view class="row-more"></view>
+      </view>
     </view>
 
     <u-gap height="8" bgColor="#f3f3f3"></u-gap>
-    <view class="info-box">
-      <text class="info-title">领券</text>
+    <view class="row-box">
+      <view class="row-left">促销</view>
+      <view class="row-right" v-if="promotionList.length > 0" @click="promotionPopup = true">
+        <view class="row-content">
+          <view class="prom-box">
+            <view class="prom-item">
+              <view class="prom-title">{{ promotionList[0].title }}</view>
+              <text class="prom-desc">{{ promotionList[0].desc }}</text>
+            </view>
+          </view>
+        </view>
+        <view class="row-more">
+          <u-icon name="more-dot-fill" color="#939393" size="14"></u-icon>
+        </view>
+      </view>
     </view>
 
+    <!-- 促销信息弹窗 -->
+    <u-popup :show="promotionPopup" :round="10" :closeable="true" :closeOnClickOverlay="false" @close="promotionPopup = false">
+      <view class="prom-popup-slot">
+        <view class="prom-info">促销信息</view>
+        <view class="prom-list">
+          <view v-for="(item, index) in promotionList" :key="index.id" class="prom-item">
+            <view class="prom-title">{{ item.title }}</view>
+            <text class="prom-desc">{{ item.desc }}</text>
+          </view>
+        </view>
+      </view>
+    </u-popup>
+
     <u-gap height="8" bgColor="#f3f3f3"></u-gap>
-    <view class="info-box">
-      <text class="info-title">已选</text>
+    <view class="row-box">
+      <view class="row-left">领券</view>
+      <view class="row-right" @click="handleCouponClick">
+        <view class="row-content">
+          <view class="coupon-box">
+            <view v-if="couponList.length > 0" class="coupon-list">
+              <view v-for="(item, index) in couponList" :key="item.id" class="coupon-item">
+                <view v-if="index < 2" class="coupon-desc">{{ item.desc }}</view>
+              </view>
+            </view>
+            <view class="coupon-total">共 {{ couponList.length }} 张</view>
+          </view>
+        </view>
+        <view class="row-more">
+          <u-icon name="more-dot-fill" color="#939393" size="14"></u-icon>
+        </view>
+      </view>
     </view>
 
     <u-gap height="8" bgColor="#f3f3f3"></u-gap>
@@ -65,46 +141,39 @@
         <view class="evaluation-title">评价</view>
         <view class="evaluation-info">
           <view class="evan-type-list">
-            <view class="evan-type-item" v-for="(item, index) in evanTypeList" :key="index" @click="handleEvanTypeClick(index)">
-              {{item.name}}({{item.count}})
-            </view>
+            <view class="evan-type-item" :class="{ active: currentEvanIndex === index }" v-for="(item, index) in evanTypeList" :key="item.id" @click="handleEvanTypeClick(index)"> {{ item.name }}({{ item.count }}) </view>
           </view>
           <view class="comment-empty" v-if="true">
             <u-empty mode="comment" icon="/static/images/empty/comment.png"></u-empty>
           </view>
-          <view v-else class="comment-list" style="min-height: 50px">
-
-          </view>
+          <view v-else class="comment-list" style="min-height: 50px"> </view>
         </view>
       </view>
     </view>
 
     <view class="fixed-btn-box">
       <view class="btn-group">
-        <view class="btn-item">
+        <navigator class="btn-item" url="/pages/index/index" open-type="switchTab" hover-class="none">
           <u-icon name="home" :size="24"></u-icon>
           <view class="btn-text">首页</view>
-        </view>
-        <view class="btn-item">
+        </navigator>
+        <navigator class="btn-item" url="/pages/xxx/xxx" open-type="navigate" hover-class="none">
           <u-icon name="server-man" :size="24"></u-icon>
           <view class="btn-text">客服</view>
-        </view>
-        <view class="btn-item">
+        </navigator>
+        <navigator class="btn-item" url="/pages/cart/cart" open-type="switchTab" hover-class="none">
           <u-icon name="bag" :size="24"></u-icon>
           <view class="btn-text">购物车</view>
-        </view>
-        <view style="width: 200rpx">
+        </navigator>
+        <view class="btn-item-main">
           <u-button type="warning" shape="circle" size="small" text="加入购物车"></u-button>
         </view>
-        <view style="width: 200rpx">
+        <view class="btn-item-main">
           <u-button type="error" shape="circle" size="small" text="立即购买"></u-button>
         </view>
       </view>
     </view>
-
-
   </view>
-
 </template>
 
 <script>
@@ -113,15 +182,86 @@ export default {
     return {
       current: 0,
       currentNum: 0,
+      currentSkuIndex: 0,
+      skuPopup: false,
       product: {
         id: '',
         images: ['https://cdn.uviewui.com/uview/album/1.jpg', 'https://cdn.uviewui.com/uview/album/2.jpg', 'https://cdn.uviewui.com/uview/album/3.jpg'],
         title: '山不在高,有仙则名。水不在深,有龙则灵。斯是陋室,惟吾德馨。',
         desc: '山不在于高,有了神仙就会有名气。水不在于深,有了龙就会有灵气。这是简陋的房子,只是我品德好就感觉不到简陋了。',
-        price: '13.00'
+        price: '13.00',
+        sku: [
+          {
+            id: 0,
+            image: 'https://cdn.uviewui.com/uview/album/1.jpg',
+            price: 13.0,
+            desc: '山不在高,有仙则名。'
+          },
+          {
+            id: 1,
+            image: 'https://cdn.uviewui.com/uview/album/2.jpg',
+            price: 11.0,
+            desc: '水不在深,有龙则灵。'
+          },
+          {
+            id: 2,
+            image: 'https://cdn.uviewui.com/uview/album/3.jpg',
+            price: 10.0,
+            desc: '斯是陋室,惟吾德馨。'
+          }
+        ]
       },
+      deliveryType: [
+        {
+          id: 0,
+          name: '快递配送'
+        },
+        {
+          id: 1,
+          name: '到店自提'
+        }
+      ],
       promotionPopup: false,
-      currentEvanType: 0,
+      promotionList: [
+        {
+          id: 0,
+          title: '满额减',
+          desc: '全场满500减100'
+        },
+        {
+          id: 1,
+          title: '满额减',
+          desc: '全场满300减50'
+        },
+        {
+          id: 2,
+          title: '满额减',
+          desc: '全场满200减20'
+        },
+        {
+          id: 3,
+          title: '满额减',
+          desc: '全场满100减5'
+        }
+      ],
+      couponList: [
+        {
+          id: 0,
+          title: '优惠券',
+          desc: '满50减10'
+        },
+        {
+          id: 1,
+          title: '优惠券',
+          desc: '满30减5'
+        },
+        {
+          id: 2,
+          title: '优惠券',
+          desc: '满20减2'
+        }
+      ],
+      currentEvanIndex: 0,
       evanTypeList: [
         {
           id: '0',
@@ -147,60 +287,53 @@ export default {
           id: '4',
           name: '有图',
           count: 0
-        },
+        }
       ]
     }
   },
   onLoad(e) {
     if (!e.productId) {
-      uni.$u.toast('请求参数错误');
+      uni.$u.toast('请求参数错误')
     } else {
-      this.product.id = e.productId;
-      this.loadProductData();
+      this.product.id = e.productId
+      this.loadProductData()
       // TODO 请求接口获取商品详情数据
     }
-    console.log(e);
   },
   methods: {
-    loadProductData(){
-
-    },
-    showPromPopup() {
-      this.promotionPopup = true
-    },
-    closePromPopup(){
-      this.promotionPopup = false
+    loadProductData() {},
+    handleSkuItemClick(index) {
+      this.currentSkuIndex = index
     },
-    handleEvanTypeClick(e) {
-      this.currentEvanType = e.index;
+    handleCouponClick() {
+      // TODO 未登录去登录,登录则跳转优惠券页面
     },
-
+    handleEvanTypeClick(index) {
+      this.currentEvanIndex = index
+      // TODO 展示评论
+    }
   },
-  computed: {
-
-  }
+  computed: {}
 }
 </script>
 
 <style lang="scss" scoped>
-
 .indicator-num {
+  @include flex-center;
   padding: 2px 0;
   background-color: rgba(0, 0, 0, 0.35);
   border-radius: 100px;
   width: 35px;
-  @include flex;
-  justify-content: center;
 
   &__text {
-    color: #FFFFFF;
+    color: #ffffff;
     font-size: 12px;
   }
 }
 
 .product-box {
   padding: 40rpx 40rpx 10rpx 40rpx;
-  display: flex;
+  @include flex;
   border-bottom: $custom-border-style;
   .prod-info {
     padding-right: 30rpx;
@@ -208,8 +341,7 @@ export default {
       padding-bottom: 10rpx;
     }
     .price-and-cart {
-      display: flex;
-      justify-content: space-between;
+      @include flex-space-between;
     }
   }
   .prod-favor {
@@ -217,28 +349,174 @@ export default {
   }
 }
 
-.info-box {
-  padding: 15rpx 30rpx;
-  .info-title {
-    font-size: 30rpx;
+.row-box {
+  @include flex-left;
+  padding: 0 30rpx;
+  height: 70rpx;
+  .row-left {
+    width: 70rpx;
+    font-size: 22rpx;
+    color: #939393;
+  }
+
+  .row-right {
+    @include flex-space-between;
+    width: 620rpx;
+
+    .row-content {
+      width: 590rpx;
+
+      .delivery-box {
+        @include flex-left;
+        .delivery-item {
+          margin-right: 20rpx;
+          @include flex-left;
+          font-size: 14rpx;
+          .delivery-name {
+            margin-left: 5rpx;
+          }
+        }
+      }
+
+      .prom-box {
+        @include flex-left;
+        .prom-item {
+          @include flex-left;
+          font-size: 12rpx;
+          .prom-title {
+            padding: 1rpx 10rpx;
+            border: 1rpx solid red;
+            border-radius: 5rpx;
+            color: red;
+            transform: scale(0.9);
+          }
+          .prom-desc {
+            margin-left: 15rpx;
+          }
+        }
+      }
+
+      .coupon-box {
+        @include flex-space-between;
+        .coupon-list {
+          @include flex-left;
+          .coupon-item {
+            @include flex-left;
+            font-size: 12rpx;
+            .coupon-desc {
+              padding: 2rpx 15rpx;
+              margin-right: 15rpx;
+              background: red;
+              color: #ffffff;
+            }
+          }
+        }
+        .coupon-total {
+          color: #939393;
+          font-size: 12rpx;
+          padding: 0 15rpx;
+        }
+      }
+
+      .sku-box {
+        @include flex-space-between;
+        .sku-item {
+          @include flex-left;
+          font-size: 12rpx;
+          .sku-desc {
+            margin-left: 15rpx;
+            font-weight: 700;
+          }
+        }
+      }
+    }
+
+    .row-more {
+      @include flex-right;
+      width: 30rpx;
+    }
+  }
+}
+
+.sku-popup-slot {
+  width: 750rpx;
+  .current-sku-info {
+    @include flex;
+    padding: 30rpx 100rpx 0 30rpx;
+    .current-sku-img {
+      border-radius: 10rpx;
+      /deep/ * {
+        border-radius: 10rpx;
+      }
+    }
+    .current-sku-desc {
+      padding: 0 30rpx;
+      font-size: 28rpx;
+      .current-sku-stock {
+        height: 40rpx;
+        line-height: 40rpx;
+        color: #666666;
+        font-size: 24rpx;
+      }
+    }
+  }
+  .sku-selection {
+    margin: 30rpx;
+    font-size: 26rpx;
+    color: #939393;
+    .sku-item {
+      margin-bottom: 20rpx;
+      border-radius: 6rpx;
+      padding: 5rpx 15rpx;
+      border: 1rpx solid #e3e3e3;
+      width: fit-content !important;
+      &.active {
+        color: #666666;
+        border: 1rpx solid #666666;
+      }
+    }
+  }
+  .sku-num-box {
+    @include flex-space-between padding: 30rpx;
+    .text {
+      font-size: 30rpx;
+    }
+  }
+  .sku-btn-group {
+    @include flex-space-around;
+    height: 100rpx;
+    .btn-item-main {
+      width: 350rpx;
+    }
   }
 }
 
 .prom-popup-slot {
   width: 750rpx;
   min-height: 500rpx;
-  .prom-title {
+  .prom-info {
     background: #f3f3f3;
-    line-height: 100rpx;
+    line-height: 90rpx;
     padding-left: 30rpx;
     font-size: 36rpx;
     border-radius: 10px 10px 0 0;
   }
-  .prom-list{
+  .prom-list {
     padding: 30rpx;
-    .prom-item{
-      line-height: 40rpx;
-      font-size: 24rpx;
+    .prom-item {
+      @include flex-left;
+      font-size: 14rpx;
+      margin-bottom: 15rpx;
+      .prom-title {
+        padding: 1rpx 10rpx;
+        border: 1rpx solid red;
+        border-radius: 5rpx;
+        color: red;
+        transform: scale(0.9);
+      }
+      .prom-desc {
+        margin-left: 15rpx;
+      }
     }
   }
 }
@@ -251,34 +529,36 @@ export default {
     background: $custom-bg-color;
     padding-bottom: 120rpx;
 
-    .evaluation-title{
+    .evaluation-title {
       border-radius: 20rpx 20rpx 0 0;
       padding: 20rpx 30rpx;
       border-bottom: $custom-border-style;
       font-size: 30rpx;
     }
 
-    .evaluation-info{
-
+    .evaluation-info {
     }
 
-    .evan-type-list{
+    .evan-type-list {
       padding: 20rpx;
-      display: flex;
-      align-items: center;
-      justify-content: space-around;
+      @include flex-space-around;
 
       .evan-type-item {
         border-radius: 8rpx;
-        padding: 8rpx 12rpx;
+        padding: 7rpx 12rpx;
         background: #f3f3f3;
         font-size: 12rpx;
         text-align: center;
+        &.active {
+          background: #ffffff;
+          border: 1rpx solid red;
+          padding: 5rpx 10rpx;
+          color: red;
+        }
       }
     }
 
     .comment-empty {
-
     }
   }
 }
@@ -292,23 +572,21 @@ export default {
     border-top: $custom-border-style;
 
     width: 750rpx;
-    display: flex;
-    align-items: center;
-    justify-content: space-around;
+    @include flex-space-around;
     height: 100rpx;
 
     .btn-item {
       width: 80rpx;
-      display: flex;
-      flex-direction: column;
-      align-items: center;
+      @include flex-center(column);
       .btn-text {
         font-size: 12rpx;
         color: #666666;
       }
     }
+
+    .btn-item-main {
+      width: 200rpx;
+    }
   }
 }
-
-
 </style>