Browse Source

feat: 优化运费计算器功能,支持多个规格选择和自动匹配车型

main
TraeAI 6 hours ago
parent
commit
6eb320c202
  1. 189
      pages/freight-calculator/index.js
  2. 10
      pages/freight-calculator/index.wxml

189
pages/freight-calculator/index.js

@ -49,6 +49,10 @@ Page({
selectedGoods: {},
// 选中的规格索引
selectedSpecIndex: 0,
// 规格列表
specList: [],
// 格式化后的规格列表(用于 picker 显示)
formattedSpecList: [],
// 计算结果
calculationResult: null,
// 地址选择器状态
@ -170,22 +174,56 @@ Page({
try {
const goodsInfo = JSON.parse(options.goodsInfo);
let weight = goodsInfo.grossWeight || '';
if (!weight && goodsInfo.netWeight && goodsInfo.quantity) {
// 计算总重量:净重(斤) * 件数 / 2(换算为公斤)
weight = (parseFloat(goodsInfo.netWeight) * parseInt(goodsInfo.quantity)) / 2;
} else if (!weight && (goodsInfo.spec || goodsInfo.specification || goodsInfo.specs) && goodsInfo.quantity) {
// 从规格中提取重量数字并计算总重量
weight = this.calculateWeightFromSpec(goodsInfo);
}
// 计算体积
let volume = '';
if (goodsInfo.quantity) {
volume = this.calculateVolumeFromPackaging(goodsInfo);
let specList = [];
let selectedSpecIndex = 0;
// 检查是否有多个规格
if (goodsInfo.weightQuantityData && goodsInfo.weightQuantityData.length > 0) {
specList = goodsInfo.weightQuantityData;
// 选择第一个规格作为默认值
const firstSpec = specList[0];
if (firstSpec) {
// 从规格中提取重量和体积
if (firstSpec.weightSpec) {
// 从重量规格中提取数字
const weightMatch = firstSpec.weightSpec.match(/(\d+(?:\.\d+)?)/);
if (weightMatch && weightMatch.length > 1) {
const weightPerUnit = parseFloat(weightMatch[1]);
const quantity = parseInt(firstSpec.soldQuantity || goodsInfo.quantity) || 1;
weight = (weightPerUnit * quantity) / 2; // 换算为公斤
}
}
// 计算体积
if (goodsInfo.producting && (goodsInfo.quantity || firstSpec.soldQuantity)) {
const quantity = parseInt(firstSpec.soldQuantity || goodsInfo.quantity) || 1;
volume = this.calculateVolumeFromPackaging({ ...goodsInfo, quantity: quantity });
}
}
} else {
// 单个规格的情况
if (!weight && goodsInfo.netWeight && goodsInfo.quantity) {
// 计算总重量:净重(斤) * 件数 / 2(换算为公斤)
weight = (parseFloat(goodsInfo.netWeight) * parseInt(goodsInfo.quantity)) / 2;
} else if (!weight && (goodsInfo.spec || goodsInfo.specification || goodsInfo.specs) && goodsInfo.quantity) {
// 从规格中提取重量数字并计算总重量
weight = this.calculateWeightFromSpec(goodsInfo);
}
// 计算体积
if (goodsInfo.quantity) {
volume = this.calculateVolumeFromPackaging(goodsInfo);
}
}
// 生成格式化后的规格列表(用于 picker 显示)
const formattedSpecList = specList.map((item, index) => item.weightSpec || '规格' + (index + 1));
this.setData({
selectedGoods: goodsInfo,
specList: specList,
formattedSpecList: formattedSpecList,
selectedSpecIndex: selectedSpecIndex,
'goodsInfo.weight': weight,
'goodsInfo.volume': volume,
'goodsInfo.quantity': goodsInfo.quantity || 1,
@ -221,22 +259,56 @@ Page({
}
let weight = goodsData.grossWeight || '';
if (!weight && goodsData.netWeight && goodsData.quantity) {
// 计算总重量:净重(斤) * 件数 / 2(换算为公斤)
weight = (parseFloat(goodsData.netWeight) * parseInt(goodsData.quantity)) / 2;
} else if (!weight && (goodsData.spec || goodsData.specification || goodsData.specs) && goodsData.quantity) {
// 从规格中提取重量数字并计算总重量
weight = this.calculateWeightFromSpec(goodsData);
}
// 计算体积
let volume = '';
if (goodsData.quantity) {
volume = this.calculateVolumeFromPackaging(goodsData);
let specList = [];
let selectedSpecIndex = 0;
// 检查是否有多个规格
if (goodsData.weightQuantityData && goodsData.weightQuantityData.length > 0) {
specList = goodsData.weightQuantityData;
// 选择第一个规格作为默认值
const firstSpec = specList[0];
if (firstSpec) {
// 从规格中提取重量和体积
if (firstSpec.weightSpec) {
// 从重量规格中提取数字
const weightMatch = firstSpec.weightSpec.match(/(\d+(?:\.\d+)?)/);
if (weightMatch && weightMatch.length > 1) {
const weightPerUnit = parseFloat(weightMatch[1]);
const quantity = parseInt(firstSpec.soldQuantity || goodsData.quantity) || 1;
weight = (weightPerUnit * quantity) / 2; // 换算为公斤
}
}
// 计算体积
if (goodsData.producting && (goodsData.quantity || firstSpec.soldQuantity)) {
const quantity = parseInt(firstSpec.soldQuantity || goodsData.quantity) || 1;
volume = this.calculateVolumeFromPackaging({ ...goodsData, quantity: quantity });
}
}
} else {
// 单个规格的情况
if (!weight && goodsData.netWeight && goodsData.quantity) {
// 计算总重量:净重(斤) * 件数 / 2(换算为公斤)
weight = (parseFloat(goodsData.netWeight) * parseInt(goodsData.quantity)) / 2;
} else if (!weight && (goodsData.spec || goodsData.specification || goodsData.specs) && goodsData.quantity) {
// 从规格中提取重量数字并计算总重量
weight = this.calculateWeightFromSpec(goodsData);
}
// 计算体积
if (goodsData.quantity) {
volume = this.calculateVolumeFromPackaging(goodsData);
}
}
// 生成格式化后的规格列表(用于 picker 显示)
const formattedSpecList = specList.map((item, index) => item.weightSpec || '规格' + (index + 1));
this.setData({
selectedGoods: goodsData,
specList: specList,
formattedSpecList: formattedSpecList,
selectedSpecIndex: selectedSpecIndex,
'goodsInfo.weight': weight,
'goodsInfo.volume': volume,
'goodsInfo.quantity': goodsData.quantity || 1,
@ -331,6 +403,33 @@ Page({
volume = this.calculateVolumeFromPackaging(goodsItem);
}
// 检查是否有多个规格
let specList = [];
let selectedSpecIndex = 0;
if (goodsItem.weightQuantityData && goodsItem.weightQuantityData.length > 0) {
specList = goodsItem.weightQuantityData;
// 选择第一个规格作为默认值
const firstSpec = specList[0];
if (firstSpec) {
// 从规格中提取重量和体积
if (firstSpec.weightSpec) {
// 从重量规格中提取数字
const weightMatch = firstSpec.weightSpec.match(/(\d+(?:\.\d+)?)/);
if (weightMatch && weightMatch.length > 1) {
const weightPerUnit = parseFloat(weightMatch[1]);
const quantity = parseInt(firstSpec.soldQuantity || goodsItem.quantity) || 1;
weight = (weightPerUnit * quantity) / 2; // 换算为公斤
}
}
// 计算体积
if (goodsItem.producting && (goodsItem.quantity || firstSpec.soldQuantity)) {
const quantity = parseInt(firstSpec.soldQuantity || goodsItem.quantity) || 1;
volume = this.calculateVolumeFromPackaging({ ...goodsItem, quantity: quantity });
}
}
}
// 设置重量和体积
if (weight) {
this.setData({
@ -345,6 +444,16 @@ Page({
});
}
// 生成格式化后的规格列表(用于 picker 显示)
const formattedSpecList = specList.map((item, index) => item.weightSpec || '规格' + (index + 1));
// 设置规格列表
this.setData({
specList: specList,
formattedSpecList: formattedSpecList,
selectedSpecIndex: selectedSpecIndex
});
// 自动匹配车型和车长
if (weight && volume) {
this.autoMatchVehicle(weight, volume);
@ -551,6 +660,42 @@ Page({
this.setData({
selectedSpecIndex: index
});
// 根据选择的规格更新重量和体积
const selectedSpec = this.data.specList[index];
if (selectedSpec) {
let weight = '';
let volume = '';
// 从规格中提取重量
if (selectedSpec.weightSpec) {
const weightMatch = selectedSpec.weightSpec.match(/(\d+(?:\.\d+)?)/);
if (weightMatch && weightMatch.length > 1) {
const weightPerUnit = parseFloat(weightMatch[1]);
const quantity = parseInt(selectedSpec.soldQuantity || this.data.goodsInfo.quantity) || 1;
weight = (weightPerUnit * quantity) / 2; // 换算为公斤
}
}
// 计算体积
if (this.data.selectedGoods.producting && (this.data.goodsInfo.quantity || selectedSpec.soldQuantity)) {
const quantity = parseInt(selectedSpec.soldQuantity || this.data.goodsInfo.quantity) || 1;
volume = this.calculateVolumeFromPackaging({ ...this.data.selectedGoods, quantity: quantity });
}
// 更新重量和体积
this.setData({
'goodsInfo.weight': weight,
'goodsInfo.volume': volume,
weight: weight, // 同步到运输参数的重量输入框
volume: volume // 同步到运输参数的体积输入框
});
// 自动匹配车型和车长
if (weight && volume) {
this.autoMatchVehicle(weight, volume);
}
}
},

10
pages/freight-calculator/index.wxml

@ -73,7 +73,15 @@
</picker>
</view>
<!-- 规格选择 -->
<view class="form-item" wx:if="{{specList.length > 0}}">
<text class="label">规格选择</text>
<picker bindchange="bindSpecChange" value="{{selectedSpecIndex}}" range="{{formattedSpecList}}">
<view class="picker">
{{formattedSpecList[selectedSpecIndex]}}
</view>
</picker>
</view>
<!-- 鸡蛋重量 -->
<view class="form-item">

Loading…
Cancel
Save