1178 lines
33 KiB
Vue
1178 lines
33 KiB
Vue
<template>
|
|
<view
|
|
:style="{
|
|
'padding-top': (statusBarHeight + 54) + 'px'
|
|
}"
|
|
class="pages-cart tabbar-page"
|
|
>
|
|
<u-navbar
|
|
:left-icon="selectCount > 0 ? '' : ''"
|
|
title="购物车"
|
|
fixed
|
|
/>
|
|
<view
|
|
v-if="isLoad"
|
|
:style="{paddingBottom: list.length > 0 ? '120rpx;' : ''}"
|
|
class="list-wrap"
|
|
>
|
|
<view v-if="isNoLogin" class="no-login-wrap">
|
|
<image
|
|
:src="webUrl + '/page/my/nologin.png'"
|
|
class="img"
|
|
/>
|
|
<view class="txt">您还未登录</view>
|
|
<view class="desc">请注册/登录账户后重试</view>
|
|
<view class="btn" @click="toLoginHandle">去登录</view>
|
|
</view>
|
|
<view v-else>
|
|
<view class="v12-justify-between v12-px-2">
|
|
<view class="v12-font-28 v12-dark-text v12-align-center" @click="show = true">
|
|
<image :src="webUrl+'/orderIcon/map.png'" style="width: 30rpx;height: 30rpx" class="v12-mr-1"/>
|
|
<text>{{ addressInfo.city }}</text>
|
|
<view class="v12-ml-1" style="margin-top: 2px;">
|
|
<u-icon name="arrow-down"></u-icon>
|
|
</view>
|
|
</view>
|
|
<view
|
|
v-if="list.length > 0"
|
|
class="v12-font-28 v12-font-bold v12-dark-text"
|
|
@click="editCart"
|
|
>{{ isEdit ? '完成' : '管理' }}</view>
|
|
</view>
|
|
<view
|
|
v-if="list.length === 0"
|
|
class="tc v12-my-6"
|
|
>
|
|
<image
|
|
:src="$VUE_APP_RESOURCES_URL + '/orderIcon/购物车2.png'"
|
|
style="width: 294rpx;height: 354rpx"
|
|
mode="scaleToFill"
|
|
/>
|
|
</view>
|
|
<view v-if="list.length === 0">
|
|
<view class="v12-px-14">
|
|
<u-divider
|
|
text=" · 猜你喜欢 · "
|
|
textColor="#333"
|
|
lineColor="#333"
|
|
textPosition="center"
|
|
></u-divider>
|
|
</view>
|
|
<view class="userlike-wrap">
|
|
<view
|
|
v-for="(item, index) in userLikeList"
|
|
:key="index"
|
|
@click="goGoodsCon(item)"
|
|
class="v12-radius-20 v12-white v12-mb-3 like-card"
|
|
>
|
|
<view class="img-wrap">
|
|
<image :src="item.image" class="img"></image>
|
|
|
|
<image
|
|
v-if="item.isOldBrand"
|
|
:src="webUrl + '/home/old-mark.png'"
|
|
class="mark-img"
|
|
/>
|
|
<image
|
|
v-if="item.isLandmarkGoods"
|
|
:src="webUrl + '/home/mark-land.png'"
|
|
class="mark-img"
|
|
/>
|
|
<image
|
|
v-if="item.isIch"
|
|
:src="webUrl + '/home/ich-mark.png'"
|
|
class="mark-img"
|
|
style="right: 20rpx; width: 70rpx"
|
|
/>
|
|
<image
|
|
v-if="item.isCountyFamous"
|
|
:src="webUrl + '/home/qixian-mark.png'"
|
|
class="mark-img"
|
|
/>
|
|
</view>
|
|
<view class="info-wrap v12-pa-2">
|
|
<view class="more-t v12-font-28 v12-dark-text v12-mb-2">
|
|
{{ item.storeName }}
|
|
</view>
|
|
<view v-if="item.bestContent" class="more-t v12-mb-2 v12-font-24 v12-yellow-text v12-font-weight-300">
|
|
{{ item.bestContent }}
|
|
</view>
|
|
<view class="v12-align-center v12-primary-text v12-font-24 v12-mb-2" v-if="item.couponName">
|
|
<view class="v12-primary-border v12-radius-8 v12-px-1">券</view>
|
|
<view class="v12-primary-border v12-radius-8 v12-px-1">{{ item.couponName }}</view>
|
|
</view>
|
|
<view class="v12-justify-between v12-align-center">
|
|
<view class="v12-font-40 v12-font-bold v12-primary-text">
|
|
<text class="">¥</text>
|
|
<text class="price-txt price-red">{{ item.price }}</text>
|
|
</view>
|
|
<view class="btn">
|
|
<image
|
|
:src="webUrl + '/home/icon-cart.png'"
|
|
class="img-icon"
|
|
/>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view
|
|
v-for="(item, index) in list"
|
|
:key="index"
|
|
class="group-item"
|
|
>
|
|
<view class="flex jc-between">
|
|
<view class="flex ai-center mer-left">
|
|
<!-- <CheckboxIcon
|
|
:default-state="item['state']"
|
|
:mark="[index]"
|
|
style="margin-right: 24rpx;"
|
|
@change="onChange"
|
|
/> -->
|
|
<image
|
|
:src="item['merAvatar']"
|
|
class="store-cover"
|
|
mode="scaleToFill"
|
|
/>
|
|
<view class="mer-name v12-font-24 v12-font-bold">{{ item['merName'] }}</view>
|
|
</view>
|
|
<view
|
|
class="flex ai-center hotle-btn v12-primary-text"
|
|
@click="navToStore(item['hotelId'])"
|
|
>
|
|
进店逛逛>
|
|
<!-- <image
|
|
:src="$VUE_APP_RESOURCES_URL + '/20240109234706982937.png'"
|
|
style="width: 24rpx;height: 24rpx"
|
|
mode="scaleToFill"
|
|
/> -->
|
|
</view>
|
|
</view>
|
|
<view class="good-box">
|
|
<view
|
|
v-for="(good, gIndex) in item['carts']"
|
|
:key="gIndex"
|
|
class="good flex v12-align-start"
|
|
>
|
|
<view class="v12-align-center">
|
|
<CheckboxIcon
|
|
v-if="good['truePrice'] !== null"
|
|
:default-state="good['state']"
|
|
:mark="[index, gIndex]"
|
|
style="margin-right: 24rpx;"
|
|
@change="onChange"
|
|
/>
|
|
<CheckboxIcon
|
|
v-else
|
|
:default-state="good['state']"
|
|
:mark="[index, gIndex]"
|
|
style="margin-right: 24rpx;"
|
|
/>
|
|
<image
|
|
v-if="good['productInfo']['attrInfo']['image']"
|
|
:src="good['productInfo']['attrInfo']['image']"
|
|
class="good-cover flex-0 v12-radius-16"
|
|
mode="scaleToFill"
|
|
@click="navToGood(good, item)"
|
|
/>
|
|
<image
|
|
v-else
|
|
:src="good['productInfo']['image']"
|
|
mode="scaleToFill"
|
|
class="good-cover flex-0"
|
|
@click="navToGood(good, item)"
|
|
/>
|
|
</view>
|
|
<view style="width: 100%">
|
|
<view
|
|
class="one-t v12-font-28"
|
|
@click="navToGood(good, item)"
|
|
>{{ good['productInfo']['storeName'] }}</view>
|
|
<view
|
|
class="sku ai-center"
|
|
@click="changeGoodAttrHandle(good)"
|
|
>
|
|
规格:{{ good['productInfo']['attrInfo']['sku'] ? good['productInfo']['attrInfo']['sku'] : '' }}
|
|
</view>
|
|
<!-- <view class="v12-mt-1 v12-align-center">
|
|
<view class="v12-primary-text v12-primary-border v12-radius-8 v12-font-24 v12-px-1">
|
|
<text>券</text>
|
|
</view>
|
|
<view class="v12-primary-text v12-primary-border v12-radius-8 v12-font-24 v12-px-1">
|
|
<text>满100-30</text>
|
|
</view>
|
|
</view> -->
|
|
<view
|
|
class="flex jc-between ai-center"
|
|
style="width: 100%;margin-top: 4rpx;"
|
|
v-if="good['truePrice'] !== null"
|
|
>
|
|
<view
|
|
class="v12-font-bold v12-primary-text"
|
|
@click="navToGood(good, item)"
|
|
>
|
|
<text class="bold v12-font-22">¥</text>
|
|
<text class="v12-font-36">{{ good['truePrice'] }}</text>
|
|
</view>
|
|
<u-number-box
|
|
:value="good.cartNum"
|
|
:max="good['productInfo']['attrInfo']['stock']"
|
|
integer
|
|
disabledInput
|
|
iconStyle="color: #fff"
|
|
class="num-step"
|
|
@change="e => changeNumHandle(index, gIndex, good, e)"
|
|
@overlimit="overlimit"
|
|
>
|
|
<template v-slot:minus>
|
|
<view class="v12-minus-btn v12-font-bold flex jc-center ai-center">
|
|
<u-icon name="minus" size="12" color="#FFFFFF"/>
|
|
</view>
|
|
</template>
|
|
<template v-slot:input>
|
|
<view class="num-input tc v12-num-input">{{ good['cartNum'] }}</view>
|
|
</template>
|
|
<template v-slot:plus>
|
|
<view class="v12-plus-btn v12-font-bold flex jc-center ai-center v12-primary">
|
|
<u-icon name="plus" size="12" color="#FFFFFF"/>
|
|
</view>
|
|
</template>
|
|
</u-number-box>
|
|
</view>
|
|
<view v-else class="v12-secondary-dark-text v12-font-24" style="padding: 0 10rpx">商品已下架</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="footer-fixed flex jc-between ai-center" v-if="list.length > 0">
|
|
<view style="margin-left: 32rpx;">
|
|
<CheckboxIcon
|
|
style="margin-right: 24rpx;"
|
|
:default-state="isAll"
|
|
:mark="[-1]"
|
|
@change="onChange"
|
|
/>
|
|
<text class="v12-dark-text v12-font-32 v12-font-bold">全选({{ selectCount }})</text>
|
|
</view>
|
|
<view class="flex ai-center" v-if="!isEdit">
|
|
<view >
|
|
<text class="v12-font-24 v12-dark-text v12-font-weight-550"> 合计:</text>
|
|
<text class="v12-font-22 v12-primary-text v12-font-bold">¥</text>
|
|
<text class="v12-font-26 v12-primary-text v12-font-bold">{{ total }}</text>
|
|
</view>
|
|
<view class="btn-submit v12-mx-3 flex jc-center ai-center v12-radius-80 v12-primary" @click="submit">结算</view>
|
|
</view>
|
|
<view class="flex ai-center" v-else>
|
|
<view @click="clearCart" class="v12-justify-between v12-align-center">
|
|
<view style="margin-top: 1px"><u-icon name="trash"></u-icon> </view>
|
|
<view>清空</view>
|
|
</view>
|
|
<view @click="remove" class="btn-submit v12-mx-3 flex jc-center ai-center v12-radius-80 v12-primary">删除</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,
|
|
'disabled': getAttrItemData(attr.attr).stock === 0
|
|
}"
|
|
class="attr"
|
|
@click="attrItemClick(attr, attrIndex, index)"
|
|
>
|
|
{{ attr.attr }}
|
|
<text
|
|
v-if="getAttrItemData(attr.attr).stock === 0"
|
|
class="tag"
|
|
>缺货</text>
|
|
</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
|
|
v-else
|
|
:show-avatar="false"
|
|
/>
|
|
<u-popup :show="show " @close="closePopup" closeable>
|
|
<view class="v12-secondary-dark-text v12-font-32 v12-text-center v12-py-4">收货地址</view>
|
|
<view v-if="addressInfo">
|
|
<view class="v12-px-3 v12-mb-3 v12-font-32 v12-justify-start v12-align-center">
|
|
<view style="opacity: 0; width: 28px">
|
|
<image :src="webUrl+'/orderIcon/map.png'" style="width: 30rpx;height: 30rpx" class="v12-mr-1"/>
|
|
</view>
|
|
<view>收货人:{{ addressInfo.realName }} {{ addressInfo.phone }}</view>
|
|
|
|
</view>
|
|
<view class="v12-px-3 v12-mb-3 v12-font-28 v12-justify-between v12-align-start">
|
|
<view style="width: 30px;">
|
|
<image :src="webUrl+'/orderIcon/map.png'" style="width: 30rpx;height: 30rpx" class="v12-mr-1"/>
|
|
</view>
|
|
<view style="margin-bottom: 4px;width: 100%" class="more-t v12-text-left">{{ addressInfo.province }}{{ addressInfo.city }}{{ addressInfo.district }}{{ addressInfo.detail }}</view>
|
|
<view style="width: 50px;" @click="editAddress">
|
|
<image :src="webUrl+'/orderIcon/编辑.png'" style="width: 30rpx;height: 30rpx" class="v12-mr-1"/>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-else>
|
|
<view class="v12-font-28 v12-pa-3 v12-secondary-dark-text ">尚未设置收货地址!</view>
|
|
</view>
|
|
<view class=" v12-px-3 v12-mb-3">
|
|
<view class="v12-py-2 v12-primary-text v12-font-28 v12-radius-60 v12-text-center plus-btn" @click="addNewAddress">+ 添加新地址</view>
|
|
</view>
|
|
|
|
</u-popup>
|
|
<xdd-tabbar :curr-index="2" />
|
|
</view>
|
|
</template>
|
|
<script>
|
|
import XddTabbar from '@/components/xdd-tabbar'
|
|
import {getAddressList, getUserLike} from "@/api/user";
|
|
import {
|
|
changeCartNum,
|
|
getCartGroup,
|
|
postCartDel,
|
|
getCartGoodAttr,
|
|
cartGoodChangeAttr
|
|
} from '@/api/store'
|
|
import CheckboxIcon from '@/components/CheckboxIcon.vue'
|
|
import { pageListenMixins } from '@/mixins/pageListenMixins'
|
|
import cookie from "@/utils/store/cookie"
|
|
export default {
|
|
components: {
|
|
CheckboxIcon,
|
|
XddTabbar
|
|
},
|
|
mixins: [pageListenMixins],
|
|
data() {
|
|
return {
|
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
|
show: false,
|
|
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
|
|
isLoad: false,
|
|
list: [],
|
|
isAll: false,
|
|
currGood: {},
|
|
currGoodAttr: {},
|
|
goodAttr: {
|
|
productAttr: [],
|
|
productValueArr: []
|
|
},
|
|
showAttr: false,
|
|
pageKeyId: Object.freeze('landmarkGoodsIndex'),
|
|
isEdit: false,
|
|
addressList:[],
|
|
addressInfo: {},
|
|
userLikeList: [],
|
|
// 是否已登录
|
|
isNoLogin: false
|
|
}
|
|
},
|
|
computed: {
|
|
total() {
|
|
let price = 0
|
|
this.list.forEach(item => {
|
|
item['carts'].forEach(good => {
|
|
if (good.state) price += Math.round(good['cartNum'] * good['truePrice'] * 100) / 100
|
|
})
|
|
})
|
|
return Math.round(price * 100) / 100
|
|
},
|
|
selectCount() {
|
|
let count = 0
|
|
this.list.forEach(item => {
|
|
item['carts'].forEach(good => {
|
|
if (good.state) count += good.cartNum || 1
|
|
})
|
|
})
|
|
return count
|
|
}
|
|
},
|
|
created() {
|
|
this.getCart()
|
|
this.getAddress()
|
|
},
|
|
onShow() {
|
|
this.isEdit = false
|
|
if (!this.isLoad) {
|
|
return
|
|
}
|
|
this.closeAttr()
|
|
this.getCart()
|
|
// 选择地址
|
|
const cartChooseAddress = uni.getStorageSync('cartChooseAddress') || {}
|
|
if (cartChooseAddress.id) {
|
|
this.addressInfo = cartChooseAddress
|
|
// uni.setStorageSync('cartChooseAddress', {})
|
|
return
|
|
}
|
|
this.getAddress()
|
|
},
|
|
onHide() {
|
|
this.pageToHideHandle()
|
|
},
|
|
methods: {
|
|
toLoginHandle() {
|
|
cookie.set('redirect', '/pages/cart')
|
|
uni.reLaunch({
|
|
url: '/pages/authorization/index'
|
|
})
|
|
},
|
|
goGoodsCon(item) {
|
|
this.$yrouter.push({
|
|
path: '/pages/shop/GoodsCon/index',
|
|
query: {
|
|
id: item.productId
|
|
}
|
|
})
|
|
},
|
|
closePopup() {
|
|
this.show = false
|
|
},
|
|
editAddress() {
|
|
this.$yrouter.push({
|
|
path: "/pages/user/address/AddressManagement/index",
|
|
query: {
|
|
choosMode: 2
|
|
}
|
|
});
|
|
},
|
|
addNewAddress() {
|
|
this.$yrouter.push({
|
|
path: "/pages/user/address/AddAddress/index",
|
|
query: {
|
|
choosMode: 2
|
|
}
|
|
});
|
|
},
|
|
getAddress() {
|
|
getAddressList({page: 1, limit: 9999}).then(res => {
|
|
if (res.isNoLogin) {
|
|
this.isNoLogin = true
|
|
return
|
|
} else {
|
|
const { data = [] } = res
|
|
this.addressList = data
|
|
this.addressInfo = data.find(e => e.isDefault == 1) || uni.getStorageSync('cartChooseAddress') || (data && data[0]) || null
|
|
if (!this.addressInfo.id) {
|
|
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
|
|
} else {
|
|
let isExist = false
|
|
data.map(item => {
|
|
if (item.id === this.addressInfo.id) {
|
|
isExist = true
|
|
}
|
|
})
|
|
console.log(2, isExist);
|
|
if (!isExist) {
|
|
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
clearCart() {
|
|
const ids = this.list.map(l => {
|
|
return l.carts.map(g => g.id)
|
|
}).flat()
|
|
uni.showModal({
|
|
title: '确定清空购物车吗?',
|
|
content: '',
|
|
showCancel: true,
|
|
cancelText: '取消',
|
|
confirmText: '确认',
|
|
success: async (result) => {
|
|
if (result.confirm) {
|
|
uni.showLoading()
|
|
postCartDel(ids).then(res => {
|
|
const { success } = res
|
|
if (success) {
|
|
this.getCart()
|
|
}
|
|
}).finally(() => {
|
|
uni.hideLoading()
|
|
})
|
|
}
|
|
}
|
|
})
|
|
|
|
},
|
|
editCart() {
|
|
this.isEdit = !this.isEdit
|
|
},
|
|
async getCart() {
|
|
const res = await getCartGroup()
|
|
if (res.isNoLogin) {
|
|
this.isNoLogin = true
|
|
this.isLoad = true
|
|
return
|
|
}
|
|
if (res.success) {
|
|
this.isLoad = true
|
|
const invalid = res.data['invalid'].map(e => {
|
|
return {
|
|
...e,
|
|
isInvalid: true
|
|
}
|
|
})
|
|
this.list = res.data['valid'].concat(invalid)
|
|
this.handleAll(false)
|
|
const _res = await getUserLike()
|
|
this.userLikeList = _res.data
|
|
}
|
|
},
|
|
handleAll(state) {
|
|
this.isAll = state
|
|
this.list = this.list.map(item => {
|
|
item.state = state
|
|
item.carts = item.carts.map(good => {
|
|
good.state = state
|
|
return good
|
|
})
|
|
return item
|
|
})
|
|
},
|
|
navToStore(id) {
|
|
if (id === 0) {
|
|
uni.showToast({
|
|
title: '店铺装修中~',
|
|
icon: 'none',
|
|
duration: 3000
|
|
})
|
|
return
|
|
}
|
|
uni.navigateTo({
|
|
url: '/pagesInn/inn/innHome?id=' + id
|
|
})
|
|
},
|
|
onChange(state, mark) {
|
|
if (mark.length === 1) {
|
|
if (mark[0] === -1) {
|
|
this.handleAll(state)
|
|
} else {
|
|
this.list[mark[0]]['state'] = state
|
|
this.list[mark[0]]['carts'] = this.list[mark[0]]['carts'].map(good => {
|
|
good.state = state
|
|
return good
|
|
})
|
|
}
|
|
}
|
|
if (mark.length === 2) {
|
|
this.list[mark[0]]['carts'][mark[1]]['state'] = state
|
|
const length = this.list[mark[0]]['carts'].length
|
|
let count = 0
|
|
this.list[mark[0]]['carts'] = this.list[mark[0]]['carts'].map((good, gIndex) => {
|
|
if (gIndex === mark[1]) good['state'] = state
|
|
if (good['state']) count++
|
|
return good
|
|
})
|
|
this.list[mark[0]]['state'] = count === length
|
|
}
|
|
let shopCheckNumber = 0
|
|
this.list.map(item => {
|
|
if (item.state) {
|
|
shopCheckNumber++
|
|
}
|
|
})
|
|
this.isAll = shopCheckNumber === this.list.length
|
|
},
|
|
changeNumHandle(index, gIndex, good, e) {
|
|
const { type } = e
|
|
const value = good.cartNum + (type === 'plus' ? 1 : -1)
|
|
console.log('index', value);
|
|
const id = good.id
|
|
// uni.showLoading()
|
|
changeCartNum(id, value).then(res => {
|
|
const { success } = res
|
|
if (success) {
|
|
// uni.hideLoading()
|
|
this.$set(this.list[index].carts[gIndex], 'cartNum', value)
|
|
}
|
|
}).catch(() => {
|
|
setTimeout(() => {
|
|
uni.hideLoading()
|
|
}, 3000)
|
|
})
|
|
},
|
|
overlimit(e) {
|
|
const tip = {
|
|
'plus': '商品数量超出库存',
|
|
'minus': '商品数量不能减少了呦~'
|
|
}
|
|
uni.showToast({
|
|
title: tip[e],
|
|
icon: 'none'
|
|
})
|
|
},
|
|
handleIds() {
|
|
if (this.selectCount === 0) {
|
|
uni.showToast({
|
|
title: '请选择产品',
|
|
icon: 'none',
|
|
duration: 2000
|
|
})
|
|
return []
|
|
}
|
|
const ids = []
|
|
this.list.forEach(item => {
|
|
item['carts'].forEach(good => {
|
|
if (good['state']) ids.push(good['id'])
|
|
})
|
|
})
|
|
return ids
|
|
},
|
|
remove() {
|
|
const ids = this.handleIds()
|
|
if (ids.length === 0) return
|
|
uni.showModal({
|
|
title: '确认删除已选商品?',
|
|
content: '',
|
|
showCancel: true,
|
|
cancelText: '取消',
|
|
confirmText: '确认',
|
|
success: async (result) => {
|
|
if (result.confirm) {
|
|
uni.showLoading()
|
|
postCartDel(ids).then(res => {
|
|
const { success } = res
|
|
if (success) {
|
|
this.getCart()
|
|
}
|
|
}).finally(() => {
|
|
uni.hideLoading()
|
|
})
|
|
}
|
|
}
|
|
})
|
|
},
|
|
changeGoodAttrHandle(good) {
|
|
if (good.seckillId) {
|
|
return
|
|
}
|
|
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.productAttr = data.productAttr
|
|
for (const key in data.productValue) {
|
|
this.goodAttr.productValueArr.push({
|
|
attrItemkey: key,
|
|
...data.productValue[key]
|
|
})
|
|
}
|
|
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 = {
|
|
stock: 0
|
|
}
|
|
// 只有一组规格
|
|
if (this.goodAttr.productAttr.length === 1) {
|
|
this.goodAttr.productValueArr.map(item => {
|
|
if (item.attrItemkey === attr) {
|
|
result = item
|
|
}
|
|
})
|
|
} else {
|
|
result.stock = 1
|
|
}
|
|
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(',')
|
|
let targat = null
|
|
this.goodAttr.productValueArr.map(item => {
|
|
if (item.attrItemkey === attrStr) {
|
|
targat = item
|
|
}
|
|
})
|
|
if (targat) {
|
|
const stock = targat.stock
|
|
this.currGoodAttr = targat
|
|
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
|
|
})
|
|
}
|
|
this.$forceUpdate()
|
|
} else {
|
|
uni.showToast({
|
|
title: '库存不足',
|
|
icon: 'none',
|
|
duration: 3000
|
|
})
|
|
}
|
|
}
|
|
},
|
|
// 确认切换
|
|
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(good, item) {
|
|
if(item.isInvalid) {
|
|
uni.showToast({
|
|
title: '商品已下架或被删除',
|
|
icon: 'none',
|
|
duration: 3000
|
|
})
|
|
return
|
|
}
|
|
const query = {
|
|
id: good.productId
|
|
}
|
|
if (good.seckillId) {
|
|
query.activityId = good.seckillId
|
|
query.from = 'kill'
|
|
}
|
|
this.$yrouter.push({
|
|
path: '/pages/shop/GoodsCon/index',
|
|
query
|
|
})
|
|
},
|
|
submit() {
|
|
const ids = this.handleIds()
|
|
if (ids.length === 0) return
|
|
uni.navigateTo({
|
|
url: '/pages/order/OrderSubmission/index?id=' + ids.join(',') + '&address=' + JSON.stringify(this.addressInfo)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.img-icon{
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
}
|
|
.list-wrap{
|
|
height: calc(100vh - 410rpx);
|
|
overflow: auto;
|
|
}
|
|
.plus-btn{
|
|
background: rgba(197,39,51,0.2);
|
|
}
|
|
.v12-minus-btn{
|
|
border-radius: 28rpx 0rpx 0rpx 28rpx;
|
|
border: 1px solid #E6E6E6;
|
|
background-color: rgba(208,208,208,0.39);
|
|
height: 40rpx;
|
|
width: 40rpx;
|
|
padding: 0 20rpx;
|
|
font-weight: bold;
|
|
}
|
|
.v12-plus-btn{
|
|
border-radius: 0rpx 28rpx 28rpx 0rpx;
|
|
border: 1px solid #C52733;
|
|
background-color: #C52733;
|
|
height: 40rpx;
|
|
width: 40rpx;
|
|
padding: 0 20rpx;
|
|
font-weight: bold;
|
|
}
|
|
.v12-num-input{
|
|
height: 40rpx;
|
|
// width: 40rpx;
|
|
border: 1px solid #E6E6E6;
|
|
line-height: 40rpx;
|
|
font-weight: bold;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
view {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.pages-cart {
|
|
min-height: 100vh;
|
|
padding-bottom: 100rpx;
|
|
}
|
|
|
|
.group-item {
|
|
width: 710rpx;
|
|
margin: 12rpx 20rpx;
|
|
padding: 20rpx 8rpx 32rpx 20rpx;
|
|
background: #FFFFFF;
|
|
border-radius: 12rpx;
|
|
|
|
.store-cover {
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
margin-right: 8rpx;
|
|
border-radius: 50%;
|
|
}
|
|
.mer-left {
|
|
width: calc(100% - 140rpx);
|
|
}
|
|
.mer-name {
|
|
width: calc(100% - 104rpx);
|
|
color: #333;
|
|
font-size: 30rpx;
|
|
}
|
|
.hotle-btn {
|
|
justify-content: flex-end;
|
|
width: 140rpx;
|
|
color: #E92727;
|
|
font-size: 24rpx;
|
|
}
|
|
}
|
|
|
|
.good-box {
|
|
.good {
|
|
margin-top: 24rpx;
|
|
|
|
.good-cover {
|
|
width: 140rpx;
|
|
height: 140rpx;
|
|
margin-right: 16rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
|
|
.one-t {
|
|
width: 420rpx;
|
|
color: #333333;
|
|
font-size: 30rpx;
|
|
line-height: 42rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.sku {
|
|
display: inline-flex;
|
|
margin: 4rpx;
|
|
padding: 10rpx 20rpx;
|
|
border-radius: 60rpx;
|
|
background: rgba(240,240,240,0.6);
|
|
color: #666666;
|
|
font-size: 24rpx;
|
|
}
|
|
|
|
.num-btn {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
background: rgba(236, 236, 238, 1);
|
|
// border: 2px solid rgba(236, 236, 238, 1);
|
|
border-radius: 40rpx;
|
|
}
|
|
|
|
.num-input {
|
|
width: 64rpx;
|
|
color: #333333;
|
|
font-size: 30rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.footer-fixed {
|
|
position: fixed;
|
|
left: 0;
|
|
bottom: 200rpx;
|
|
width: 100vw;
|
|
height: 100rpx;
|
|
box-shadow: 0 6rpx 12rpx rgba(0, 0, 0, 0.16);
|
|
background: #FFFFFF;
|
|
width: 708rpx;
|
|
right: 0;
|
|
margin: auto;
|
|
border-radius: 26rpx;
|
|
|
|
.btn-submit {
|
|
width: 196rpx;
|
|
height: 64rpx;
|
|
background: #C52733;
|
|
color: #FFFFFF;
|
|
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 {
|
|
position: absolute;
|
|
top: -18upx;
|
|
right: -18upx;
|
|
height: 28upx;
|
|
padding: 0 6upx;
|
|
border-radius: 6upx;
|
|
color: #fff;
|
|
line-height: 28upx;
|
|
font-size: 10px;
|
|
background-color: #FD5749;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.tabbar-page {
|
|
padding: 0 0 180rpx 0;
|
|
}
|
|
.userlike-wrap{
|
|
column-count: 2;
|
|
padding: 0 20rpx;
|
|
column-fill: balance;
|
|
}
|
|
.like-card{
|
|
break-inside: avoid;
|
|
}
|
|
.img {
|
|
position: relative;
|
|
z-index: 2;
|
|
display: block;
|
|
width: 345rpx;
|
|
height: 345rpx;
|
|
border-radius: 20rpx;
|
|
}
|
|
.mark-img {
|
|
position: absolute;
|
|
top: 0;
|
|
right: -2px;
|
|
z-index: 3;
|
|
display: block;
|
|
width: 84rpx;
|
|
height: 74rpx;
|
|
}
|
|
.img-wrap{
|
|
position: relative;
|
|
overflow: hidden;
|
|
border-radius: 20rpx;
|
|
}
|
|
.no-login-wrap {
|
|
position: relative;
|
|
top: 50%;
|
|
text-align: center;
|
|
transform: translateY(-50%);
|
|
.img {
|
|
display: block;
|
|
width: 478rpx;
|
|
height: 398rpx;
|
|
margin: 0 auto;
|
|
}
|
|
.txt {
|
|
font-size: 36rpx;
|
|
line-height: 56rpx;
|
|
color: #666;
|
|
}
|
|
.desc {
|
|
font-size: 28rpx;
|
|
line-height: 56rpx;
|
|
color: #999;
|
|
}
|
|
.btn {
|
|
width: 320rpx;
|
|
height: 80rpx;
|
|
margin: 40rpx auto 0 auto;
|
|
border-radius: 40rpx;
|
|
line-height: 80rpx;
|
|
color: #fff;
|
|
font-size: 30rpx;
|
|
background-color: #C52733;
|
|
}
|
|
}
|
|
</style> |