1155 lines
39 KiB
JavaScript
1155 lines
39 KiB
JavaScript
import Toast from 'tdesign-miniprogram/toast/index';
|
||
import { fetchSettleDetail } from '../../../services/order/orderConfirm';
|
||
import { commitPay, wechatPayOrder } from './pay';
|
||
import { getAddressPromise } from '../../../services/address/list';
|
||
import { fetchDeliveryAddress, parseAddressRegion } from '../../../services/address/fetchAddress';
|
||
|
||
// 保留错误日志工具
|
||
const logger = {
|
||
error: (module, message, data = {}) => {
|
||
console.error(`[ERROR][${module}] ${message}`, data);
|
||
}
|
||
};
|
||
|
||
const stripeImg = `https://tdesign.gtimg.com/miniprogram/template/retail/order/stripe.png`;
|
||
|
||
Page({
|
||
data: {
|
||
placeholder: '备注信息',
|
||
stripeImg,
|
||
loading: false,
|
||
payLock: false,
|
||
settleDetailData: {
|
||
storeGoodsList: [], //正常下单商品列表
|
||
outOfStockGoodsList: [], //库存不足商品
|
||
abnormalDeliveryGoodsList: [], // 不能正常配送商品
|
||
inValidGoodsList: [], // 失效或者库存不足
|
||
limitGoodsList: [], //限购商品
|
||
couponList: [], //门店优惠券信息
|
||
}, // 获取结算页详情 data
|
||
orderCardList: [], // 仅用于商品卡片展示
|
||
couponsShow: false, // 显示优惠券的弹框
|
||
invoiceData: {
|
||
email: '', // 发票发送邮箱
|
||
buyerTaxNo: '', // 税号
|
||
invoiceType: null, // 开票类型 1:增值税专用发票; 2:增值税普通发票; 3:增值税电子发票;4:增值税卷式发票;5:区块链电子发票。
|
||
buyerPhone: '', //手机号
|
||
buyerName: '', //个人或公司名称
|
||
titleType: '', // 发票抬头 1-公司 2-个人
|
||
contentType: '', //发票内容 1-明细 2-类别
|
||
},
|
||
goodsRequestList: [],
|
||
userAddressReq: null,
|
||
popupShow: false, // 不在配送范围 失效 库存不足 商品展示弹框
|
||
notesPosition: 'center',
|
||
storeInfoList: [],
|
||
storeNoteIndex: 0, //当前填写备注门店index
|
||
promotionGoodsList: [], //当前门店商品列表(优惠券)
|
||
couponList: [], //当前门店所选优惠券
|
||
submitCouponList: [], //所有门店所选优惠券
|
||
currentStoreId: '', //当前优惠券storeId
|
||
userAddress: null,
|
||
},
|
||
|
||
payLock: false,
|
||
noteInfo: [],
|
||
tempNoteInfo: [],
|
||
onLoad(options) {
|
||
this.setData({
|
||
loading: true,
|
||
});
|
||
|
||
// 确保有有效的token
|
||
this.ensureValidToken().then(() => {
|
||
// 如果没有传入地址信息,则自动获取默认地址
|
||
if (!options.userAddressReq) {
|
||
this.loadDefaultAddress(options);
|
||
} else {
|
||
this.handleOptionsParams(options);
|
||
}
|
||
}).catch((error) => {
|
||
logger.error('ORDER_CONFIRM_PAGE', '设置token失败', { error });
|
||
// 即使token设置失败,也继续初始化页面
|
||
if (!options.userAddressReq) {
|
||
this.loadDefaultAddress(options);
|
||
} else {
|
||
this.handleOptionsParams(options);
|
||
}
|
||
});
|
||
},
|
||
|
||
// 确保有有效的token
|
||
ensureValidToken() {
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
const existingToken = wx.getStorageSync('token');
|
||
if (existingToken) {
|
||
resolve();
|
||
return;
|
||
}
|
||
|
||
// 如果没有token,设置一个测试用的有效token
|
||
const testToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX3R5cGUiOiJ1c2VyIiwiaXNzIjoiZGlhbnNoYW5nIiwiZXhwIjoxNzYwMDcyNDk2LCJuYmYiOjE3NjAwNjUyOTYsImlhdCI6MTc2MDA2NTI5Nn0.mnpIlCY-wUMgaEwNMOqGPKFFWWQKuobQhPk0AQGUKd0';
|
||
|
||
wx.setStorageSync('token', testToken);
|
||
resolve();
|
||
} catch (error) {
|
||
logger.error('ORDER_CONFIRM_PAGE', '设置token时出错', { error });
|
||
reject(error);
|
||
}
|
||
});
|
||
},
|
||
onShow() {
|
||
const invoiceData = wx.getStorageSync('invoiceData');
|
||
if (invoiceData) {
|
||
//处理发票
|
||
this.invoiceData = invoiceData;
|
||
this.setData({
|
||
invoiceData,
|
||
});
|
||
wx.removeStorageSync('invoiceData');
|
||
}
|
||
|
||
// 检查是否有地址选择返回的数据
|
||
const selectedAddress = wx.getStorageSync('selectedAddress');
|
||
if (selectedAddress) {
|
||
// 使用解析函数处理地址数据,确保包含完整的区域信息
|
||
const parsedAddress = parseAddressRegion(selectedAddress);
|
||
|
||
// 清除存储的地址数据
|
||
wx.removeStorageSync('selectedAddress');
|
||
|
||
// 设置地址数据到页面状态 - 修复:同时设置userAddress和userAddressReq
|
||
this.setData({
|
||
userAddress: parsedAddress,
|
||
userAddressReq: { ...parsedAddress, checked: true }
|
||
});
|
||
|
||
// 使用新选择的地址重新获取结算数据
|
||
this.handleOptionsParams({
|
||
userAddressReq: { ...parsedAddress, checked: true },
|
||
});
|
||
}
|
||
|
||
// 检查是否从优惠券中心返回,如果是则刷新优惠券数据
|
||
const shouldRefreshCoupons = wx.getStorageSync('shouldRefreshCoupons');
|
||
if (shouldRefreshCoupons) {
|
||
// 清除标识
|
||
wx.removeStorageSync('shouldRefreshCoupons');
|
||
|
||
// 重新获取结算数据以刷新优惠券列表
|
||
if (this.goodsRequestList && this.goodsRequestList.length > 0) {
|
||
this.handleOptionsParams({
|
||
goodsRequestList: this.goodsRequestList,
|
||
userAddressReq: this.userAddressReq
|
||
});
|
||
}
|
||
}
|
||
},
|
||
|
||
init() {
|
||
this.setData({
|
||
loading: true,
|
||
});
|
||
const { goodsRequestList } = this;
|
||
this.handleOptionsParams({ goodsRequestList });
|
||
},
|
||
|
||
// 加载默认地址
|
||
loadDefaultAddress(options) {
|
||
fetchDeliveryAddress()
|
||
.then((defaultAddress) => {
|
||
if (defaultAddress) {
|
||
// 使用解析函数处理地址数据,确保包含完整的区域信息
|
||
const parsedAddress = parseAddressRegion(defaultAddress);
|
||
|
||
// 将解析后的地址转换为订单确认页面需要的格式
|
||
const userAddressReq = {
|
||
...parsedAddress,
|
||
checked: true
|
||
};
|
||
|
||
// 设置地址数据到页面状态
|
||
this.setData({
|
||
userAddressReq: userAddressReq,
|
||
userAddress: parsedAddress
|
||
});
|
||
|
||
// 使用默认地址初始化页面
|
||
const optionsWithAddress = {
|
||
...options,
|
||
userAddressReq
|
||
};
|
||
|
||
this.handleOptionsParams(optionsWithAddress);
|
||
} else {
|
||
this.handleOptionsParams(options);
|
||
}
|
||
})
|
||
.catch((error) => {
|
||
logger.error('ORDER_CONFIRM_PAGE', '获取默认地址失败', { error });
|
||
// 获取默认地址失败时,继续正常初始化
|
||
this.handleOptionsParams(options);
|
||
});
|
||
},
|
||
// 处理不同情况下跳转到结算页时需要的参数
|
||
handleOptionsParams(options, couponList) {
|
||
let { goodsRequestList } = this; // 商品列表
|
||
let { userAddressReq } = this; // 收货地址
|
||
|
||
const storeInfoList = []; // 门店列表
|
||
|
||
// 处理地址信息
|
||
if (options.userAddressReq) {
|
||
userAddressReq = options.userAddressReq;
|
||
// 设置地址数据到页面状态
|
||
this.setData({
|
||
userAddress: options.userAddressReq
|
||
});
|
||
}
|
||
|
||
if (options.type === 'cart') {
|
||
// 从购物车获取商品列表
|
||
const goodsRequestListJson = wx.getStorageSync('order.goodsRequestList');
|
||
goodsRequestList = JSON.parse(goodsRequestListJson);
|
||
} else if (typeof options.goodsRequestList === 'string') {
|
||
const raw = options.goodsRequestList;
|
||
try {
|
||
goodsRequestList = JSON.parse(raw);
|
||
} catch (e) {
|
||
try {
|
||
goodsRequestList = JSON.parse(decodeURIComponent(raw));
|
||
} catch (err) {
|
||
logger.error('ORDER_CONFIRM_PAGE', '解析商品列表失败', { error: err, raw });
|
||
goodsRequestList = [];
|
||
}
|
||
}
|
||
}
|
||
|
||
//获取结算页请求数据列表
|
||
const storeMap = {};
|
||
goodsRequestList.forEach((goods) => {
|
||
if (!storeMap[goods.storeId]) {
|
||
storeInfoList.push({
|
||
storeId: goods.storeId,
|
||
storeName: goods.storeName,
|
||
});
|
||
storeMap[goods.storeId] = true;
|
||
}
|
||
});
|
||
|
||
this.goodsRequestList = goodsRequestList;
|
||
this.storeInfoList = storeInfoList;
|
||
|
||
// 添加调试日志,查看接收到的商品数据
|
||
console.log('=== 订单确认页面接收到的商品数据 ===');
|
||
console.log('goodsRequestList:', JSON.stringify(goodsRequestList, null, 2));
|
||
goodsRequestList.forEach((item, index) => {
|
||
console.log(`商品 ${index + 1}:`, {
|
||
spuId: item.spuId,
|
||
skuId: item.skuId,
|
||
title: item.title,
|
||
specInfo: item.specInfo,
|
||
price: item.price,
|
||
quantity: item.quantity
|
||
});
|
||
});
|
||
|
||
const params = {
|
||
goodsRequestList,
|
||
storeInfoList,
|
||
userAddressReq,
|
||
couponList,
|
||
};
|
||
|
||
fetchSettleDetail(params).then(
|
||
(res) => {
|
||
this.setData({
|
||
loading: false,
|
||
});
|
||
this.initData(res.data);
|
||
},
|
||
(error) => {
|
||
logger.error('ORDER_CONFIRM_PAGE', '结算接口调用失败', {
|
||
error: error.message || error,
|
||
params,
|
||
stack: error.stack
|
||
});
|
||
//接口异常处理
|
||
this.handleError();
|
||
},
|
||
);
|
||
},
|
||
|
||
initData(resData) {
|
||
logger.error('order-confirm', 'initData called with:', resData);
|
||
logger.error('order-confirm', 'settleType:', resData.settleType);
|
||
|
||
// 为可能缺失的字段提供默认值
|
||
const data = {
|
||
...resData,
|
||
storeGoodsList: resData.storeGoodsList || [],
|
||
limitGoodsList: resData.limitGoodsList || [],
|
||
abnormalDeliveryGoodsList: resData.abnormalDeliveryGoodsList || [],
|
||
inValidGoodsList: resData.inValidGoodsList || [],
|
||
outOfStockGoodsList: resData.outOfStockGoodsList || [],
|
||
couponList: resData.couponList || [],
|
||
deliveryFeeList: resData.deliveryFeeList || [],
|
||
invoiceRequest: resData.invoiceRequest || null,
|
||
invoiceSupport: resData.invoiceSupport || 0
|
||
};
|
||
|
||
logger.error('order-confirm', 'storeGoodsList length:', data.storeGoodsList.length);
|
||
logger.error('order-confirm', 'limitGoodsList length:', data.limitGoodsList.length);
|
||
logger.error('order-confirm', 'abnormalDeliveryGoodsList length:', data.abnormalDeliveryGoodsList.length);
|
||
logger.error('order-confirm', 'inValidGoodsList length:', data.inValidGoodsList.length);
|
||
|
||
const isInvalid = this.isInvalidOrder(data);
|
||
logger.error('order-confirm', 'isInvalidOrder result:', isInvalid);
|
||
|
||
if (isInvalid) {
|
||
logger.error('order-confirm', 'Order is invalid, calling handleError');
|
||
this.handleError();
|
||
return;
|
||
}
|
||
|
||
// 处理用户地址信息
|
||
if (data.userAddress) {
|
||
const userAddress = data.userAddress;
|
||
|
||
// 解析地址区域信息
|
||
const addressRegion = parseAddressRegion(userAddress);
|
||
|
||
// 设置用户地址到页面data
|
||
this.setData({
|
||
userAddress: {
|
||
...userAddress,
|
||
...addressRegion
|
||
}
|
||
});
|
||
|
||
logger.error('order-confirm', 'User address set:', {
|
||
...userAddress,
|
||
...addressRegion
|
||
});
|
||
} else {
|
||
logger.error('order-confirm', 'No user address in response');
|
||
}
|
||
|
||
// 处理商品数据,生成商品卡片列表
|
||
this.handleResToGoodsCard(data);
|
||
|
||
// 设置结算详情数据
|
||
this.setData({
|
||
settleDetailData: data,
|
||
});
|
||
|
||
logger.error('order-confirm', 'initData completed successfully');
|
||
},
|
||
|
||
isInvalidOrder(data) {
|
||
console.log('[isInvalidOrder] 开始检查订单有效性', data);
|
||
|
||
// 失效 不在配送范围 限购的商品 提示弹窗
|
||
console.log('[isInvalidOrder] 检查商品状态:');
|
||
console.log('[isInvalidOrder] - limitGoodsList:', data.limitGoodsList);
|
||
console.log('[isInvalidOrder] - abnormalDeliveryGoodsList:', data.abnormalDeliveryGoodsList);
|
||
console.log('[isInvalidOrder] - inValidGoodsList:', data.inValidGoodsList);
|
||
|
||
// 修复:正确处理undefined和null值,只有当数组存在且长度大于0时才认为有问题商品
|
||
const hasLimitGoods = Array.isArray(data.limitGoodsList) && data.limitGoodsList.length > 0;
|
||
const hasAbnormalDeliveryGoods = Array.isArray(data.abnormalDeliveryGoodsList) && data.abnormalDeliveryGoodsList.length > 0;
|
||
const hasInValidGoods = Array.isArray(data.inValidGoodsList) && data.inValidGoodsList.length > 0;
|
||
|
||
console.log('[isInvalidOrder] 问题商品检查结果:');
|
||
console.log('- hasLimitGoods:', hasLimitGoods);
|
||
console.log('- hasAbnormalDeliveryGoods:', hasAbnormalDeliveryGoods);
|
||
console.log('- hasInValidGoods:', hasInValidGoods);
|
||
|
||
if (hasLimitGoods || hasAbnormalDeliveryGoods || hasInValidGoods) {
|
||
console.log('[isInvalidOrder] 发现问题商品,显示弹窗');
|
||
this.setData({ popupShow: true });
|
||
return true;
|
||
}
|
||
console.log('[isInvalidOrder] 商品状态检查通过');
|
||
this.setData({ popupShow: false });
|
||
|
||
// 检查是否有有效的商品列表
|
||
console.log('[isInvalidOrder] 检查商品列表:', data.storeGoodsList);
|
||
if (!Array.isArray(data.storeGoodsList) || data.storeGoodsList.length === 0) {
|
||
console.log('[isInvalidOrder] 商品列表为空或不存在,订单无效');
|
||
return true;
|
||
}
|
||
console.log('[isInvalidOrder] 商品列表检查通过,商品数量:', data.storeGoodsList.length);
|
||
|
||
// settleType为0只是表示没有地址,不应该视为无效订单
|
||
// 用户可以在订单确认页面选择地址
|
||
console.log('[isInvalidOrder] 订单有效性检查完成,订单有效');
|
||
return false;
|
||
},
|
||
|
||
handleError() {
|
||
this.setData({
|
||
loading: false,
|
||
});
|
||
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '获取订单信息失败,请重试',
|
||
theme: 'error',
|
||
direction: 'column',
|
||
});
|
||
|
||
// 延迟返回上一页,给用户时间看到错误提示
|
||
setTimeout(() => {
|
||
wx.navigateBack({
|
||
delta: 1,
|
||
});
|
||
}, 2000);
|
||
},
|
||
getRequestGoodsList(storeGoodsList) {
|
||
const filterStoreGoodsList = [];
|
||
storeGoodsList &&
|
||
storeGoodsList.forEach((store) => {
|
||
const { storeName } = store;
|
||
store.skuDetailVos &&
|
||
store.skuDetailVos.forEach((goods) => {
|
||
const data = goods;
|
||
data.storeName = storeName;
|
||
filterStoreGoodsList.push(data);
|
||
});
|
||
});
|
||
return filterStoreGoodsList;
|
||
},
|
||
handleGoodsRequest(goods, isOutStock = false) {
|
||
const { reminderStock, quantity, storeId, uid, saasId, spuId, goodsName, skuId, storeName, roomId } = goods;
|
||
const resQuantity = isOutStock ? reminderStock : quantity;
|
||
return {
|
||
quantity: resQuantity,
|
||
storeId,
|
||
uid,
|
||
saasId,
|
||
spuId,
|
||
goodsName,
|
||
skuId,
|
||
storeName,
|
||
roomId,
|
||
};
|
||
},
|
||
handleResToGoodsCard(data) {
|
||
// 数据校验
|
||
if (!data) {
|
||
console.error('结算数据为空:', data);
|
||
wx.showToast({
|
||
title: '获取订单信息失败',
|
||
icon: 'none'
|
||
});
|
||
return data;
|
||
}
|
||
|
||
// 转换数据 符合 goods-card展示
|
||
const orderCardList = []; // 订单卡片列表
|
||
const storeInfoList = [];
|
||
const submitCouponList = []; //使用优惠券列表;
|
||
|
||
// 检查 storeGoodsList 是否存在且为数组
|
||
if (!data.storeGoodsList || !Array.isArray(data.storeGoodsList)) {
|
||
console.error('storeGoodsList 数据异常:', data.storeGoodsList);
|
||
wx.showToast({
|
||
title: '商品信息异常',
|
||
icon: 'none'
|
||
});
|
||
this.setData({ orderCardList, storeInfoList, submitCouponList });
|
||
return data;
|
||
}
|
||
|
||
data.storeGoodsList.forEach((ele) => {
|
||
// 检查店铺数据
|
||
if (!ele || !ele.skuDetailVos || !Array.isArray(ele.skuDetailVos)) {
|
||
console.error('店铺商品数据异常:', ele);
|
||
return;
|
||
}
|
||
|
||
const orderCard = {
|
||
id: ele.storeId || '1000',
|
||
storeName: ele.storeName || '默认店铺',
|
||
status: 0,
|
||
statusDesc: '',
|
||
amount: ele.storeTotalPayAmount || 0,
|
||
goodsList: [],
|
||
}; // 订单卡片
|
||
|
||
ele.skuDetailVos.forEach((item, index) => {
|
||
// 检查商品数据
|
||
if (!item || !item.spuId) {
|
||
console.error('商品数据异常:', item);
|
||
return;
|
||
}
|
||
|
||
orderCard.goodsList.push({
|
||
id: index,
|
||
thumb: item.image || '',
|
||
title: item.goodsName || '商品名称',
|
||
specs: (item.skuSpecLst || []).map((s) => s.specValue || ''), // 规格列表 string[]
|
||
price: item.tagPrice || item.settlePrice || '0', // 优先取限时活动价
|
||
settlePrice: item.settlePrice || 0,
|
||
titlePrefixTags: item.tagText ? [{ text: item.tagText }] : [],
|
||
num: item.quantity || 1,
|
||
skuId: item.skuId || item.spuId,
|
||
spuId: item.spuId,
|
||
storeId: item.storeId || ele.storeId || '1000',
|
||
});
|
||
});
|
||
|
||
if (orderCard.goodsList.length > 0) {
|
||
storeInfoList.push({
|
||
storeId: ele.storeId || '1000',
|
||
storeName: ele.storeName || '默认店铺',
|
||
remark: '',
|
||
});
|
||
submitCouponList.push({
|
||
storeId: ele.storeId || '1000',
|
||
couponList: ele.couponList || [],
|
||
});
|
||
this.noteInfo.push('');
|
||
this.tempNoteInfo.push('');
|
||
orderCardList.push(orderCard);
|
||
}
|
||
});
|
||
|
||
this.setData({ orderCardList, storeInfoList, submitCouponList });
|
||
return data;
|
||
},
|
||
onGotoAddress() {
|
||
getAddressPromise()
|
||
.then((address) => {
|
||
// 地址选择成功处理
|
||
})
|
||
.catch((error) => {
|
||
// 地址选择失败处理
|
||
});
|
||
|
||
const { userAddressReq } = this; // 收货地址
|
||
|
||
let id = '';
|
||
|
||
if (userAddressReq?.id) {
|
||
id = `&id=${userAddressReq.id}`;
|
||
}
|
||
|
||
const addressUrl = `/pages/user/address/list/index?selectMode=1&isOrderSure=1${id}`;
|
||
|
||
wx.navigateTo({
|
||
url: addressUrl,
|
||
});
|
||
},
|
||
onNotes(e) {
|
||
const { storenoteindex: storeNoteIndex } = e.currentTarget.dataset;
|
||
// 添加备注信息
|
||
this.setData({
|
||
dialogShow: true,
|
||
storeNoteIndex,
|
||
});
|
||
},
|
||
onInput(e) {
|
||
const { storeNoteIndex } = this.data;
|
||
this.noteInfo[storeNoteIndex] = e.detail.value;
|
||
},
|
||
onBlur() {
|
||
this.setData({
|
||
notesPosition: 'center',
|
||
});
|
||
},
|
||
onFocus() {
|
||
this.setData({
|
||
notesPosition: 'self',
|
||
});
|
||
},
|
||
onTap() {
|
||
this.setData({
|
||
placeholder: '',
|
||
});
|
||
},
|
||
onNoteConfirm() {
|
||
// 备注信息 确认按钮
|
||
const { storeInfoList, storeNoteIndex } = this.data;
|
||
if (storeInfoList && storeInfoList[storeNoteIndex]) {
|
||
this.tempNoteInfo[storeNoteIndex] = this.noteInfo[storeNoteIndex];
|
||
storeInfoList[storeNoteIndex].remark = this.noteInfo[storeNoteIndex];
|
||
}
|
||
|
||
this.setData({
|
||
dialogShow: false,
|
||
storeInfoList,
|
||
});
|
||
},
|
||
onNoteCancel() {
|
||
// 备注信息 取消按钮
|
||
const { storeNoteIndex } = this.data;
|
||
this.noteInfo[storeNoteIndex] = this.tempNoteInfo[storeNoteIndex];
|
||
this.setData({
|
||
dialogShow: false,
|
||
});
|
||
},
|
||
|
||
onSureCommit() {
|
||
// 商品库存不足继续结算
|
||
const { settleDetailData } = this.data;
|
||
const { outOfStockGoodsList, storeGoodsList, inValidGoodsList } = settleDetailData;
|
||
if ((outOfStockGoodsList && outOfStockGoodsList.length > 0) || (inValidGoodsList && storeGoodsList)) {
|
||
// 合并正常商品 和 库存 不足商品继续支付
|
||
// 过滤不必要的参数
|
||
const filterOutGoodsList = [];
|
||
outOfStockGoodsList &&
|
||
outOfStockGoodsList.forEach((outOfStockGoods) => {
|
||
const { storeName } = outOfStockGoods;
|
||
outOfStockGoods.unSettlementGoods.forEach((ele) => {
|
||
const data = ele;
|
||
data.quantity = ele.reminderStock;
|
||
data.storeName = storeName;
|
||
filterOutGoodsList.push(data);
|
||
});
|
||
});
|
||
const filterStoreGoodsList = this.getRequestGoodsList(storeGoodsList);
|
||
const goodsRequestList = filterOutGoodsList.concat(filterStoreGoodsList);
|
||
this.handleOptionsParams({ goodsRequestList });
|
||
}
|
||
},
|
||
// 提交订单
|
||
submitOrder() {
|
||
console.log('=== 订单提交开始 ===');
|
||
console.log('submitOrder函数被调用,时间:', new Date().toLocaleString());
|
||
|
||
const { settleDetailData, userAddressReq, invoiceData, storeInfoList, submitCouponList } = this.data;
|
||
const { goodsRequestList } = this;
|
||
|
||
// 详细日志:检查关键数据
|
||
console.log('订单提交数据检查:');
|
||
console.log('- settleDetailData:', settleDetailData);
|
||
console.log('- userAddressReq:', userAddressReq);
|
||
console.log('- goodsRequestList:', goodsRequestList);
|
||
console.log('- storeInfoList:', storeInfoList);
|
||
console.log('- submitCouponList:', submitCouponList);
|
||
console.log('- invoiceData:', invoiceData);
|
||
|
||
// 检查收货地址
|
||
if (!userAddressReq && !settleDetailData.userAddress) {
|
||
console.log('❌ 订单提交失败:缺少收货地址');
|
||
console.log('- userAddressReq:', userAddressReq);
|
||
console.log('- settleDetailData.userAddress:', settleDetailData.userAddress);
|
||
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '请添加收货地址',
|
||
duration: 2000,
|
||
icon: 'help-circle',
|
||
});
|
||
|
||
return;
|
||
}
|
||
console.log('✅ 收货地址检查通过');
|
||
|
||
// 检查支付锁和必要参数
|
||
console.log('支付锁和参数检查:');
|
||
console.log('- payLock:', this.data.payLock);
|
||
console.log('- totalAmount:', settleDetailData.totalAmount);
|
||
|
||
if (this.data.payLock || !settleDetailData.totalAmount) {
|
||
if (this.data.payLock) {
|
||
console.log('❌ 订单提交失败:支付锁已激活,防止重复提交');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '订单正在提交中,请勿重复点击',
|
||
duration: 1500,
|
||
icon: 'loading',
|
||
});
|
||
} else if (!settleDetailData.totalAmount) {
|
||
console.log('❌ 订单提交失败:缺少totalAmount');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '订单金额异常,请重试',
|
||
duration: 2000,
|
||
icon: 'error',
|
||
});
|
||
}
|
||
return;
|
||
}
|
||
console.log('✅ 支付锁和参数检查通过');
|
||
|
||
console.log('🔒 开始提交订单,设置提交锁');
|
||
this.setData({ payLock: true });
|
||
this.payLock = true;
|
||
|
||
console.log('📦 构建订单提交参数...');
|
||
console.log('🎫 优惠券数据调试:');
|
||
console.log('- 原始submitCouponList:', submitCouponList);
|
||
console.log('- 原始submitCouponList类型:', typeof submitCouponList);
|
||
console.log('- 原始submitCouponList是否为数组:', Array.isArray(submitCouponList));
|
||
|
||
const resSubmitCouponList = this.handleCouponList(submitCouponList);
|
||
|
||
console.log('=== resSubmitCouponList 详细打印 ===');
|
||
console.log('- resSubmitCouponList:', resSubmitCouponList);
|
||
console.log('- resSubmitCouponList类型:', typeof resSubmitCouponList);
|
||
console.log('- resSubmitCouponList是否为数组:', Array.isArray(resSubmitCouponList));
|
||
console.log('- resSubmitCouponList长度:', resSubmitCouponList ? resSubmitCouponList.length : 'null/undefined');
|
||
console.log('- resSubmitCouponList JSON字符串:', JSON.stringify(resSubmitCouponList, null, 2));
|
||
|
||
if (resSubmitCouponList && resSubmitCouponList.length > 0) {
|
||
console.log('=== 优惠券列表详情 ===');
|
||
resSubmitCouponList.forEach((coupon, index) => {
|
||
console.log(`- 优惠券[${index}]:`, coupon);
|
||
console.log(`- 优惠券[${index}] ID字段:`, {
|
||
id: coupon.id,
|
||
couponId: coupon.couponId,
|
||
userCouponId: coupon.userCouponId,
|
||
storeId: coupon.storeId,
|
||
name: coupon.name,
|
||
type: coupon.type
|
||
});
|
||
});
|
||
console.log('- 第一张优惠券的userCouponId:', resSubmitCouponList[0].userCouponId);
|
||
console.log('- 第一张优惠券的userCouponId类型:', typeof resSubmitCouponList[0].userCouponId);
|
||
} else {
|
||
console.log('=== 无优惠券选择 ===');
|
||
console.log('- resSubmitCouponList为空或长度为0');
|
||
}
|
||
|
||
// 调试用户地址信息
|
||
console.log('🏠 用户地址信息检查:');
|
||
console.log('- settleDetailData.userAddress:', settleDetailData.userAddress);
|
||
console.log('- userAddressReq:', userAddressReq);
|
||
|
||
const finalUserAddress = settleDetailData.userAddress || userAddressReq;
|
||
const finalUserName = (settleDetailData.userAddress && settleDetailData.userAddress.name) || (userAddressReq && userAddressReq.name);
|
||
|
||
console.log('- 最终使用的地址:', finalUserAddress);
|
||
console.log('- 最终使用的用户名:', finalUserName);
|
||
|
||
const params = {
|
||
userAddressReq: finalUserAddress,
|
||
goodsRequestList: goodsRequestList,
|
||
userName: finalUserName,
|
||
totalAmount: settleDetailData.totalPayAmount, //取优惠后的结算金额
|
||
invoiceRequest: null,
|
||
storeInfoList,
|
||
couponList: resSubmitCouponList,
|
||
};
|
||
|
||
if (invoiceData && invoiceData.email) {
|
||
console.log('📄 添加发票信息:', invoiceData);
|
||
params.invoiceRequest = invoiceData;
|
||
}
|
||
|
||
console.log('📋 最终提交参数:', params);
|
||
console.log('🚀 开始调用commitPay API...');
|
||
|
||
commitPay(params).then(
|
||
(res) => {
|
||
console.log('✅ commitPay API调用成功');
|
||
console.log('📥 API响应数据:', res);
|
||
console.log('- 响应码:', res.code);
|
||
console.log('- 响应消息:', res.msg);
|
||
console.log('- 响应数据:', res.data);
|
||
|
||
const { data } = res;
|
||
|
||
// 注意:commitPay API响应的data结构与fetchSettleDetail不同
|
||
// 此时订单已经提交成功,不需要再次验证订单有效性
|
||
console.log('✅ 订单已提交成功,跳过有效性检查');
|
||
|
||
if (res.code === 'Success') {
|
||
console.log('🎉 订单提交成功,开始处理支付');
|
||
console.log('- 支付数据:', data);
|
||
console.log('- 结算数据:', settleDetailData);
|
||
// 注意:这里不释放锁,在支付完成后才释放
|
||
this.handlePay(data, settleDetailData);
|
||
} else {
|
||
console.log('❌ 订单提交失败,响应码不是Success');
|
||
console.log('- 实际响应码:', res.code);
|
||
console.log('- 错误消息:', res.msg);
|
||
console.log('🔓 释放提交锁');
|
||
this.setData({ payLock: false });
|
||
this.payLock = false;
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: res.msg || '提交订单超时,请稍后重试',
|
||
duration: 2000,
|
||
icon: 'error-circle',
|
||
});
|
||
setTimeout(() => {
|
||
console.log('⬅️ 返回购物车');
|
||
// 提交支付失败 返回购物车
|
||
wx.navigateBack();
|
||
}, 2000);
|
||
}
|
||
},
|
||
(err) => {
|
||
console.log('💥 commitPay API调用失败');
|
||
console.error('❌ 订单提交异常,释放提交锁', err);
|
||
console.log('- 错误类型:', typeof err);
|
||
console.log('- 错误码:', err.code);
|
||
console.log('- 错误消息:', err.msg);
|
||
console.log('- 完整错误对象:', err);
|
||
|
||
console.log('🔓 释放提交锁');
|
||
this.setData({ payLock: false });
|
||
this.payLock = false;
|
||
|
||
if (err.code === 'CONTAINS_INSUFFICIENT_GOODS' || err.code === 'TOTAL_AMOUNT_DIFFERENT') {
|
||
console.log('🛒 处理库存不足或金额不匹配错误');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: err.msg || '支付异常',
|
||
duration: 2000,
|
||
icon: 'error-circle',
|
||
});
|
||
console.log('🔄 重新初始化页面数据');
|
||
this.init();
|
||
} else if (err.code === 'ORDER_PAY_FAIL') {
|
||
console.log('💳 处理支付失败错误');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '支付失败',
|
||
duration: 2000,
|
||
icon: 'close-circle',
|
||
});
|
||
setTimeout(() => {
|
||
console.log('📱 跳转到订单列表页面');
|
||
wx.redirectTo({ url: '/pages/order/order-list/index' });
|
||
});
|
||
} else if (err.code === 'ILLEGAL_CONFIG_PARAM') {
|
||
console.log('⚙️ 处理微信支付配置错误');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '支付失败,微信支付商户号设置有误,请商家重新检查支付设置。',
|
||
duration: 2000,
|
||
icon: 'close-circle',
|
||
});
|
||
setTimeout(() => {
|
||
console.log('📱 跳转到订单列表页面');
|
||
wx.redirectTo({ url: '/pages/order/order-list/index' });
|
||
});
|
||
} else {
|
||
console.log('🔄 处理其他类型错误');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: err.msg || '提交支付超时,请稍后重试',
|
||
duration: 2000,
|
||
icon: 'error-circle',
|
||
});
|
||
setTimeout(() => {
|
||
console.log('⬅️ 返回购物车');
|
||
// 提交支付失败 返回购物车
|
||
wx.navigateBack();
|
||
}, 2000);
|
||
}
|
||
},
|
||
);
|
||
},
|
||
|
||
// 处理支付
|
||
handlePay(data, settleDetailData) {
|
||
console.log('💳 [handlePay] 开始处理支付流程');
|
||
console.log('[handlePay] 支付数据:', data);
|
||
console.log('[handlePay] 结算数据:', settleDetailData);
|
||
|
||
const { channel, payInfo, tradeNo, interactId, transactionId } = data;
|
||
const { totalAmount, totalPayAmount } = settleDetailData;
|
||
|
||
console.log('[handlePay] 解析支付参数:');
|
||
console.log('- channel:', channel);
|
||
console.log('- payInfo:', payInfo);
|
||
console.log('- tradeNo:', tradeNo);
|
||
console.log('- interactId:', interactId);
|
||
console.log('- transactionId:', transactionId);
|
||
console.log('- totalAmount:', totalAmount);
|
||
console.log('- totalPayAmount:', totalPayAmount);
|
||
|
||
const payOrderInfo = {
|
||
payInfo: payInfo,
|
||
orderId: tradeNo,
|
||
orderAmt: totalAmount,
|
||
payAmt: totalPayAmount,
|
||
interactId: interactId,
|
||
tradeNo: tradeNo,
|
||
transactionId: transactionId,
|
||
};
|
||
|
||
console.log('[handlePay] 构建支付订单信息:', payOrderInfo);
|
||
|
||
if (channel === 'wechat') {
|
||
console.log('🎯 [handlePay] 使用微信支付渠道');
|
||
console.log('[handlePay] 调用wechatPayOrder函数...');
|
||
|
||
// 传递页面上下文给支付函数
|
||
wechatPayOrder(payOrderInfo, this).then(() => {
|
||
console.log('✅ [handlePay] 微信支付流程完成');
|
||
console.log('🔓 [handlePay] 支付成功,释放支付锁');
|
||
// 支付成功后释放锁
|
||
this.setData({ payLock: false });
|
||
this.payLock = false;
|
||
}).catch((error) => {
|
||
console.error('❌ [handlePay] 微信支付流程失败:', error);
|
||
console.log('- 错误类型:', typeof error);
|
||
console.log('- 错误消息:', error.message || error);
|
||
console.log('- 完整错误对象:', error);
|
||
|
||
console.log('🔓 [handlePay] 支付失败,释放支付锁');
|
||
// 支付失败时释放锁
|
||
this.setData({ payLock: false });
|
||
this.payLock = false;
|
||
|
||
console.log('📱 [handlePay] 显示支付失败提示');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '支付失败,请重试',
|
||
duration: 2000,
|
||
icon: 'close-circle',
|
||
});
|
||
});
|
||
} else {
|
||
console.warn('⚠️ [handlePay] 不支持的支付渠道:', channel);
|
||
console.log('🔓 [handlePay] 不支持的支付方式,释放支付锁');
|
||
// 不支持的支付方式时释放锁
|
||
this.setData({ payLock: false });
|
||
this.payLock = false;
|
||
|
||
console.log('📱 [handlePay] 显示不支持支付方式提示');
|
||
Toast({
|
||
context: this,
|
||
selector: '#t-toast',
|
||
message: '不支持的支付方式',
|
||
duration: 2000,
|
||
icon: 'close-circle',
|
||
});
|
||
}
|
||
},
|
||
|
||
hide() {
|
||
// 隐藏 popup
|
||
this.setData({
|
||
'settleDetailData.abnormalDeliveryGoodsList': [],
|
||
});
|
||
},
|
||
onReceipt() {
|
||
// 跳转 开发票
|
||
const invoiceData = this.invoiceData || {};
|
||
wx.navigateTo({
|
||
url: `/pages/order/receipt/index?invoiceData=${JSON.stringify(invoiceData)}`,
|
||
});
|
||
},
|
||
|
||
onCoupons(e) {
|
||
const { submitCouponList, currentStoreId } = this.data;
|
||
const { goodsRequestList } = this;
|
||
const { selectedList } = e.detail;
|
||
|
||
console.log('=== 优惠券选择事件详细调试 ===');
|
||
console.log('selectedList:', selectedList);
|
||
console.log('selectedList JSON:', JSON.stringify(selectedList, null, 2));
|
||
console.log('selectedList 数据结构:', selectedList.map(item => ({
|
||
id: item.id,
|
||
userCouponId: item.userCouponId,
|
||
couponId: item.couponId,
|
||
key: item.key,
|
||
storeId: item.storeId,
|
||
allFields: Object.keys(item),
|
||
fullItem: item
|
||
})));
|
||
console.log('currentStoreId:', currentStoreId);
|
||
console.log('submitCouponList:', submitCouponList);
|
||
|
||
// 检查selectedList中每个优惠券的关键字段
|
||
selectedList.forEach((item, index) => {
|
||
console.log(`=== 优惠券 ${index + 1} 详细字段检查 ===`);
|
||
console.log(`- id: ${item.id} (类型: ${typeof item.id})`);
|
||
console.log(`- userCouponId: ${item.userCouponId} (类型: ${typeof item.userCouponId})`);
|
||
console.log(`- couponId: ${item.couponId} (类型: ${typeof item.couponId})`);
|
||
console.log(`- key: ${item.key} (类型: ${typeof item.key})`);
|
||
console.log(`- storeId: ${item.storeId} (类型: ${typeof item.storeId})`);
|
||
console.log(`- 是否有userCouponId字段: ${item.hasOwnProperty('userCouponId')}`);
|
||
console.log(`- userCouponId是否为null/undefined: ${item.userCouponId == null}`);
|
||
});
|
||
|
||
// 更新选中的优惠券列表
|
||
console.log('=== 构建tempSubmitCouponList ===');
|
||
const tempSubmitCouponList = submitCouponList.map((storeCoupon) => {
|
||
const isCurrentStore = storeCoupon.storeId === currentStoreId;
|
||
const couponList = isCurrentStore ? selectedList : storeCoupon.couponList;
|
||
|
||
console.log(`店铺 ${storeCoupon.storeId}:`, {
|
||
isCurrentStore,
|
||
originalCouponList: storeCoupon.couponList,
|
||
newCouponList: couponList,
|
||
couponListLength: couponList ? couponList.length : 0
|
||
});
|
||
|
||
if (isCurrentStore && couponList) {
|
||
console.log('当前店铺的优惠券详情:', couponList.map(item => ({
|
||
id: item.id,
|
||
userCouponId: item.userCouponId,
|
||
couponId: item.couponId,
|
||
hasUserCouponId: item.hasOwnProperty('userCouponId'),
|
||
userCouponIdValue: item.userCouponId
|
||
})));
|
||
}
|
||
|
||
return {
|
||
storeId: storeCoupon.storeId,
|
||
couponList: couponList,
|
||
};
|
||
});
|
||
|
||
console.log('=== tempSubmitCouponList 构建完成 ===');
|
||
console.log('tempSubmitCouponList:', JSON.stringify(tempSubmitCouponList, null, 2));
|
||
|
||
const resSubmitCouponList = this.handleCouponList(tempSubmitCouponList);
|
||
console.log('=== 处理后的优惠券列表详细调试 ===');
|
||
console.log('resSubmitCouponList:', resSubmitCouponList);
|
||
console.log('resSubmitCouponList 数据结构:', resSubmitCouponList.map(item => ({
|
||
id: item.id,
|
||
userCouponId: item.userCouponId,
|
||
couponId: item.couponId,
|
||
allFields: Object.keys(item)
|
||
})));
|
||
|
||
//确定选择优惠券
|
||
this.handleOptionsParams({ goodsRequestList }, resSubmitCouponList);
|
||
this.setData({
|
||
couponsShow: false,
|
||
submitCouponList: tempSubmitCouponList
|
||
});
|
||
},
|
||
onOpenCoupons(e) {
|
||
const { storeid } = e.currentTarget.dataset;
|
||
const { storeInfoList = [], submitCouponList = [] } = this.data;
|
||
|
||
console.log('onOpenCoupons 调用:', {
|
||
storeid,
|
||
storeInfoListLength: storeInfoList.length,
|
||
submitCouponListLength: submitCouponList.length
|
||
});
|
||
|
||
// 查找当前店铺的商品列表
|
||
const currentStore = storeInfoList.find(store => store.storeId === storeid);
|
||
const promotionGoodsList = (currentStore && currentStore.goodsList) ? currentStore.goodsList : [];
|
||
|
||
// 查找当前店铺的已选优惠券
|
||
const currentStoreCoupons = submitCouponList.find(store => store.storeId === storeid);
|
||
const couponList = (currentStoreCoupons && currentStoreCoupons.couponList) ? currentStoreCoupons.couponList : [];
|
||
|
||
console.log('打开优惠券选择:', {
|
||
storeid,
|
||
currentStore: !!currentStore,
|
||
currentStoreCoupons: !!currentStoreCoupons,
|
||
promotionGoodsListLength: promotionGoodsList.length,
|
||
couponListLength: couponList.length
|
||
});
|
||
|
||
this.setData({
|
||
couponsShow: true,
|
||
currentStoreId: String(storeid || ''),
|
||
promotionGoodsList,
|
||
couponList
|
||
});
|
||
|
||
console.log('setData后的状态:', {
|
||
couponsShow: this.data.couponsShow,
|
||
currentStoreId: this.data.currentStoreId,
|
||
promotionGoodsListLength: this.data.promotionGoodsList.length,
|
||
couponListLength: this.data.couponList.length
|
||
});
|
||
},
|
||
|
||
onCouponsClose() {
|
||
console.log('优惠券弹窗关闭');
|
||
this.setData({
|
||
couponsShow: false
|
||
});
|
||
},
|
||
|
||
handleCouponList(storeCouponList) {
|
||
//处理门店优惠券 转换成接口需要
|
||
console.log('=== handleCouponList 开始处理 ===');
|
||
console.log('输入 storeCouponList:', JSON.stringify(storeCouponList, null, 2));
|
||
|
||
if (!storeCouponList) {
|
||
console.log('storeCouponList 为空,返回空数组');
|
||
return [];
|
||
}
|
||
|
||
const resSubmitCouponList = [];
|
||
storeCouponList.forEach((ele, index) => {
|
||
console.log(`=== 处理店铺 ${index + 1} (ID: ${ele.storeId}) ===`);
|
||
console.log('店铺优惠券列表:', ele.couponList);
|
||
console.log('优惠券数量:', ele.couponList ? ele.couponList.length : 0);
|
||
|
||
if (ele.couponList && ele.couponList.length > 0) {
|
||
ele.couponList.forEach((coupon, couponIndex) => {
|
||
console.log(`店铺 ${ele.storeId} 优惠券 ${couponIndex + 1}:`, {
|
||
id: coupon.id,
|
||
userCouponId: coupon.userCouponId,
|
||
couponId: coupon.couponId,
|
||
key: coupon.key,
|
||
storeId: coupon.storeId,
|
||
hasUserCouponId: coupon.hasOwnProperty('userCouponId'),
|
||
userCouponIdType: typeof coupon.userCouponId,
|
||
allFields: Object.keys(coupon)
|
||
});
|
||
});
|
||
|
||
resSubmitCouponList.push(...ele.couponList);
|
||
} else {
|
||
console.log(`店铺 ${ele.storeId} 没有优惠券`);
|
||
}
|
||
});
|
||
|
||
console.log('=== handleCouponList 处理完成 ===');
|
||
console.log('最终 resSubmitCouponList:', JSON.stringify(resSubmitCouponList, null, 2));
|
||
console.log('最终优惠券数量:', resSubmitCouponList.length);
|
||
|
||
return resSubmitCouponList;
|
||
},
|
||
|
||
onGoodsNumChange(e) {
|
||
const {
|
||
detail: { value },
|
||
currentTarget: {
|
||
dataset: { goods },
|
||
},
|
||
} = e;
|
||
const index = this.goodsRequestList.findIndex(
|
||
({ storeId, spuId, skuId }) => goods.storeId === storeId && goods.spuId === spuId && goods.skuId === skuId,
|
||
);
|
||
if (index >= 0) {
|
||
// eslint-disable-next-line no-confusing-arrow
|
||
const goodsRequestList = this.goodsRequestList.map((item, i) =>
|
||
i === index ? { ...item, quantity: value } : item,
|
||
);
|
||
this.handleOptionsParams({ goodsRequestList });
|
||
}
|
||
},
|
||
|
||
onPopupChange() {
|
||
this.setData({
|
||
popupShow: !this.data.popupShow,
|
||
});
|
||
},
|
||
|
||
handleImageError(e) {
|
||
console.warn('Image load error:', e.detail);
|
||
// 可以在这里设置默认图片或其他错误处理逻辑
|
||
},
|
||
});
|