Files
ai_dianshang/miniprogram/services/order/orderConfirm.js

352 lines
12 KiB
JavaScript
Raw Normal View History

2025-11-17 14:11:46 +08:00
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');
});
}