Files
ai_dianshang/miniprogram/services/order/orderConfirm.js
2025-11-17 14:11:46 +08:00

352 lines
12 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 { config } from '../../config/index';
import { mockIp, mockReqId } from '../../utils/mock';
// 添加日志工具
const logger = {
info: (module, message, data = {}) => {
console.log(`[${module}] ${message}`, data);
},
debug: (module, message, data = {}) => {
console.log(`[DEBUG][${module}] ${message}`, data);
},
error: (module, message, data = {}) => {
console.error(`[ERROR][${module}] ${message}`, data);
},
warn: (module, message, data = {}) => {
console.warn(`[WARN][${module}] ${message}`, data);
}
};
/** 获取结算mock数据 */
function mockFetchSettleDetail(params) {
const { delay } = require('../_utils/delay');
const { genSettleDetail } = require('../../model/order/orderConfirm');
logger.info('ORDER_SETTLE_SERVICE', '使用Mock数据获取结算详情', { params });
return delay().then(() => genSettleDetail(params));
}
/** 提交mock订单 */
function mockDispatchCommitPay() {
const { delay } = require('../_utils/delay');
logger.info('ORDER_SETTLE_SERVICE', '使用Mock数据提交订单');
return delay().then(() => ({
data: {
isSuccess: true,
tradeNo: '350930961469409099',
payInfo: '{}',
code: null,
transactionId: 'E-200915180100299000',
msg: null,
interactId: '15145',
channel: 'wechat',
limitGoodsList: null,
},
code: 'Success',
msg: null,
requestId: mockReqId(),
clientIp: mockIp(),
rt: 891,
success: true,
}));
}
/** 获取结算数据 */
export function fetchSettleDetail(params) {
logger.info('ORDER_SETTLE_SERVICE', '开始获取结算详情', {
useMock: config.useMock,
apiBase: config.apiBase,
params
});
if (config.useMock) {
return mockFetchSettleDetail(params);
}
return new Promise((resolve, reject) => {
const token = wx.getStorageSync('token') || '';
const requestUrl = `${config.apiBase}/orders/settle`;
// 数据类型转换和验证
const processedParams = {
...params,
// 确保userAddressReq中的addressId是数字类型
userAddressReq: params.userAddressReq ? {
...params.userAddressReq,
addressId: params.userAddressReq.addressId ? parseInt(params.userAddressReq.addressId) : undefined
} : null,
// 确保goodsRequestList中的数字字段是正确类型
goodsRequestList: (params.goodsRequestList || []).map(goods => ({
...goods,
quantity: parseInt(goods.quantity) || 0,
price: parseInt(goods.price) || 0,
originPrice: parseInt(goods.originPrice) || 0,
available: parseInt(goods.available) || 0
})),
// 确保couponList中的数字字段是正确类型
couponList: (params.couponList || []).map(coupon => ({
...coupon,
couponId: coupon.couponId ? parseInt(coupon.couponId) : undefined,
userCouponId: coupon.userCouponId ? parseInt(coupon.userCouponId) : undefined,
type: coupon.type ? parseInt(coupon.type) : undefined,
value: coupon.value ? parseInt(coupon.value) : undefined
}))
};
logger.debug('ORDER_SETTLE_SERVICE', '准备发送API请求', {
url: requestUrl,
method: 'POST',
hasToken: !!token,
originalParams: params,
processedParams
});
wx.request({
url: requestUrl,
method: 'POST',
data: processedParams,
header: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
success: (res) => {
logger.info('ORDER_SETTLE_SERVICE', 'API请求成功', {
statusCode: res.statusCode,
data: res.data,
header: res.header
});
if (res.statusCode === 200) {
if (res.data && res.data.code === 200) {
logger.info('ORDER_SETTLE_SERVICE', '结算数据获取成功', { data: res.data.data });
resolve(res.data);
} else {
const errorMsg = res.data?.message || res.data?.msg || '结算失败';
logger.error('ORDER_SETTLE_SERVICE', 'API返回错误', {
code: res.data?.code,
message: errorMsg,
fullResponse: res.data
});
reject(new Error(errorMsg));
}
} else {
logger.error('ORDER_SETTLE_SERVICE', 'HTTP状态码错误', {
statusCode: res.statusCode,
data: res.data
});
reject(new Error(`HTTP ${res.statusCode}: ${res.data?.message || '请求失败'}`));
}
},
fail: (err) => {
logger.error('ORDER_SETTLE_SERVICE', '网络请求失败', {
error: err,
url: requestUrl,
originalParams: params,
processedParams
});
reject(new Error('网络请求失败: ' + (err.errMsg || '未知错误')));
}
});
});
}
/* 提交订单 */
export function dispatchCommitPay(params) {
logger.info('ORDER_SETTLE_SERVICE', '开始提交订单', {
useMock: config.useMock,
params
});
if (config.useMock) {
return mockDispatchCommitPay(params);
}
return new Promise((resolve, reject) => {
// 转换前端参数为后端期望的格式
const addressId = params.addressId ||
(params.userAddressReq && params.userAddressReq.addressId) ||
(params.userAddressReq && params.userAddressReq.id);
logger.debug('ORDER_SETTLE_SERVICE', '地址ID提取调试', {
'params.addressId': params.addressId,
'params.userAddressReq': params.userAddressReq,
'userAddressReq.addressId': params.userAddressReq?.addressId,
'userAddressReq.id': params.userAddressReq?.id,
'extractedAddressId': addressId,
'addressIdType': typeof addressId,
'parsedAddressId': parseInt(addressId),
'isValidNumber': !isNaN(parseInt(addressId))
});
// 处理优惠券ID
console.log('=== dispatchCommitPay 优惠券处理开始 ===');
console.log('- params.couponList:', params.couponList);
console.log('- params.couponList类型:', typeof params.couponList);
console.log('- params.couponList是否为数组:', Array.isArray(params.couponList));
console.log('- params.couponList长度:', params.couponList ? params.couponList.length : 'null/undefined');
console.log('- params.couponList JSON:', JSON.stringify(params.couponList, null, 2));
let couponId = null;
if (params.couponList && params.couponList.length > 0) {
// 取第一个优惠券的ID假设一次只能使用一张优惠券
const firstCoupon = params.couponList[0];
console.log('- 第一张优惠券对象:', firstCoupon);
console.log('- 第一张优惠券JSON:', JSON.stringify(firstCoupon, null, 2));
// 修复应该传递userCouponId用户优惠券表的ID而不是couponId优惠券模板ID
// 这样后端才能正确验证用户权限并获取优惠券信息
couponId = firstCoupon.couponId;
console.log('=== 优惠券ID提取详情 ===');
console.log('- firstCoupon.userCouponId:', firstCoupon.userCouponId);
console.log('- firstCoupon.userCouponId类型:', typeof firstCoupon.userCouponId);
console.log('- firstCoupon.id:', firstCoupon.id);
console.log('- firstCoupon.couponId:', firstCoupon.couponId);
console.log('- 最终提取的couponId:', couponId);
console.log('- 最终couponId类型:', typeof couponId);
console.log('- parseInt(couponId):', parseInt(couponId));
console.log('- parseInt(couponId)类型:', typeof parseInt(couponId));
logger.debug('ORDER_SETTLE_SERVICE', '提取优惠券ID', {
couponList: params.couponList,
firstCoupon,
extractedCouponId: couponId,
idFields: {
userCouponId: firstCoupon.userCouponId,
id: firstCoupon.id,
couponId: firstCoupon.couponId
}
});
} else {
console.log('=== 无优惠券处理 ===');
console.log('- 优惠券列表为空或不存在');
console.log('- couponId将设置为null');
}
console.log('=== 构建orderData ===');
console.log('- couponId值:', couponId);
console.log('- couponId类型:', typeof couponId);
console.log('- couponId是否为null:', couponId === null);
console.log('- couponId是否为undefined:', couponId === undefined);
console.log('- couponId转换为布尔值:', !!couponId);
const parsedCouponId = couponId ? parseInt(couponId) : undefined;
console.log('- parseInt(couponId):', parsedCouponId);
console.log('- parseInt(couponId)类型:', typeof parsedCouponId);
const orderData = {
address_id: parseInt(addressId),
items: params.goodsRequestList.map(goods => ({
product_id: parseInt(goods.spuId),
sku_id: goods.skuId ? parseInt(goods.skuId) : 0,
quantity: goods.quantity,
spec_info: goods.specInfo || {}
})),
remark: params.remark || '',
coupon_id: parsedCouponId
};
console.log('=== orderData构建完成 ===');
console.log('- orderData:', orderData);
console.log('- orderData.coupon_id:', orderData.coupon_id);
console.log('- orderData.coupon_id类型:', typeof orderData.coupon_id);
console.log('- orderData是否包含coupon_id属性:', 'coupon_id' in orderData);
console.log('- orderData JSON字符串:', JSON.stringify(orderData, null, 2));
// 检查JSON序列化后是否包含coupon_id
const jsonString = JSON.stringify(orderData);
console.log('- JSON序列化字符串:', jsonString);
console.log('- JSON中是否包含coupon_id:', jsonString.includes('coupon_id'));
logger.debug('ORDER_SETTLE_SERVICE', '最终订单数据', {
orderData,
'address_id_type': typeof orderData.address_id,
'address_id_value': orderData.address_id,
'coupon_id_value': orderData.coupon_id,
'coupon_id_type': typeof orderData.coupon_id
});
const token = wx.getStorageSync('token') || '';
const requestUrl = `${config.apiBase}/orders`;
logger.debug('ORDER_SETTLE_SERVICE', '准备提交订单API请求', {
url: requestUrl,
orderData,
hasToken: !!token
});
wx.request({
url: requestUrl,
method: 'POST',
data: orderData,
header: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
success: (res) => {
logger.info('ORDER_SETTLE_SERVICE', '订单提交API响应', {
statusCode: res.statusCode,
data: res.data
});
if (res.statusCode === 200 && res.data.code === 200) {
// 转换后端返回数据为前端期望的格式
const result = {
data: {
isSuccess: true,
tradeNo: res.data.data.order_no,
payInfo: '{}',
code: null,
transactionId: res.data.data.order_no,
msg: null,
interactId: res.data.data.id.toString(),
channel: 'wechat',
limitGoodsList: null,
},
code: 'Success',
msg: null,
requestId: Date.now().toString(),
clientIp: '127.0.0.1',
rt: 200,
success: true,
};
logger.info('ORDER_SETTLE_SERVICE', '订单提交成功', { result });
resolve(result);
} else {
const errorMsg = res.data?.message || '订单创建失败';
logger.error('ORDER_SETTLE_SERVICE', '订单提交失败', {
code: res.data?.code,
message: errorMsg,
fullResponse: res.data
});
reject(new Error(errorMsg));
}
},
fail: (err) => {
logger.error('ORDER_SETTLE_SERVICE', '订单提交网络请求失败', {
error: err,
url: requestUrl,
orderData
});
reject(new Error('网络请求失败: ' + (err.errMsg || '未知错误')));
}
});
});
}
/** 开发票 */
export function dispatchSupplementInvoice() {
logger.info('ORDER_SETTLE_SERVICE', '开始开发票', { useMock: config.useMock });
if (config.useMock) {
const { delay } = require('../_utils/delay');
return delay();
}
return new Promise((resolve) => {
resolve('real api');
});
}