Files
2025-04-30 14:08:39 +08:00

917 lines
24 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!-- 未登录状态 显示空购物车 按钮为去登录 -->
<view v-if="!isLogin" class="cart-empty">
<image class="empty-img" src="@/static/empty/cart.png" mode="widthFix"></image>
<view class="empty-text">您的购物车还没有商品快去挑选吧</view>
<view class="empty-btn" @tap="toLoginDiy">去登录</view>
</view>
<!-- 未登录状态 end-->
<view v-if="isLogin && cartListArr == 0" class="cart-empty">
<image class="empty-img" src="@/static/empty/cart.png" mode="widthFix"></image>
<view class="empty-text">您的购物车还没有商品快去挑选吧</view>
<view class="empty-btn" @tap="toHomeDiy">去挑选好货</view>
</view>
<!-- 已登录状态 显示空购物车 end-->
<!-- 购物车商品列表模块 已登录状态 并且购物车列表有值 -->
<!-- 购物车列表 -->
<view class="cart-box" v-if="isLogin && cartListArr != 0">
<!-- 当商品不能购买(item.stock == 0 || item.is_sale == 0) 选中按钮失效 并且添加滤镜效果 -->
<view v-for="(dataItem, i) in cartListArr" :key="i" class="cart-box-item">
<!-- 店铺信息 -->
<view class="flex align-center merchant-info" v-if="dataItem.shop_info">
<view class="check-box-1" @tap="check(dataItem, i)">
<text
v-if="isEditor"
:class="{
checked_icon: true,
checked_active: dataItem.delChecked,
}"
class="fu-iconfont2"
>
{{ dataItem.delChecked ? '' : '' }}
</text>
<text v-else :class="{ checked_icon: true, checked_active: dataItem.checked }" class="fu-iconfont2">
{{ dataItem.checked ? '' : '' }}
</text>
</view>
<view class="text-df text-666" @click="goMerchant(dataItem.shop_info)">
<text class="fu-iconfont2 shop_icon"></text>
<text>{{ dataItem.shop_info.store_name }}</text>
<text class="fu-iconfont2 shop_right_icon"></text>
</view>
</view>
<!-- 判断没有绑定商品的商品放在一起 -->
<view
class="cart-item"
v-for="(item, index) in dataItem.cart_list"
:key="index"
:class="{
'not-but-class': item.stock == 0 || item.is_sale == 0 || item.is_check == 0,
}"
>
<view class="check-box" @tap="icheck(item, i, index)">
<text v-if="isEditor" :class="{ checked_icon: true, checked_active: item.delChecked }" class="fu-iconfont2">
{{ item.delChecked ? '' : '' }}
</text>
<text v-else :class="{ checked_icon: true, checked_active: item.checked }" class="fu-iconfont2">
{{ item.checked ? '' : '' }}
</text>
</view>
<!-- 商品图片 -->
<view class="img-box">
<view class="no-stok" v-if="item.is_check == 0">
<image class="no-stock-img" src="@/static/cart/no.png" mode=""></image>
</view>
<view class="no-stok" v-if="item.stock == 0">
<image class="no-stock-img" src="@/static/cart/sellOut.png" mode=""></image>
</view>
<view class="no-stok" v-if="item.is_sale == 0">
<image class="no-stock-img" src="@/static/cart/shelf.png" mode=""></image>
</view>
<view class="img" @tap="toDetail(item, 1)">
<fu-image :src="item.goods_thumb" mode="aspectFill"></fu-image>
</view>
</view>
<!-- 商品详细信息 -->
<view class="info-box">
<view class="info-top">
<view class="title" @tap="toDetail(item, 1)">{{ item.goods_name }}</view>
<view class="text-df text-999 sku_name" v-if="item.sku_name" @tap="openPopup(item)">
<view class="overFlow_text">
<text>{{ item.sku_name }}</text>
</view>
<view style="flex-shrink: 0">
<text style="margin-right: 16rpx">选规格</text>
<text class="cuIcon-unfold lg text-gray"></text>
</view>
</view>
</view>
<view class="price-box">
<view class="price">
<text class="small"></text>
{{ filterGoodsPrice(item) }}
</view>
<view class="number">
<uni-number-box
:min="1"
:disabled="item.is_valid == 2"
:max="Number(item.stock)"
:value="item.num"
@change="numberChange($event, i, index)"
></uni-number-box>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 购物车列表 end-->
<!-- 购物车底部操作栏部分 -->
<view class="cart-footer">
<view class="footer-left">
<view class="check-box" @tap="checkAll">
<text v-if="isEditor" :class="{ checked_icon: true, checked_active: delAllChecked }" class="fu-iconfont2">
{{ delAllChecked ? '' : '' }}
</text>
<text v-else :class="{ checked_icon: true, checked_active: allChecked }" class="fu-iconfont2">
{{ allChecked ? '' : '' }}
</text>
</view>
<view class="text-box">
<text class="text1 margin-left-xs">全选</text>
</view>
</view>
<!-- 右边 正常状态 未点击管理时isEditor=false -->
<view class="footer-right" v-if="!isEditor">
<view class="all-text">
<view class="text1">合计</view>
<view class="text-price-box">
<text class="small"></text>
{{ totalPrice }}
</view>
</view>
<view class="jiesuan-btn" @click="createOrder">结算 ({{ totalNumber }})</view>
</view>
<!-- 右边 编辑状态 已经点击管理时 isEditor=true-->
<view class="footer-right" v-if="isEditor">
<view class="footer-btn" @click="delCart(2)">移入收藏</view>
<view class="footer-btn delect" @click="delCart(1)">删除</view>
</view>
</view>
<!-- 购物车底部操作栏部分 end-->
</view>
</template>
<script>
function isDisabled(ele) {
// || ele.is_valid != 1
return ele.stock == 0 || ele.is_valid != 0 || ele.is_check == 0 || ele.is_sale == 0
}
export default {
name: 'benben-multiquotient-cart',
components: {},
mixins: [],
// 购物车列表
props: {
cartList: {
type: [Array, Object],
default: () => [],
},
// 管理 or 完成
isEditor: {
type: Boolean,
default: false,
},
},
data() {
return {
cartListArr: [],
checkedCache: uni.getStorageSync('cart_checked_cache') || [], // 上一次缓存的选中状态
setTimeoutFn: null,
}
},
computed: {
isLogin() {
return this.$store.state.token == '' ? false : true
},
// // 选择的商品总价
totalPrice() {
let list = this.cartListArr
let total = 0
// if (list == undefined) return
// console.log(list)
list.forEach((item) => {
item.cart_list.forEach((j) => {
if (j.checked == true) {
// 价格区分会员用户
let _price = this.filterGoodsPrice(j)
total += Number(_price) * Number(j.num)
}
})
})
return Number(total.toFixed(2))
},
// 正常状态选择的商品数量
totalNumber() {
let list = this.cartListArr
let total = 0
if (list == undefined) return
list.forEach((item) => {
item.cart_list.forEach((j) => {
if (j.checked == true) {
total += Number(j.num)
}
})
})
return total
},
// 删除时选择的商品数量
totalNumberDel() {
let list = this.cartListArr
let total = 0
if (list == undefined) return
list.forEach((item) => {
item.cart_list.forEach((j) => {
if (j.delChecked == true) {
total += Number(j.num)
}
})
})
return total
},
// 购物车内的商品数量
allNumber() {
let list = this.cartListArr
let total = 0
if (list == undefined) return
list.forEach((item) => {
total += Number(item.num)
})
return total
},
// 管理模式全选状态
delAllChecked() {
let list = this.cartListArr
let bool = true
if (list == undefined) return
list.forEach((item) => {
if (!item.delChecked) {
bool = false
}
})
return bool
},
// 正常模式全选状态
allChecked: {
cache: false,
get: function () {
let list = this.cartListArr
let bool = true
console.log(list)
if (list == undefined) return false
list.forEach((item) => {
console.log('item.checked', item.checked)
if (!item.checked) {
bool = false
}
})
return bool
},
},
},
watch: {
cartList: {
handler(value) {
console.log(value)
if (value.length == 0) {
this.$emit('update:is-editor', false)
}
value.forEach((item) => {
let bool = true
item.cart_list.forEach((ele) => {
ele.delChecked = false
if (isDisabled(ele) || !this.checkedCache.includes(ele.aid)) {
ele.checked = false
bool = false
} else {
ele.checked = true
}
})
item.checked = bool
})
this.cartListArr = JSON.parse(JSON.stringify(value))
},
deep: true,
immediate: true,
},
cartListArr: {
handler(value) {
console.log(value)
if (value.length == 0) return
let arr = []
value.forEach((item) => {
item.cart_list.forEach((ele) => {
if (ele.checked) {
arr.push(ele.aid)
}
})
})
this.checkedCache = arr
},
deep: true,
immediate: true,
},
},
created() {},
beforeDestroy() {
uni.setStorageSync('cart_checked_cache', this.checkedCache)
},
mounted() {},
methods: {
openPopup(item) {
this.$emit('update:cart-id', item.aid)
this.$emit('update:sku-id', item.sku_id)
this.$emit('update:cart-num', item.num)
this.$emit('update:goods-id', item.goods_id)
this.$emit('changeSku')
},
// 判断是否为会员价,活动价和商品价
filterGoodsPrice(value) {
if (!value) return ''
let isMember = this.$store.getters.isMember // 是否是会员
let isActivity = value.activity_type == undefined || value.activity_type == 0 ? false : true // 是否是活动
let member_activity_price = value.member_activity_price ? value.member_activity_price : value.activity_price //会员活动价
let activity_price = value.activity_price // 活动价
let member_price = value.member_price ? value.member_price : value.shop_price // 会员价
let shop_price = value.shop_price // 售卖价
if (isActivity) {
return isMember ? member_activity_price : activity_price
} else {
return isMember ? member_price : shop_price
}
},
// 去店铺
goMerchant(item) {
this.$emit('update:merchant-id', item.aid)
this.$emit('goMerchant')
},
// 店铺选中状态处理
check(item, i) {
if (this.isEditor) {
let delChecked = !item.delChecked
this.$set(item, 'delChecked', delChecked)
item.cart_list.forEach((j) => {
j.delChecked = delChecked
})
} else {
let checked = !item.checked
this.$set(item, 'checked', checked)
item.cart_list.forEach((j) => {
if (isDisabled(j)) {
j.checked = false
} else {
this.$set(j, 'checked', checked)
}
})
}
},
// 监听是否店铺全选商品
allcheckGood(item, i) {
console.log(item)
if (this.isEditor) {
// 店铺内商品全选
if (item.cart_list.findIndex((target) => target.delChecked == false) == -1) {
item.delChecked = true
} else {
// 店铺内商品全不选
item.delChecked = false
}
} else {
// 店铺内商品全选
if (item.cart_list.findIndex((target) => target.checked == false) == -1) {
item.checked = true
} else {
// 店铺内商品全不选
this.cartListArr[i].checked = false
}
}
},
// 商品选中处理状态
icheck(item, i, index) {
// if (item.is_check == 0) return this.$message.info('该商品已下架');
// if (item.stock == 0) return this.$message.info('该商品已售完,正在采购中');
// if (item.is_sale == 0) return this.$message.info('该商品已下架');
if (!this.isEditor && !isDisabled(item)) {
this.$set(item, 'checked', !item.checked)
this.allcheckGood(this.cartListArr[i], i)
}
if (this.isEditor) {
this.$set(item, 'delChecked', !item.delChecked)
this.allcheckGood(this.cartListArr[i], i)
}
},
//全选|取消全选
checkAll() {
if (this.isEditor) {
const bool = !this.delAllChecked
this.cartListArr.forEach((item) => {
item.delChecked = bool
// 商品全选
item.cart_list.forEach((j) => {
j.delChecked = bool
})
})
} else {
const bool = !this.allChecked
this.cartListArr.forEach((item) => {
item.checked = bool
// 商品全选
item.cart_list.forEach((j) => {
if (j.is_sale == 0 || j.stock == 0) {
j.checked = false
} else {
j.checked = bool
}
})
})
}
},
/** @description 数量改变
* @param {Object} e
* @param {string} index
*/
numberChange(e, i, index) {
this.setTimeoutFn && clearTimeout(this.setTimeoutFn)
this.setTimeoutFn = setTimeout(() => {
let list = this.cartListArr[i].cart_list
if (e != list[index].num) {
if (list[index].stock < e) {
e = list[index].stock
}
this.$set(list[index], 'num', e)
this.$emit('update:cart-id', list[index].aid)
this.$emit('update:sku-id', list[index].sku_id)
this.$emit('update:cart-num', e)
this.$emit('numberChange')
}
}, 500)
},
/**
* @method 移入收藏卡
* @param {Number} type 1: 删除, 2: 移入收藏
*/
delCart(type) {
let ids = []
this.cartListArr.forEach((item) => {
item.cart_list.map((val) => {
if (val.delChecked) {
ids.push(val.aid)
}
})
})
if (ids.length == 0) return this.$message.info(type == 1 ? '请选择要删除的商品' : '请选择要移动的商品')
this.$util.showModal({
title: '提示',
content: type == 1 ? '确认删除吗?' : '确认移入收藏夹吗?',
success: (res) => {
if (res.confirm) {
if (type == 1) {
this.$emit('update:cart-ids', ids.join(','))
this.$emit('delCart')
} else {
this.$emit('update:cart-ids', ids.join(','))
this.$emit('transCartGoods')
}
}
},
})
},
// 创建订单
createOrder() {
const list = this.cartListArr
let ids = []
let cartXia = false
let is_sale = false
let is_check = false
list.forEach((item) => {
item.cart_list.forEach((j) => {
if (j.checked && j.stock != 0 && j.is_sale != 0 && j.is_check != 0) {
ids.push(j.aid)
} else if (j.checked && j.stock == 0) {
cartXia = true
} else if (j.checked && j.is_sale == 0) {
is_sale = true
} else if (j.checked && j.is_check == 0) {
is_check = true
}
})
})
console.log(ids, 'ids')
if (cartXia) return this.$message.info('该商品已售完,正在采购中')
if (is_sale) return this.$message.info('该商品已下架')
if (is_check) return this.$message.info('该商品已下架')
const cart_ids = ids.join(',')
if (cart_ids == '') return this.$message.info('请选择商品')
this.$emit('update:cart-ids', cart_ids)
this.$emit('createOrder')
},
toDetail(item, type) {
if (item.is_valid == 2) return
this.$emit('update:goods-id', item.goods_id)
this.$emit('toGoods')
},
},
}
</script>
<style lang="scss" scoped>
.shop_icon {
color: var(--benbenFontColor5);
font-weight: 600;
font-size: 28rpx;
padding-right: 15rpx;
}
.shop_right_icon {
color: #999;
font-size: 22rpx;
}
.checked_icon {
color: #999;
}
.checked_active {
color: var(--benbenFontColor5);
}
.round {
transform: scale(0.7);
}
.text-cut-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
// 2021-01-07 新版本样式修改 by:技术五部 wyh
.cart-empty {
width: 750rpx;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
.empty-img {
display: block;
margin-top: 64rpx;
width: 440rpx;
height: 220rpx;
}
.empty-text {
margin-top: 28rpx;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 33rpx;
color: #999999;
}
.empty-btn {
margin-top: 27rpx;
margin-bottom: 64rpx;
width: 280rpx;
background: $bgtheme;
border-radius: 38rpx;
text-align: center;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 70rpx;
color: #ffffff;
}
}
// 购物车商品列表模块
.cart-box {
width: 750rpx;
// background-color: #fff;
overflow: hidden;
.cart-box-item {
background: #ffffff;
padding-top: 32rpx;
margin-top: 20rpx;
border-radius: 24rpx;
// #ifdef MP-WEIXIN
&:first-child {
margin-top: 0;
}
// #endif
}
// padding-bottom: 24rpx;
.cart-item {
width: 718rpx;
margin: 32rpx 0 0 32rpx;
display: flex;
padding-bottom: 32rpx;
// border-bottom: 1px solid #eee;
// align-items: center;
//当不能购买时 调整灰度
&.not-but-class {
filter: grayscale(100%);
}
&:nth-last-of-type(1) {
border-bottom: none;
}
// checkbox部分
.check-box {
margin-top: 72rpx;
width: 37rpx;
height: 37rpx;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
// 商品图片
.img-box {
width: 180rpx;
height: 180rpx;
flex-shrink: 0;
margin-left: 24rpx;
overflow: hidden;
border-radius: 16rpx;
position: relative;
.no-stok {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
width: 148rpx;
height: 148rpx;
z-index: 2;
background: rgba(0, 0, 0, 0.4);
border-radius: 74rpx;
display: flex;
align-items: center;
justify-content: center;
.no-stock-text {
color: #fff;
}
.no-stock-img {
display: block;
width: 95rpx;
height: 95rpx;
}
}
.img {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
z-index: 1;
width: 180rpx;
height: 180rpx;
}
}
// 商品详细信息
.info-box {
width: 422rpx;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.info-top {
display: flex;
flex-direction: column;
.title {
//两行溢出隐藏
white-space: nowrap;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 40rpx;
// height: 80rpx;
color: #333333;
opacity: 1;
}
.sku {
//单行溢出隐藏
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
margin-top: 16rpx;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 42rpx;
height: 42rpx;
color: #999999;
opacity: 1;
}
.jiang-jia {
display: flex;
align-items: center;
margin-top: 25rpx;
.jiang-jia-tip {
background: linear-gradient(126deg, #fa2033 0%, #ff6530 100%);
padding: 0 8rpx;
border-radius: 8rpx;
font-size: 22rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 32rpx;
color: #ffffff;
margin-right: 8rpx;
}
.jiang-jia-text {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 42rpx;
color: #fb2a25;
}
}
}
.price-box {
width: 100%;
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-top: 25rpx;
.price {
font-size: 32rpx;
font-weight: 600;
line-height: 36rpx;
color: #fe5014;
opacity: 1;
.small {
font-size: 28rpx;
}
}
}
}
}
}
.check-box-1 {
width: 37rpx;
height: 37rpx;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
// 购物车底部操作栏部分
.cart-footer {
height: 90rpx;
width: 750rpx;
left: 0;
position: fixed;
bottom: var(--window-bottom);
width: 100%;
z-index: 999;
background: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
.footer-left {
display: flex;
align-items: center;
.check-box {
margin-left: 32rpx;
}
.text-box {
margin-left: 16rpx;
.text1 {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 40rpx;
color: #333333;
}
.text2 {
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 33rpx;
color: #999999;
}
}
}
.footer-right {
// 右边 正常状态
display: flex;
align-items: center;
justify-content: flex-end;
.all-text {
display: flex;
align-items: center;
margin-right: 24rpx;
.text1 {
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 32rpx;
color: #666666;
opacity: 1;
}
.text-price-box {
font-size: 32rpx;
font-family: Oswald;
font-weight: 500;
line-height: 36rpx;
color: #fe5014;
.small {
font-size: 28rpx;
}
}
}
.jiesuan-btn {
width: 230rpx;
background: var(--benbenbgColor3);
opacity: 1;
text-align: center;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 90rpx;
color: #ffffff;
}
// 右边 编辑状态
.footer-btn {
width: 200rpx;
background: #f8f8f8;
opacity: 1;
border-radius: 64rpx;
text-align: center;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
line-height: 72rpx;
color: #333333;
margin-right: 24rpx;
margin-left: -8rpx;
}
.delect {
// background-color: $bgtheme;
// color: #FFFFFF;
}
}
}
.merchant-info {
margin: 0rpx 30rpx;
.icon {
margin-left: 6rpx;
font-size: 24rpx;
}
}
.merchant-icon {
width: 30rpx;
height: 26rpx;
margin-left: 11rpx;
margin-right: 8rpx;
top: 2rpx;
}
.sku_name {
display: flex;
justify-content: space-between;
background-color: #f8f8f8;
height: 48rpx;
line-height: 48rpx;
padding: 0 16rpx;
box-sizing: border-box;
margin: 8rpx 0;
border-radius: 8rpx;
}
.overFlow_text {
width: 250rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>