2024-05-29 21:49:52 +08:00
|
|
|
|
<template>
|
|
|
|
|
<view class="flex column">
|
|
|
|
|
<!-- topbar -->
|
|
|
|
|
<u-navbar :title="spu.name" bgColor="#d43030" :titleStyle="{ color: '#FFF'}" :autoBack="true" placeholder>
|
|
|
|
|
<view class="u-nav-slot" slot="left">
|
|
|
|
|
<u-icon name="arrow-left" color="#fff" size="19"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
</u-navbar>
|
|
|
|
|
<!-- 主图 -->
|
|
|
|
|
<u-swiper :list="spu.photo" height="572.5rpx" easingFunction="easeInCubic" radius="0" circular></u-swiper>
|
|
|
|
|
<!-- 标题 和 内容 -->
|
|
|
|
|
<view class="p-24 z-top fz44 fb bg-w">{{spu.name}}</view>
|
|
|
|
|
<view class="p-l-24 p-r-24 p-b-24 fcb fz24 borderB bg-w">
|
|
|
|
|
<u-read-more ref="uReadMore" showHeight="36" closeText="详情展开" openText="收起" toggle="true" color="#808080">
|
|
|
|
|
<u-parse class="fz28 l-h-18" :content="spu.content" @load="load"></u-parse>
|
|
|
|
|
</u-read-more>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- spu列表 -->
|
|
|
|
|
<view class="p-l-24 p-r-24 m-t-24" v-for="(spuB,index) in spu.bind_sku" :key="index">
|
|
|
|
|
<!-- sku组标题 -->
|
|
|
|
|
<view class="flex mac m-b-12">
|
|
|
|
|
<u-icon name="plus-square-fill" size="36rpx" color="#333"></u-icon>
|
|
|
|
|
<text class="fz36 fb">{{spuB.tit}}</text>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- sku组内容 -->
|
|
|
|
|
<view class="grid-container m-b-24">
|
|
|
|
|
<view v-for="(sku,i) in spuB.skuG" :key="i" class="grid-item bg-g rad8 border4 border-g flex column"
|
|
|
|
|
:class="isSel(sku.id)?'border-m':''" style="height: 296rpx;" @click="selSku(sku.id)">
|
|
|
|
|
<u--image :src="sku.photo[0]" width="100%" height="182rpx" radius="4rpx"></u--image>
|
|
|
|
|
<view class="fz28 tc l-h-18 m-t-12">{{sku.name}}</view>
|
|
|
|
|
<view class="flex1 flex msb mac">
|
|
|
|
|
<view class="m-l-12 fcm">
|
|
|
|
|
<text v-if="priceDifference(sku.id)!==0">
|
|
|
|
|
{{priceDifference(sku.id) | formatPrice}}
|
|
|
|
|
</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="border rad-c m-r-12" :class="isSel(sku.id)?'border-m bg-m':''"
|
|
|
|
|
style="width: 40rpx;height: 40rpx;">
|
|
|
|
|
<u-icon name="checkbox-mark" size="40rpx" color="#fff" v-if="isSel(sku.id)"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 底部占位 -->
|
|
|
|
|
<view class="extra-space">
|
|
|
|
|
<u-divider text="产品包装以实物为准" :hairline="true"></u-divider>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 购物车按钮 -->
|
|
|
|
|
<view class="cartBox flex mc">
|
|
|
|
|
<!-- 购物车框 -->
|
|
|
|
|
<view class="bottomBox rad32 flex mc mac">
|
|
|
|
|
<view class="flex mc mac bottomBoxin">
|
|
|
|
|
<view class="rad8 flex mc mac bottomBoxinin ">
|
|
|
|
|
<view class="flex mac bottomBoxCon p-b-24">
|
|
|
|
|
<view v-for="(spuB,index) in spu.bind_sku" :key="index" class="m-t-24 bowlBox">
|
|
|
|
|
<!-- 删除小按钮 -->
|
|
|
|
|
<view v-if="isSelSkuG(spuB.value)" class="cBUt bg-w rad-c flex mc mac z-top"
|
|
|
|
|
@click="delSku(spuB.value)">
|
|
|
|
|
<u-icon :name="spuB.skuG.length!==1?'close':'lock'" :bold="true" color="#333"
|
|
|
|
|
size="10"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 碗 -->
|
|
|
|
|
<view class="bg-mg rad-c bowl ofh border4"
|
|
|
|
|
:class="isSelSkuG(spuB.value)?'border-m':'border-g'">
|
|
|
|
|
<u--image v-for="(sku,i) in spuB.skuG" :key="i" v-if="isSel(sku.id)"
|
|
|
|
|
:src="sku.photo[0]" width="108rpx" height="108rpx" mode="aspectFit"></u--image>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 加入购物车 -->
|
|
|
|
|
<view v-if="isSelAll" class="bg-m rad16 fci flex msb cartButBox">
|
|
|
|
|
<view class="flex1 p-l-24 flex column mc">
|
|
|
|
|
<view class="fz36">¥{{totalPrice | formatPrice}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="flex column mac mc" style="width: 220rpx;" @click="handleAddCart">
|
|
|
|
|
<view class="fz36">加入购物车</view>
|
|
|
|
|
<view class="fz24">Add to Cart</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-else class="bg-g rad16 flex mc mac cartButBox">
|
|
|
|
|
<view class="fz36 fb">请选择餐品</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {
|
|
|
|
|
formatPrice
|
|
|
|
|
} from '@/utils/index.js'
|
|
|
|
|
export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
spu_id: null, //get接收spuid
|
|
|
|
|
initerr: true, //sel初始化之前 禁止 selSku点击事件
|
|
|
|
|
sel: [] //选中的sku
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
spu() {
|
|
|
|
|
return this.$store.state.spuList.find(item => item.id === this.spu_id)
|
|
|
|
|
},
|
|
|
|
|
//判断 是否每项sku组都 被选中其一
|
|
|
|
|
isSelAll() {
|
|
|
|
|
if (this.spu !== null) {
|
|
|
|
|
return this.sel.length === this.spu.bind_sku.length
|
|
|
|
|
} else {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
//已选中sku 的价格总和
|
|
|
|
|
totalPrice() {
|
|
|
|
|
let totalPrice = 0
|
|
|
|
|
let sku
|
|
|
|
|
this.sel.forEach(id => {
|
|
|
|
|
for (let i = 0; i < this.spu.bind_sku.length; i++) {
|
|
|
|
|
let index = this.spu.bind_sku[i].value.indexOf(Number(id))
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
sku = this.spu.bind_sku[i].skuG[index]
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
totalPrice += parseFloat(sku.price)
|
|
|
|
|
})
|
|
|
|
|
return totalPrice.toFixed(2)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
load() {
|
|
|
|
|
this.$refs.uReadMore.init()
|
|
|
|
|
},
|
|
|
|
|
//判断是否选择 改变样式
|
|
|
|
|
isSel(id) {
|
|
|
|
|
return this.sel.indexOf(id.toString()) !== -1
|
|
|
|
|
},
|
|
|
|
|
//判断 一组id中 有没有没选择 有一个被选择 改变样式
|
|
|
|
|
isSelSkuG(idArr) {
|
|
|
|
|
let res = false
|
|
|
|
|
idArr.forEach(id => {
|
|
|
|
|
if (this.sel.indexOf(id.toString()) !== -1) {
|
|
|
|
|
res = true
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return res
|
|
|
|
|
},
|
|
|
|
|
//选择sku
|
|
|
|
|
selSku(sku_id) {
|
|
|
|
|
if (this.initerr === true) { //sel初始化 完成与否
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
let ord = this.sel.indexOf(sku_id) //点击的id 在选中sel组中的位置
|
|
|
|
|
//当前没有选中 执行
|
|
|
|
|
if (ord === -1) {
|
|
|
|
|
// 遍历 spu.bind_sku 数组
|
|
|
|
|
this.spu.bind_sku.forEach(item => {
|
|
|
|
|
// 如果当前 item.value 中包含 sku_id,则将其从 this.sel 中移除
|
|
|
|
|
if (item.value.indexOf(Number(sku_id)) !== -1) {
|
|
|
|
|
item.value.forEach(v => {
|
|
|
|
|
// 找到要移除的值在 this.sel 中的索引
|
|
|
|
|
let index = this.sel.indexOf(v.toString())
|
|
|
|
|
// 如果索引不为 -1,则从 this.sel 中移除该值
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
this.sel.splice(index, 1)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
// 将新的 sku_id 添加到 sel 数组中
|
|
|
|
|
this.sel.push(sku_id)
|
|
|
|
|
} else { //如果当前已经选中 还被点击 则取消选择
|
|
|
|
|
this.sel.splice(ord, 1)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
//小按钮 删除 清楚当前选中sku
|
|
|
|
|
delSku(idArr) {
|
|
|
|
|
if (idArr.length > 1) {
|
|
|
|
|
idArr.forEach(id => {
|
|
|
|
|
const subscript = this.sel.indexOf(id.toString())
|
|
|
|
|
if (subscript !== -1) {
|
|
|
|
|
this.sel.splice(subscript, 1)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
//sel 初始化 sku组只有单sku的 默认选中 即将sku id添加到sel数组
|
|
|
|
|
initSel() {
|
|
|
|
|
// 遍历 spu.bind_sku 数组
|
|
|
|
|
this.spu.bind_sku.forEach(item => {
|
|
|
|
|
this.sel.push(item.value[0].toString()) //添加
|
|
|
|
|
})
|
|
|
|
|
//初始化完成后 才允许selSku点击事件执行
|
|
|
|
|
this.initerr = false
|
|
|
|
|
},
|
|
|
|
|
//添加购物车
|
|
|
|
|
handleAddCart() {
|
|
|
|
|
let orderSel = [] //把sel数组 按照sku组的顺序 重新排序
|
|
|
|
|
this.spu.bind_sku.forEach(item => {
|
|
|
|
|
item.value.forEach(id => {
|
|
|
|
|
if (this.sel.indexOf(id.toString()) !== -1) {
|
|
|
|
|
orderSel.push(id.toString())
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
let orderPrice = [] //skuG对应的单价
|
|
|
|
|
let orderCount = [] //skuG对应的数量
|
|
|
|
|
orderSel.forEach(id => {
|
|
|
|
|
const sku = this.$store.state.skuList.find(item => item.id.toString() === id.toString())
|
|
|
|
|
orderPrice.push(Number(parseFloat(sku.price).toFixed(2)))
|
|
|
|
|
orderCount.push(1)
|
|
|
|
|
})
|
|
|
|
|
let cart = {
|
|
|
|
|
"spu_id": this.spu.id,
|
|
|
|
|
"skuG": orderSel,
|
|
|
|
|
"countG": orderCount,
|
|
|
|
|
"priceG": orderPrice
|
|
|
|
|
}
|
|
|
|
|
this.$store.commit('setCartList', cart)
|
|
|
|
|
|
|
|
|
|
// 返回上一页
|
|
|
|
|
uni.navigateBack({
|
|
|
|
|
delta: 1 // 返回的页面数,这里是返回上一页,如果是返回多级页面,可以设置为对应的值
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
//sku组 差价显示 ps:sku组第一个为默认选择 其价格为价格基数 算各sku的差价
|
|
|
|
|
priceDifference(sku_id) {
|
|
|
|
|
let priceDifference = 0 //记录差价
|
|
|
|
|
for (let i = 0; i < this.spu.bind_sku.length; i++) {
|
|
|
|
|
let index = this.spu.bind_sku[i].value.indexOf(Number(sku_id))
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
if (index !== 0) { //因为第一个是基数所以差价是0 只有不是第一个值时才计算差价
|
|
|
|
|
const baseSku = this.spu.bind_sku[i].skuG[0]
|
|
|
|
|
const sku = this.spu.bind_sku[i].skuG[index]
|
|
|
|
|
priceDifference = Number(sku.price) - Number(baseSku.price)
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return priceDifference
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onLoad: function(option) { //option为object类型,会序列化上个页面传递的 get参数
|
|
|
|
|
this.spu_id = option.spu_id //get 传spuid
|
|
|
|
|
this.initSel() //sel初始化
|
|
|
|
|
console.log(this.spu.bind_sku)
|
|
|
|
|
},
|
|
|
|
|
filters: {
|
|
|
|
|
formatPrice //格式化价格
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.grid-container {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr); //每行3列,等分
|
|
|
|
|
grid-gap: 24rpx; //设置网格项之间的间距
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.grid-item {}
|
|
|
|
|
|
|
|
|
|
.extra-space {
|
|
|
|
|
height: 420rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cartBox {
|
|
|
|
|
z-index: 10076;
|
|
|
|
|
width: 100vw;
|
|
|
|
|
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.7) 70%, rgba(255, 255, 255, 1) 100%);
|
|
|
|
|
position: fixed;
|
|
|
|
|
bottom: 0rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottomBox {
|
|
|
|
|
width: 678rpx;
|
|
|
|
|
margin-bottom: 102rpx;
|
|
|
|
|
background: #333;
|
|
|
|
|
padding: 12rpx;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottomBoxin {
|
|
|
|
|
width: 100%;
|
|
|
|
|
background-color: black;
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
padding: 12rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottomBoxinin {
|
|
|
|
|
width: 100%;
|
|
|
|
|
background-color: #231e1f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bottomBoxCon {
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin-bottom: 36rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cartButBox {
|
|
|
|
|
height: 108rpx;
|
|
|
|
|
width: 100%;
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: -54rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bowlBox {
|
|
|
|
|
margin-left: 20rpx;
|
|
|
|
|
width: 108rpx;
|
|
|
|
|
height: 108rpx;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bowl {
|
|
|
|
|
width: 108rpx;
|
|
|
|
|
height: 108rpx;
|
2024-05-30 20:34:22 +08:00
|
|
|
|
background-image: url(#{$image-base-url}/Public/images/appUrlImg/null-100.svg);
|
2024-05-29 21:49:52 +08:00
|
|
|
|
background-size: cover;
|
|
|
|
|
background-position: center;
|
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cBUt {
|
|
|
|
|
width: 28rpx;
|
|
|
|
|
height: 28rpx;
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: -12rpx;
|
|
|
|
|
right: -16rpx;
|
|
|
|
|
}
|
|
|
|
|
</style>
|