Files
cattleTransportation/EDIT_PLATE_NUMBER_FIX.md
2025-10-29 17:33:32 +08:00

8.8 KiB
Raw Blame History

编辑功能 - 车牌号未正确传递问题修复

问题描述

用户反馈:在编辑运送清单时,车牌号没有正确传递/显示

问题根源

原因分析

  1. 异步加载时序问题

    • open() 方法中使用 setTimeout(fillFormWithEditData, 500) 来等待下拉列表加载
    • 但车辆列表 API 响应时间可能超过 500ms
    • 导致 fillFormWithEditData 执行时,vehicleOptions 还是空的
    • 车牌号虽然赋值了,但因为下拉框选项列表为空,无法正确显示
  2. 数据结构问题

    • 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. 测试编辑功能

  1. 进入"入境检疫"页面
  2. 点击任意运送清单的"编辑"按钮
  3. 观察控制台日志:
    [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. 验证字段是否正确填充

  • 发货方下拉框应显示正确的供应商
  • 采购方下拉框应显示正确的买家
  • 车牌号下拉框应显示正确的车牌号
  • 司机下拉框应显示正确的司机
  • 设备下拉框应显示已绑定的设备

关键改进点

🔑 核心改进

  1. 从固定延迟改为 Promise.all 等待

    • 确保所有下拉列表数据加载完成后才填充表单
    • 避免因网络延迟导致的数据不匹配
  2. 后端补充完整数据

    • detail 接口返回 supplierId, buyerId 用于下拉框回显
    • 返回 eartagIds, collarIds 用于设备选择器回显
  3. 增强日志

    • 每一步都有清晰的日志输出
    • 便于排查问题

常见问题排查

Q1: 车牌号显示为空?

检查:

  1. 控制台日志:[EDIT-FILL] 车牌号: 的值是否正确
  2. 控制台日志:[EDIT-FILL] 当前车辆列表: 是否包含该车牌号
  3. 如果车辆列表为空,检查 loadVehicleList() 是否正常执行

Q2: 车牌号有值但下拉框未选中?

可能原因:

  • 数据库中的车牌号与车辆表中的车牌号不完全匹配(空格、大小写等)
  • 检查日志:⚠️ 车牌号在车辆列表中不存在

解决办法:

  • 确保 delivery.licensePlatevehicle.licensePlate 完全一致

Q3: 编辑时其他字段正常,唯独车牌号不对?

检查:

  1. 数据库 delivery 表的 license_plate 字段值
  2. 后端日志:是否正确返回 licensePlate
  3. 前端网络请求:查看 /delivery/detail?id=xxx 返回的数据

总结

问题已修复

  • 使用 Promise.all 确保所有下拉列表加载完成
  • 后端补充完整的设备信息和 ID 字段
  • 增强日志便于问题排查

用户体验改善

  • 编辑对话框打开速度更快(并行加载)
  • 所有字段都能正确回显
  • 错误信息更清晰