// pages/freight-calculator/index.js const API = require('../../utils/api.js'); Page({ data: { // 出发地信息 origin: { province: '', city: '', district: '', detail: '' }, // 目的地信息 destination: { province: '', city: '', district: '', detail: '' }, // 货物信息 goodsInfo: { weight: '', // 重量(kg) volume: '', // 体积(m³) quantity: 1, // 数量 type: 'egg' // 货物类型,默认为鸡蛋 }, // 物流人员信息 logisticsPersonnel: [ { id: 1, name: '张三', position: '物流经理', experience: 5, phone: '13800138000' }, { id: 2, name: '李四', position: '物流经理', experience: 3, phone: '13900139000' }, { id: 3, name: '王五', position: '物流经理', experience: 2, phone: '13700137000' } ], // 选中的货源信息 selectedGoods: {}, // 选中的规格索引 selectedSpecIndex: 0, // 计算结果 calculationResult: null, // 地址选择器状态 showOriginPicker: false, showDestinationPicker: false, // 加载状态 loading: false, // 历史记录 historyRecords: [], // 地址选择器数据 regionList: { provinces: [], cities: [], districts: [] }, // 地址选择器当前选中 pickerValues: { origin: [0, 0, 0], destination: [0, 0, 0] }, // 运输模式 transportModes: ['货拉拉', '运满满', '零担拼车'], transportModeIndex: 0, // 包装类型 packagingTypes: ['标准包装', '加强包装'], packagingIndex: 0, // 车型 vehicleTypes: ['面包车', '依维柯', '平板', '厢式', '高栏车', '集装箱', '自卸', '冷藏', '保温', '棉被车', '爬梯车', '飞翼车', '高低板'], vehicleTypeIndex: 0, // 车长 truckLengths: ['1.4米', '1.8米', '2.7米', '3.3米', '3.8米', '4.2米'], truckLengthIndex: 5, // 天气状况 weatherTypes: ['晴朗', '多云', '小雨', '中雨', '大雨', '暴雨', '雪', '雾'], weatherIndex: 0, // 是否节假日 holidayOptions: ['否', '是'], holidayIndex: 0, // 时间段 timePeriods: ['上午', '下午', '晚上'], timePeriodIndex: 0, // 输入值 distance: '', weight: '', volume: '', waitTime: '40', // 车型信息 vehicleInfo: '面包车(1.4米): 0-500kg, 0-5m³', // 计算结果 showResult: false, feeRange: '', marketPrice: '', complianceStatus: '', isCompliant: true, detailText: '', // 车型和车长对应关系 vehicleLengthMap: { '面包车': ['1.4米', '1.8米', '2.7米', '3.3米', '3.8米', '4.2米'], '依维柯': ['3.3米', '3.8米', '4.2米', '5米'], '平板': ['4.2米', '5米', '6.2米', '6.8米', '7.7米', '8.2米', '8.7米', '9.6米', '11.7米', '12.5米', '13米', '13.7米', '15米', '16米', '17.5米'], '厢式': ['4.2米', '5米', '6.2米', '6.8米', '7.7米', '8.2米', '8.7米', '9.6米', '11.7米', '12.5米'], '高栏车': ['4.2米', '5米', '6.2米', '6.8米', '7.7米', '8.2米', '8.7米', '9.6米', '11.7米', '12.5米', '13米', '13.7米', '15米', '16米', '17.5米'], '集装箱': ['9.6米', '11.7米', '12.5米', '13米', '13.7米', '15米', '16米', '17.5米'], '自卸': ['4.2米', '5米', '6.2米', '6.8米', '7.7米', '8.2米', '8.7米', '9.6米'], '冷藏': ['4.2米', '5米', '6.2米', '6.8米', '7.7米', '8.2米', '8.7米', '9.6米'], '保温': ['4.2米', '5米', '6.2米', '6.8米'], '棉被车': ['4.2米', '5米', '6.2米', '6.8米', '7.7米'], '爬梯车': ['6.8米', '7.7米', '8.2米', '8.7米', '9.6米'], '飞翼车': ['4.2米', '5米', '6.2米', '6.8米', '7.7米', '8.2米', '8.7米', '9.6米'], '高低板': ['6.8米', '7.7米', '8.2米', '8.7米', '9.6米', '11.7米', '12.5米', '13米', '13.7米', '15米', '16米', '17.5米'] }, // 基础车型信息 baseInfo: { '面包车': ['0-500kg', '0-5m³'], '依维柯': ['500-1500kg', '5-12m³'], '平板': ['3000-15000kg', '20-60m³'], '厢式': ['2000-10000kg', '15-45m³'], '高栏车': ['3000-15000kg', '20-60m³'], '集装箱': ['8000-20000kg', '40-80m³'], '自卸': ['5000-12000kg', '20-45m³'], '冷藏': ['2000-8000kg', '15-40m³'], '保温': ['2000-6000kg', '15-30m³'], '棉被车': ['2000-8000kg', '15-40m³'], '爬梯车': ['5000-12000kg', '20-45m³'], '飞翼车': ['3000-10000kg', '20-45m³'], '高低板': ['8000-20000kg', '40-80m³'] } }, onLoad: function (options) { // 页面加载时的初始化逻辑 console.log('物流运费估算页面加载,options:', options); // 加载历史记录 this.loadHistoryRecords(); // 初始化地址选择器数据 this.initRegionData(); // 如果从商品详情页跳转过来,获取商品信息 if (options.goodsId) { this.loadGoodsInfo(options.goodsId); } // 如果直接传递了货源信息 (goodsInfo) if (options.goodsInfo) { try { const goodsInfo = JSON.parse(options.goodsInfo); this.setData({ selectedGoods: goodsInfo, 'goodsInfo.weight': goodsInfo.grossWeight || '', 'goodsInfo.quantity': 1 }); } catch (e) { console.error('解析货源信息失败:', e); } } // 如果直接传递了货源信息 (goodsData) if (options.goodsData) { try { // 尝试直接解析 let goodsData; try { goodsData = JSON.parse(options.goodsData); } catch (e1) { // 如果直接解析失败,尝试解码后再解析 try { const decodedGoodsData = decodeURIComponent(options.goodsData); goodsData = JSON.parse(decodedGoodsData); } catch (e2) { console.error('解析货源信息失败 (已尝试解码):', e2); throw e2; } } this.setData({ selectedGoods: goodsData, 'goodsInfo.weight': goodsData.grossWeight || '', 'goodsInfo.quantity': 1 }); // 设置出发地为商品所在地 if (goodsData.region) { const regionInfo = this.parseRegion(goodsData.region); this.setData({ 'origin.province': regionInfo.province || '', 'origin.city': regionInfo.city || '', 'origin.district': regionInfo.district || '' }); } } catch (e) { console.error('解析货源信息失败:', e); } } }, // 初始化地址选择器数据 initRegionData: function () { // 这里可以从API获取地址数据,或者使用本地数据 const provinces = [ '北京市', '上海市', '广东省', '江苏省', '浙江省', '山东省', '河南省', '四川省', '湖北省', '福建省', '湖南省', '安徽省', '河北省', '辽宁省', '陕西省', '江西省', '云南省', '黑龙江省', '山西省', '广西壮族自治区', '内蒙古自治区', '吉林省', '贵州省', '新疆维吾尔自治区', '甘肃省', '重庆市', '宁夏回族自治区', '青海省', '西藏自治区', '海南省' ]; this.setData({ 'regionList.provinces': provinces }); }, // 加载商品信息 loadGoodsInfo: function (goodsId) { // 从本地存储获取商品信息 const goods = wx.getStorageSync('goods') || []; const goodsItem = goods.find(item => item.id === goodsId || item.productId === goodsId); if (goodsItem) { // 设置选中的货源信息 this.setData({ selectedGoods: goodsItem }); // 设置出发地为商品所在地 if (goodsItem.region) { const regionInfo = this.parseRegion(goodsItem.region); this.setData({ 'origin.province': regionInfo.province || '', 'origin.city': regionInfo.city || '', 'origin.district': regionInfo.district || '' }); } // 设置货物重量(如果有) if (goodsItem.grossWeight) { this.setData({ 'goodsInfo.weight': goodsItem.grossWeight }); } } }, // 解析地区信息 parseRegion: function (region) { if (!region) return {}; // 简单的地区解析逻辑,实际项目中可能需要更复杂的解析 const parts = region.split(' '); return { province: parts[0] || '', city: parts[1] || '', district: parts[2] || '' }; }, // 加载历史记录 loadHistoryRecords: function () { 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条记录 }); }); }, // 保存历史记录 saveHistoryRecord: function (result) { const history = wx.getStorageSync('freightCalculatorHistory') || []; const record = { id: Date.now(), origin: this.data.origin, destination: this.data.destination, goodsInfo: this.data.goodsInfo, vehicleInfo: this.data.vehicleInfo, transportMode: this.data.transportMode, result: result, timestamp: new Date().toISOString() }; // 添加到历史记录开头 history.unshift(record); // 只保留最近20条记录 const newHistory = history.slice(0, 20); wx.setStorageSync('freightCalculatorHistory', newHistory); // 更新页面数据 this.setData({ historyRecords: newHistory.slice(0, 10) }); }, // 输入出发地 bindOriginInput: function (e) { const { key } = e.currentTarget.dataset; this.setData({ [`origin.${key}`]: e.detail.value }); }, // 输入目的地 bindDestinationInput: function (e) { const { key } = e.currentTarget.dataset; this.setData({ [`destination.${key}`]: e.detail.value }); }, // 输入货物信息 bindGoodsInfoInput: function (e) { const { key } = e.currentTarget.dataset; this.setData({ [`goodsInfo.${key}`]: e.detail.value }); }, // 选择规格组合 bindSpecChange: function (e) { const index = e.detail.value; this.setData({ selectedSpecIndex: index }); }, // 地址选择器值变化 bindRegionChange: function (e) { const { type } = e.currentTarget.dataset; const values = e.detail.value; // 更新地址信息 if (type === 'origin') { this.setData({ 'origin.province': values[0], 'origin.city': values[1], 'origin.district': values[2] }); } else if (type === 'destination') { this.setData({ 'destination.province': values[0], 'destination.city': values[1], 'destination.district': values[2] }); } }, // 打开出发地选择器 openOriginPicker: function () { this.setData({ showOriginPicker: true }); }, // 打开目的地选择器 openDestinationPicker: function () { this.setData({ showDestinationPicker: true }); }, // 关闭地址选择器 closePicker: function () { this.setData({ showOriginPicker: false, showDestinationPicker: false }); }, // 选择地址 selectAddress: function (e) { const { type, address } = e.detail; if (type === 'origin') { this.setData({ origin: address, showOriginPicker: false }); } else if (type === 'destination') { this.setData({ destination: address, showDestinationPicker: false }); } }, // 使用当前位置作为目的地 useCurrentLocation: 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({ destination: { 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' }); } }); }, // 使用当前位置作为出发地 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; wx.chooseLocation({ success(res) { console.log('用户选择的出发地位置信息:', res); const name = res.name; const address = res.address; const latitude = res.latitude; const longitude = res.longitude; // 使用腾讯地图API进行逆地理编码,获取详细地址信息 wx.request({ url: 'https://apis.map.qq.com/ws/geocoder/v1/', data: { location: `${latitude},${longitude}`, key: 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77' }, success: function (response) { 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: `${name} ${address}`, latitude: latitude, longitude: longitude } }); wx.showToast({ title: '出发地选择成功', icon: 'success' }); } else { wx.showToast({ title: '地址解析失败,请手动输入', icon: 'none' }); } }, fail: function (err) { console.error('地址解析失败:', err); wx.showToast({ title: '地址解析失败,请手动输入', icon: 'none' }); } }); }, fail(err) { console.error('选择出发地位置失败:', err); if (err.errMsg === 'chooseLocation:fail auth deny') { wx.showToast({ title: '需要位置授权才能选择地点', icon: 'none', duration: 2000 }); // 引导用户重新授权 that.requestLocationAuth(); } else { wx.showToast({ title: '选择位置失败', icon: 'none', duration: 2000 }); } } }); }, // 手动选择目的地位置 chooseDestinationLocation: function () { const that = this; wx.chooseLocation({ success(res) { console.log('用户选择的目的地位置信息:', res); const name = res.name; const address = res.address; const latitude = res.latitude; const longitude = res.longitude; // 使用腾讯地图API进行逆地理编码,获取详细地址信息 wx.request({ url: 'https://apis.map.qq.com/ws/geocoder/v1/', data: { location: `${latitude},${longitude}`, key: 'OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77' }, success: function (response) { if (response.data.status === 0) { const result = response.data.result; that.setData({ destination: { province: result.address_component.province || '', city: result.address_component.city || '', district: result.address_component.district || '', detail: `${name} ${address}`, latitude: latitude, longitude: longitude } }); wx.showToast({ title: '目的地选择成功', icon: 'success' }); } else { wx.showToast({ title: '地址解析失败,请手动输入', icon: 'none' }); } }, fail: function (err) { console.error('地址解析失败:', err); wx.showToast({ title: '地址解析失败,请手动输入', icon: 'none' }); } }); }, fail(err) { console.error('选择目的地位置失败:', err); if (err.errMsg === 'chooseLocation:fail auth deny') { wx.showToast({ title: '需要位置授权才能选择地点', icon: 'none', duration: 2000 }); // 引导用户重新授权 that.requestLocationAuth(); } else { wx.showToast({ title: '选择位置失败', icon: 'none', duration: 2000 }); } } }); }, // 请求位置授权 requestLocationAuth: function () { const that = this; console.log('开始请求位置授权'); wx.showLoading({ title: '请求授权中...', mask: true }); // 检查用户是否已经拒绝过授权 wx.getSetting({ success(res) { wx.hideLoading(); if (res.authSetting['scope.userLocation'] === false) { // 用户已经拒绝过授权,直接引导到设置页面 wx.showModal({ title: '需要位置授权', content: '请在设置中开启位置授权,以便我们为您提供相关服务', showCancel: true, cancelText: '取消', confirmText: '去授权', success: (res) => { if (res.confirm) { // 打开设置页面让用户手动开启授权 wx.openSetting({ success: (settingRes) => { console.log('设置页面返回结果:', settingRes); if (settingRes.authSetting['scope.userLocation']) { // 用户在设置中开启了位置授权 wx.showToast({ title: '授权成功', icon: 'success', duration: 1500 }); } else { // 用户在设置中仍未开启位置授权 wx.showToast({ title: '您已拒绝位置授权', icon: 'none' }); } }, fail: (err) => { console.error('打开设置失败:', err); wx.showToast({ title: '打开设置失败', icon: 'none' }); } }); } } }); } else { // 用户未拒绝过授权,调用 authorize wx.authorize({ scope: 'scope.userLocation', success() { console.log('位置授权成功'); wx.showToast({ title: '授权成功', icon: 'success', duration: 1500 }); }, fail(err) { console.log('位置授权失败:', err); // 授权失败,弹出模态框引导用户重新授权 wx.showModal({ title: '需要位置授权', content: '请在设置中开启位置授权,以便我们为您提供相关服务', showCancel: true, cancelText: '取消', confirmText: '去授权', success: (res) => { if (res.confirm) { // 打开设置页面让用户手动开启授权 wx.openSetting({ success: (settingRes) => { console.log('设置页面返回结果:', settingRes); if (settingRes.authSetting['scope.userLocation']) { // 用户在设置中开启了位置授权 wx.showToast({ title: '授权成功', icon: 'success', duration: 1500 }); } else { // 用户在设置中仍未开启位置授权 wx.showToast({ title: '您已拒绝位置授权', icon: 'none' }); } }, fail: (err) => { console.error('打开设置失败:', err); wx.showToast({ title: '打开设置失败', icon: 'none' }); } }); } } }); } }); } }, fail(err) { wx.hideLoading(); console.error('获取设置失败:', err); wx.showToast({ title: '获取设置失败', icon: 'none' }); } }); }, // 计算运费 calculateFreight: function () { // 验证输入 if (!this.data.origin.province || !this.data.destination.province) { wx.showToast({ title: '请填写完整的出发地和目的地', icon: 'none' }); return; } // 如果没有重量和体积,使用默认值 1 if (!this.data.goodsInfo.weight && !this.data.goodsInfo.volume) { this.setData({ 'goodsInfo.weight': 1 }); } this.setData({ loading: true }); // 构建请求参数 const params = { origin: this.data.origin, destination: this.data.destination, goodsInfo: this.data.goodsInfo, productId: this.data.selectedGoods.productId || this.data.selectedGoods.id }; // 调用API计算运费 API.calculateFreight(params).then(res => { this.setData({ loading: false }); if (res.success) { this.setData({ calculationResult: res.data }); // 保存历史记录 this.saveHistoryRecord(res.data); } else { wx.showToast({ title: res.message || '计算失败,请稍后重试', icon: 'none' }); } }).catch(err => { this.setData({ loading: false }); console.error('计算运费失败:', err); wx.showToast({ title: '网络错误,请稍后重试', icon: 'none' }); }); }, // 清空输入 clearInput: function () { this.setData({ origin: { province: '', city: '', district: '', detail: '' }, destination: { province: '', city: '', district: '', detail: '' }, goodsInfo: { weight: '', volume: '', quantity: 1 }, // 运输参数 transportModeIndex: 0, packagingIndex: 0, vehicleTypeIndex: 0, truckLengthIndex: 5, weight: '', volume: '', vehicleInfo: '面包车(1.4米): 0-500kg, 0-5m³', // 计算结果 showResult: false, feeRange: '', marketPrice: '', complianceStatus: '', isCompliant: true, detailText: '', calculationResult: null }); }, // 使用历史记录 useHistoryRecord: function (e) { const index = e.currentTarget.dataset.index; const record = this.data.historyRecords[index]; this.setData({ origin: record.origin, destination: record.destination, goodsInfo: record.goodsInfo, transportMode: record.transportMode, calculationResult: record.result }); }, // 删除历史记录 deleteHistoryRecord: function (e) { const index = e.currentTarget.dataset.index; const history = wx.getStorageSync('freightCalculatorHistory') || []; history.splice(index, 1); wx.setStorageSync('freightCalculatorHistory', history); this.setData({ historyRecords: history.slice(0, 10) }); }, // 清空历史记录 clearHistory: function () { wx.setStorageSync('freightCalculatorHistory', []); this.setData({ historyRecords: [] }); }, // 返回上一页 navigateBack: function () { wx.navigateBack({ delta: 1 }); }, // 拨打电话 makePhoneCall: function (e) { const phone = e.currentTarget.dataset.phone; if (phone) { wx.makePhoneCall({ phoneNumber: phone, success: function () { console.log('拨打电话成功'); }, fail: function (err) { console.error('拨打电话失败:', err); wx.showToast({ title: '拨打电话失败', icon: 'none' }); } }); } }, // 运输模式选择 bindTransportModeChange: function(e) { this.setData({ transportModeIndex: e.detail.value }); }, // 包装类型选择 bindPackagingChange: function(e) { this.setData({ packagingIndex: e.detail.value }); }, // 车型选择 bindVehicleTypeChange: function(e) { const vehicleTypeIndex = e.detail.value; const vehicleType = this.data.vehicleTypes[vehicleTypeIndex]; // 更新车长选项 const truckLengths = this.data.vehicleLengthMap[vehicleType]; this.setData({ vehicleTypeIndex: vehicleTypeIndex, truckLengths: truckLengths, truckLengthIndex: 0 }); // 更新车型信息 this.updateVehicleInfo(); }, // 车长选择 bindTruckLengthChange: function(e) { this.setData({ truckLengthIndex: e.detail.value }); // 更新车型信息 this.updateVehicleInfo(); }, // 输入处理 bindWeightInput: function(e) { this.setData({ weight: e.detail.value }); }, bindVolumeInput: function(e) { this.setData({ volume: e.detail.value }); }, // 更新车型信息 updateVehicleInfo: function() { const vehicleType = this.data.vehicleTypes[this.data.vehicleTypeIndex]; const truckLength = this.data.truckLengths[this.data.truckLengthIndex]; if (this.data.baseInfo[vehicleType]) { const [weightRange, volumeRange] = this.data.baseInfo[vehicleType]; this.setData({ vehicleInfo: `${vehicleType}(${truckLength}): ${weightRange}, ${volumeRange}` }); } else { this.setData({ vehicleInfo: '请选择车型' }); } }, // 计算运费 calculate: function(e) { try { // 获取输入参数 const transportMode = this.data.transportModes[this.data.transportModeIndex]; const weight = parseFloat(this.data.weight); const volume = parseFloat(this.data.volume); const packagingType = this.data.packagingIndex === 0 ? 'standard' : 'enhanced'; const vehicleType = this.data.vehicleTypes[this.data.vehicleTypeIndex]; const truckLength = this.data.truckLengths[this.data.truckLengthIndex]; // 验证输入 if (isNaN(weight) || weight <= 0) { wx.showToast({ title: '鸡蛋重量必须大于0', icon: 'none' }); return; } if (isNaN(volume) || volume <= 0) { wx.showToast({ title: '货物体积必须大于0', icon: 'none' }); return; } // 检查是否有出发地和目的地信息 if (!this.data.origin.province || !this.data.destination.province) { wx.showToast({ title: '请选择出发地和目的地', icon: 'none' }); return; } this.setData({ loading: true }); // 更新 goodsInfo 中的重量和体积 this.setData({ 'goodsInfo.weight': weight, 'goodsInfo.volume': volume }); // 构建请求参数 const params = { origin: this.data.origin, destination: this.data.destination, 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计算运费,获取距离信息 API.calculateFreight(params).then(res => { this.setData({ loading: false }); if (res.success) { // 使用API返回的距离 const distance = res.data.distance || 100; // 自动获取当前时间、天气情况和是否节假日 const { weather, holiday, timePeriod } = this.getAutoData(); // 调用计算函数(使用默认等候时间40分钟) const result = this.calculateEggShippingFee( transportMode, distance, weight, volume, packagingType, vehicleType, truckLength, 40, weather, holiday, timePeriod ); // 更新结果 this.setData({ showResult: true, feeRange: `${result.feeMin} - ${result.feeMax}元`, marketPrice: `${result.marketPrice}元`, complianceStatus: result.compliance.isCompliant ? '✓ 运输方案合规' : '✗ 运输方案不合规', isCompliant: result.compliance.isCompliant, detailText: this.generateDetailText(result, transportMode, weight, volume, packagingType, 40), calculationResult: res.data // 保存API返回的结果 }); // 保存历史记录 this.saveHistoryRecord({ freight: (result.feeMin + result.feeMax) / 2, distance: distance, deliveryTime: Math.ceil(distance / 80), // 简单估算,假设平均速度80km/h feeRange: `${result.feeMin} - ${result.feeMax}元`, marketPrice: result.marketPrice, complianceStatus: result.compliance.isCompliant ? '合规' : '不合规' }); } else { wx.showToast({ title: res.message || '计算失败,请稍后重试', icon: 'none' }); } }).catch(err => { this.setData({ loading: false }); console.error('计算运费失败:', err); wx.showToast({ title: '网络错误,请稍后重试', icon: 'none' }); }); } catch (error) { this.setData({ loading: false }); wx.showToast({ title: '计算出错,请检查输入', icon: 'none' }); console.error(error); } }, // 自动获取当前时间、天气情况和是否节假日 getAutoData: function() { // 获取当前时间 const now = new Date(); const hour = now.getHours(); // 确定时间段 let timePeriod; if (hour >= 6 && hour < 12) { timePeriod = '上午'; } else if (hour >= 12 && hour < 18) { timePeriod = '下午'; } else { timePeriod = '晚上'; } // 简单判断是否节假日(这里只是示例,实际需要更复杂的逻辑) // 这里假设周末为节假日 const dayOfWeek = now.getDay(); const holiday = dayOfWeek === 0 || dayOfWeek === 6; // 天气情况(这里只是示例,实际需要调用天气API) // 这里使用默认值晴朗 const weather = '晴朗'; return { weather, holiday, timePeriod }; }, // 生成详细文本 generateDetailText: function(result, transportMode, weight, volume, packagingType, waitTime) { let text = `费用明细:\n`; text += ` 最低运费: ${result.feeMin}元\n`; text += ` 最高运费: ${result.feeMax}元\n`; text += ` 平均运费: ${result.feeAvg}元\n\n`; if (result.details.breakdown) { text += `费用组成:\n`; for (const [key, value] of Object.entries(result.details.breakdown)) { text += ` ${key}: ${value}元\n`; } text += `\n`; } text += `运输详情:\n`; text += ` 运输模式: ${transportMode}\n`; text += ` 车型: ${result.details.vehicleType}\n`; text += ` 包装类型: ${packagingType === 'standard' ? '标准包装' : '加强包装'}\n`; text += ` 实际重量: ${weight}公斤\n`; text += ` 体积: ${volume}立方米\n`; if (result.details.volumeWeight) { text += ` 体积重量: ${result.details.volumeWeight}公斤\n`; } if (result.details.chargeWeight) { text += ` 计费重量: ${result.details.chargeWeight}公斤\n`; } text += ` 预计等候时间: ${waitTime}分钟\n`; if (result.details.estimatedPackages) { text += ` 估算包装数量: ${result.details.estimatedPackages}个\n`; } // 添加运输距离信息 text += ` 运输距离: ${result.distance || 0}公里\n`; text += `\n`; if (result.details.marketFactor) { text += `市场因素:\n`; text += ` 天气状况: ${result.details.weather}\n`; text += ` 是否节假日: ${result.details.holiday}\n`; text += ` 时间段: ${result.details.timePeriod}\n`; text += ` 市场因素系数: ${result.details.marketFactor}\n\n`; } text += `市场参考:\n`; text += ` 市场参考价: ${result.marketPrice}元\n`; text += ` 价格合理性: ${result.priceReasonability}\n\n`; if (!result.compliance.isCompliant) { text += `不合规原因:\n`; for (const issue of result.compliance.issues) { text += ` - ${issue}\n`; } } return text; }, // 计算鸡蛋运输运费 calculateEggShippingFee: function(transportMode, distance, weight, volume, packagingType, vehicleType, truckLength, waitTime, weather, holiday, timePeriod) { // 计算市场因素系数 const calculateMarketFactor = (weather, holiday, timePeriod) => { let factor = 1.0; // 天气因素 const weatherFactors = { '晴朗': 1.0, '多云': 1.05, '小雨': 1.1, '中雨': 1.2, '大雨': 1.3, '暴雨': 1.5, '雪': 1.4, '雾': 1.3 }; factor *= weatherFactors[weather] || 1.0; // 节假日因素 if (holiday) { factor *= 1.2; } // 时间段因素 const timeFactors = { '上午': 1.0, '下午': 1.1, '晚上': 1.2 }; factor *= timeFactors[timePeriod] || 1.0; return factor; }; // 计算体积重量(物流行业标准:1立方米 = 333公斤) const volumeWeight = volume * 333; // 计费重量取实际重量和体积重量的较大值 const chargeWeight = Math.max(weight, volumeWeight); // 计算市场因素系数 const marketFactor = calculateMarketFactor(weather, holiday, timePeriod); // 车长系数计算 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 truckLengthFactor = getTruckLengthFactor(truckLength); // 合规性检查参数 const complianceParams = { maxWeightPerVehicle: { '面包车': 500, '依维柯': 1500, '平板': 15000, '厢式': 10000, '高栏车': 15000, '集装箱': 20000, '自卸': 12000, '冷藏': 8000, '保温': 6000, '棉被车': 8000, '爬梯车': 12000, '飞翼车': 10000, '高低板': 20000 }, maxVolumePerVehicle: { '面包车': 5, '依维柯': 12, '平板': 60, '厢式': 45, '高栏车': 60, '集装箱': 80, '自卸': 45, '冷藏': 40, '保温': 30, '棉被车': 40, '爬梯车': 45, '飞翼车': 45, '高低板': 80 }, weightPerPackage: 20, volumePerPackage: 0.2, minDistance: 1, maxDistance: 2000 }; // 合规性检查 const compliance = { isCompliant: true, issues: [] }; // 检查距离 if (distance < complianceParams.minDistance) { compliance.isCompliant = false; compliance.issues.push(`运输距离必须大于等于${complianceParams.minDistance}公里`); } if (distance > complianceParams.maxDistance) { compliance.isCompliant = false; compliance.issues.push(`运输距离不能超过${complianceParams.maxDistance}公里`); } // 检查车型载重 if (complianceParams.maxWeightPerVehicle[vehicleType]) { if (chargeWeight > complianceParams.maxWeightPerVehicle[vehicleType]) { compliance.isCompliant = false; compliance.issues.push(`${vehicleType}载重不能超过${complianceParams.maxWeightPerVehicle[vehicleType]}公斤`); } } // 检查车型体积 if (complianceParams.maxVolumePerVehicle[vehicleType]) { if (volume > complianceParams.maxVolumePerVehicle[vehicleType]) { compliance.isCompliant = false; compliance.issues.push(`${vehicleType}体积不能超过${complianceParams.maxVolumePerVehicle[vehicleType]}立方米`); } } // 检查包装要求 const estimatedPackages = Math.max(weight / complianceParams.weightPerPackage, volume / complianceParams.volumePerPackage); if (estimatedPackages > 100) { compliance.isCompliant = false; compliance.issues.push('包装数量过多,建议分批运输'); } // 检查是否合规 const isCompliant = compliance.isCompliant; // 计算运费区间 let feeMin, feeMax, breakdown; if (transportMode === '货拉拉') { // 货拉拉收费标准 [feeMin, feeMax, breakdown] = this.calculateHuolalaFee(distance, vehicleType, truckLength, waitTime, packagingType); } else if (transportMode === '运满满') { // 运满满收费标准 [feeMin, feeMax, breakdown] = this.calculateYunmanmanFee(distance, weight, volume, vehicleType, truckLength); } else { // 零担拼车收费标准 [feeMin, feeMax, breakdown] = this.calculateLessThanTruckloadFee(distance, chargeWeight, packagingType, truckLength); } // 如果不合规(货物超过车型限制),调整运费 if (!isCompliant) { // 检查是否是载重或体积超过限制 const weightExceeded = weight > (complianceParams.maxWeightPerVehicle[vehicleType] || Infinity); const volumeExceeded = volume > (complianceParams.maxVolumePerVehicle[vehicleType] || Infinity); if (weightExceeded || volumeExceeded) { // 取重量和体积超出比例的最大值 let maxExceedRatio = 1.0; if (weightExceeded) { const maxWeight = complianceParams.maxWeightPerVehicle[vehicleType] || 1; const weightRatio = weight / maxWeight; maxExceedRatio = Math.max(maxExceedRatio, weightRatio); } if (volumeExceeded) { const maxVolume = complianceParams.maxVolumePerVehicle[vehicleType] || 1; const volumeRatio = volume / maxVolume; maxExceedRatio = Math.max(maxExceedRatio, volumeRatio); } // 根据最大超出比例计算调整系数 let exceedFactor; if (maxExceedRatio > 5) { exceedFactor = 2.0; } else if (maxExceedRatio > 3) { exceedFactor = 1.8; } else if (maxExceedRatio > 2) { exceedFactor = 1.6; } else { exceedFactor = 1.4; } // 应用超出系数 feeMin *= exceedFactor; feeMax *= exceedFactor; } } // 应用市场因素系数 feeMin *= marketFactor; feeMax *= marketFactor; // 计算平均运费 const feeAvg = (feeMin + feeMax) / 2; // 计算市场参考价 let marketPrice = this.calculateMarketPrice(transportMode, distance, weight, volume, vehicleType, truckLength); // 如果不合规(货物超过车型限制),调整市场参考价 if (!isCompliant) { // 检查是否是载重或体积超过限制 const weightExceeded = weight > (complianceParams.maxWeightPerVehicle[vehicleType] || Infinity); const volumeExceeded = volume > (complianceParams.maxVolumePerVehicle[vehicleType] || Infinity); if (weightExceeded || volumeExceeded) { // 取重量和体积超出比例的最大值 let maxExceedRatio = 1.0; if (weightExceeded) { const maxWeight = complianceParams.maxWeightPerVehicle[vehicleType] || 1; const weightRatio = weight / maxWeight; maxExceedRatio = Math.max(maxExceedRatio, weightRatio); } if (volumeExceeded) { const maxVolume = complianceParams.maxVolumePerVehicle[vehicleType] || 1; const volumeRatio = volume / maxVolume; maxExceedRatio = Math.max(maxExceedRatio, volumeRatio); } // 根据最大超出比例计算调整系数 let exceedFactor; if (maxExceedRatio > 5) { exceedFactor = 2.0; } else if (maxExceedRatio > 3) { exceedFactor = 1.8; } else if (maxExceedRatio > 2) { exceedFactor = 1.6; } else { exceedFactor = 1.4; } // 应用超出系数 marketPrice *= exceedFactor; } } // 应用市场因素系数 marketPrice *= marketFactor; // 评估价格合理性 let priceReasonability; if (feeAvg < marketPrice * 0.8) { priceReasonability = '价格偏低,可能存在服务质量风险'; } else if (feeAvg > marketPrice * 1.2) { priceReasonability = '价格偏高,建议重新议价'; } else { priceReasonability = '价格合理,符合市场行情'; } // 详细信息 const details = { breakdown: breakdown, volumeWeight: Math.round(volumeWeight * 100) / 100, chargeWeight: Math.round(chargeWeight * 100) / 100, estimatedPackages: Math.round(estimatedPackages), vehicleType: vehicleType, packagingType: packagingType, marketFactor: Math.round(marketFactor * 100) / 100, weather: weather, holiday: holiday ? '是' : '否', timePeriod: timePeriod }; return { feeMin: Math.round(feeMin * 100) / 100, feeMax: Math.round(feeMax * 100) / 100, feeAvg: Math.round(feeAvg * 100) / 100, marketPrice: Math.round(marketPrice * 100) / 100, priceReasonability: priceReasonability, compliance: compliance, details: details, distance: distance // 添加距离信息 }; }, // 货拉拉运费计算 calculateHuolalaFee: function(distance, vehicleType, truckLength, waitTime, packagingType) { // 车长系数计算 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: 30, startDistance: 5, unitPrice: 2.8, extraStart: 6, freeWaitTime: 40, waitFee: 5, waitInterval: 10 }, '依维柯': { startFee: 65, startDistance: 5, unitPrice: 4, extraStart: 6, freeWaitTime: 40, waitFee: 5, waitInterval: 10 }, '平板': { startFee: 200, startDistance: 10, unitPrice: 4.8, extraStart: 11, freeWaitTime: 60, waitFee: 20, waitInterval: 15 }, '厢式': { startFee: 220, startDistance: 10, unitPrice: 5.0, extraStart: 11, freeWaitTime: 60, waitFee: 20, waitInterval: 15 }, '高栏车': { startFee: 180, startDistance: 10, unitPrice: 4.5, extraStart: 11, freeWaitTime: 60, waitFee: 25, waitInterval: 15 }, '冷藏': { startFee: 280, startDistance: 10, unitPrice: 6.0, extraStart: 11, freeWaitTime: 60, waitFee: 30, waitInterval: 15 }, '保温': { startFee: 250, startDistance: 10, unitPrice: 5.5, extraStart: 11, freeWaitTime: 60, waitFee: 25, waitInterval: 15 }, '棉被车': { startFee: 230, startDistance: 10, unitPrice: 5.2, extraStart: 11, freeWaitTime: 60, waitFee: 22, waitInterval: 15 }, '飞翼车': { startFee: 240, startDistance: 10, unitPrice: 5.3, extraStart: 11, freeWaitTime: 60, waitFee: 23, waitInterval: 15 } }; const rate = rates[vehicleType] || rates['面包车']; // 获取车长系数 const truckLengthFactor = getTruckLengthFactor(truckLength); // 计算距离费用 let distanceFee; if (distance <= rate.startDistance) { distanceFee = rate.startFee; } else { const extraDistance = distance - rate.startDistance; distanceFee = rate.startFee + extraDistance * rate.unitPrice; } // 计算等候费用 let waitFee; if (waitTime > rate.freeWaitTime) { const extraWaitTime = waitTime - rate.freeWaitTime; waitFee = Math.ceil(extraWaitTime / rate.waitInterval) * rate.waitFee; } else { waitFee = 0; } // 应用车长系数 distanceFee *= truckLengthFactor; waitFee *= truckLengthFactor; // 计算包装费用 const packagingFee = packagingType === 'standard' ? 1 : 2; // 计算最低和最高运费(考虑价格波动10%) const baseFee = distanceFee + waitFee; const feeMin = baseFee * 0.9; const feeMax = baseFee * 1.1; // 费用明细 const breakdown = { '起步费': Math.round(rate.startFee * truckLengthFactor * 100) / 100, '距离费': Math.round((distanceFee - rate.startFee * truckLengthFactor) * 100) / 100, '等候费': Math.round(waitFee * 100) / 100, '包装费': packagingFee }; return [feeMin, feeMax, breakdown]; }, // 运满满运费计算 calculateYunmanmanFee: function(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; // 费用明细 const breakdown = { '起步费': rate.startFee, '距离费': Math.round((feeMin / 1.05 - rate.startFee) * 100) / 100, '平台佣金': Math.round((feeMin - feeMin / 1.05) * 100) / 100 }; return [feeMin, feeMax, breakdown]; }, // 零担拼车运费计算 calculateLessThanTruckloadFee: function(distance, chargeWeight, packagingType, truckLength) { // 车长系数计算 const getTruckLengthFactor = (truckLength) => { try { const length = parseFloat(truckLength.replace('米', '')); if (length <= 3.8) { return 0.9; } else if (length <= 4.2) { return 0.95; } else if (length <= 5) { return 1.0; } else if (length <= 6.8) { return 1.05; } else if (length <= 7.7) { return 1.1; } else if (length <= 9.6) { return 1.15; } else if (length <= 13) { return 1.2; } else { return 1.25; } } catch { return 1.0; } }; // 零担拼车收费标准 const perKgPer1000kmMin = 0.3; const perKgPer1000kmMax = 0.5; // 包装费用 const packagingFeeMin = packagingType === 'standard' ? 0.15 : 0.4; const packagingFeeMax = packagingType === 'standard' ? 0.25 : 0.6; // 易碎品加价 const fragileFactorMin = 1.02; const fragileFactorMax = 1.08; // 计算距离因子 const distanceFactor = distance / 1000; // 获取车长系数 const truckLengthFactor = getTruckLengthFactor(truckLength); // 计算运费 let freightFeeMin = chargeWeight * perKgPer1000kmMin * distanceFactor; let freightFeeMax = chargeWeight * perKgPer1000kmMax * distanceFactor; const packagingFeeTotalMin = chargeWeight * packagingFeeMin; const packagingFeeTotalMax = chargeWeight * packagingFeeMax; // 计算易碎品附加费 const fragileFeeMin = (freightFeeMin + packagingFeeTotalMin) * (fragileFactorMin - 1); const fragileFeeMax = (freightFeeMax + packagingFeeTotalMax) * (fragileFactorMax - 1); // 总运费 let feeMin = freightFeeMin + packagingFeeTotalMin + fragileFeeMin; let feeMax = freightFeeMax + packagingFeeTotalMax + fragileFeeMax; // 应用车长系数 feeMin *= truckLengthFactor; feeMax *= truckLengthFactor; // 费用明细 const breakdown = { '运费': Math.round(freightFeeMin * 100) / 100, '包装费': Math.round(packagingFeeTotalMin * 100) / 100, '易碎品附加费': Math.round(fragileFeeMin * 100) / 100 }; return [feeMin, feeMax, breakdown]; }, // 计算市场参考价 calculateMarketPrice: function(transportMode, 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 truckLengthFactor = getTruckLengthFactor(truckLength); let marketPrice; if (transportMode === '货拉拉') { // 基于货拉拉真实收费标准 const rates = { '面包车': 30 + Math.max(0, distance - 5) * 2.8, '依维柯': 65 + Math.max(0, distance - 5) * 4, '平板': 200 + Math.max(0, distance - 10) * 4.8, '厢式': 220 + Math.max(0, distance - 10) * 5.0, '高栏车': 180 + Math.max(0, distance - 10) * 4.5, '冷藏': 280 + Math.max(0, distance - 10) * 6.0, '保温': 250 + Math.max(0, distance - 10) * 5.5, '棉被车': 230 + Math.max(0, distance - 10) * 5.2, '飞翼车': 240 + Math.max(0, distance - 10) * 5.3 }; marketPrice = rates[vehicleType] || rates['面包车']; // 应用车长系数 marketPrice *= truckLengthFactor; } else if (transportMode === '运满满') { // 基于运满满真实收费标准 const rates = { '面包车': { startFee: 80, startDistance: 10, unitPrice: 1.15 }, '依维柯': { startFee: 160, startDistance: 10, unitPrice: 1.65 }, '平板': { startFee: 300, startDistance: 10, unitPrice: 2.7 }, '厢式': { startFee: 220, startDistance: 10, unitPrice: 2.25 }, '高栏车': { startFee: 200, startDistance: 10, unitPrice: 2.65 }, '集装箱': { startFee: 300, startDistance: 10, unitPrice: 2.95 }, '自卸': { startFee: 250, startDistance: 10, unitPrice: 2.35 }, '冷藏': { startFee: 300, startDistance: 10, unitPrice: 2.65 }, '保温': { startFee: 280, startDistance: 10, unitPrice: 2.45 }, '棉被车': { startFee: 260, startDistance: 10, unitPrice: 2.35 }, '爬梯车': { startFee: 280, startDistance: 10, unitPrice: 2.45 }, '飞翼车': { startFee: 270, startDistance: 10, unitPrice: 2.35 }, '高低板': { startFee: 350, startDistance: 10, unitPrice: 2.95 } }; const rate = rates[vehicleType] || rates['面包车']; if (distance <= rate.startDistance) { marketPrice = rate.startFee; } else { const extraDistance = distance - rate.startDistance; marketPrice = rate.startFee + extraDistance * rate.unitPrice; } // 根据货物重量和体积调整价格 if (weight > 1000 || volume > 10) { marketPrice *= 1.1; } // 添加平台佣金 marketPrice *= 1.05; // 应用车长系数 marketPrice *= truckLengthFactor; } else { // 零担拼车市场参考价 const chargeWeight = Math.max(weight, volume * 333); marketPrice = chargeWeight * 0.4 * (distance / 1000) * 1.05; // 包含易碎品附加费 // 应用车长系数 marketPrice *= truckLengthFactor; } // 确保最低价格 const minPrice = 100; // 最低起步价 marketPrice = Math.max(minPrice, marketPrice); return marketPrice; } });