|
|
|
@ -1,178 +1,219 @@
|
|
|
|
|
<!--
|
|
|
|
|
* @Author: ch
|
|
|
|
|
* @Date: 2022-03-24 11:30:55
|
|
|
|
|
* @LastEditors: ch
|
|
|
|
|
* @LastEditTime: 2022-04-02 18:10:15
|
|
|
|
|
* @Description: file content
|
|
|
|
|
-->
|
|
|
|
|
<template>
|
|
|
|
|
<goods-sku-popup :value="value" @input="onChangeValue" border-radius="20" :localdata="goodsInfo" :mode="skuMode"
|
|
|
|
|
:maskCloseAble="true" @open="openSkuPopup" @close="closeSkuPopup" @add-cart="addCart" @buy-now="buyNow"
|
|
|
|
|
buyNowText="立即购买" />
|
|
|
|
|
<u-popup :show="value" round="24rpx">
|
|
|
|
|
<view class="sku-popup">
|
|
|
|
|
<view class="product-info">
|
|
|
|
|
<image class="product-img" src="https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/test/1.png"/>
|
|
|
|
|
<view>
|
|
|
|
|
<view>{{curSku.sellPrice}}</view>
|
|
|
|
|
<text>{{curSku.name}}</text>
|
|
|
|
|
<view>库存{{curSku.stock}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="attr-group" v-for="(item, index) in attributeGroupList" :key="item.id">
|
|
|
|
|
<text class="attr-name">{{item.name}}</text>
|
|
|
|
|
<view class="attr-items">
|
|
|
|
|
<text class="attr-item" :class="{'attr-item__active' : i.active, 'attr-item__disabled' : i.disabled}"
|
|
|
|
|
v-for="i in item.attributes" :key="i.symbol"
|
|
|
|
|
@click="handleAttrItem(i, index)"
|
|
|
|
|
>{{i.name}}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="sku-num">
|
|
|
|
|
<view>
|
|
|
|
|
<text>数量</text>
|
|
|
|
|
<text>有货</text>
|
|
|
|
|
</view>
|
|
|
|
|
<u-number-box :min="1" :max="curSku.stock" button-size="40rpx" bgColor="#F5F6FA"
|
|
|
|
|
:value="curNum" >
|
|
|
|
|
<text slot="minus" class="cart-item--stepper-icon">-</text>
|
|
|
|
|
<text slot="plus" class="cart-item--stepper-icon">+</text>
|
|
|
|
|
</u-number-box>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="footer">
|
|
|
|
|
<UiButton>加入购物车</UiButton>
|
|
|
|
|
<UiButton>立即购买</UiButton>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
</u-popup>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
// import { setCartTotalNum } from '@/core/app'
|
|
|
|
|
// import * as CartApi from '@/api/cart'
|
|
|
|
|
import GoodsSkuPopup from '@/components/goods-sku-popup'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
GoodsSkuPopup
|
|
|
|
|
},
|
|
|
|
|
model: {
|
|
|
|
|
prop: 'value',
|
|
|
|
|
event: 'input'
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
// true 组件显示 false 组件隐藏
|
|
|
|
|
value: {
|
|
|
|
|
Type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
},
|
|
|
|
|
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
|
|
|
|
skuMode: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 1
|
|
|
|
|
},
|
|
|
|
|
// 商品详情信息
|
|
|
|
|
goods: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: {}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
goodsInfo: {}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
created() {
|
|
|
|
|
const app = this
|
|
|
|
|
const { goods } = app
|
|
|
|
|
app.goodsInfo = {
|
|
|
|
|
_id: goods.goods_id,
|
|
|
|
|
name: goods.goods_name,
|
|
|
|
|
goods_thumb: goods.goods_image,
|
|
|
|
|
sku_list: app.getSkuList(),
|
|
|
|
|
spec_list: app.getSpecList()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
|
|
// 监听组件显示隐藏
|
|
|
|
|
onChangeValue(val) {
|
|
|
|
|
this.$emit('input', val)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 整理商品SKU列表
|
|
|
|
|
getSkuList() {
|
|
|
|
|
const app = this
|
|
|
|
|
const { goods: { goods_name, goods_image, skuList } } = app
|
|
|
|
|
const skuData = []
|
|
|
|
|
skuList.forEach(item => {
|
|
|
|
|
skuData.push({
|
|
|
|
|
_id: item.id,
|
|
|
|
|
goods_sku_id: item.goods_sku_id,
|
|
|
|
|
goods_id: item.goods_id,
|
|
|
|
|
goods_name: goods_name,
|
|
|
|
|
image: item.image_url ? item.image_url : goods_image,
|
|
|
|
|
price: item.goods_price * 100,
|
|
|
|
|
stock: item.stock_num,
|
|
|
|
|
spec_value_ids: item.spec_value_ids,
|
|
|
|
|
sku_name_arr: app.getSkuNameArr(item.spec_value_ids)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
return skuData
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取sku记录的规格值列表
|
|
|
|
|
getSkuNameArr(specValueIds) {
|
|
|
|
|
const app = this
|
|
|
|
|
const defaultData = ['默认']
|
|
|
|
|
const skuNameArr = []
|
|
|
|
|
if (specValueIds) {
|
|
|
|
|
specValueIds.forEach((valueId, groupIndex) => {
|
|
|
|
|
const specValueName = app.getSpecValueName(valueId, groupIndex)
|
|
|
|
|
skuNameArr.push(specValueName)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return skuNameArr.length ? skuNameArr : defaultData
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取指定的规格值名称
|
|
|
|
|
getSpecValueName(valueId, groupIndex) {
|
|
|
|
|
const app = this
|
|
|
|
|
const { goods: { specList } } = app
|
|
|
|
|
const res = specList[groupIndex].valueList.find(specValue => {
|
|
|
|
|
return specValue.spec_value_id == valueId
|
|
|
|
|
})
|
|
|
|
|
return res.spec_value
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 整理规格数据
|
|
|
|
|
getSpecList() {
|
|
|
|
|
const { goods: { specList } } = this
|
|
|
|
|
const defaultData = [{ name: '默认', list: [{ name: '默认' }] }]
|
|
|
|
|
const specData = []
|
|
|
|
|
specList.forEach(group => {
|
|
|
|
|
const children = []
|
|
|
|
|
group.valueList.forEach(specValue => {
|
|
|
|
|
children.push({ name: specValue.spec_value })
|
|
|
|
|
})
|
|
|
|
|
specData.push({
|
|
|
|
|
name: group.spec_name,
|
|
|
|
|
list: children
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
return specData.length ? specData : defaultData
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// sku组件 开始-----------------------------------------------------------
|
|
|
|
|
openSkuPopup() {
|
|
|
|
|
// console.log("监听 - 打开sku组件")
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
closeSkuPopup() {
|
|
|
|
|
// console.log("监听 - 关闭sku组件")
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 加入购物车按钮
|
|
|
|
|
addCart(selectShop) {
|
|
|
|
|
const app = this
|
|
|
|
|
const { goods_id, goods_sku_id, buy_num } = selectShop
|
|
|
|
|
// CartApi.add(goods_id, goods_sku_id, buy_num)
|
|
|
|
|
// .then(result => {
|
|
|
|
|
// // 显示成功
|
|
|
|
|
// app.$toast(result.message)
|
|
|
|
|
// // 隐藏当前弹窗
|
|
|
|
|
// app.onChangeValue(false)
|
|
|
|
|
// // 购物车商品总数量
|
|
|
|
|
// const cartTotal = result.data.cartTotal
|
|
|
|
|
// // 缓存购物车数量
|
|
|
|
|
// setCartTotalNum(cartTotal)
|
|
|
|
|
// // 传递给父级
|
|
|
|
|
// app.$emit('addCart', cartTotal)
|
|
|
|
|
// })
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 立即购买
|
|
|
|
|
buyNow(selectShop) {
|
|
|
|
|
// 跳转到订单结算页
|
|
|
|
|
this.$Router.push({path : '/orderSubmit', query:{
|
|
|
|
|
mode: 'buyNow',
|
|
|
|
|
skuId: selectShop.goods_sku_id,
|
|
|
|
|
num: selectShop.buy_num
|
|
|
|
|
}})
|
|
|
|
|
// this.$navTo('pages/checkout/index', {
|
|
|
|
|
// mode: 'buyNow',
|
|
|
|
|
// goodsId: selectShop.goods_id,
|
|
|
|
|
// goodsSkuId: selectShop.goods_sku_id,
|
|
|
|
|
// goodsNum: selectShop.buy_num
|
|
|
|
|
// })
|
|
|
|
|
// 隐藏当前弹窗
|
|
|
|
|
this.onChangeValue(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
import UiButton from '../../../components/UiButton.vue';
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
components: { UiButton },
|
|
|
|
|
props: {
|
|
|
|
|
// true 组件显示 false 组件隐藏
|
|
|
|
|
value: {
|
|
|
|
|
Type: Boolean,
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
|
|
|
|
mode: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 1,
|
|
|
|
|
},
|
|
|
|
|
// 商品详情信息
|
|
|
|
|
goodsInfo: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: {},
|
|
|
|
|
},
|
|
|
|
|
// 商品sku信息
|
|
|
|
|
skuInfo : {
|
|
|
|
|
type : Array,
|
|
|
|
|
default : []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
// 属性组数据,因为会修改数据,不能直接操作props中传入的数据
|
|
|
|
|
attributeGroupList : [],
|
|
|
|
|
// 数量
|
|
|
|
|
curNum : 1,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
watch : {
|
|
|
|
|
goodsInfo(newData){
|
|
|
|
|
if(newData.attributeGroupList){
|
|
|
|
|
this.attributeGroupList = newData.attributeGroupList;
|
|
|
|
|
// 请求数据返回后设置默认选中规格
|
|
|
|
|
if(this.skuInfo.length){
|
|
|
|
|
this.setDefaultAttr();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
skuInfo(newData){
|
|
|
|
|
// 请求数据返回后设置默认选中规格
|
|
|
|
|
if(newData.length){
|
|
|
|
|
this.setDefaultAttr();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed : {
|
|
|
|
|
/**
|
|
|
|
|
* 当前选中SKU,根据选中规格计算
|
|
|
|
|
*/
|
|
|
|
|
curSku(){
|
|
|
|
|
const skuSymbolList = this.attributeGroupList.map(item => {
|
|
|
|
|
const activeAttr = item.attributes.find(i => i.active);
|
|
|
|
|
return activeAttr ? activeAttr.symbol : ''
|
|
|
|
|
}).filter(i => i);
|
|
|
|
|
return this.skuInfo.find(i => i.attributeSymbolList === skuSymbolList.join(',')) || {};
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
/**
|
|
|
|
|
* 设置默认选中规格
|
|
|
|
|
*/
|
|
|
|
|
setDefaultAttr(){
|
|
|
|
|
const curSku = this.skuInfo.find(i => i.stock > 0);
|
|
|
|
|
this.attributeGroupList.forEach(item => {
|
|
|
|
|
for(let i of item.attributes){
|
|
|
|
|
if(curSku.attributeSymbolList.includes(i.symbol)){
|
|
|
|
|
this.$set(i,'active', true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 点击属性项,设置选中和禁用项
|
|
|
|
|
*/
|
|
|
|
|
handleAttrItem(item, groupIndex){
|
|
|
|
|
// 禁用选项
|
|
|
|
|
if(item.disabled){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 每次重选规格,购买数量都置为1
|
|
|
|
|
this.curNum = 1;
|
|
|
|
|
|
|
|
|
|
// 把当前选项组的装先置为未选状态
|
|
|
|
|
this.attributeGroupList[groupIndex].attributes.forEach(item =>{
|
|
|
|
|
this.$set(item,'active', false);
|
|
|
|
|
});
|
|
|
|
|
// 设置当前点击选项选中
|
|
|
|
|
this.$set(item,'active', true);
|
|
|
|
|
// 找到有效SKU的symbol 有效定义:包含当前选项属性,且库存大于0的所有SKU,
|
|
|
|
|
const symbols = this.skuInfo.filter(i => i.attributeSymbolList.includes(item.symbol) && i.stock > 0)
|
|
|
|
|
.map(i => i.attributeSymbolList).join(',');
|
|
|
|
|
|
|
|
|
|
this.attributeGroupList.forEach((group, index) => {
|
|
|
|
|
if(groupIndex === index){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 遍历其他选项组的所有属性项,对比是否在有效SKU的symbos中,在则启用,不再则禁用
|
|
|
|
|
group.attributes.forEach(item =>{
|
|
|
|
|
if(!symbols.includes(item.symbol)){
|
|
|
|
|
this.$set(item,'disabled', true);
|
|
|
|
|
}else{
|
|
|
|
|
this.$set(item,'disabled', false);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
|
|
|
|
.sku-popup{
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
.product-info{
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
.product-img{
|
|
|
|
|
width: 200rpx;
|
|
|
|
|
height: 200rpx;
|
|
|
|
|
}
|
|
|
|
|
.attr-group{
|
|
|
|
|
margin-top: 40rpx;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
.attr-items{
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
padding: 10rpx 0;
|
|
|
|
|
}
|
|
|
|
|
.attr-item{
|
|
|
|
|
background: #F8F8F8;
|
|
|
|
|
line-height: 70rpx;
|
|
|
|
|
border-radius: 100rpx;
|
|
|
|
|
border: 1px solid #F8F8F8;
|
|
|
|
|
color: #666;
|
|
|
|
|
display: block;
|
|
|
|
|
min-width: 158rpx;
|
|
|
|
|
max-width: 630rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin: 20rpx 28rpx 0 0;
|
|
|
|
|
padding: 0 20rpx;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
&__active{
|
|
|
|
|
background: #FFF3EE;
|
|
|
|
|
border-color: #FF512B;
|
|
|
|
|
color: #FF875B;
|
|
|
|
|
}
|
|
|
|
|
&__disabled{
|
|
|
|
|
color: #ccc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.sku-num{
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin: 40rpx 0;
|
|
|
|
|
}
|
|
|
|
|
.footer{
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|