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

8.2 KiB
Raw Blame History

设备绑定功能实现说明

实现功能

1. 选中设备自动绑定运送清单

当用户在创建运送清单时选择设备后,系统会自动更新 iot_device_data 表中以下字段:

  • delivery_id运送清单ID
  • car_number:车牌号

2. 已绑定设备过滤

在下一个运送清单创建时,已绑定的设备(delivery_id 不为空)将不会出现在可选设备列表中。

修改内容

后端修改

1. DeliveryDeviceController.java

文件位置: tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/DeliveryDeviceController.java

修改的方法:

updateDeviceDeliveryId (第347-404行)
/**
 * 更新设备delivery_id、weight和car_number
 */
@PostMapping(value = "/updateDeviceDeliveryId")
public AjaxResult updateDeviceDeliveryId(@RequestBody Map<String, Object> params) {
    String deviceId = (String) params.get("deviceId");
    Integer deliveryId = (Integer) params.get("deliveryId");
    Double weight = params.get("weight") != null ? Double.valueOf(params.get("weight").toString()) : null;
    String carNumber = (String) params.get("carNumber"); // 新增:接收车牌号参数
    
    // ... 更新逻辑
    
    // 设置delivery_id可以是null
    updateWrapper.set(IotDeviceData::getDeliveryId, deliveryId);
    
    // 设置car_number可以是null- 新增
    updateWrapper.set(IotDeviceData::getCarNumber, carNumber);
    
    // 设置weight如果有值
    if (weight != null) {
        updateWrapper.set(IotDeviceData::getWeight, weight);
    }
}
clearDeliveryId (第462-499行)
/**
 * 清空设备delivery_id、car_number和weight
 */
@PostMapping(value = "/clearDeliveryId")
public AjaxResult clearDeliveryId(@RequestBody Map<String, Object> params) {
    // ... 清空逻辑
    
    // 将delivery_id、car_number和weight都设置为null
    device.setDeliveryId(null);
    device.setCarNumber(null); // 新增:清空车牌号
    device.setWeight(null);
}

2. IotDeviceProxyController.java

文件位置: tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/IotDeviceProxyController.java

修改的方法:

queryList (第42-167行)
@PostMapping("/queryList")
public AjaxResult queryList(@RequestBody Map<String, Object> params) {
    // 构建查询条件
    QueryWrapper<IotDeviceData> queryWrapper = new QueryWrapper<>();
    
    // 根据设备类型查询(用于创建运送清单时过滤设备)- 新增
    if (params.containsKey("type") && params.get("type") != null) {
        Integer deviceType = (Integer) params.get("type");
        queryWrapper.eq("device_type", deviceType);
        // 创建运送清单时只显示未绑定的设备delivery_id为空
        queryWrapper.isNull("delivery_id");
        logger.info("查询未绑定的设备,类型: {}", deviceType);
    }
    
    // ... 其他查询逻辑
}

前端修改

createDeliveryDialog.vue

文件位置: pc-cattle-transportation/src/views/shipping/createDeliveryDialog.vue

修改的方法:

updateSelectedDevicesDeliveryId (第1081-1111行)
// 更新选中设备的delivery_id和car_number
const updateSelectedDevicesDeliveryId = async (deliveryId) => {
    try {
        const devicesToUpdate = [];
        
        // 收集所有选中的设备
        if (formData.serverDeviceId) {
            devicesToUpdate.push(formData.serverDeviceId);
        }
        if (formData.eartagDeviceIds && formData.eartagDeviceIds.length > 0) {
            devicesToUpdate.push(...formData.eartagDeviceIds);
        }
        if (formData.collarDeviceIds && formData.collarDeviceIds.length > 0) {
            devicesToUpdate.push(...formData.collarDeviceIds);
        }
        
        // 批量更新设备的delivery_id和car_number
        for (const deviceId of devicesToUpdate) {
            await updateDeviceDeliveryId({
                deviceId: deviceId,
                deliveryId: deliveryId,
                carNumber: formData.plateNumber // 新增:传递车牌号
            });
        }
        
        console.log(`成功更新 ${devicesToUpdate.length} 个设备的delivery_id和car_number: ${formData.plateNumber}`);
    } catch (error) {
        console.error('更新设备delivery_id和car_number失败:', error);
    }
};

