Feat(购物车):增加切换规格功能
This commit is contained in:
@@ -144,6 +144,20 @@ export function changeCartNum(id, number) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 购物车 获取商品规格
|
||||||
|
* */
|
||||||
|
export function getCartGoodAttr(id, uniqueId) {
|
||||||
|
return request.get(`/product/attr/${id}?uniqueId=${uniqueId}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 购物车 商品规格修改
|
||||||
|
* */
|
||||||
|
export function cartGoodChangeAttr(data) {
|
||||||
|
return request.post('/cart/changeAttr', data)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索推荐关键字
|
* 搜索推荐关键字
|
||||||
*/
|
*/
|
||||||
|
|||||||
+294
-3
@@ -84,7 +84,7 @@
|
|||||||
>{{ good['productInfo']['storeName'] }}</view>
|
>{{ good['productInfo']['storeName'] }}</view>
|
||||||
<view
|
<view
|
||||||
class="sku ai-center"
|
class="sku ai-center"
|
||||||
@click="navToGood(good['productId'])"
|
@click="changeGoodAttrHandle(good)"
|
||||||
>
|
>
|
||||||
规格:{{ good['productInfo']['attrInfo']['sku'] }}
|
规格:{{ good['productInfo']['attrInfo']['sku'] }}
|
||||||
</view>
|
</view>
|
||||||
@@ -144,6 +144,61 @@
|
|||||||
<view class="btn-submit bold flex jc-center ai-center" @click="submit">结算</view>
|
<view class="btn-submit bold flex jc-center ai-center" @click="submit">结算</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view
|
||||||
|
v-show="showAttr"
|
||||||
|
class="good-attr-wrap"
|
||||||
|
>
|
||||||
|
<view class="layer" @click="closeAttr" />
|
||||||
|
<view class="content">
|
||||||
|
<view class="close">
|
||||||
|
<text class="iconfont icon-guanbi" @click="closeAttr"></text>
|
||||||
|
</view>
|
||||||
|
<view class="good-info">
|
||||||
|
<view class="name-img">
|
||||||
|
<image :src="currGoodAttr.image" class="img" />
|
||||||
|
<view class="name">
|
||||||
|
<view class="more-t">
|
||||||
|
{{ currGood.productInfo.storeName }}
|
||||||
|
</view>
|
||||||
|
<view class="price">
|
||||||
|
<text class="txt">¥</text>{{ currGoodAttr.price }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="attr-wrap">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in goodAttr.productAttr"
|
||||||
|
:key="index"
|
||||||
|
class="item"
|
||||||
|
>
|
||||||
|
<view class="title">{{ item.attrName }}</view>
|
||||||
|
<view class="acea-row row-middle">
|
||||||
|
<view
|
||||||
|
v-for="(attr, attrIndex) in item.attrValue"
|
||||||
|
:key="attr"
|
||||||
|
:class="{
|
||||||
|
'on': attr.check
|
||||||
|
}"
|
||||||
|
class="attr"
|
||||||
|
@click="attrItemClick(attr, attrIndex, index)"
|
||||||
|
>
|
||||||
|
{{ attr.attr }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bottom">
|
||||||
|
<view
|
||||||
|
:class="currGoodAttr.stock === 0 ? 'disabled' : ''"
|
||||||
|
class="btn"
|
||||||
|
@click="changeAttrConfirm"
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<goo-skeleton
|
<goo-skeleton
|
||||||
v-else
|
v-else
|
||||||
@@ -152,7 +207,13 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {changeCartNum, getCartGroup, postCartDel} from '@/api/store'
|
import {
|
||||||
|
changeCartNum,
|
||||||
|
getCartGroup,
|
||||||
|
postCartDel,
|
||||||
|
getCartGoodAttr,
|
||||||
|
cartGoodChangeAttr
|
||||||
|
} from '@/api/store'
|
||||||
import CheckboxIcon from '@/components/CheckboxIcon.vue'
|
import CheckboxIcon from '@/components/CheckboxIcon.vue'
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -162,7 +223,14 @@ export default {
|
|||||||
return {
|
return {
|
||||||
isLoad: false,
|
isLoad: false,
|
||||||
list: [],
|
list: [],
|
||||||
isAll: false
|
isAll: false,
|
||||||
|
currGood: {},
|
||||||
|
currGoodAttr: {},
|
||||||
|
goodAttr: {
|
||||||
|
productAttr: [],
|
||||||
|
productValue: {}
|
||||||
|
},
|
||||||
|
showAttr: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -192,6 +260,7 @@ export default {
|
|||||||
if (!this.isLoad) {
|
if (!this.isLoad) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.closeAttr()
|
||||||
this.getCart()
|
this.getCart()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -308,6 +377,114 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
changeGoodAttrHandle(good) {
|
||||||
|
const id = good.productInfo.id
|
||||||
|
const unique = good.productInfo.attrInfo.unique
|
||||||
|
uni.showLoading()
|
||||||
|
getCartGoodAttr(id, unique).then(res => {
|
||||||
|
const { success, data } = res
|
||||||
|
if (success) {
|
||||||
|
this.currGood = good
|
||||||
|
this.goodAttr = data
|
||||||
|
this.goodAttr.productAttr.map((item, index) => {
|
||||||
|
item.attrValue.map((attr, attrIndex) => {
|
||||||
|
attr.check = data.defaultSkuIndex[index] === attrIndex
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.currGoodAttr = data.productValue[data.defaultSku.sort().join(',')]
|
||||||
|
this.showAttr = true
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
uni.hideLoading()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getAttrItemData(attr) {
|
||||||
|
let result = {}
|
||||||
|
this.goodAttr.productAttr.map(item => {
|
||||||
|
if (item.attrItemkey === attr) {
|
||||||
|
result = item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
},
|
||||||
|
// 规格切换
|
||||||
|
attrItemClick(attr, attrIndex, index) {
|
||||||
|
const tempArr = JSON.parse(JSON.stringify(this.goodAttr))
|
||||||
|
tempArr.productAttr[index].attrValue.map(attrItem => {
|
||||||
|
attrItem.check = false
|
||||||
|
})
|
||||||
|
// 预设目标规格选中
|
||||||
|
tempArr.productAttr[index].attrValue[attrIndex].check = true
|
||||||
|
const arr = []
|
||||||
|
tempArr.productAttr.map((item) => {
|
||||||
|
item.attrValue.map((attrItem) => {
|
||||||
|
if (attrItem.check) {
|
||||||
|
// 将预选中的规格组合起来
|
||||||
|
arr.push(attrItem.attr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (arr.length > 0) {
|
||||||
|
const attrStr = arr.sort().join(',')
|
||||||
|
if (this.goodAttr.productValue[attrStr]) {
|
||||||
|
const stock = this.goodAttr.productValue[attrStr].stock
|
||||||
|
this.currGoodAttr = this.goodAttr.productValue[attrStr]
|
||||||
|
this.goodAttr.productAttr[index].attrValue.map(attrItem => {
|
||||||
|
attrItem.check = false
|
||||||
|
})
|
||||||
|
this.goodAttr.productAttr[index].attrValue[attrIndex].check = true
|
||||||
|
if (stock === 0) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '库存不足',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// if (stock > 0) {
|
||||||
|
// this.currGoodAttr = this.goodAttr.productValue[attrStr]
|
||||||
|
// this.goodAttr.productAttr[index].attrValue.map(attrItem => {
|
||||||
|
// attrItem.check = false
|
||||||
|
// })
|
||||||
|
// this.goodAttr.productAttr[index].attrValue[attrIndex].check = true
|
||||||
|
// } else {
|
||||||
|
|
||||||
|
// }
|
||||||
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 确认切换
|
||||||
|
changeAttrConfirm() {
|
||||||
|
if (this.currGoodAttr.stock === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.showLoading()
|
||||||
|
cartGoodChangeAttr({
|
||||||
|
id: this.currGood.id,
|
||||||
|
uniqueId: this.currGoodAttr.unique
|
||||||
|
}).then(res => {
|
||||||
|
const { success } = res
|
||||||
|
if (success) {
|
||||||
|
this.getCart()
|
||||||
|
this.closeAttr()
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
uni.hideLoading()
|
||||||
|
}).finally(() => {
|
||||||
|
uni.hideLoading()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
closeAttr() {
|
||||||
|
this.currGoodAttr = {}
|
||||||
|
this.currGood = {}
|
||||||
|
this.showAttr = false
|
||||||
|
},
|
||||||
|
navToGood(id) {
|
||||||
|
this.$yrouter.push({
|
||||||
|
path: '/pages/shop/GoodsCon/index',
|
||||||
|
query: { id }
|
||||||
|
})
|
||||||
|
},
|
||||||
submit() {
|
submit() {
|
||||||
const ids = this.handleIds()
|
const ids = this.handleIds()
|
||||||
if (ids.length === 0) return
|
if (ids.length === 0) return
|
||||||
@@ -407,4 +584,118 @@ view {
|
|||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.good-attr-wrap {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
.layer {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 2;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 5;
|
||||||
|
max-height: 75vh;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-top-left-radius: 30rpx;
|
||||||
|
border-top-right-radius: 30rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow-y: auto;
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
top: 30rpx;
|
||||||
|
right: 30rpx;
|
||||||
|
.iconfont {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.good-info {
|
||||||
|
padding: 20rpx 0 0 0;
|
||||||
|
.name-img {
|
||||||
|
display: flex;
|
||||||
|
.img {
|
||||||
|
display: block;
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
margin: 0 20rpx 0 0;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
width: calc(100% - 220rpx);
|
||||||
|
color: #333;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.price {
|
||||||
|
margin: 20rpx 0 0 0;
|
||||||
|
color: #E92727;
|
||||||
|
font-size: 16px;
|
||||||
|
.txt{
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.attr-wrap {
|
||||||
|
padding: 30rpx 0 0 0;
|
||||||
|
.item + .item {
|
||||||
|
margin: 20rpx 0 0 0;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
margin: 0 0 10rpx 0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
.attr {
|
||||||
|
position: relative;
|
||||||
|
padding: 7rpx 33rpx;
|
||||||
|
margin: 14rpx 14rpx 0 0;
|
||||||
|
border: 1rpx solid #bbb;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
color: #333;
|
||||||
|
font-size: 26rpx;
|
||||||
|
&.on {
|
||||||
|
color: #fff;
|
||||||
|
border-color: #eb3729;
|
||||||
|
background-color: #eb3729;
|
||||||
|
}
|
||||||
|
&.disabled {
|
||||||
|
color: #333;
|
||||||
|
border-color: #f1f1f1;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
.tag {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom {
|
||||||
|
padding: 30rpx 0 0 0;
|
||||||
|
.btn {
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: #E92727;
|
||||||
|
&.disabled {
|
||||||
|
color: #666;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user