diff --git a/pages/freight-calculator/index.js b/pages/freight-calculator/index.js index 3915ae4..4c867b4 100644 --- a/pages/freight-calculator/index.js +++ b/pages/freight-calculator/index.js @@ -280,9 +280,32 @@ Page({ // 加载历史记录 loadHistoryRecords: function () { - const history = wx.getStorageSync('freightCalculatorHistory') || []; - this.setData({ - historyRecords: history.slice(0, 10) // 只显示最近10条记录 + this.setData({ loading: true }); + + 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 () { const that = this; 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 () { const that = this; @@ -764,7 +851,8 @@ Page({ const params = { origin: this.data.origin, destination: this.data.destination, - goodsInfo: this.data.goodsInfo + goodsInfo: this.data.goodsInfo, + productId: this.data.selectedGoods.productId || this.data.selectedGoods.id }; // 调用API计算运费 @@ -987,12 +1075,28 @@ Page({ this.setData({ loading: true }); + // 更新 goodsInfo 中的重量和体积 + this.setData({ + 'goodsInfo.weight': weight, + 'goodsInfo.volume': volume + }); + // 构建请求参数 const params = { origin: this.data.origin, destination: this.data.destination, - goodsInfo: this.data.goodsInfo, - vehicleInfo: this.data.vehicleInfo + goodsInfo: { + 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计算运费,获取距离信息 diff --git a/pages/freight-calculator/index.wxml b/pages/freight-calculator/index.wxml index ce2b09b..0b14d61 100644 --- a/pages/freight-calculator/index.wxml +++ b/pages/freight-calculator/index.wxml @@ -34,9 +34,14 @@ - + + + + diff --git a/server-example/server-mysql.js b/server-example/server-mysql.js index 8440af6..b4579b8 100644 --- a/server-example/server-mysql.js +++ b/server-example/server-mysql.js @@ -4,6 +4,149 @@ function getCurrentTime() { 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() { return getCurrentTime().toISOString(); } @@ -131,7 +274,7 @@ app.post('/api/freight/calculate', (req, res) => { console.log('===== 运费计算接口被调用 ====='); 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; // 验证参数 @@ -149,10 +292,6 @@ app.post('/api/freight/calculate', (req, res) => { goodsInfo = { ...goodsInfo, weight: 1 }; } - // 计算运费(使用默认费率,用户可根据自己的物流标准调整) - const baseRate = 0.5; // 默认基础费率(元/公里/公斤) - const weight = goodsInfo.weight || 1; - // 检查是否有经纬度信息 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); console.log('腾讯地图API响应:', response); - if (response.status === 0 && response.result && response.result.elements && response.result.elements.length > 0) { - const distance = response.result.elements[0].distance / 1000; // 转换为公里 - const freight = Math.floor(distance * baseRate * weight); - const deliveryTime = Math.ceil(distance / 200); // 公路:200公里/天 - - console.log('腾讯地图API距离计算成功,距离:', distance, '公里'); - - res.json({ - success: true, - data: { - freight: freight, + let result; + if (response.status === 0 && response.result && response.result.rows && response.result.rows.length > 0) { + // 检查rows[0]是否有elements属性 + const row = response.result.rows[0]; + if (row.elements && row.elements.length > 0) { + const distance = row.elements[0].distance / 1000; // 转换为公里 + // 计算运费区间 + const [feeMin, feeMax] = calculateYunmanmanFee(distance, goodsInfo.weight || 1, goodsInfo.volume || 0, vehicleType || '平板', truckLength || '5米'); + const deliveryTime = Math.ceil(distance / 80); // 公路:80公里/天 + + 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, // 保留一位小数 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 { console.error('腾讯地图API距离计算失败:', response); // 如果腾讯地图API调用失败,使用固定距离作为fallback 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公里/天 - res.json({ - success: true, - data: { - freight: freight, - distance: distance, - deliveryTime: deliveryTime - } + result = { + freight: Math.floor((feeMin + feeMax) / 2), // 中间值 + feeMin: feeMin, + feeMax: feeMax, + 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({ + success: true, + data: result + }); } catch (error) { console.error('处理腾讯地图API响应时出错:', error); // 如果处理响应时出错,使用固定距离作为fallback @@ -213,13 +399,36 @@ app.post('/api/freight/calculate', (req, res) => { const freight = Math.floor(distance * baseRate * weight); 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({ success: true, - data: { - freight: freight, - distance: distance, - deliveryTime: deliveryTime - } + data: result }); } }); @@ -230,13 +439,36 @@ app.post('/api/freight/calculate', (req, res) => { const freight = Math.floor(distance * baseRate * weight); 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({ success: true, - data: { - freight: freight, - distance: distance, - deliveryTime: deliveryTime - } + data: result }); }); } else { @@ -245,13 +477,36 @@ app.post('/api/freight/calculate', (req, res) => { const freight = Math.floor(distance * baseRate * weight); 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({ success: true, - data: { - freight: freight, - distance: distance, - deliveryTime: deliveryTime - } + data: result }); } @@ -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 帖子创建接口 app.post('/api/eggbar/posts', async (req, res) => { @@ -1784,7 +2108,7 @@ Product.init({ allowNull: false }, region: { - type: DataTypes.STRING(100), + type: DataTypes.STRING(255), }, price: { type: DataTypes.STRING(10), @@ -2775,6 +3099,105 @@ UserFollowupHistory.init({ 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和创建时间联合索引' + } + ] +}); + // 定义模型之间的关联关系 // 用户和商品的一对多关系 (卖家发布商品) diff --git a/utils/api.js b/utils/api.js index 2fddf4b..73fb066 100644 --- a/utils/api.js +++ b/utils/api.js @@ -1226,290 +1226,56 @@ module.exports = { params.goodsInfo.weight = 1; } - // 直接使用腾讯地图API计算真实距离 - return new Promise((resolve, reject) => { - // 定义获取经纬度的函数 - function getCoordinates(address) { - 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); - } - }); - }); + // 获取用户信息 + const userId = wx.getStorageSync('userId'); + const userInfo = wx.getStorageSync('userInfo'); + const phoneNumber = userInfo?.phoneNumber || wx.getStorageSync('phoneNumber'); + + // 构建请求数据 + const requestData = { + ...params, + userId: userId, + phoneNumber: phoneNumber + }; + + // 调用后端API计算运费 + return request('/api/freight/calculate', 'POST', requestData).then(res => { + console.log('API.calculateFreight - 后端响应:', res); + if (res && res.success) { + return res; + } else { + throw new Error(res?.message || '运费计算失败'); } - - // 检查是否有经纬度信息 - 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, - data: { - freight: freight, - distance: Math.round(distance * 10) / 10, // 保留一位小数 - 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({ - success: true, - data: { - freight: mockFreight, - distance: mockDistance, - deliveryTime: mockDeliveryTime - } - }); - } - }); + }).catch(err => { + console.error('API.calculateFreight - 计算运费失败:', err); + throw err; + }); + }, + + // 获取运费估算历史记录 + getFreightHistory: function (params) { + console.log('API.getFreightHistory - 获取运费估算历史记录'); + console.log('API.getFreightHistory - 参数:', params); + + // 构建查询参数 + const queryParams = { + userId: params?.userId || wx.getStorageSync('userId'), + productId: params?.productId, + page: params?.page || 1, + pageSize: params?.pageSize || 10 + }; + + // 调用后端API获取历史记录 + return request('/api/freight/history', 'GET', queryParams).then(res => { + console.log('API.getFreightHistory - 后端响应:', res); + if (res && res.success) { + return res; } else { - // 没有经纬度信息,先进行地址解析 - 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}`; - - Promise.all([ - 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, - data: { - freight: freight, - distance: Math.round(distance * 10) / 10, // 保留一位小数 - 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({ - 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({ - success: true, - data: { - freight: mockFreight, - distance: mockDistance, - deliveryTime: mockDeliveryTime - } - }); - }); + throw new Error(res?.message || '获取运费估算历史记录失败'); } + }).catch(err => { + console.error('API.getFreightHistory - 获取历史记录失败:', err); + throw err; }); },