Files
ipms-sjy/yudao-ui-app/pages/product/product.vue
2022-07-27 16:04:53 +08:00

612 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<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>
</u-swiper>
<view class="product-box">
<view class="prod-info">
<view class="info-text">
<u--text :lines="2" size="14px" color="#333333" :text="product.title"></u--text>
<u-gap height="5px"></u-gap>
<u--text :lines="3" size="12px" color="#939393" :text="product.desc"></u--text>
</view>
<view class="price-and-cart">
<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="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>
<!-- 商品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].picUrl" 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>
<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>
<view class="row-more"></view>
</view>
</view>
<u-gap height="8" bgColor="#f3f3f3"></u-gap>
<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="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>
<view class="evaluation-box-wrap">
<view class="evaluation-box">
<view class="evaluation-title">评价</view>
<view class="evaluation-info">
<view class="evan-type-list">
<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" width="350rpx" height="350rpx" icon="/static/images/empty/comment.png"></u-empty>
</view>
<view v-else class="comment-list" style="min-height: 50px"> </view>
</view>
</view>
</view>
<view class="fixed-btn-box">
<view class="btn-group">
<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>
</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>
</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>
</navigator>
<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" color="#ea322b" shape="circle" size="small" text="立即购买"></u-button>
</view>
</view>
<u-safe-bottom customStyle="background: #ffffff"></u-safe-bottom>
</view>
</view>
</template>
<script>
import { productSpu } from '../../api/product';
export default {
data() {
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',
sku: [
{
id: 0,
picUrl: 'https://cdn.uviewui.com/uview/album/1.jpg',
price: 13.0,
desc: '山不在高,有仙则名。'
},
{
id: 1,
picUrl: 'https://cdn.uviewui.com/uview/album/2.jpg',
price: 11.0,
desc: '水不在深,有龙则灵。'
},
{
id: 2,
picUrl: 'https://cdn.uviewui.com/uview/album/3.jpg',
price: 10.0,
desc: '斯是陋室,惟吾德馨。'
}
]
},
deliveryType: [
{
id: 0,
name: '快递配送'
},
{
id: 1,
name: '到店自提'
}
],
promotionPopup: false,
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',
name: '全部',
count: 0
},
{
id: '1',
name: '好评',
count: 0
},
{
id: '2',
name: '中评',
count: 0
},
{
id: '3',
name: '差评',
count: 0
},
{
id: '4',
name: '有图',
count: 0
}
]
}
},
onLoad(e) {
if (!e.productId) {
uni.$u.toast('请求参数错误')
} else {
this.product.id = e.productId
this.loadProductData()
// TODO 请求接口获取商品详情数据
}
},
methods: {
loadProductData() {
let param = {}
param.spuId = this.product.id
productSpu(param).then(res => {
this.product.images = res.data.picUrls;
this.product.sku = res.data.skus;
this.product.desc = res.data.description.replace(/<[^>]*>/g,'');
this.product.price = res.data.price;
this.product.title = res.data.name;
console.log(res)
})
},
handleSkuItemClick(index) {
this.currentSkuIndex = index
},
handleCouponClick() {
// TODO 未登录去登录,登录则跳转优惠券页面
},
handleEvanTypeClick(index) {
this.currentEvanIndex = index
// TODO 展示评论
}
},
computed: {
hasLogin() {
return this.$store.getters.hasLogin
}
}
}
</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;
&__text {
color: #ffffff;
font-size: 12px;
}
}
.product-box {
padding: 40rpx 40rpx 10rpx 40rpx;
@include flex;
border-bottom: $custom-border-style;
.prod-info {
padding-right: 30rpx;
.info-text {
padding-bottom: 10rpx;
}
.price-and-cart {
@include flex-space-between;
}
}
.prod-favor {
margin-top: 15rpx;
}
}
.row-box {
@include flex-left;
padding: 0 30rpx;
height: 70rpx;
.row-left {
width: 70rpx;
font-size: 24rpx;
color: #939393;
}
.row-right {
@include flex-space-between;
flex: 1;
.row-content {
flex: 1;
.delivery-box {
@include flex-left;
.delivery-item {
margin-right: 20rpx;
@include flex-left;
font-size: 22rpx;
.delivery-name {
margin-left: 5rpx;
}
}
}
.prom-box {
@include flex-left;
.prom-item {
@include flex-left;
font-size: 22rpx;
.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: 22rpx;
.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: 22rpx;
.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-info {
background: #f3f3f3;
line-height: 90rpx;
padding-left: 30rpx;
font-size: 36rpx;
border-radius: 10px 10px 0 0;
}
.prom-list {
padding: 30rpx;
.prom-item {
@include flex-left;
font-size: 22rpx;
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;
}
}
}
}
.evaluation-box-wrap {
background: #f3f3f3;
.evaluation-box {
border-radius: 20rpx 20rpx 0 0;
background: $custom-bg-color;
padding-bottom: 120rpx;
.evaluation-title {
border-radius: 20rpx 20rpx 0 0;
padding: 20rpx 30rpx;
border-bottom: $custom-border-style;
font-size: 30rpx;
}
.evaluation-info {
}
.evan-type-list {
padding: 20rpx;
@include flex-space-around;
.evan-type-item {
border-radius: 8rpx;
padding: 7rpx 12rpx;
background: #f3f3f3;
font-size: 22rpx;
text-align: center;
&.active {
background: #ffffff;
border: 1rpx solid red;
padding: 5rpx 10rpx;
color: red;
}
}
}
.comment-empty {
margin-bottom: 100rpx;
}
}
}
.fixed-btn-box {
position: fixed;
bottom: 0;
left: 0;
.btn-group {
background: $custom-bg-color;
border-top: $custom-border-style;
width: 750rpx;
@include flex-space-around;
height: 100rpx;
.btn-item {
width: 80rpx;
@include flex-center(column);
.btn-text {
font-size: 18rpx;
color: #666666;
}
}
.btn-item-main {
width: 200rpx;
}
}
}
</style>