8.8 KiB
8.8 KiB
编辑功能 - 车牌号未正确传递问题修复
问题描述
用户反馈:在编辑运送清单时,车牌号没有正确传递/显示。
问题根源
原因分析
-
异步加载时序问题:
open()方法中使用setTimeout(fillFormWithEditData, 500)来等待下拉列表加载- 但车辆列表 API 响应时间可能超过 500ms
- 导致
fillFormWithEditData执行时,vehicleOptions还是空的 - 车牌号虽然赋值了,但因为下拉框选项列表为空,无法正确显示
-
数据结构问题:
detail接口返回的数据结构:{ delivery: { licensePlate: "鄂A 66662", ... }, supplierId: 44, buyerId: 41, eartagIds: [...], collarIds: [...], serverIds: "..." }- 需要从
editData.delivery.licensePlate中获取车牌号
解决方案
1. 后端修改 - 补充设备信息和 ID 字段
文件: DeliveryServiceImpl.java
// 在 detail() 方法中补充设备信息
// 查询耳标设备信息(类型2)
List<DeliveryDevice> eartagDevices = deliveryDeviceMapper.selectList(
new LambdaQueryWrapper<DeliveryDevice>()
.eq(DeliveryDevice::getDeliveryId, id)
.eq(DeliveryDevice::getDeviceType, 2)
);
List<String> eartagIds = new ArrayList<>();
if (eartagDevices != null && !eartagDevices.isEmpty()) {
for (DeliveryDevice device : eartagDevices) {
if (device.getDeviceId() != null && !device.getDeviceId().isEmpty()) {
eartagIds.add(device.getDeviceId());
}
}
}
resMap.put("eartagIds", eartagIds);
// 查询项圈设备信息(类型3)
List<DeliveryDevice> collarDevices = deliveryDeviceMapper.selectList(
new LambdaQueryWrapper<DeliveryDevice>()
.eq(DeliveryDevice::getDeliveryId, id)
.eq(DeliveryDevice::getDeviceType, 3)
);
List<String> collarIds = new ArrayList<>();
if (collarDevices != null && !collarDevices.isEmpty()) {
for (DeliveryDevice device : collarDevices) {
if (device.getDeviceId() != null && !device.getDeviceId().isEmpty()) {
collarIds.add(device.getDeviceId());
}
}
}
resMap.put("collarIds", collarIds);
// 补充 supplierId 和 buyerId
if (delivery.getSupplierId() != null && !delivery.getSupplierId().isEmpty()) {
String firstSupplierId = delivery.getSupplierId().split(",")[0].trim();
try {
resMap.put("supplierId", Integer.parseInt(firstSupplierId));
} catch (NumberFormatException e) {
resMap.put("supplierId", null);
}
} else {
resMap.put("supplierId", null);
}
resMap.put("buyerId", delivery.getBuyerId());
2. 前端修改 - 改为 Promise.all 等待所有下拉列表加载完成
文件: createDeliveryDialog.vue
修改前(有问题)
const open = (editData = null) => {
dialogVisible.value = true;
loadSupplierAndBuyerList(); // 异步但不等待
loadDeviceOptions(); // 异步但不等待
loadDriverList(); // 异步但不等待
loadVehicleList(); // 异步但不等待
loadOrderList(); // 异步但不等待
// 如果传入了编辑数据,则填充表单
if (editData) {
setTimeout(() => {
fillFormWithEditData(editData);
}, 500); // ❌ 固定延迟,不可靠
}
};
修改后(正确)
const open = async (editData = null) => {
dialogVisible.value = true;
// 并行加载所有下拉列表数据,等待全部完成
await Promise.all([
loadSupplierAndBuyerList(),
loadDeviceOptions(),
loadDriverList(),
loadVehicleList(), // ✅ 确保车辆列表加载完成
loadOrderList()
]);
console.log('[OPEN-DIALOG] 所有下拉列表加载完成');
console.log('[OPEN-DIALOG] 车辆列表:', vehicleOptions.value);
// 如果传入了编辑数据,则填充表单
if (editData) {
fillFormWithEditData(editData); // ✅ 此时所有选项都已加载
}
};
3. 增强车牌号填充日志
const fillFormWithEditData = (editData) => {
// ...
// 车牌号
formData.plateNumber = delivery.licensePlate || '';
console.log('[EDIT-FILL] 车牌号:', formData.plateNumber);
console.log('[EDIT-FILL] 当前车辆列表:', vehicleOptions.value);
// 检查车牌号是否在车辆列表中
const vehicleExists = vehicleOptions.value.find(v => v.licensePlate === formData.plateNumber);
if (!vehicleExists && formData.plateNumber) {
console.warn('[EDIT-FILL] ⚠️ 车牌号在车辆列表中不存在:', formData.plateNumber);
}
// ...
};
4. 前端调用 detail 接口获取完整数据
文件: attestation.vue
const editDelivery = async (row) => {
try {
console.log('[EDIT-DELIVERY] 准备编辑运送清单, ID:', row.id);
// 检查编辑对话框组件是否已加载
if (!editDialogRef.value || !editDialogRef.value.open) {
ElMessage.warning('编辑功能暂不可用,请刷新页面重试');
return;
}
// ✅ 调用 detail 接口获取完整数据(包含 supplierId, buyerId, 设备信息等)
const detailRes = await getDeliveryDetail(row.id);
console.log('[EDIT-DELIVERY] 获取到详情数据:', detailRes);
if (detailRes.code === 200 && detailRes.data) {
// 传入完整的 detail 数据给 open() 方法
editDialogRef.value.open(detailRes.data);
} else {
ElMessage.error('获取运单详情失败:' + (detailRes.msg || '未知错误'));
}
} catch (error) {
console.error('[EDIT-DELIVERY] 打开编辑对话框失败:', error);
ElMessage.error('打开编辑对话框失败,请重试');
}
};
测试步骤
1. 清理并重新编译后端
cd tradeCattle
mvn clean compile -DskipTests
2. 重启后端服务
确保新的 detail 接口逻辑生效。
3. 刷新前端浏览器
清除缓存,重新加载 Vue 组件。
4. 测试编辑功能
- 进入"入境检疫"页面
- 点击任意运送清单的"编辑"按钮
- 观察控制台日志:
[EDIT-DELIVERY] 准备编辑运送清单, ID: 95 [EDIT-DELIVERY] 获取到详情数据: { delivery: {...}, supplierId: 44, buyerId: 41, eartagIds: [...], collarIds: [...], serverIds: "..." } [OPEN-DIALOG] 所有下拉列表加载完成 [OPEN-DIALOG] 车辆列表: [{ id: 1, licensePlate: "鄂A 66662", ... }, ...] [EDIT-FILL] 开始填充编辑数据: {...} [EDIT-FILL] 发货方ID: 44, 采购方ID: 41 [EDIT-FILL] 车牌号: 鄂A 66662 [EDIT-FILL] 当前车辆列表: [{ id: 1, licensePlate: "鄂A 66662", ... }] [EDIT-FILL] 主机ID: host001 [EDIT-FILL] 耳标IDs: ["ear001", "ear002"] [EDIT-FILL] 项圈IDs: ["collar001"]
5. 验证字段是否正确填充
- ✅ 发货方下拉框应显示正确的供应商
- ✅ 采购方下拉框应显示正确的买家
- ✅ 车牌号下拉框应显示正确的车牌号
- ✅ 司机下拉框应显示正确的司机
- ✅ 设备下拉框应显示已绑定的设备
关键改进点
🔑 核心改进
-
从固定延迟改为 Promise.all 等待
- 确保所有下拉列表数据加载完成后才填充表单
- 避免因网络延迟导致的数据不匹配
-
后端补充完整数据
detail接口返回supplierId,buyerId用于下拉框回显- 返回
eartagIds,collarIds用于设备选择器回显
-
增强日志
- 每一步都有清晰的日志输出
- 便于排查问题
常见问题排查
Q1: 车牌号显示为空?
检查:
- 控制台日志:
[EDIT-FILL] 车牌号:的值是否正确 - 控制台日志:
[EDIT-FILL] 当前车辆列表:是否包含该车牌号 - 如果车辆列表为空,检查
loadVehicleList()是否正常执行
Q2: 车牌号有值但下拉框未选中?
可能原因:
- 数据库中的车牌号与车辆表中的车牌号不完全匹配(空格、大小写等)
- 检查日志:
⚠️ 车牌号在车辆列表中不存在
解决办法:
- 确保
delivery.licensePlate和vehicle.licensePlate完全一致
Q3: 编辑时其他字段正常,唯独车牌号不对?
检查:
- 数据库
delivery表的license_plate字段值 - 后端日志:是否正确返回
licensePlate - 前端网络请求:查看
/delivery/detail?id=xxx返回的数据
总结
✅ 问题已修复:
- 使用
Promise.all确保所有下拉列表加载完成 - 后端补充完整的设备信息和 ID 字段
- 增强日志便于问题排查
✅ 用户体验改善:
- 编辑对话框打开速度更快(并行加载)
- 所有字段都能正确回显
- 错误信息更清晰