food_wechat/pages/shop/content.vue

335 lines
9.8 KiB
Vue
Raw Normal View History

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">
2024-05-29 21:49:52 +08:00
{{priceDifference(sku.id) | formatPrice}}
</text>
<text v-else-if="priceDifference(sku.id)>0">
+{{priceDifference(sku.id) | formatPrice}}
</text>
2024-05-29 21:49:52 +08:00
</view>
<view class="border rad-c m-r-12 checkBox" :class="isSel(sku.id)?'border-m bg-m':''">
2024-05-29 21:49:52 +08:00
<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初始化
},
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;
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>