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'); }); }