447 lines
14 KiB
JavaScript
447 lines
14 KiB
JavaScript
|
|
import { config } from '../../config/index';
|
|||
|
|
|
|||
|
|
// 日志工具函数
|
|||
|
|
const logger = {
|
|||
|
|
info: (tag, message, data = null) => {
|
|||
|
|
const timestamp = new Date().toISOString();
|
|||
|
|
console.log(`[${timestamp}] [INFO] [${tag}] ${message}`, data ? data : '');
|
|||
|
|
},
|
|||
|
|
error: (tag, message, error = null) => {
|
|||
|
|
const timestamp = new Date().toISOString();
|
|||
|
|
console.error(`[${timestamp}] [ERROR] [${tag}] ${message}`, error ? error : '');
|
|||
|
|
},
|
|||
|
|
warn: (tag, message, data = null) => {
|
|||
|
|
const timestamp = new Date().toISOString();
|
|||
|
|
console.warn(`[${timestamp}] [WARN] [${tag}] ${message}`, data ? data : '');
|
|||
|
|
},
|
|||
|
|
debug: (tag, message, data = null) => {
|
|||
|
|
const timestamp = new Date().toISOString();
|
|||
|
|
if (config.debug) {
|
|||
|
|
console.log(`[${timestamp}] [DEBUG] [${tag}] ${message}`, data ? data : '');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 从完整地址中解析区域信息
|
|||
|
|
* @param {Object} addressData - 地址数据对象
|
|||
|
|
* @returns {Object} 包含区域信息的地址数据
|
|||
|
|
*/
|
|||
|
|
function parseAddressRegion(addressData) {
|
|||
|
|
// 如果已经有区域信息,直接返回
|
|||
|
|
if (addressData.provinceName && addressData.cityName && addressData.districtName) {
|
|||
|
|
return addressData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果有完整的address字段但缺少区域信息,尝试解析
|
|||
|
|
if (addressData.address && !addressData.provinceName) {
|
|||
|
|
const fullAddress = addressData.address;
|
|||
|
|
const detailAddress = addressData.detailAddress || '';
|
|||
|
|
|
|||
|
|
// 移除详细地址部分,获取区域部分
|
|||
|
|
const regionPart = fullAddress.replace(detailAddress, '');
|
|||
|
|
|
|||
|
|
logger.debug('ADDRESS_SERVICE', '尝试解析地址区域信息', {
|
|||
|
|
fullAddress,
|
|||
|
|
detailAddress,
|
|||
|
|
regionPart
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 简单的区域解析逻辑(可以根据实际需要优化)
|
|||
|
|
let provinceName = '', cityName = '', districtName = '';
|
|||
|
|
|
|||
|
|
// 匹配省份
|
|||
|
|
const provinceMatch = regionPart.match(/(.*?[省市])/);
|
|||
|
|
if (provinceMatch) {
|
|||
|
|
provinceName = provinceMatch[1];
|
|||
|
|
const remaining = regionPart.replace(provinceName, '');
|
|||
|
|
|
|||
|
|
// 匹配城市
|
|||
|
|
const cityMatch = remaining.match(/(.*?[市州盟])/);
|
|||
|
|
if (cityMatch) {
|
|||
|
|
cityName = cityMatch[1];
|
|||
|
|
const remaining2 = remaining.replace(cityName, '');
|
|||
|
|
|
|||
|
|
// 匹配区县
|
|||
|
|
const districtMatch = remaining2.match(/(.*?[区县旗])/);
|
|||
|
|
if (districtMatch) {
|
|||
|
|
districtName = districtMatch[1];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.debug('ADDRESS_SERVICE', '地址解析结果', {
|
|||
|
|
provinceName,
|
|||
|
|
cityName,
|
|||
|
|
districtName
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
...addressData,
|
|||
|
|
provinceName,
|
|||
|
|
cityName,
|
|||
|
|
districtName
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return addressData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 获取收货地址 */
|
|||
|
|
function mockFetchDeliveryAddress(id) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', `开始获取模拟收货地址, ID: ${id}`);
|
|||
|
|
const { delay } = require('../_utils/delay');
|
|||
|
|
const { genAddress } = require('../../model/address');
|
|||
|
|
|
|||
|
|
return delay().then(() => {
|
|||
|
|
const address = genAddress(id);
|
|||
|
|
logger.info('ADDRESS_SERVICE', `模拟收货地址获取成功`, { id, address });
|
|||
|
|
return address;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 获取收货地址 */
|
|||
|
|
export function fetchDeliveryAddress(id = 0) {
|
|||
|
|
if (config.useMock) {
|
|||
|
|
return mockFetchDeliveryAddress(id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const token = wx.getStorageSync('token') || '';
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${config.apiBase}/users/addresses`,
|
|||
|
|
method: 'GET',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${token}`
|
|||
|
|
},
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|||
|
|
const addresses = res.data.data || [];
|
|||
|
|
// 返回默认地址或第一个地址
|
|||
|
|
const defaultAddress = addresses.find(addr => addr.is_default === 1) || addresses[0];
|
|||
|
|
|
|||
|
|
if (defaultAddress) {
|
|||
|
|
// 转换地址数据格式,确保字段名称一致
|
|||
|
|
const formattedAddress = {
|
|||
|
|
id: defaultAddress.id,
|
|||
|
|
addressId: defaultAddress.id,
|
|||
|
|
name: defaultAddress.name,
|
|||
|
|
phone: defaultAddress.phone,
|
|||
|
|
provinceName: defaultAddress.province_name,
|
|||
|
|
provinceCode: defaultAddress.province_code,
|
|||
|
|
cityName: defaultAddress.city_name,
|
|||
|
|
cityCode: defaultAddress.city_code,
|
|||
|
|
districtName: defaultAddress.district_name,
|
|||
|
|
districtCode: defaultAddress.district_code,
|
|||
|
|
detailAddress: defaultAddress.detail_address,
|
|||
|
|
isDefault: defaultAddress.is_default === 1,
|
|||
|
|
addressTag: defaultAddress.address_tag || '',
|
|||
|
|
// 保持向后兼容
|
|||
|
|
address: `${defaultAddress.province_name || ''}${defaultAddress.city_name || ''}${defaultAddress.district_name || ''}${defaultAddress.detail_address || ''}`,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
resolve(formattedAddress);
|
|||
|
|
} else {
|
|||
|
|
resolve(null);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '获取收货地址失败', {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
errorCode: res.data?.code,
|
|||
|
|
message: res.data?.message
|
|||
|
|
});
|
|||
|
|
resolve(null);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '收货地址请求失败', err);
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 获取收货地址列表 */
|
|||
|
|
function mockFetchDeliveryAddressList(len = 0) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', `开始获取模拟收货地址列表, 长度: ${len}`);
|
|||
|
|
const { delay } = require('../_utils/delay');
|
|||
|
|
const { genAddressList } = require('../../model/address');
|
|||
|
|
|
|||
|
|
return delay().then(() => {
|
|||
|
|
const addressList = genAddressList(len).map((address) => {
|
|||
|
|
return {
|
|||
|
|
...address,
|
|||
|
|
phoneNumber: address.phone,
|
|||
|
|
address: `${address.provinceName}${address.cityName}${address.districtName}${address.detailAddress}`,
|
|||
|
|
tag: address.addressTag,
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
logger.info('ADDRESS_SERVICE', `模拟收货地址列表获取成功`, {
|
|||
|
|
count: addressList.length,
|
|||
|
|
addresses: addressList.map(addr => ({ id: addr.id, name: addr.name }))
|
|||
|
|
});
|
|||
|
|
return addressList;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 获取收货地址列表 */
|
|||
|
|
export function fetchDeliveryAddressList(len = 10) {
|
|||
|
|
if (config.useMock) {
|
|||
|
|
return mockFetchDeliveryAddressList(len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const token = wx.getStorageSync('token') || '';
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${config.apiBase}/users/addresses`,
|
|||
|
|
method: 'GET',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${token}`
|
|||
|
|
},
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|||
|
|
const addresses = res.data.data || [];
|
|||
|
|
resolve(addresses);
|
|||
|
|
} else {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '获取收货地址列表失败', {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
errorCode: res.data?.code,
|
|||
|
|
message: res.data?.message
|
|||
|
|
});
|
|||
|
|
resolve([]);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '收货地址列表请求失败', err);
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 创建收货地址 */
|
|||
|
|
export function createAddress(addressData) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', '开始创建收货地址', {
|
|||
|
|
name: addressData.name,
|
|||
|
|
phone: addressData.phone,
|
|||
|
|
province: addressData.province,
|
|||
|
|
city: addressData.city,
|
|||
|
|
district: addressData.district,
|
|||
|
|
isDefault: addressData.isDefault
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const token = wx.getStorageSync('token') || '';
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `准备发起创建地址API请求`, {
|
|||
|
|
url: `${config.apiBase}/users/addresses`,
|
|||
|
|
hasToken: !!token,
|
|||
|
|
tokenLength: token.length,
|
|||
|
|
dataKeys: Object.keys(addressData)
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${config.apiBase}/users/addresses`,
|
|||
|
|
method: 'POST',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${token}`,
|
|||
|
|
'Content-Type': 'application/json'
|
|||
|
|
},
|
|||
|
|
data: addressData,
|
|||
|
|
success: (res) => {
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `创建地址API请求响应`, {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
dataCode: res.data?.code,
|
|||
|
|
message: res.data?.message
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', '创建收货地址成功', {
|
|||
|
|
newAddressId: res.data.data?.id,
|
|||
|
|
name: addressData.name
|
|||
|
|
});
|
|||
|
|
resolve(res.data.data);
|
|||
|
|
} else {
|
|||
|
|
const errorMsg = res.data.message || '创建地址失败';
|
|||
|
|
logger.error('ADDRESS_SERVICE', '创建收货地址失败', {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
errorCode: res.data?.code,
|
|||
|
|
message: errorMsg
|
|||
|
|
});
|
|||
|
|
reject(new Error(errorMsg));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '创建地址请求失败', err);
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 更新收货地址 */
|
|||
|
|
export function updateAddress(addressId, addressData) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', `开始更新收货地址, ID: ${addressId}`, {
|
|||
|
|
addressId,
|
|||
|
|
name: addressData.name,
|
|||
|
|
phone: addressData.phone,
|
|||
|
|
province: addressData.province,
|
|||
|
|
city: addressData.city,
|
|||
|
|
district: addressData.district,
|
|||
|
|
isDefault: addressData.isDefault
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const token = wx.getStorageSync('token') || '';
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `准备发起更新地址API请求`, {
|
|||
|
|
url: `${config.apiBase}/users/addresses/${addressId}`,
|
|||
|
|
hasToken: !!token,
|
|||
|
|
tokenLength: token.length,
|
|||
|
|
dataKeys: Object.keys(addressData)
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${config.apiBase}/users/addresses/${addressId}`,
|
|||
|
|
method: 'PUT',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${token}`,
|
|||
|
|
'Content-Type': 'application/json'
|
|||
|
|
},
|
|||
|
|
data: addressData,
|
|||
|
|
success: (res) => {
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `更新地址API请求响应`, {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
dataCode: res.data?.code,
|
|||
|
|
message: res.data?.message
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', '更新收货地址成功', {
|
|||
|
|
addressId,
|
|||
|
|
name: addressData.name
|
|||
|
|
});
|
|||
|
|
resolve(res.data.data);
|
|||
|
|
} else {
|
|||
|
|
const errorMsg = res.data.message || '更新地址失败';
|
|||
|
|
logger.error('ADDRESS_SERVICE', '更新收货地址失败', {
|
|||
|
|
addressId,
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
errorCode: res.data?.code,
|
|||
|
|
message: errorMsg
|
|||
|
|
});
|
|||
|
|
reject(new Error(errorMsg));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '更新地址请求失败', { addressId, error: err });
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 删除收货地址 */
|
|||
|
|
export function deleteAddress(addressId) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', `开始删除收货地址, ID: ${addressId}`, { addressId });
|
|||
|
|
|
|||
|
|
const token = wx.getStorageSync('token') || '';
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `准备发起删除地址API请求`, {
|
|||
|
|
url: `${config.apiBase}/users/addresses/${addressId}`,
|
|||
|
|
hasToken: !!token,
|
|||
|
|
tokenLength: token.length
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${config.apiBase}/users/addresses/${addressId}`,
|
|||
|
|
method: 'DELETE',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${token}`
|
|||
|
|
},
|
|||
|
|
success: (res) => {
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `删除地址API请求响应`, {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
dataCode: res.data?.code,
|
|||
|
|
message: res.data?.message
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', '删除收货地址成功', { addressId });
|
|||
|
|
resolve(res.data.data);
|
|||
|
|
} else {
|
|||
|
|
const errorMsg = res.data.message || '删除地址失败';
|
|||
|
|
logger.error('ADDRESS_SERVICE', '删除收货地址失败', {
|
|||
|
|
addressId,
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
errorCode: res.data?.code,
|
|||
|
|
message: errorMsg
|
|||
|
|
});
|
|||
|
|
reject(new Error(errorMsg));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '删除地址请求失败', { addressId, error: err });
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 设置默认地址 */
|
|||
|
|
export function setDefaultAddress(addressId) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', `开始设置默认收货地址, ID: ${addressId}`, { addressId });
|
|||
|
|
|
|||
|
|
const token = wx.getStorageSync('token') || '';
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `准备发起设置默认地址API请求`, {
|
|||
|
|
url: `${config.apiBase}/users/addresses/${addressId}/default`,
|
|||
|
|
hasToken: !!token,
|
|||
|
|
tokenLength: token.length
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return new Promise((resolve, reject) => {
|
|||
|
|
wx.request({
|
|||
|
|
url: `${config.apiBase}/users/addresses/${addressId}/default`,
|
|||
|
|
method: 'PUT',
|
|||
|
|
header: {
|
|||
|
|
'Authorization': `Bearer ${token}`
|
|||
|
|
},
|
|||
|
|
success: (res) => {
|
|||
|
|
logger.debug('ADDRESS_SERVICE', `设置默认地址API请求响应`, {
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
dataCode: res.data?.code,
|
|||
|
|
message: res.data?.message
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (res.statusCode === 200 && res.data.code === 200) {
|
|||
|
|
logger.info('ADDRESS_SERVICE', '设置默认收货地址成功', { addressId });
|
|||
|
|
resolve(res.data.data);
|
|||
|
|
} else {
|
|||
|
|
const errorMsg = res.data.message || '设置默认地址失败';
|
|||
|
|
logger.error('ADDRESS_SERVICE', '设置默认收货地址失败', {
|
|||
|
|
addressId,
|
|||
|
|
statusCode: res.statusCode,
|
|||
|
|
errorCode: res.data?.code,
|
|||
|
|
message: errorMsg
|
|||
|
|
});
|
|||
|
|
reject(new Error(errorMsg));
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
fail: (err) => {
|
|||
|
|
logger.error('ADDRESS_SERVICE', '设置默认地址请求失败', { addressId, error: err });
|
|||
|
|
reject(err);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = {
|
|||
|
|
fetchDeliveryAddress,
|
|||
|
|
fetchDeliveryAddressList,
|
|||
|
|
createAddress,
|
|||
|
|
updateAddress,
|
|||
|
|
deleteAddress,
|
|||
|
|
setDefaultAddress,
|
|||
|
|
parseAddressRegion,
|
|||
|
|
};
|