352 lines
12 KiB
JavaScript
352 lines
12 KiB
JavaScript
|
|
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');
|
|||
|
|
});
|
|||
|
|
}
|