479 lines
17 KiB
Vue
479 lines
17 KiB
Vue
<template>
|
||
<div class="shop-cart">
|
||
<div class="cart-list">
|
||
<div v-show="!isDataNull">
|
||
<div class="cart-hd flex bg-white">
|
||
<div class="check-box">
|
||
<!-- 更改选中状态 type为1选中店铺/2选中商品/3全选 -->
|
||
<el-checkbox
|
||
v-model="isSelectedAll"
|
||
@change="onBoxClick($event, 3, '')"
|
||
>全选</el-checkbox
|
||
>
|
||
</div>
|
||
<div class="info flex row-center">商品信息</div>
|
||
<div class="price flex row-center">单价</div>
|
||
<div class="num flex row-center">数量</div>
|
||
<div class="money flex row-center">合计</div>
|
||
<div class="operate flex row-center">操作</div>
|
||
</div>
|
||
|
||
<div class="cart-con bg-white">
|
||
<div
|
||
class="m-b-10 bg-white"
|
||
v-for="(item, index) in shopCartList"
|
||
:key="index"
|
||
>
|
||
<div class="flex shop">
|
||
<!-- 更改选中状态 type为1选中店铺/2选中商品/3全选 -->
|
||
<el-checkbox
|
||
:value="item.is_selected == 1"
|
||
@change="onBoxClick($event, 1, index)"
|
||
>
|
||
</el-checkbox>
|
||
|
||
<div class="xs normal m-l-10">
|
||
{{ item.shop.shop_name }}
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="item flex"
|
||
v-for="(item2, index2) in item.cart"
|
||
:key="index2"
|
||
>
|
||
<div class="check-box">
|
||
<!-- 更改选中状态 type为1选中店铺/2选中商品/3全选 -->
|
||
<el-checkbox
|
||
:value="item2.selected == 1"
|
||
@change="
|
||
onBoxClick($event, 2, item2.cart_id)
|
||
"
|
||
>
|
||
</el-checkbox>
|
||
</div>
|
||
<nuxt-link
|
||
class="info flex"
|
||
:to="'/goods_details/' + item2.goods_id"
|
||
>
|
||
<div class="pictrue flexnone">
|
||
<img :src="item2.image" alt="" />
|
||
</div>
|
||
<div>
|
||
<div class="name line2">
|
||
{{ item2.goods_name }}
|
||
</div>
|
||
<div class="muted">
|
||
{{ item2.spec_value_str }}
|
||
</div>
|
||
</div>
|
||
</nuxt-link>
|
||
<div class="price flex row-center">
|
||
¥{{ item2.price }}
|
||
</div>
|
||
<div class="num flex row-center">
|
||
<number-box
|
||
:min="1"
|
||
v-model="item2.goods_num"
|
||
@change="
|
||
changeShopCartCount(
|
||
$event,
|
||
item2.cart_id
|
||
)
|
||
"
|
||
async-change
|
||
/>
|
||
</div>
|
||
<div class="money flex row-center">
|
||
¥{{ item2.sub_price }}
|
||
</div>
|
||
<el-popconfirm
|
||
title="确定删除该商品吗?"
|
||
confirm-button-text="确定"
|
||
cancel-button-text="取消"
|
||
icon="el-icon-info"
|
||
icon-color="red"
|
||
@confirm="goodsDelete(item2.cart_id)"
|
||
>
|
||
<div
|
||
class="operate flex row-center delete-btn"
|
||
slot="reference"
|
||
>
|
||
<img
|
||
src="~/static/images/icon_cart_del.png"
|
||
/>
|
||
</div>
|
||
</el-popconfirm>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="cart-footer flex row-between bg-white">
|
||
<div class="lighter flex">
|
||
<div class="check-box">
|
||
<el-checkbox
|
||
v-model="isSelectedAll"
|
||
@change="onBoxClick($event, 3, '')"
|
||
>全选</el-checkbox
|
||
>
|
||
</div>
|
||
<div style="margin: 0 24px"></div>
|
||
<el-popconfirm
|
||
title="确定删除选中商品吗?"
|
||
confirm-button-text="确定"
|
||
cancel-button-text="取消"
|
||
icon="el-icon-info"
|
||
icon-color="red"
|
||
@confirm="deleteSelectedGoods"
|
||
>
|
||
<div
|
||
class="xs normal"
|
||
style="cursor: pointer"
|
||
slot="reference"
|
||
>
|
||
删除选中商品
|
||
</div>
|
||
</el-popconfirm>
|
||
<el-popconfirm
|
||
title="确定清空吗?"
|
||
confirm-button-text="确定"
|
||
cancel-button-text="取消"
|
||
icon="el-icon-info"
|
||
icon-color="red"
|
||
@confirm="deleteAlldGoods"
|
||
>
|
||
<div
|
||
class="m-l-14 xs muted"
|
||
style="cursor: pointer"
|
||
slot="reference"
|
||
>
|
||
清空购物车
|
||
</div>
|
||
</el-popconfirm>
|
||
</div>
|
||
<div class="total flex">
|
||
<div class="flex m-r-14">
|
||
<div class="xs">已选{{ selected }}件商品</div>
|
||
<div class="primary m-l-20" style="font-size: 22px">
|
||
¥{{ totalAmount }}
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="white lg btn flex row-center"
|
||
:style="{
|
||
background:
|
||
selected == 0 ? '#A4ADB3' : '#FF2C3C',
|
||
}"
|
||
@click="toOrderBuy"
|
||
>
|
||
去结算
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="column-center data-null" v-show="isDataNull">
|
||
<img
|
||
src="@/static/images/cart_null.png"
|
||
style="width: 150px; height: 150px"
|
||
/>
|
||
<div class="muted xs m-t-10">购物车是空的~</div>
|
||
<div class="m-t-30">
|
||
<el-button
|
||
round
|
||
type="primary"
|
||
size="medium"
|
||
@click="toIndex"
|
||
>去逛逛~</el-button
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { mapActions } from 'vuex'
|
||
export default {
|
||
head() {
|
||
return {
|
||
title: this.$store.getters.headTitle,
|
||
link: [
|
||
{
|
||
rel: 'icon',
|
||
type: 'image/x-icon',
|
||
href: this.$store.getters.favicon,
|
||
},
|
||
],
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
shopCartList: [],
|
||
totalAmount: 0,
|
||
totalNum: 0,
|
||
isDataNull: false,
|
||
}
|
||
},
|
||
mounted() {},
|
||
computed: {
|
||
// 是否全选
|
||
isSelectedAll: {
|
||
get() {
|
||
if (!this.shopCartList.length) return false
|
||
if (this.allInvalid()) return false
|
||
let index = this.shopCartList.findIndex(
|
||
(item) => item.is_selected == 0
|
||
)
|
||
return index == -1 ? true : false
|
||
},
|
||
set(val) {
|
||
return val
|
||
},
|
||
},
|
||
// 已经选择的数量
|
||
selected: {
|
||
get() {
|
||
return this.shopCartList.reduce((pre, item) => {
|
||
return pre.concat(item.cart.filter((i) => i.selected == 1))
|
||
}, []).length
|
||
},
|
||
},
|
||
},
|
||
methods: {
|
||
...mapActions(['getPublicData']),
|
||
async getCartList() {
|
||
let res = await this.$get('cart/lists')
|
||
if (res.code == 1) {
|
||
this.shopCartList = Object.assign([], res.data.lists)
|
||
this.totalAmount = res.data.total_amount
|
||
this.totalNum = res.data.total_num
|
||
|
||
if (this.shopCartList.length > 0) {
|
||
this.isDataNull = false
|
||
} else {
|
||
this.isDataNull = true
|
||
}
|
||
}
|
||
},
|
||
|
||
// 更改选中状态 type为1选中店铺/2选中商品/3全选
|
||
onBoxClick(e, type, number) {
|
||
let cartId = []
|
||
switch (type) {
|
||
case 1:
|
||
cartId = this.shopCartList[number].cart.map(
|
||
(item) => item.cart_id
|
||
)
|
||
break
|
||
case 2:
|
||
cartId.push(number)
|
||
break
|
||
case 3:
|
||
cartId = this.shopCartList.reduce((pre, item) => {
|
||
return pre.concat(item.cart.map((i) => i.cart_id))
|
||
}, cartId)
|
||
break
|
||
}
|
||
this.changeSelected(cartId, e)
|
||
},
|
||
cartInvalid(item) {
|
||
return item.goods_status == 0 || item.goods_del != 0 ? true : false
|
||
},
|
||
shopInvalid(item) {
|
||
return item.cart.every((citem) => this.cartInvalid(citem))
|
||
},
|
||
allInvalid() {
|
||
return this.shopCartList.every((item) => this.shopInvalid(item))
|
||
},
|
||
|
||
// 选中/取消选中购物车
|
||
async changeSelected(id, selected) {
|
||
let res = await this.$post('cart/selected', {
|
||
cart_id: id,
|
||
selected: selected,
|
||
})
|
||
if (res.code == 1) {
|
||
this.getCartList()
|
||
}
|
||
},
|
||
|
||
// 修改购物车商品数量
|
||
async changeShopCartCount(number, cartId) {
|
||
let res = await this.$post('cart/change', {
|
||
cart_id: cartId,
|
||
goods_num: number,
|
||
})
|
||
if (res.code == 1) {
|
||
this.getCartList()
|
||
this.getPublicData()
|
||
}
|
||
},
|
||
// 删除购物车商品
|
||
async goodsDelete(cartId) {
|
||
let res = await this.$post('cart/del', {
|
||
cart_id: cartId,
|
||
})
|
||
if (res.code == 1) {
|
||
this.getPublicData()
|
||
this.getCartList()
|
||
this.$message({
|
||
message: '删除商品成功',
|
||
type: 'success',
|
||
})
|
||
}
|
||
},
|
||
// 删除选中购物车
|
||
deleteSelectedGoods() {
|
||
let selectedGoodsArr = this.shopCartList.reduce((pre, item) => {
|
||
return pre.concat(item.cart.filter((i) => i.selected == 1))
|
||
}, [])
|
||
if (selectedGoodsArr.length <= 0) {
|
||
this.$message({
|
||
message: '没有选择商品',
|
||
type: 'error',
|
||
})
|
||
return
|
||
}
|
||
let cartIdArr = selectedGoodsArr.map((item) => item.cart_id)
|
||
this.goodsDelete(cartIdArr)
|
||
},
|
||
// 清空购物车
|
||
deleteAlldGoods() {
|
||
let allGoodsArr = this.shopCartList.reduce((pre, item) => {
|
||
return pre.concat(item.cart.filter((i) => i.cart_id))
|
||
}, [])
|
||
if (allGoodsArr.length <= 0) {
|
||
this.$message({
|
||
message: '没有商品',
|
||
type: 'error',
|
||
})
|
||
return
|
||
}
|
||
let cartIdArr = allGoodsArr.map((item) => item.cart_id)
|
||
this.goodsDelete(cartIdArr)
|
||
},
|
||
getSelectCart() {
|
||
const { shopCartList } = this
|
||
return shopCartList.reduce((pre, item) => {
|
||
return pre.concat(
|
||
item.cart
|
||
.filter((i) => i.selected && !this.cartInvalid(i))
|
||
.map((i) => i.cart_id)
|
||
)
|
||
}, [])
|
||
},
|
||
// 去购买商品
|
||
toOrderBuy() {
|
||
let { shopCartList } = this
|
||
let goods = []
|
||
let carts = this.getSelectCart()
|
||
if (carts.length == 0) return this.$message.err('您还没有选择商品哦')
|
||
// 处理出商品数组数据
|
||
shopCartList.forEach((item) => {
|
||
if (item.cart.length != 0) {
|
||
item.cart.forEach((el, i) => {
|
||
// 选中的商品才能进入
|
||
if (el.selected == 1) {
|
||
goods.push({
|
||
item_id: el.item_id,
|
||
num: el.goods_num,
|
||
goods_id: el.goods_id,
|
||
shop_id: item.shop.shop_id,
|
||
})
|
||
}
|
||
})
|
||
}
|
||
})
|
||
const params = {
|
||
carts: carts,
|
||
goods: goods,
|
||
type: 'cart',
|
||
}
|
||
this.$router.push({
|
||
path: '/confirm_order',
|
||
query: {
|
||
data: encodeURIComponent(JSON.stringify(params)),
|
||
},
|
||
})
|
||
},
|
||
toIndex() {
|
||
this.$router.push('/')
|
||
},
|
||
},
|
||
|
||
created() {
|
||
this.getCartList()
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.shop-cart {
|
||
padding: 24px 0;
|
||
.cart-list {
|
||
min-height: 600px;
|
||
.cart-hd {
|
||
height: 50px;
|
||
color: #101010;
|
||
padding: 10px 10px;
|
||
margin-bottom: 10px;
|
||
}
|
||
.cart-con {
|
||
padding: 0 10px;
|
||
.shop {
|
||
padding: 20px 10px;
|
||
border-bottom: 1px solid #d7d7d7;
|
||
}
|
||
.item {
|
||
padding: 20px 10px;
|
||
border-bottom: 1px dashed #e5e5e5;
|
||
}
|
||
.item:last-child {
|
||
border-bottom: 0;
|
||
}
|
||
}
|
||
.check-box {
|
||
padding-left: 10px;
|
||
width: 40px;
|
||
}
|
||
.info {
|
||
width: 450px;
|
||
.pictrue {
|
||
margin-right: 10px;
|
||
img {
|
||
width: 72px;
|
||
height: 72px;
|
||
}
|
||
}
|
||
.name {
|
||
margin-bottom: 10px;
|
||
}
|
||
}
|
||
.price {
|
||
width: 150px;
|
||
}
|
||
.num {
|
||
width: 250px;
|
||
}
|
||
.money {
|
||
width: 150px;
|
||
}
|
||
.delete-btn {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
.cart-footer {
|
||
padding: 20px;
|
||
.total {
|
||
.btn {
|
||
width: 152px;
|
||
height: 50px;
|
||
cursor: pointer;
|
||
border-radius: 4px;
|
||
}
|
||
}
|
||
}
|
||
.data-null {
|
||
text-align: center;
|
||
padding-top: 170px;
|
||
}
|
||
}
|
||
</style> |