Browse Source

优化运费估算功能,将估算历史记录写入数据库

main
Default User 2 days ago
parent
commit
f92b8b768e
  1. 118
      pages/freight-calculator/index.js
  2. 11
      pages/freight-calculator/index.wxml
  3. 509
      server-example/server-mysql.js
  4. 322
      utils/api.js

118
pages/freight-calculator/index.js

@ -280,9 +280,32 @@ Page({
// 加载历史记录 // 加载历史记录
loadHistoryRecords: function () { loadHistoryRecords: function () {
const history = wx.getStorageSync('freightCalculatorHistory') || []; this.setData({ loading: true });
this.setData({
historyRecords: history.slice(0, 10) // 只显示最近10条记录 API.getFreightHistory({
productId: this.data.selectedGoods.productId || this.data.selectedGoods.id
}).then(res => {
this.setData({ loading: false });
if (res.success) {
this.setData({
historyRecords: res.data.records || []
});
} else {
console.error('获取历史记录失败:', res.message);
// 失败时使用本地存储作为 fallback
const history = wx.getStorageSync('freightCalculatorHistory') || [];
this.setData({
historyRecords: history.slice(0, 10) // 只显示最近10条记录
});
}
}).catch(err => {
this.setData({ loading: false });
console.error('获取历史记录失败:', err);
// 失败时使用本地存储作为 fallback
const history = wx.getStorageSync('freightCalculatorHistory') || [];
this.setData({
historyRecords: history.slice(0, 10) // 只显示最近10条记录
});
}); });
}, },
@ -409,7 +432,7 @@ Page({
} }
}, },
// 使用当前位置作为出发 // 使用当前位置作为目的
useCurrentLocation: function () { useCurrentLocation: function () {
const that = this; const that = this;
wx.getLocation({ wx.getLocation({
@ -473,6 +496,70 @@ Page({
}); });
}, },
// 使用当前位置作为出发地
useCurrentLocationForOrigin: function () {
const that = this;
wx.getLocation({
type: 'wgs84',
success: function (res) {
// 显示加载提示
wx.showLoading({
title: '获取地址中...',
mask: true
});
// 使用微信的地址解析服务获取详细地址
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
data: {
location: `${res.latitude},${res.longitude}`,
key: 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77' // 这里使用腾讯地图API密钥,实际项目中应该替换为自己的密钥
},
success: function (response) {
wx.hideLoading();
if (response.data.status === 0) {
const result = response.data.result;
that.setData({
origin: {
province: result.address_component.province || '',
city: result.address_component.city || '',
district: result.address_component.district || '',
detail: result.address || '',
latitude: res.latitude,
longitude: res.longitude
}
});
wx.showToast({
title: '地址获取成功',
icon: 'success'
});
} else {
wx.showToast({
title: '地址解析失败,请手动输入',
icon: 'none'
});
}
},
fail: function (err) {
wx.hideLoading();
console.error('地址解析失败:', err);
wx.showToast({
title: '地址解析失败,请手动输入',
icon: 'none'
});
}
});
},
fail: function (err) {
console.error('获取位置失败:', err);
wx.showToast({
title: '获取位置失败,请手动输入',
icon: 'none'
});
}
});
},
// 手动选择出发地位置 // 手动选择出发地位置
chooseOriginLocation: function () { chooseOriginLocation: function () {
const that = this; const that = this;
@ -764,7 +851,8 @@ Page({
const params = { const params = {
origin: this.data.origin, origin: this.data.origin,
destination: this.data.destination, destination: this.data.destination,
goodsInfo: this.data.goodsInfo goodsInfo: this.data.goodsInfo,
productId: this.data.selectedGoods.productId || this.data.selectedGoods.id
}; };
// 调用API计算运费 // 调用API计算运费
@ -987,12 +1075,28 @@ Page({
this.setData({ loading: true }); this.setData({ loading: true });
// 更新 goodsInfo 中的重量和体积
this.setData({
'goodsInfo.weight': weight,
'goodsInfo.volume': volume
});
// 构建请求参数 // 构建请求参数
const params = { const params = {
origin: this.data.origin, origin: this.data.origin,
destination: this.data.destination, destination: this.data.destination,
goodsInfo: this.data.goodsInfo, goodsInfo: {
vehicleInfo: this.data.vehicleInfo weight: weight,
volume: volume,
quantity: this.data.goodsInfo.quantity || 1,
type: this.data.goodsInfo.type || 'egg'
},
vehicleInfo: this.data.vehicleInfo,
productId: this.data.selectedGoods.productId || this.data.selectedGoods.id,
transportMode: transportMode,
vehicleType: vehicleType,
truckLength: truckLength,
packagingType: packagingType
}; };
// 调用API计算运费,获取距离信息 // 调用API计算运费,获取距离信息

11
pages/freight-calculator/index.wxml

@ -34,9 +34,14 @@
</view> </view>
</picker> </picker>
</view> </view>
<button class="location-btn" bindtap="chooseOriginLocation" style="background-color: #1677ff;"> <view style="display: flex; justify-content: space-between; gap: 12rpx;">
<text>手动选择位置</text> <button class="location-btn" bindtap="useCurrentLocationForOrigin">
</button> <text>使用当前位置</text>
</button>
<button class="location-btn" bindtap="chooseOriginLocation" style="background-color: #1677ff;">
<text>手动选择位置</text>
</button>
</view>
</view> </view>
</view> </view>

509
server-example/server-mysql.js

@ -4,6 +4,149 @@ function getCurrentTime() {
return new Date(); return new Date();
} }
// 运费计算辅助函数 - 计算运满满运费区间
function calculateYunmanmanFee(distance, weight, volume, vehicleType, truckLength) {
// 车长系数计算
const getTruckLengthFactor = (truckLength) => {
try {
const length = parseFloat(truckLength.replace('米', ''));
if (length <= 3.8) {
return 0.8;
} else if (length <= 4.2) {
return 0.9;
} else if (length <= 5) {
return 1.0;
} else if (length <= 6.8) {
return 1.1;
} else if (length <= 7.7) {
return 1.2;
} else if (length <= 9.6) {
return 1.3;
} else if (length <= 13) {
return 1.4;
} else {
return 1.5;
}
} catch {
return 1.0;
}
};
// 运满满收费标准
const rates = {
'面包车': {
startFee: 80,
startDistance: 10,
unitPriceMin: 1.0,
unitPriceMax: 1.3
},
'依维柯': {
startFee: 160,
startDistance: 10,
unitPriceMin: 1.5,
unitPriceMax: 1.8
},
'平板': {
startFee: 300,
startDistance: 10,
unitPriceMin: 2.5,
unitPriceMax: 2.9
},
'厢式': {
startFee: 220,
startDistance: 10,
unitPriceMin: 2.1,
unitPriceMax: 2.4
},
'高栏车': {
startFee: 200,
startDistance: 10,
unitPriceMin: 2.5,
unitPriceMax: 2.8
},
'集装箱': {
startFee: 300,
startDistance: 10,
unitPriceMin: 2.8,
unitPriceMax: 3.1
},
'自卸': {
startFee: 250,
startDistance: 10,
unitPriceMin: 2.2,
unitPriceMax: 2.5
},
'冷藏': {
startFee: 300,
startDistance: 10,
unitPriceMin: 2.5,
unitPriceMax: 2.8
},
'保温': {
startFee: 280,
startDistance: 10,
unitPriceMin: 2.3,
unitPriceMax: 2.6
},
'棉被车': {
startFee: 260,
startDistance: 10,
unitPriceMin: 2.2,
unitPriceMax: 2.5
},
'爬梯车': {
startFee: 280,
startDistance: 10,
unitPriceMin: 2.3,
unitPriceMax: 2.6
},
'飞翼车': {
startFee: 270,
startDistance: 10,
unitPriceMin: 2.2,
unitPriceMax: 2.5
},
'高低板': {
startFee: 350,
startDistance: 10,
unitPriceMin: 2.8,
unitPriceMax: 3.1
}
};
const rate = rates[vehicleType] || rates['平板'];
// 获取车长系数
const truckLengthFactor = getTruckLengthFactor(truckLength);
// 计算距离费用
let feeMin, feeMax;
if (distance <= rate.startDistance) {
feeMin = rate.startFee;
feeMax = rate.startFee;
} else {
const extraDistance = distance - rate.startDistance;
feeMin = rate.startFee + extraDistance * rate.unitPriceMin;
feeMax = rate.startFee + extraDistance * rate.unitPriceMax;
}
// 应用车长系数
feeMin *= truckLengthFactor;
feeMax *= truckLengthFactor;
// 根据货物重量和体积调整价格
if (weight > 1000 || volume > 10) {
feeMin *= 1.1;
feeMax *= 1.1;
}
// 添加平台佣金(运费的5%左右)
feeMin *= 1.05;
feeMax *= 1.05;
return [Math.floor(feeMin), Math.floor(feeMax)];
}
function getCurrentTimeISOString() { function getCurrentTimeISOString() {
return getCurrentTime().toISOString(); return getCurrentTime().toISOString();
} }
@ -131,7 +274,7 @@ app.post('/api/freight/calculate', (req, res) => {
console.log('===== 运费计算接口被调用 ====='); console.log('===== 运费计算接口被调用 =====');
console.log('1. 收到请求体:', JSON.stringify(req.body, null, 2)); console.log('1. 收到请求体:', JSON.stringify(req.body, null, 2));
const { origin, destination, goodsInfo: originalGoodsInfo } = req.body; const { origin, destination, goodsInfo: originalGoodsInfo, productId, userId, phoneNumber, vehicleInfo, transportMode, vehicleType, truckLength, packagingType } = req.body;
let goodsInfo = originalGoodsInfo; let goodsInfo = originalGoodsInfo;
// 验证参数 // 验证参数
@ -149,10 +292,6 @@ app.post('/api/freight/calculate', (req, res) => {
goodsInfo = { ...goodsInfo, weight: 1 }; goodsInfo = { ...goodsInfo, weight: 1 };
} }
// 计算运费(使用默认费率,用户可根据自己的物流标准调整)
const baseRate = 0.5; // 默认基础费率(元/公里/公斤)
const weight = goodsInfo.weight || 1;
// 检查是否有经纬度信息 // 检查是否有经纬度信息
if (origin.latitude && origin.longitude && destination.latitude && destination.longitude) { if (origin.latitude && origin.longitude && destination.latitude && destination.longitude) {
// 直接使用经纬度计算距离 // 直接使用经纬度计算距离
@ -175,37 +314,84 @@ app.post('/api/freight/calculate', (req, res) => {
const response = JSON.parse(data); const response = JSON.parse(data);
console.log('腾讯地图API响应:', response); console.log('腾讯地图API响应:', response);
if (response.status === 0 && response.result && response.result.elements && response.result.elements.length > 0) { let result;
const distance = response.result.elements[0].distance / 1000; // 转换为公里 if (response.status === 0 && response.result && response.result.rows && response.result.rows.length > 0) {
const freight = Math.floor(distance * baseRate * weight); // 检查rows[0]是否有elements属性
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天 const row = response.result.rows[0];
if (row.elements && row.elements.length > 0) {
console.log('腾讯地图API距离计算成功,距离:', distance, '公里'); const distance = row.elements[0].distance / 1000; // 转换为公里
// 计算运费区间
res.json({ const [feeMin, feeMax] = calculateYunmanmanFee(distance, goodsInfo.weight || 1, goodsInfo.volume || 0, vehicleType || '平板', truckLength || '5米');
success: true, const deliveryTime = Math.ceil(distance / 80); // 公路:80公里/天
data: {
freight: freight, console.log('腾讯地图API距离计算成功,距离:', distance, '公里');
console.log('运费区间:', feeMin, '-', feeMax, '元');
result = {
freight: Math.floor((feeMin + feeMax) / 2), // 中间值
feeMin: feeMin,
feeMax: feeMax,
distance: Math.round(distance * 10) / 10, // 保留一位小数 distance: Math.round(distance * 10) / 10, // 保留一位小数
deliveryTime: deliveryTime deliveryTime: deliveryTime
} };
}); } else {
console.error('腾讯地图API距离计算失败: 响应格式错误', response);
// 如果腾讯地图API调用失败,使用固定距离作为fallback
const distance = 200; // 示例距离:200公里
// 计算运费区间
const [feeMin, feeMax] = calculateYunmanmanFee(distance, goodsInfo.weight || 1, goodsInfo.volume || 0, vehicleType || '平板', truckLength || '5米');
const deliveryTime = Math.ceil(distance / 80); // 公路:80公里/天
result = {
freight: Math.floor((feeMin + feeMax) / 2), // 中间值
feeMin: feeMin,
feeMax: feeMax,
distance: distance,
deliveryTime: deliveryTime
};
}
} else { } else {
console.error('腾讯地图API距离计算失败:', response); console.error('腾讯地图API距离计算失败:', response);
// 如果腾讯地图API调用失败,使用固定距离作为fallback // 如果腾讯地图API调用失败,使用固定距离作为fallback
const distance = 200; // 示例距离:200公里 const distance = 200; // 示例距离:200公里
const freight = Math.floor(distance * baseRate * weight); // 计算运费区间
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天 const [feeMin, feeMax] = calculateYunmanmanFee(distance, goodsInfo.weight || 1, goodsInfo.volume || 0, vehicleType || '平板', truckLength || '5米');
const deliveryTime = Math.ceil(distance / 80); // 公路:80公里/天
result = {
freight: Math.floor((feeMin + feeMax) / 2), // 中间值
feeMin: feeMin,
feeMax: feeMax,
distance: distance,
deliveryTime: deliveryTime
};
}
res.json({ // 保存运费估算历史记录
success: true, if (userId && phoneNumber) {
data: { FreightCalculationHistory.create({
freight: freight, productId: productId || '',
distance: distance, userId: userId,
deliveryTime: deliveryTime phoneNumber: phoneNumber,
} origin: JSON.stringify(origin),
destination: JSON.stringify(destination),
weight: goodsInfo.weight,
volume: goodsInfo.volume,
goodsInfo: JSON.stringify(goodsInfo),
vehicleInfo: vehicleInfo,
transportMode: transportMode,
result: JSON.stringify(result)
}).then(() => {
console.log('运费估算历史记录保存成功');
}).catch((error) => {
console.error('保存运费估算历史记录失败:', error);
}); });
} }
res.json({
success: true,
data: result
});
} catch (error) { } catch (error) {
console.error('处理腾讯地图API响应时出错:', error); console.error('处理腾讯地图API响应时出错:', error);
// 如果处理响应时出错,使用固定距离作为fallback // 如果处理响应时出错,使用固定距离作为fallback
@ -213,13 +399,36 @@ app.post('/api/freight/calculate', (req, res) => {
const freight = Math.floor(distance * baseRate * weight); const freight = Math.floor(distance * baseRate * weight);
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天 const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天
const result = {
freight: freight,
distance: distance,
deliveryTime: deliveryTime
};
// 保存运费估算历史记录
if (userId && phoneNumber) {
FreightCalculationHistory.create({
productId: productId || '',
userId: userId,
phoneNumber: phoneNumber,
origin: JSON.stringify(origin),
destination: JSON.stringify(destination),
weight: goodsInfo.weight,
volume: goodsInfo.volume,
goodsInfo: JSON.stringify(goodsInfo),
vehicleInfo: vehicleInfo,
transportMode: transportMode,
result: JSON.stringify(result)
}).then(() => {
console.log('运费估算历史记录保存成功');
}).catch((error) => {
console.error('保存运费估算历史记录失败:', error);
});
}
res.json({ res.json({
success: true, success: true,
data: { data: result
freight: freight,
distance: distance,
deliveryTime: deliveryTime
}
}); });
} }
}); });
@ -230,13 +439,36 @@ app.post('/api/freight/calculate', (req, res) => {
const freight = Math.floor(distance * baseRate * weight); const freight = Math.floor(distance * baseRate * weight);
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天 const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天
const result = {
freight: freight,
distance: distance,
deliveryTime: deliveryTime
};
// 保存运费估算历史记录
if (userId && phoneNumber) {
FreightCalculationHistory.create({
productId: productId || '',
userId: userId,
phoneNumber: phoneNumber,
origin: JSON.stringify(origin),
destination: JSON.stringify(destination),
weight: goodsInfo.weight,
volume: goodsInfo.volume,
goodsInfo: JSON.stringify(goodsInfo),
vehicleInfo: vehicleInfo,
transportMode: transportMode,
result: JSON.stringify(result)
}).then(() => {
console.log('运费估算历史记录保存成功');
}).catch((error) => {
console.error('保存运费估算历史记录失败:', error);
});
}
res.json({ res.json({
success: true, success: true,
data: { data: result
freight: freight,
distance: distance,
deliveryTime: deliveryTime
}
}); });
}); });
} else { } else {
@ -245,13 +477,36 @@ app.post('/api/freight/calculate', (req, res) => {
const freight = Math.floor(distance * baseRate * weight); const freight = Math.floor(distance * baseRate * weight);
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天 const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天
const result = {
freight: freight,
distance: distance,
deliveryTime: deliveryTime
};
// 保存运费估算历史记录
if (userId && phoneNumber) {
FreightCalculationHistory.create({
productId: productId || '',
userId: userId,
phoneNumber: phoneNumber,
origin: JSON.stringify(origin),
destination: JSON.stringify(destination),
weight: goodsInfo.weight,
volume: goodsInfo.volume,
goodsInfo: JSON.stringify(goodsInfo),
vehicleInfo: vehicleInfo,
transportMode: transportMode,
result: JSON.stringify(result)
}).then(() => {
console.log('运费估算历史记录保存成功');
}).catch((error) => {
console.error('保存运费估算历史记录失败:', error);
});
}
res.json({ res.json({
success: true, success: true,
data: { data: result
freight: freight,
distance: distance,
deliveryTime: deliveryTime
}
}); });
} }
@ -264,6 +519,75 @@ app.post('/api/freight/calculate', (req, res) => {
} }
}); });
// 获取运费估算历史记录接口
app.get('/api/freight/history', async (req, res) => {
try {
console.log('===== 获取运费估算历史记录接口被调用 =====');
console.log('1. 收到查询参数:', req.query);
const { userId, productId, page = 1, pageSize = 10 } = req.query;
// 构建查询条件
const whereCondition = {};
if (userId) {
whereCondition.userId = userId;
}
if (productId) {
whereCondition.productId = productId;
}
// 计算分页偏移量
const offset = (parseInt(page) - 1) * parseInt(pageSize);
// 查询历史记录
const historyRecords = await FreightCalculationHistory.findAll({
where: whereCondition,
order: [['created_at', 'DESC']],
limit: parseInt(pageSize),
offset: offset
});
// 计算总记录数
const totalCount = await FreightCalculationHistory.count({
where: whereCondition
});
// 格式化响应数据
const formattedRecords = historyRecords.map(record => {
const recordData = record.toJSON();
try {
recordData.origin = JSON.parse(recordData.origin);
recordData.destination = JSON.parse(recordData.destination);
recordData.goodsInfo = JSON.parse(recordData.goodsInfo);
recordData.result = JSON.parse(recordData.result);
} catch (error) {
console.error('解析JSON字段失败:', error);
}
return recordData;
});
res.json({
success: true,
data: {
records: formattedRecords,
pagination: {
page: parseInt(page),
pageSize: parseInt(pageSize),
total: totalCount,
totalPages: Math.ceil(totalCount / parseInt(pageSize))
}
}
});
} catch (error) {
console.error('获取运费估算历史记录失败:', error);
res.status(500).json({
success: false,
message: '获取运费估算历史记录失败: ' + error.message
});
}
});
// Eggbar 帖子创建接口 // Eggbar 帖子创建接口
app.post('/api/eggbar/posts', async (req, res) => { app.post('/api/eggbar/posts', async (req, res) => {
@ -1784,7 +2108,7 @@ Product.init({
allowNull: false allowNull: false
}, },
region: { region: {
type: DataTypes.STRING(100), type: DataTypes.STRING(255),
}, },
price: { price: {
type: DataTypes.STRING(10), type: DataTypes.STRING(10),
@ -2775,6 +3099,105 @@ UserFollowupHistory.init({
timestamps: false timestamps: false
}); });
// 定义运费估算历史记录模型
class FreightCalculationHistory extends Model { }
FreightCalculationHistory.init({
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
productId: {
type: DataTypes.STRING(100),
allowNull: true,
defaultValue: null,
comment: '产品id'
},
userId: {
type: DataTypes.STRING(100),
allowNull: false,
comment: '用户id'
},
phoneNumber: {
type: DataTypes.STRING(20),
allowNull: false,
comment: '电话号码'
},
origin: {
type: DataTypes.STRING(255),
defaultValue: '',
comment: '出发地信息'
},
destination: {
type: DataTypes.STRING(255),
defaultValue: '',
comment: '目的地信息'
},
weight: {
type: DataTypes.DECIMAL(10, 2),
allowNull: true,
comment: '货物重量(kg)'
},
volume: {
type: DataTypes.DECIMAL(10, 2),
allowNull: true,
comment: '货物体积(m³)'
},
goodsInfo: {
type: DataTypes.TEXT,
allowNull: false,
comment: '货物信息'
},
vehicleInfo: {
type: DataTypes.STRING(255),
allowNull: true,
comment: '车型信息'
},
transportMode: {
type: DataTypes.STRING(50),
allowNull: true,
comment: '运输模式'
},
result: {
type: DataTypes.TEXT,
allowNull: false,
comment: '计算结果'
},
created_at: {
type: DataTypes.DATE,
defaultValue: Sequelize.NOW,
comment: '创建时间'
},
updated_at: {
type: DataTypes.DATE,
defaultValue: Sequelize.NOW,
onUpdate: Sequelize.NOW,
comment: '更新时间'
}
}, {
sequelize,
modelName: 'FreightCalculationHistory',
tableName: 'freight_calculation_history',
timestamps: false,
indexes: [
{
fields: ['productId'],
name: 'idx_productId',
comment: '产品ID索引'
},
{
fields: ['created_at'],
name: 'idx_created_at',
comment: '创建时间索引'
},
{
fields: ['productId', 'created_at'],
name: 'idx_productId_created_at',
comment: '产品ID和创建时间联合索引'
}
]
});
// 定义模型之间的关联关系 // 定义模型之间的关联关系
// 用户和商品的一对多关系 (卖家发布商品) // 用户和商品的一对多关系 (卖家发布商品)

322
utils/api.js

@ -1226,290 +1226,56 @@ module.exports = {
params.goodsInfo.weight = 1; params.goodsInfo.weight = 1;
} }
// 直接使用腾讯地图API计算真实距离 // 获取用户信息
return new Promise((resolve, reject) => { const userId = wx.getStorageSync('userId');
// 定义获取经纬度的函数 const userInfo = wx.getStorageSync('userInfo');
function getCoordinates(address) { const phoneNumber = userInfo?.phoneNumber || wx.getStorageSync('phoneNumber');
return new Promise((resolve, reject) => {
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
data: {
address: address,
key: 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77'
},
success: function (response) {
if (response.data.status === 0 && response.data.result && response.data.result.location) {
resolve({
latitude: response.data.result.location.lat,
longitude: response.data.result.location.lng
});
} else {
reject(new Error('地址解析失败'));
}
},
fail: function (err) {
reject(err);
}
});
});
}
// 检查是否有经纬度信息
if (params.origin.latitude && params.origin.longitude && params.destination.latitude && params.destination.longitude) {
// 直接使用经纬度计算距离
const origin = `${params.origin.latitude},${params.origin.longitude}`;
const destination = `${params.destination.latitude},${params.destination.longitude}`;
wx.request({
url: 'https://apis.map.qq.com/ws/distance/v1/matrix',
data: {
mode: 'driving',
from: origin,
to: destination,
key: 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77'
},
success: function (response) {
console.log('腾讯地图API距离计算成功:', response);
console.log('腾讯地图API响应状态:', response.data.status);
console.log('腾讯地图API响应结果:', response.data.result);
if (response.data.status === 0 && response.data.result) {
// 检查result结构,适应不同的API响应格式
let distance;
try {
// 优先检查 rows 字段(腾讯地图 API 的标准格式)
if (response.data.result.rows && response.data.result.rows.length > 0) {
const row = response.data.result.rows[0];
if (row.elements && row.elements.length > 0) {
distance = row.elements[0].distance / 1000; // 转换为公里
}
}
// 然后检查 elements 字段
else if (response.data.result.elements && response.data.result.elements.length > 0) {
distance = response.data.result.elements[0].distance / 1000; // 转换为公里
}
// 最后检查 distance 字段
else if (response.data.result.distance) {
distance = response.data.result.distance / 1000; // 转换为公里
}
// 如果都没有,抛出错误
else {
console.error('无法获取距离数据,响应结构:', response.data.result);
throw new Error('无法获取距离数据');
}
const baseRate = 0.5; // 默认基础费率(元/公里/公斤)
const weight = params.goodsInfo.weight || 1;
const freight = Math.floor(distance * baseRate * weight);
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天
console.log('腾讯地图API距离计算成功,距离:', distance, '公里');
resolve({ // 构建请求数据
success: true, const requestData = {
data: { ...params,
freight: freight, userId: userId,
distance: Math.round(distance * 10) / 10, // 保留一位小数 phoneNumber: phoneNumber
deliveryTime: deliveryTime };
}
});
} catch (error) {
console.error('处理距离数据时出错:', error);
// 如果处理距离数据时出错,使用随机数据作为fallback
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({
success: true,
data: {
freight: mockFreight,
distance: mockDistance,
deliveryTime: mockDeliveryTime
}
});
}
} else {
console.error('腾讯地图API距离计算失败:', response.data);
// 如果腾讯地图API调用失败,使用随机数据作为fallback
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({
success: true,
data: {
freight: mockFreight,
distance: mockDistance,
deliveryTime: mockDeliveryTime
}
});
}
},
fail: function (err) {
console.error('腾讯地图API调用失败:', err);
// 如果API调用失败,使用随机数据作为fallback
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({ // 调用后端API计算运费
success: true, return request('/api/freight/calculate', 'POST', requestData).then(res => {
data: { console.log('API.calculateFreight - 后端响应:', res);
freight: mockFreight, if (res && res.success) {
distance: mockDistance, return res;
deliveryTime: mockDeliveryTime
}
});
}
});
} else { } else {
// 没有经纬度信息,先进行地址解析 throw new Error(res?.message || '运费计算失败');
const originAddress = `${params.origin.province}${params.origin.city}${params.origin.district}${params.origin.detail}`; }
const destinationAddress = `${params.destination.province}${params.destination.city}${params.destination.district}${params.destination.detail}`; }).catch(err => {
console.error('API.calculateFreight - 计算运费失败:', err);
Promise.all([ throw err;
getCoordinates(originAddress), });
getCoordinates(destinationAddress) },
]).then(([originCoords, destinationCoords]) => {
// 使用解析得到的经纬度计算距离
const origin = `${originCoords.latitude},${originCoords.longitude}`;
const destination = `${destinationCoords.latitude},${destinationCoords.longitude}`;
wx.request({
url: 'https://apis.map.qq.com/ws/distance/v1/matrix',
data: {
mode: 'driving',
from: origin,
to: destination,
key: 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77'
},
success: function (response) {
console.log('腾讯地图API距离计算成功:', response);
console.log('腾讯地图API响应状态:', response.data.status);
console.log('腾讯地图API响应结果:', response.data.result);
if (response.data.status === 0 && response.data.result) {
// 检查result结构,适应不同的API响应格式
let distance;
try {
// 优先检查 rows 字段(腾讯地图 API 的标准格式)
if (response.data.result.rows && response.data.result.rows.length > 0) {
const row = response.data.result.rows[0];
if (row.elements && row.elements.length > 0) {
distance = row.elements[0].distance / 1000; // 转换为公里
}
}
// 然后检查 elements 字段
else if (response.data.result.elements && response.data.result.elements.length > 0) {
distance = response.data.result.elements[0].distance / 1000; // 转换为公里
}
// 最后检查 distance 字段
else if (response.data.result.distance) {
distance = response.data.result.distance / 1000; // 转换为公里
}
// 如果都没有,抛出错误
else {
console.error('无法获取距离数据,响应结构:', response.data.result);
throw new Error('无法获取距离数据');
}
const baseRate = 0.5; // 默认基础费率(元/公里/公斤)
const weight = params.goodsInfo.weight || 1;
const freight = Math.floor(distance * baseRate * weight);
const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天
console.log('腾讯地图API距离计算成功,距离:', distance, '公里');
resolve({ // 获取运费估算历史记录
success: true, getFreightHistory: function (params) {
data: { console.log('API.getFreightHistory - 获取运费估算历史记录');
freight: freight, console.log('API.getFreightHistory - 参数:', params);
distance: Math.round(distance * 10) / 10, // 保留一位小数
deliveryTime: deliveryTime // 构建查询参数
} const queryParams = {
}); userId: params?.userId || wx.getStorageSync('userId'),
} catch (error) { productId: params?.productId,
console.error('处理距离数据时出错:', error); page: params?.page || 1,
// 如果处理距离数据时出错,使用随机数据作为fallback pageSize: params?.pageSize || 10
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里 };
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({
success: true,
data: {
freight: mockFreight,
distance: mockDistance,
deliveryTime: mockDeliveryTime
}
});
}
} else {
console.error('腾讯地图API距离计算失败:', response.data);
// 如果腾讯地图API调用失败,使用随机数据作为fallback
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({
success: true,
data: {
freight: mockFreight,
distance: mockDistance,
deliveryTime: mockDeliveryTime
}
});
}
},
fail: function (err) {
console.error('腾讯地图API调用失败:', err);
// 如果API调用失败,使用随机数据作为fallback
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({
success: true,
data: {
freight: mockFreight,
distance: mockDistance,
deliveryTime: mockDeliveryTime
}
});
}
});
}).catch(err => {
console.error('地址解析失败:', err);
// 如果地址解析失败,使用随机数据作为fallback
const mockDistance = Math.floor(Math.random() * 1000) + 100; // 100-1100公里
const baseRate = 0.5;
const weight = params.goodsInfo.weight || 1;
const mockFreight = Math.floor(mockDistance * baseRate * weight);
const mockDeliveryTime = Math.ceil(mockDistance / 200);
resolve({ // 调用后端API获取历史记录
success: true, return request('/api/freight/history', 'GET', queryParams).then(res => {
data: { console.log('API.getFreightHistory - 后端响应:', res);
freight: mockFreight, if (res && res.success) {
distance: mockDistance, return res;
deliveryTime: mockDeliveryTime } else {
} throw new Error(res?.message || '获取运费估算历史记录失败');
});
});
} }
}).catch(err => {
console.error('API.getFreightHistory - 获取历史记录失败:', err);
throw err;
}); });
}, },

Loading…
Cancel
Save