Browse Source

优化运费计算器功能:调整价格计算逻辑,添加自动匹配车型功能

main
TraeAI 15 hours ago
parent
commit
03e6d805c0
  1. 361
      pages/freight-calculator/index.js

361
pages/freight-calculator/index.js

@ -136,16 +136,16 @@ Page({
baseInfo: {
'面包车': ['0-500kg', '0-5m³'],
'依维柯': ['500-1500kg', '5-12m³'],
'平板': ['3000-15000kg', '20-60m³'],
'厢式': ['2000-10000kg', '15-45m³'],
'高栏车': ['3000-15000kg', '20-60m³'],
'平板': ['1000-15000kg', '5-60m³'],
'厢式': ['1000-10000kg', '5-45m³'],
'高栏车': ['1000-15000kg', '5-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³'],
'自卸': ['5000-12000kg', '10-45m³'],
'冷藏': ['1000-8000kg', '5-40m³'],
'保温': ['1000-6000kg', '5-30m³'],
'棉被车': ['1000-8000kg', '5-40m³'],
'爬梯车': ['5000-12000kg', '10-45m³'],
'飞翼车': ['1000-10000kg', '10-45m³'],
'高低板': ['8000-20000kg', '40-80m³']
}
},
@ -177,12 +177,26 @@ Page({
// 从规格中提取重量数字并计算总重量
weight = this.calculateWeightFromSpec(goodsInfo);
}
// 计算体积
let volume = '';
if (goodsInfo.quantity) {
volume = this.calculateVolumeFromPackaging(goodsInfo);
}
this.setData({
selectedGoods: goodsInfo,
'goodsInfo.weight': weight,
'goodsInfo.volume': volume,
'goodsInfo.quantity': goodsInfo.quantity || 1,
weight: weight // 同步到运输参数的重量输入框
weight: weight, // 同步到运输参数的重量输入框
volume: volume // 同步到运输参数的体积输入框
});
// 自动匹配车型和车长
if (weight && volume) {
this.autoMatchVehicle(weight, volume);
}
} catch (e) {
console.error('解析货源信息失败:', e);
}
@ -215,12 +229,25 @@ Page({
weight = this.calculateWeightFromSpec(goodsData);
}
// 计算体积
let volume = '';
if (goodsData.quantity) {
volume = this.calculateVolumeFromPackaging(goodsData);
}
this.setData({
selectedGoods: goodsData,
'goodsInfo.weight': weight,
'goodsInfo.volume': volume,
'goodsInfo.quantity': goodsData.quantity || 1,
weight: weight // 同步到运输参数的重量输入框
weight: weight, // 同步到运输参数的重量输入框
volume: volume // 同步到运输参数的体积输入框
});
// 自动匹配车型和车长
if (weight && volume) {
this.autoMatchVehicle(weight, volume);
}
// 设置出发地为商品所在地
const regionToUse = goodsData.fullRegion || goodsData.region;
@ -287,26 +314,41 @@ Page({
}
// 设置货物重量(如果有)
let weight = '';
if (goodsItem.grossWeight) {
this.setData({
'goodsInfo.weight': goodsItem.grossWeight,
weight: goodsItem.grossWeight // 同步到运输参数的重量输入框
});
weight = goodsItem.grossWeight;
} else if (goodsItem.netWeight && goodsItem.quantity) {
// 计算总重量:净重(斤) * 件数 / 2(换算为公斤)
const totalWeight = (parseFloat(goodsItem.netWeight) * parseInt(goodsItem.quantity)) / 2;
this.setData({
'goodsInfo.weight': totalWeight,
weight: totalWeight // 同步到运输参数的重量输入框
});
weight = (parseFloat(goodsItem.netWeight) * parseInt(goodsItem.quantity)) / 2;
} else if ((goodsItem.spec || goodsItem.specification || goodsItem.specs) && goodsItem.quantity) {
// 从规格中提取重量数字并计算总重量
const totalWeight = this.calculateWeightFromSpec(goodsItem);
weight = this.calculateWeightFromSpec(goodsItem);
}
// 计算体积
let volume = '';
if (goodsItem.quantity) {
volume = this.calculateVolumeFromPackaging(goodsItem);
}
// 设置重量和体积
if (weight) {
this.setData({
'goodsInfo.weight': totalWeight,
weight: totalWeight // 同步到运输参数的重量输入框
'goodsInfo.weight': weight,
weight: weight // 同步到运输参数的重量输入框
});
}
if (volume) {
this.setData({
'goodsInfo.volume': volume,
volume: volume // 同步到运输参数的体积输入框
});
}
// 自动匹配车型和车长
if (weight && volume) {
this.autoMatchVehicle(weight, volume);
}
}
},
@ -320,7 +362,7 @@ Page({
// 从规格字符串中提取数字
const weightMatch = spec.match(/(\d+(?:\.\d+)?)/);
if (weightMatch) {
if (weightMatch && weightMatch.length > 1) {
const weightPerUnit = parseFloat(weightMatch[1]);
// 计算总重量:重量(斤) * 件数 / 2(换算为公斤)
const totalWeight = (weightPerUnit * quantity) / 2;
@ -332,6 +374,58 @@ Page({
return '';
},
// 根据包装信息计算体积
calculateVolumeFromPackaging: function (goodsData) {
// 获取所有可能的包装信息字段
const allSpecs = [
goodsData.spec,
goodsData.specification,
goodsData.specs,
goodsData.producting
].filter(Boolean);
const quantity = parseInt(goodsData.quantity) || 1;
console.log('从包装计算体积:', { allSpecs, quantity, producting: goodsData.producting });
// 定义包装的体积(单位:立方米)
const packageVolumes = {
'1*360枚': (60 * 30 * 33) / 1000000, // 60cm×30cm×33cm
'1*420枚': (60 * 30 * 40) / 1000000, // 60cm×30cm×40cm
'1*480枚': (60 * 30 * 45) / 1000000 // 60cm×30cm×45cm
};
// 检查是否为排除的包装类型
const excludedPackages = ['30枚蛋托散装', '360枚散托'];
for (let i = 0; i < allSpecs.length; i++) {
const spec = allSpecs[i];
for (let j = 0; j < excludedPackages.length; j++) {
if (spec.includes(excludedPackages[j])) {
console.log('排除的包装类型,不计算体积:', excludedPackages[j]);
return '';
}
}
}
// 检查包装类型 - 遍历所有可能的规格字段
for (let i = 0; i < allSpecs.length; i++) {
const spec = allSpecs[i];
// 遍历所有包装类型
for (const packageType in packageVolumes) {
if (packageVolumes.hasOwnProperty(packageType)) {
if (spec.includes(packageType)) {
// 计算总体积
const totalVolume = packageVolumes[packageType] * quantity;
console.log('计算得到的总体积:', totalVolume, '立方米');
return totalVolume;
}
}
}
}
console.log('未找到匹配的包装类型,不计算体积');
return '';
},
// 解析地区信息
parseRegion: function (region) {
if (!region) return {};
@ -1212,19 +1306,26 @@ Page({
if (weightNum > 0 || volumeNum > 0) {
const [weightRange, volumeRange] = this.data.baseInfo[vehicleType];
const [minWeight, maxWeight] = weightRange.split('-').map(w => parseFloat(w.replace('kg', '')));
const [minVolume, maxVolume] = volumeRange.split('-').map(v => parseFloat(v.replace('m³', '')));
// 检查重量和体积是否在车型的范围内
const isWeightSuitable = weightNum === 0 || (weightNum >= minWeight && weightNum <= maxWeight);
const isVolumeSuitable = volumeNum === 0 || (volumeNum >= minVolume && volumeNum <= maxVolume);
const weightRangeParts = weightRange.split('-');
const volumeRangeParts = volumeRange.split('-');
if (!isWeightSuitable || !isVolumeSuitable) {
wx.showToast({
title: '选择的车型不适合当前重量和体积',
icon: 'none'
});
return;
if (weightRangeParts.length === 2 && volumeRangeParts.length === 2) {
const minWeight = parseFloat(weightRangeParts[0].replace('kg', ''));
const maxWeight = parseFloat(weightRangeParts[1].replace('kg', ''));
const minVolume = parseFloat(volumeRangeParts[0].replace('m³', ''));
const maxVolume = parseFloat(volumeRangeParts[1].replace('m³', ''));
// 检查重量和体积是否在车型的范围内
const isWeightSuitable = weightNum === 0 || (weightNum >= minWeight && weightNum <= maxWeight);
const isVolumeSuitable = volumeNum === 0 || (volumeNum >= minVolume && volumeNum <= maxVolume);
if (!isWeightSuitable || !isVolumeSuitable) {
wx.showToast({
title: '选择的车型不适合当前重量和体积',
icon: 'none'
});
return;
}
}
}
@ -1313,12 +1414,12 @@ Page({
if (a.priority !== b.priority) {
return a.priority - b.priority;
}
// 然后按最大载重排序
// 然后按最大载重排序(从大到小)
if (a.maxWeight !== b.maxWeight) {
return a.maxWeight - b.maxWeight;
return b.maxWeight - a.maxWeight;
}
// 最后按最大体积排序
return a.maxVolume - b.maxVolume;
// 最后按最大体积排序(从大到小)
return b.maxVolume - a.maxVolume;
});
// 选择第一个合适的车型
@ -1998,15 +2099,15 @@ Page({
} else if (length <= 5) {
return 1.0;
} else if (length <= 6.8) {
return 1.1;
return 1.05;
} else if (length <= 7.7) {
return 1.2;
return 1.1;
} else if (length <= 9.6) {
return 1.3;
return 1.15;
} else if (length <= 13) {
return 1.4;
return 1.2;
} else {
return 1.5;
return 1.25;
}
} catch {
return 1.0;
@ -2018,80 +2119,80 @@ Page({
'面包车': {
startFee: 80,
startDistance: 10,
unitPriceMin: 1.0,
unitPriceMax: 1.3
unitPriceMin: 0.8,
unitPriceMax: 1.0
},
'依维柯': {
startFee: 160,
startFee: 150,
startDistance: 10,
unitPriceMin: 1.5,
unitPriceMax: 1.8
unitPriceMin: 1.2,
unitPriceMax: 1.5
},
'平板': {
startFee: 200,
startFee: 180,
startDistance: 10,
unitPriceMin: 1.8,
unitPriceMax: 2.2
unitPriceMin: 1.5,
unitPriceMax: 1.8
},
'厢式': {
startFee: 180,
startFee: 170,
startDistance: 10,
unitPriceMin: 1.7,
unitPriceMax: 2.0
unitPriceMin: 1.4,
unitPriceMax: 1.7
},
'高栏车': {
startFee: 150,
startFee: 140,
startDistance: 10,
unitPriceMin: 1.8,
unitPriceMax: 2.2
unitPriceMin: 1.5,
unitPriceMax: 1.8
},
'集装箱': {
startFee: 250,
startFee: 220,
startDistance: 10,
unitPriceMin: 2.0,
unitPriceMax: 2.4
unitPriceMin: 1.7,
unitPriceMax: 2.0
},
'自卸': {
startFee: 200,
startFee: 180,
startDistance: 10,
unitPriceMin: 1.9,
unitPriceMax: 2.3
unitPriceMin: 1.6,
unitPriceMax: 1.9
},
'冷藏': {
startFee: 250,
startFee: 220,
startDistance: 10,
unitPriceMin: 2.0,
unitPriceMax: 2.4
unitPriceMin: 1.7,
unitPriceMax: 2.0
},
'保温': {
startFee: 220,
startFee: 200,
startDistance: 10,
unitPriceMin: 1.8,
unitPriceMax: 2.2
unitPriceMin: 1.5,
unitPriceMax: 1.8
},
'棉被车': {
startFee: 200,
startFee: 180,
startDistance: 10,
unitPriceMin: 1.7,
unitPriceMax: 2.1
unitPriceMin: 1.4,
unitPriceMax: 1.7
},
'爬梯车': {
startFee: 220,
startFee: 200,
startDistance: 10,
unitPriceMin: 1.8,
unitPriceMax: 2.2
unitPriceMin: 1.5,
unitPriceMax: 1.8
},
'飞翼车': {
startFee: 210,
startFee: 190,
startDistance: 10,
unitPriceMin: 1.7,
unitPriceMax: 2.1
unitPriceMin: 1.4,
unitPriceMax: 1.7
},
'高低板': {
startFee: 280,
startFee: 250,
startDistance: 10,
unitPriceMin: 2.0,
unitPriceMax: 2.4
unitPriceMin: 1.7,
unitPriceMax: 2.0
}
};
@ -2116,23 +2217,23 @@ Page({
feeMax *= truckLengthFactor;
// 根据货物重量和体积调整价格 - 调整为更合理的系数
if (weight > 3000 || volume > 15) {
feeMin *= 1.05;
feeMax *= 1.05;
} else if (weight > 1000 || volume > 10) {
feeMin *= 1.02;
feeMax *= 1.02;
if (weight > 5000 || volume > 20) {
feeMin *= 1.03;
feeMax *= 1.03;
} else if (weight > 3000 || volume > 15) {
feeMin *= 1.01;
feeMax *= 1.01;
}
// 添加平台佣金(运费的5%左右
feeMin *= 1.05;
feeMax *= 1.05;
// 添加平台佣金(运费的3%左右,更接近实际情况
feeMin *= 1.03;
feeMax *= 1.03;
// 费用明细
const breakdown = {
'起步费': rate.startFee,
'距离费': Math.round((feeMin / 1.05 - rate.startFee) * 100) / 100,
'平台佣金': Math.round((feeMin - feeMin / 1.05) * 100) / 100
'距离费': Math.round((feeMin / 1.03 - rate.startFee) * 100) / 100,
'平台佣金': Math.round((feeMin - feeMin / 1.03) * 100) / 100
};
return [feeMin, feeMax, breakdown];
@ -2226,15 +2327,15 @@ Page({
} else if (length <= 5) {
return 1.0;
} else if (length <= 6.8) {
return 1.1;
return 1.05;
} else if (length <= 7.7) {
return 1.2;
return 1.1;
} else if (length <= 9.6) {
return 1.3;
return 1.15;
} else if (length <= 13) {
return 1.4;
return 1.2;
} else {
return 1.5;
return 1.25;
}
} catch {
return 1.0;
@ -2267,67 +2368,67 @@ Page({
'面包车': {
startFee: 80,
startDistance: 10,
unitPrice: 1.15
unitPrice: 0.9
},
'依维柯': {
startFee: 160,
startFee: 150,
startDistance: 10,
unitPrice: 1.65
unitPrice: 1.35
},
'平板': {
startFee: 200,
startFee: 180,
startDistance: 10,
unitPrice: 2.0
unitPrice: 1.65
},
'厢式': {
startFee: 180,
startFee: 170,
startDistance: 10,
unitPrice: 1.85
unitPrice: 1.55
},
'高栏车': {
startFee: 150,
startFee: 140,
startDistance: 10,
unitPrice: 2.0
unitPrice: 1.65
},
'集装箱': {
startFee: 250,
startFee: 220,
startDistance: 10,
unitPrice: 2.2
unitPrice: 1.85
},
'自卸': {
startFee: 200,
startFee: 180,
startDistance: 10,
unitPrice: 2.1
unitPrice: 1.75
},
'冷藏': {
startFee: 250,
startFee: 220,
startDistance: 10,
unitPrice: 2.2
unitPrice: 1.85
},
'保温': {
startFee: 220,
startFee: 200,
startDistance: 10,
unitPrice: 2.0
unitPrice: 1.65
},
'棉被车': {
startFee: 200,
startFee: 180,
startDistance: 10,
unitPrice: 1.9
unitPrice: 1.55
},
'爬梯车': {
startFee: 220,
startFee: 200,
startDistance: 10,
unitPrice: 2.0
unitPrice: 1.65
},
'飞翼车': {
startFee: 210,
startFee: 190,
startDistance: 10,
unitPrice: 1.9
unitPrice: 1.55
},
'高低板': {
startFee: 280,
startFee: 250,
startDistance: 10,
unitPrice: 2.2
unitPrice: 1.85
}
};
@ -2344,18 +2445,18 @@ Page({
marketPrice *= truckLengthFactor;
// 根据货物重量和体积调整价格 - 与 calculateYunmanmanFee 使用相同的系数
if (weight > 3000 || volume > 15) {
marketPrice *= 1.05;
} else if (weight > 1000 || volume > 10) {
marketPrice *= 1.02;
if (weight > 5000 || volume > 20) {
marketPrice *= 1.03;
} else if (weight > 3000 || volume > 15) {
marketPrice *= 1.01;
}
// 添加平台佣金
marketPrice *= 1.05;
marketPrice *= 1.03;
} else {
// 零担拼车市场参考价
const chargeWeight = Math.max(weight, volume * 333);
marketPrice = chargeWeight * 0.4 * (distance / 1000) * 1.05; // 包含易碎品附加费
marketPrice = chargeWeight * 0.35 * (distance / 1000) * 1.03; // 包含易碎品附加费
// 应用车长系数
marketPrice *= truckLengthFactor;

Loading…
Cancel
Save