✨ 购物车:列表
parent
8fd8ff9f70
commit
7a15c9496c
|
@ -138,7 +138,7 @@
|
||||||
state.selectedSku = e;
|
state.selectedSku = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加购物车 TODO 芋艿:待测试
|
// 添加购物车
|
||||||
function onAddCart(e) {
|
function onAddCart(e) {
|
||||||
sheep.$store('cart').add(e);
|
sheep.$store('cart').add(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
<!-- 购物车界面 -->
|
||||||
<template>
|
<template>
|
||||||
<s-layout title="购物车" tabbar="/pages/index/cart" :bgStyle="{ color: '#fff' }">
|
<s-layout title="购物车" tabbar="/pages/index/cart" :bgStyle="{ color: '#fff' }">
|
||||||
<s-empty v-if="state.list.length === 0" text="购物车空空如也,快去逛逛吧~" icon="/static/cart-empty.png" />
|
<s-empty
|
||||||
|
v-if="state.list.length === 0"
|
||||||
|
text="购物车空空如也,快去逛逛吧~"
|
||||||
|
icon="/static/cart-empty.png"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 头部 -->
|
<!-- 头部 -->
|
||||||
<view class="cart-box ss-flex ss-flex-col ss-row-between" v-if="state.list.length">
|
<view class="cart-box ss-flex ss-flex-col ss-row-between" v-if="state.list.length">
|
||||||
|
@ -19,47 +24,72 @@
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 内容 -->
|
<!-- 内容 -->
|
||||||
<view class="cart-content ss-flex-1 ss-p-x-30 ss-m-b-40">
|
<view class="cart-content ss-flex-1 ss-p-x-30 ss-m-b-40">
|
||||||
<view class="goods-box ss-r-10 ss-m-b-14" v-for="item in state.list" :key="item.id">
|
<view class="goods-box ss-r-10 ss-m-b-14" v-for="item in state.list" :key="item.id">
|
||||||
<view class="ss-flex ss-col-center">
|
<view class="ss-flex ss-col-center">
|
||||||
<label class="check-box ss-flex ss-col-center ss-p-l-10" @tap="onSelectSingle(item.id)">
|
<label class="check-box ss-flex ss-col-center ss-p-l-10" @tap="onSelectSingle(item.id)">
|
||||||
<radio :checked="state.selectedIds.includes(item.id)" color="var(--ui-BG-Main)"
|
<radio
|
||||||
style="transform: scale(0.8)" @tap.stop="onSelectSingle(item.id)" />
|
:checked="state.selectedIds.includes(item.id)"
|
||||||
|
color="var(--ui-BG-Main)"
|
||||||
|
style="transform: scale(0.8)"
|
||||||
|
@tap.stop="onSelectSingle(item.id)"
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
<s-goods-item :title="item.spu.name" :img="item.spu.picUrl || item.goods.image"
|
<s-goods-item
|
||||||
:price="item.sku.price/100"
|
:title="item.spu.name"
|
||||||
:skuText="item.sku.properties.length>1? item.sku.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.sku.properties[0].valueName"
|
:img="item.sku.picUrl || item.spu.picUrl"
|
||||||
priceColor="#FF3000" :titleWidth="400">
|
:price="fen2yuan(item.sku.price)"
|
||||||
|
:skuText="item.sku.properties.map((property) => property.valueName).join(' ')"
|
||||||
|
priceColor="#FF3000"
|
||||||
|
:titleWidth="400"
|
||||||
|
>
|
||||||
<template v-if="!state.editMode" v-slot:tool>
|
<template v-if="!state.editMode" v-slot:tool>
|
||||||
<su-number-box :min="0" :max="item.sku.stock" :step="1" v-model="item.count"
|
<su-number-box
|
||||||
@change="onNumberChange($event, item)"></su-number-box>
|
:min="0"
|
||||||
|
:max="item.sku.stock"
|
||||||
|
:step="1"
|
||||||
|
v-model="item.count"
|
||||||
|
@change="onNumberChange($event, item)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</s-goods-item>
|
</s-goods-item>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
<su-fixed bottom :val="48" placeholder v-if="state.list.length > 0" :isInset="false">
|
<su-fixed bottom :val="48" placeholder v-if="state.list.length > 0" :isInset="false">
|
||||||
<view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom">
|
<view class="cart-footer ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom">
|
||||||
<view class="footer-left ss-flex ss-col-center">
|
<view class="footer-left ss-flex ss-col-center">
|
||||||
<label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll">
|
<label class="check-box ss-flex ss-col-center ss-p-r-30" @tap="onSelectAll">
|
||||||
<radio :checked="state.isAllSelected" color="var(--ui-BG-Main)"
|
<radio
|
||||||
style="transform: scale(0.8)" @tap.stop="onSelectAll" />
|
:checked="state.isAllSelected"
|
||||||
|
color="var(--ui-BG-Main)"
|
||||||
|
style="transform: scale(0.8)"
|
||||||
|
@tap.stop="onSelectAll"
|
||||||
|
/>
|
||||||
<view class="ss-m-l-8"> 全选 </view>
|
<view class="ss-m-l-8"> 全选 </view>
|
||||||
</label>
|
</label>
|
||||||
<text>合计:</text>
|
<text>合计:</text>
|
||||||
<view class="text-price price-text">
|
<view class="text-price price-text">
|
||||||
{{ state.totalPriceSelected }}
|
{{ fen2yuan(state.totalPriceSelected) }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer-right">
|
<view class="footer-right">
|
||||||
<button v-if="state.editMode" class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
|
<button
|
||||||
@tap="onDelete">
|
v-if="state.editMode"
|
||||||
|
class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
|
||||||
|
@tap="onDelete"
|
||||||
|
>
|
||||||
删除
|
删除
|
||||||
</button>
|
</button>
|
||||||
<button v-else class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
|
<button
|
||||||
@tap="onConfirm">
|
v-else
|
||||||
|
class="ss-reset-button ui-BG-Main-Gradient pay-btn ui-Shadow-Main"
|
||||||
|
@tap="onConfirm"
|
||||||
|
>
|
||||||
去结算
|
去结算
|
||||||
{{ state.selectedIds?.length ? `(${state.selectedIds.length})` : '' }}
|
{{ state.selectedIds?.length ? `(${state.selectedIds.length})` : '' }}
|
||||||
</button>
|
</button>
|
||||||
|
@ -72,28 +102,26 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import sheep from '@/sheep';
|
import sheep from '@/sheep';
|
||||||
import {
|
import { computed, reactive } from 'vue';
|
||||||
computed,
|
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||||
reactive,
|
import { property } from 'lodash/util';
|
||||||
unref
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
const sys_navBar = sheep.$platform.navbar;
|
const sys_navBar = sheep.$platform.navbar;
|
||||||
const cart = sheep.$store('cart');
|
const cart = sheep.$store('cart');
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
editMode: false,
|
editMode: false,
|
||||||
list: computed(() => cart.list),
|
list: computed(() => cart.list), // 购物车项的列表
|
||||||
selectedList: [],
|
|
||||||
selectedIds: computed(() => cart.selectedIds),
|
selectedIds: computed(() => cart.selectedIds),
|
||||||
isAllSelected: computed(() => cart.isAllSelected),
|
isAllSelected: computed(() => cart.isAllSelected),
|
||||||
totalPriceSelected: computed(() => cart.totalPriceSelected),
|
totalPriceSelected: computed(() => cart.totalPriceSelected),
|
||||||
});
|
});
|
||||||
// 单选选中
|
|
||||||
|
// 单选
|
||||||
function onSelectSingle(id) {
|
function onSelectSingle(id) {
|
||||||
console.log('单选')
|
|
||||||
cart.selectSingle(id);
|
cart.selectSingle(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全选
|
// 全选
|
||||||
function onSelectAll() {
|
function onSelectAll() {
|
||||||
cart.selectAll(!state.isAllSelected);
|
cart.selectAll(!state.isAllSelected);
|
||||||
|
@ -101,36 +129,24 @@
|
||||||
|
|
||||||
// 结算
|
// 结算
|
||||||
function onConfirm() {
|
function onConfirm() {
|
||||||
let items = []
|
const items = state.list
|
||||||
let goods_list = [];
|
.filter((item) => state.selectedIds.includes(item.id))
|
||||||
state.selectedList = state.list.filter((item) => state.selectedIds.includes(item.id));
|
.map((item) => {
|
||||||
state.selectedList.map((item) => {
|
return {
|
||||||
console.log(item, '便利');
|
|
||||||
// 此处前端做出修改
|
|
||||||
items.push({
|
|
||||||
skuId: item.sku.id,
|
skuId: item.sku.id,
|
||||||
count: item.count,
|
count: item.count,
|
||||||
cartId: item.id,
|
cartId: item.id,
|
||||||
})
|
};
|
||||||
goods_list.push({
|
|
||||||
// goods_id: item.goods_id,
|
|
||||||
goods_id: item.spu.id,
|
|
||||||
// goods_num: item.goods_num,
|
|
||||||
goods_num: item.count,
|
|
||||||
// 商品价格id真没有
|
|
||||||
// goods_sku_price_id: item.goods_sku_price_id,
|
|
||||||
});
|
});
|
||||||
});
|
if (items.length === 0) {
|
||||||
// return;
|
|
||||||
if (goods_list.length === 0) {
|
|
||||||
sheep.$helper.toast('请选择商品');
|
sheep.$helper.toast('请选择商品');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sheep.$router.go('/pages/order/confirm', {
|
sheep.$router.go('/pages/order/confirm', {
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
|
items,
|
||||||
// order_type: 'goods',
|
// order_type: 'goods',
|
||||||
// goods_list,
|
// goods_list,
|
||||||
items,
|
|
||||||
// from: 'cart',
|
// from: 'cart',
|
||||||
deliveryType: 1,
|
deliveryType: 1,
|
||||||
pointStatus: false,
|
pointStatus: false,
|
||||||
|
@ -138,19 +154,23 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNumberChange(e, cartItem) {
|
// 更新数量
|
||||||
if (e === 0) {
|
function onNumberChange(number, cartItem) {
|
||||||
cart.delete(cartItem.id);
|
if (number === 0) {
|
||||||
|
cart.delete([cartItem.id]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cartItem.goods_num === e) return;
|
if (cartItem.goods_num === number) {
|
||||||
cartItem.goods_num = e;
|
return;
|
||||||
|
}
|
||||||
|
cartItem.goods_num = number;
|
||||||
cart.update({
|
cart.update({
|
||||||
goods_id: cartItem.id,
|
goods_id: cartItem.id,
|
||||||
goods_num: e,
|
goods_num: number,
|
||||||
goods_sku_price_id: cartItem.goods_sku_price_id,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
async function onDelete() {
|
async function onDelete() {
|
||||||
cart.delete(state.selectedIds);
|
cart.delete(state.selectedIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ export default {
|
||||||
request({
|
request({
|
||||||
url: 'cart',
|
url: 'cart',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
// TODO 芋艿:这里没提示
|
||||||
custom: {
|
custom: {
|
||||||
showSuccess: true,
|
showSuccess: true,
|
||||||
successMsg: '已添加到购物车~',
|
successMsg: '已添加到购物车~',
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import request2 from '@/sheep/request2';
|
||||||
|
|
||||||
|
const CartApi = {
|
||||||
|
addCart: (data) => {
|
||||||
|
return request2({
|
||||||
|
url: '/app-api/trade/cart/add',
|
||||||
|
method: 'POST',
|
||||||
|
data: data,
|
||||||
|
// TODO 芋艿:这里没提示
|
||||||
|
custom: {
|
||||||
|
showSuccess: true,
|
||||||
|
successMsg: '已添加到购物车~',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateCartCount: (data) => {
|
||||||
|
return request2({
|
||||||
|
url: '/app-api/trade/cart/update-count',
|
||||||
|
method: 'PUT',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateCartSelected: (data) => {
|
||||||
|
return request2({
|
||||||
|
url: '/app-api/trade/cart/update-selected',
|
||||||
|
method: 'PUT',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteCart: (ids) => {
|
||||||
|
return request2({
|
||||||
|
url: '/app-api/trade/cart/delete',
|
||||||
|
method: 'DELETE',
|
||||||
|
params: {
|
||||||
|
ids
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getCartList: () => {
|
||||||
|
return request2({
|
||||||
|
url: '/app-api/trade/cart/list',
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CartApi;
|
|
@ -1,98 +1,93 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import cartApi from '@/sheep/api/cart';
|
import CartApi from '@/sheep/api/trade/cart';
|
||||||
|
|
||||||
const cart = defineStore({
|
const cart = defineStore({
|
||||||
id: 'cart',
|
id: 'cart',
|
||||||
state: () => ({
|
state: () => ({
|
||||||
list: [], // 购物车列表
|
list: [], // 购物车列表
|
||||||
selectedIds: [], // 已选列表
|
selectedIds: [], // 已选列表
|
||||||
isAllSelected: false, //是否全选
|
isAllSelected: false, // 是否全选
|
||||||
cartSelectedTotalPrice: '0.00', // 选中项总金额
|
totalPriceSelected: 0, // 选中项总金额
|
||||||
}),
|
}),
|
||||||
getters: {
|
|
||||||
totalPriceSelected: (state) => {
|
|
||||||
let price = 0;
|
|
||||||
if (!state.selectedIds.length) return price.toFixed(2);
|
|
||||||
state.list.forEach((item) => {
|
|
||||||
price += state.selectedIds.includes(item.id)
|
|
||||||
? Number(item.sku.price/100) * item.count
|
|
||||||
: 0;
|
|
||||||
});
|
|
||||||
return price.toFixed(2);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
actions: {
|
actions: {
|
||||||
// 获取购物车列表
|
// 获取购物车列表
|
||||||
async getList() {
|
async getList() {
|
||||||
const { data, code } = await cartApi.list();
|
const { data, code } = await CartApi.getCartList();
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
this.list = data.validList;
|
this.list = data.validList;
|
||||||
|
|
||||||
|
// 计算各种关联属性
|
||||||
|
this.selectedIds = [];
|
||||||
|
this.isAllSelected = true;
|
||||||
|
this.totalPriceSelected = 0;
|
||||||
|
this.list.forEach((item) => {
|
||||||
|
if (item.selected) {
|
||||||
|
this.selectedIds.push(item.id);
|
||||||
|
this.totalPriceSelected += item.count * item.sku.price;
|
||||||
|
} else {
|
||||||
|
this.isAllSelected = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 添加购物车
|
// 添加购物车
|
||||||
async add(goodsInfo) {
|
async add(goodsInfo) {
|
||||||
const { error } = await cartApi.append({
|
// 添加购物项
|
||||||
goods_id: goodsInfo.goods_id,
|
const { code } = await CartApi.addCart({
|
||||||
goods_num: goodsInfo.goods_num,
|
skuId: goodsInfo.id,
|
||||||
goods_sku_price_id: goodsInfo.id,
|
count: goodsInfo.goods_num,
|
||||||
});
|
});
|
||||||
if (error === 0) {
|
// 刷新购物车列表
|
||||||
this.getList();
|
if (code === 0) {
|
||||||
|
await this.getList();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 更新购物车
|
// 更新购物车
|
||||||
async update(goodsInfo) {
|
async update(goodsInfo) {
|
||||||
const { error } = await cartApi.update({
|
const { code } = await CartApi.updateCartCount({
|
||||||
id: goodsInfo.goods_id,
|
id: goodsInfo.goods_id,
|
||||||
count: goodsInfo.goods_num,
|
count: goodsInfo.goods_num,
|
||||||
goods_sku_price_id: goodsInfo.goods_sku_price_id,
|
|
||||||
});
|
});
|
||||||
if (error === 0) {
|
if (code === 0) {
|
||||||
// this.getList();
|
await this.getList();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 移除购物车
|
// 移除购物车
|
||||||
async delete(ids) {
|
async delete(ids) {
|
||||||
if (typeof ids === 'array') {
|
const { code } = await CartApi.deleteCart(ids.join(','));
|
||||||
ids = ids.join(',');
|
|
||||||
}
|
|
||||||
const { code } = await cartApi.delete(ids);
|
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
this.selectAll(false);
|
await this.getList();
|
||||||
this.getList();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 选择购物车商品
|
// 单选购物车商品
|
||||||
selectSingle(goodsId) {
|
async selectSingle(goodsId) {
|
||||||
if (!this.selectedIds.includes(goodsId)) {
|
const { code } = await CartApi.updateCartSelected({
|
||||||
this.selectedIds.push(goodsId);
|
ids: [goodsId],
|
||||||
} else {
|
selected: !this.selectedIds.includes(goodsId), // 取反
|
||||||
this.selectedIds.splice(this.selectedIds.indexOf(goodsId), 1);
|
|
||||||
}
|
|
||||||
this.isAllSelected = this.selectedIds.length === this.list.length;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 全选
|
|
||||||
selectAll(flag) {
|
|
||||||
this.isAllSelected = flag;
|
|
||||||
if (!flag) {
|
|
||||||
this.selectedIds = [];
|
|
||||||
} else {
|
|
||||||
this.list.forEach((item) => {
|
|
||||||
this.selectedIds.push(item.id);
|
|
||||||
});
|
});
|
||||||
|
if (code === 0) {
|
||||||
|
await this.getList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 全选购物车商品
|
||||||
|
async selectAll(flag) {
|
||||||
|
const { code } = await CartApi.updateCartSelected({
|
||||||
|
ids: this.list.map((item) => item.id),
|
||||||
|
selected: flag
|
||||||
|
});
|
||||||
|
if (code === 0) {
|
||||||
|
await this.getList();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 清空购物车
|
// 清空购物车
|
||||||
emptyList() {
|
async emptyList() {
|
||||||
this.list = [];
|
await this.delete(this.list.map((item) => item.id));
|
||||||
this.selectedIds = [];
|
|
||||||
this.isAllSelected = false;
|
|
||||||
this.cartSelectedTotalPrice = '0.00';
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
|
|
Loading…
Reference in New Issue