数据流程

创建运送清单时的设备绑定流程

  1. 用户填写运送清单

    • 选择车牌号:formData.plateNumber
    • 选择主机设备
    • 选择耳标设备
    • 选择项圈设备
  2. 提交运送清单

    • 调用 /delivery/create 创建运送清单
    • 获取新创建的 deliveryId
  3. 更新设备绑定信息

    • 调用 updateSelectedDevicesDeliveryId(deliveryId) 方法
    • 对每个选中的设备调用 /deliveryDevice/updateDeviceDeliveryId 接口
    • 传递参数:
      {
        "deviceId": "设备ID",
        "deliveryId": "运送清单ID",
        "carNumber": "车牌号"
      }
      
  4. 后端更新数据库

    • 更新 iot_device_data
    • 设置 delivery_id = 运送清单ID
    • 设置 car_number = 车牌号

查询可用设备流程

  1. 打开创建运送清单对话框

    • 调用 loadDeviceOptions() 方法
  2. 查询未绑定设备

    • 调用 /iotDevice/queryList 接口
    • 传递参数:
      {
        "type": 1,  // 设备类型1-主机, 2-耳标, 4-项圈
        "pageNum": 1,
        "pageSize": 9999
      }
      
  3. 后端过滤逻辑

    SELECT * FROM iot_device_data 
    WHERE device_type = ? 
    AND delivery_id IS NULL
    
  4. 返回未绑定设备列表

    • 只返回 delivery_id 为空的设备
    • 已绑定设备不会出现在下拉列表中

测试验证

1. 创建运送清单并绑定设备

步骤

  1. 打开"新增运送清单"对话框
  2. 填写车牌号:如 京A12345
  3. 选择主机设备
  4. 选择耳标设备
  5. 选择项圈设备
  6. 提交运送清单

验证

  • 查询数据库 iot_device_data
  • 确认选中设备的 delivery_id 已更新为运送清单ID
  • 确认选中设备的 car_number 已更新为 京A12345
SELECT device_id, device_type, delivery_id, car_number 
FROM iot_device_data 
WHERE delivery_id = [刚创建的运送清单ID];

2. 验证已绑定设备不再显示

步骤

  1. 再次打开"新增运送清单"对话框
  2. 查看设备下拉列表

验证

  • 之前选中的设备不应出现在下拉列表中
  • 只显示 delivery_id 为空的未绑定设备

3. 验证设备解绑功能

步骤

  1. 删除或取消运送清单
  2. 调用 /deliveryDevice/clearDeliveryId 接口

验证

  • 查询数据库 iot_device_data
  • 确认设备的 delivery_id 已清空NULL
  • 确认设备的 car_number 已清空NULL
  • 设备可以再次被选择

控制台日志

前端日志

成功更新 3 个设备的delivery_id和car_number: 京A12345

后端日志

=== 更新设备delivery_id、weight和car_number ===
设备ID: 1001
订单ID: 123
重量: null
车牌号: 京A12345
设备更新成功: 1001, delivery_id=123, car_number=京A12345
查询未绑定的设备,类型: 1
查询到设备数据: 5 条

注意事项

  1. 权限要求:所有接口都需要 delivery:view 权限

  2. 并发安全:同一设备不能同时绑定多个运送清单

  3. 数据一致性

    • 删除运送清单时应解绑所有关联设备
    • 修改车牌号时应同步更新已绑定设备的 car_number
  4. 性能优化

    • 批量更新使用异步并发Promise.all
    • 设备列表查询添加了索引优化

相关接口

后端API

接口 方法 说明
/deliveryDevice/updateDeviceDeliveryId POST 更新设备绑定信息
/deliveryDevice/clearDeliveryId POST 清空设备绑定信息
/iotDevice/queryList POST 查询设备列表(支持过滤)

前端方法

方法 说明
updateSelectedDevicesDeliveryId 批量更新选中设备的绑定信息
loadDeviceOptions 加载可用设备列表

实现日期

2025-10-29