Files
2025-11-17 14:11:46 +08:00

556 lines
15 KiB
JavaScript
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.

import Dialog from 'tdesign-miniprogram/dialog/index';
import Toast from 'tdesign-miniprogram/toast/index';
import {
fetchCartGroupData,
updateCartItem,
removeFromCart,
addToCart,
selectCartItem,
selectAllCartItems
} from '../../services/cart/cart';
Page({
data: {
cartGroupData: null,
refresherTriggered: false, // 下拉刷新状态
},
// 调用自定义tabbar的init函数使页面与tabbar激活状态保持一致
onShow() {
this.getTabBar().init();
// 每次显示页面时刷新购物车数据,确保数据是最新的
this.refreshData();
},
onLoad() {
this.refreshData();
},
refreshData() {
this.getCartGroupData().then((res) => {
let isEmpty = true;
const cartGroupData = res.data;
// 一些组件中需要的字段可能接口并没有返回,或者返回的数据结构与预期不一致,需要在此先对数据做一些处理
// 统计门店下加购的商品是否全选、是否存在缺货/无货
if (cartGroupData && cartGroupData.storeGoods) {
for (const store of cartGroupData.storeGoods) {
store.isSelected = true; // 该门店已加购商品是否全选
store.storeStockShortage = false; // 该门店已加购商品是否存在库存不足
if (!store.shortageGoodsList) {
store.shortageGoodsList = []; // 该门店已加购商品如果库存为0需单独分组
}
for (const activity of store.promotionGoodsList) {
activity.goodsPromotionList = activity.goodsPromotionList.filter((goods) => {
goods.originPrice = undefined;
// 统计是否有加购数大于库存数的商品
if (goods.quantity > goods.stockQuantity) {
store.storeStockShortage = true;
}
// 统计是否全选
if (!goods.isSelected) {
store.isSelected = false;
}
// 库存为0无货的商品单独分组
if (goods.stockQuantity > 0) {
return true;
}
store.shortageGoodsList.push(goods);
return false;
});
if (activity.goodsPromotionList.length > 0) {
isEmpty = false;
}
}
if (store.shortageGoodsList.length > 0) {
isEmpty = false;
}
}
}
if (cartGroupData && cartGroupData.invalidGoodItems) {
cartGroupData.invalidGoodItems = cartGroupData.invalidGoodItems.map((goods) => {
goods.originPrice = undefined;
return goods;
});
}
if (cartGroupData) {
cartGroupData.isNotEmpty = !isEmpty;
}
this.setData({ cartGroupData });
});
},
findGoods(spuId, skuId) {
let currentStore;
let currentActivity;
let currentGoods;
if (!this.data.cartGroupData || !this.data.cartGroupData.storeGoods) {
return {
currentStore: null,
currentActivity: null,
currentGoods: null,
};
}
const { storeGoods } = this.data.cartGroupData;
for (const store of storeGoods) {
for (const activity of store.promotionGoodsList) {
for (const goods of activity.goodsPromotionList) {
if (goods.spuId === spuId && goods.skuId === skuId) {
currentStore = store;
currentActivity = activity;
currentGoods = goods;
return {
currentStore,
currentActivity,
currentGoods,
};
}
}
}
}
return {
currentStore,
currentActivity,
currentGoods,
};
},
// 获取购物车数据 - 每次都从后端获取最新数据
getCartGroupData() {
return fetchCartGroupData();
},
// 选择单个商品
selectGoodsService({ spuId, skuId, isSelected }) {
// 先更新本地状态
const { currentGoods } = this.findGoods(spuId, skuId);
if (currentGoods) {
currentGoods.isSelected = isSelected ? 1 : 0;
}
// 调用API更新后端状态
const cartId = currentGoods ? currentGoods.uid : spuId;
return selectCartItem(cartId, isSelected).catch(err => {
console.error('选择商品失败:', err);
// 如果API调用失败恢复本地状态
if (currentGoods) {
currentGoods.isSelected = isSelected ? 0 : 1;
}
throw err;
});
},
// 全选门店
// 注:实际场景时应该调用接口更改选中状态
selectStoreService({ storeId, isSelected }) {
if (!this.data.cartGroupData || !this.data.cartGroupData.storeGoods) {
return;
}
const currentStore = this.data.cartGroupData.storeGoods.find((s) => s.storeId === storeId);
if (currentStore) {
currentStore.isSelected = isSelected;
// 添加数据验证,确保数组存在
if (Array.isArray(currentStore.promotionGoodsList)) {
currentStore.promotionGoodsList.forEach((activity) => {
if (Array.isArray(activity.goodsPromotionList)) {
activity.goodsPromotionList.forEach((goods) => {
goods.isSelected = isSelected;
});
}
});
}
}
return Promise.resolve();
},
// 加购数量变更
async changeQuantityService(spuId, skuId, quantity) {
try {
const goods = this.findGoods(spuId, skuId);
if (!goods) {
Toast({
context: this,
selector: '#t-toast',
message: '商品不存在',
theme: 'error',
});
return;
}
// 调用后端API传递skuId
await updateCartItem(spuId, quantity, skuId);
// 更新本地数据
goods.quantity = quantity;
this.setData({
cartGroupData: this.data.cartGroupData,
});
Toast({
context: this,
selector: '#t-toast',
message: '修改成功',
theme: 'success',
});
} catch (error) {
console.error('修改数量失败:', error);
Toast({
context: this,
selector: '#t-toast',
message: error.message || '修改失败',
theme: 'error',
});
}
},
// 删除商品
async deleteGoodsService(spuId, skuId) {
try {
const goods = this.findGoods(spuId, skuId);
if (!goods.currentGoods) {
Toast({
context: this,
selector: '#t-toast',
message: '商品不存在',
theme: 'error',
});
return;
}
// 调用后端API传递skuId
await removeFromCart(spuId, skuId);
// 重新获取购物车数据
this.refreshData();
Toast({
context: this,
selector: '#t-toast',
message: '删除成功',
theme: 'success',
});
} catch (error) {
console.error('删除商品失败:', error);
Toast({
context: this,
selector: '#t-toast',
message: error.message || '删除失败',
theme: 'error',
});
}
},
// 清空失效商品
// 注:实际场景时应该调用接口
clearInvalidGoodsService() {
this.data.cartGroupData.invalidGoodItems = [];
return Promise.resolve();
},
onGoodsSelect(e) {
const {
goods: { spuId, skuId },
isSelected,
} = e.detail;
const { currentGoods } = this.findGoods(spuId, skuId);
Toast({
context: this,
selector: '#t-toast',
message: `${isSelected ? '选择' : '取消'}"${
currentGoods.title.length > 5 ? `${currentGoods.title.slice(0, 5)}...` : currentGoods.title
}"`,
icon: '',
});
this.selectGoodsService({ spuId, skuId, isSelected }).then(() => this.refreshData());
},
onStoreSelect(e) {
const {
store: { storeId },
isSelected,
} = e.detail;
this.selectStoreService({ storeId, isSelected }).then(() => this.refreshData());
},
onQuantityChange(e) {
const {
goods: { spuId, skuId },
quantity,
} = e.detail;
const { currentGoods } = this.findGoods(spuId, skuId);
const stockQuantity = currentGoods.stockQuantity > 0 ? currentGoods.stockQuantity : 0; // 避免后端返回的是-1
// 加购数量超过库存数量
if (quantity > stockQuantity) {
// 加购数量等于库存数量的情况下继续加购
if (currentGoods.quantity === stockQuantity && quantity - stockQuantity === 1) {
Toast({
context: this,
selector: '#t-toast',
message: '当前商品库存不足',
});
return;
}
Dialog.confirm({
title: '商品库存不足',
content: `当前商品库存不足,最大可购买数量为${stockQuantity}`,
confirmBtn: '修改为最大可购买数量',
cancelBtn: '取消',
})
.then(() => {
this.changeQuantityService(spuId, skuId, stockQuantity).then(() => this.refreshData());
})
.catch(() => {});
return;
}
this.changeQuantityService(spuId, skuId, quantity).then(() => this.refreshData());
},
// SKU变更
async onSkuChange(e) {
const { oldSpuId, oldSkuId, newSpuId, newSkuId, quantity } = e.detail;
try {
// 先删除旧SKU
await removeFromCart(oldSpuId, oldSkuId);
// 再添加新SKU使用用户选择的数量
await addToCart(newSpuId, newSkuId, quantity || 1);
// 刷新购物车数据
this.refreshData();
Toast({
context: this,
selector: '#t-toast',
message: '规格修改成功',
theme: 'success',
});
} catch (error) {
console.error('SKU变更失败:', error);
Toast({
context: this,
selector: '#t-toast',
message: error.message || '修改规格失败',
theme: 'error',
});
}
},
goCollect() {
/** 活动肯定有一个活动ID用来获取活动banner活动商品列表等 */
const promotionID = '123';
wx.navigateTo({
url: `/pages/promotion/promotion-detail/index?promotion_id=${promotionID}`,
});
},
goGoodsDetail(e) {
const { spuId, storeId } = e.detail.goods;
wx.navigateTo({
url: `/pages/goods/details/index?spuId=${spuId}&storeId=${storeId}`,
});
},
clearInvalidGoods() {
// 实际场景时应该调用接口清空失效商品
this.clearInvalidGoodsService().then(() => this.refreshData());
},
onGoodsDelete(e) {
const {
goods: { spuId, skuId },
} = e.detail;
Dialog.confirm({
content: '确认删除该商品吗?',
confirmBtn: '确定',
cancelBtn: '取消',
}).then(() => {
// deleteGoodsService 内部已经包含了Toast提示和数据刷新无需重复操作
this.deleteGoodsService(spuId, skuId);
});
},
onSelectAll(event) {
const { isAllSelected } = event?.detail ?? {};
Toast({
context: this,
selector: '#t-toast',
message: `${isAllSelected ? '取消' : '点击'}了全选按钮`,
});
// 调用接口改变全选
selectAllCartItems(!isAllSelected).then(() => {
this.refreshData();
}).catch(err => {
console.error('全选操作失败:', err);
Toast({
context: this,
selector: '#t-toast',
message: '操作失败,请重试',
});
});
},
onToSettle() {
const goodsRequestList = [];
let totalAmount = 0;
let selectedCount = 0;
// 添加数据验证,确保数据结构存在
if (this.data.cartGroupData && Array.isArray(this.data.cartGroupData.storeGoods)) {
this.data.cartGroupData.storeGoods.forEach((store) => {
if (Array.isArray(store.promotionGoodsList)) {
store.promotionGoodsList.forEach((promotion) => {
if (Array.isArray(promotion.goodsPromotionList)) {
promotion.goodsPromotionList.forEach((m) => {
if (m.isSelected == 1) {
// 检查库存
if (m.quantity > m.stockQuantity) {
Toast({
context: this,
selector: '#t-toast',
message: `${m.title}库存不足,请调整数量`,
});
return;
}
goodsRequestList.push({
...m,
// 确保价格格式正确
price: parseInt(m.price) || 0,
originPrice: parseInt(m.originPrice) || parseInt(m.price) || 0,
});
selectedCount += m.quantity;
totalAmount += (parseInt(m.price) || 0) * m.quantity;
}
});
}
});
}
});
}
// 验证是否有选中的商品
if (goodsRequestList.length === 0) {
Toast({
context: this,
selector: '#t-toast',
message: '请选择要结算的商品',
});
return;
}
// 验证用户是否登录
const token = wx.getStorageSync('token');
if (!token) {
Dialog.confirm({
title: '提示',
content: '请先登录后再进行结算',
confirmBtn: '去登录',
cancelBtn: '取消',
}).then(() => {
wx.navigateTo({ url: '/pages/login/index' });
});
return;
}
// 保存结算数据到本地存储
const orderData = {
goodsRequestList,
totalAmount,
selectedCount,
timestamp: Date.now()
};
try {
wx.setStorageSync('order.goodsRequestList', JSON.stringify(goodsRequestList));
wx.setStorageSync('order.settlementData', JSON.stringify(orderData));
// 跳转到订单确认页面
wx.navigateTo({
url: '/pages/order/order-confirm/index?type=cart',
success: () => {
console.log('跳转到订单确认页面成功');
},
fail: (err) => {
console.error('跳转失败:', err);
Toast({
context: this,
selector: '#t-toast',
message: '跳转失败,请重试',
});
}
});
} catch (error) {
console.error('保存订单数据失败:', error);
Toast({
context: this,
selector: '#t-toast',
message: '数据保存失败,请重试',
});
}
},
onGotoHome() {
wx.switchTab({ url: '/pages/home/home' });
},
// 下拉刷新相关方法
onRefresh() {
console.log('开始下拉刷新');
this.setData({
refresherTriggered: true,
});
// 重新获取购物车数据
this.refreshData();
// 模拟网络请求延迟,确保用户能看到刷新动画
setTimeout(() => {
this.setData({
refresherTriggered: false,
});
// 显示刷新成功提示
Toast({
context: this,
selector: '#t-toast',
message: '刷新成功',
theme: 'success',
duration: 1500,
});
}, 1000);
},
onRefresherPulling(e) {
console.log('下拉中', e.detail);
},
onRefresherRestore(e) {
console.log('刷新恢复', e.detail);
},
onRefresherAbort(e) {
console.log('刷新中止', e.detail);
this.setData({
refresherTriggered: false,
});
},
// 分享功能
onShareAppMessage() {
return {
title: '购物车 - 查看我的心仪好物',
path: '/pages/cart/index'
};
},
// 分享到朋友圈
onShareTimeline() {
return {
title: '购物车 - 查看我的心仪好物'
};
}
});