291 lines
8.2 KiB
Markdown
291 lines
8.2 KiB
Markdown
|
|
# 设备绑定功能实现说明
|
|||
|
|
|
|||
|
|
## 实现功能
|
|||
|
|
|
|||
|
|
### 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行)
|
|||
|
|
```java
|
|||
|
|
/**
|
|||
|
|
* 更新设备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行)
|
|||
|
|
```java
|
|||
|
|
/**
|
|||
|
|
* 清空设备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行)
|
|||
|
|
```java
|
|||
|
|
@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行)
|
|||
|
|
```javascript
|
|||
|
|
// 更新选中设备的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` 接口
|
|||
|
|
- 传递参数:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"deviceId": "设备ID",
|
|||
|
|
"deliveryId": "运送清单ID",
|
|||
|
|
"carNumber": "车牌号"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **后端更新数据库**
|
|||
|
|
- 更新 `iot_device_data` 表
|
|||
|
|
- 设置 `delivery_id` = 运送清单ID
|
|||
|
|
- 设置 `car_number` = 车牌号
|
|||
|
|
|
|||
|
|
### 查询可用设备流程
|
|||
|
|
|
|||
|
|
1. **打开创建运送清单对话框**
|
|||
|
|
- 调用 `loadDeviceOptions()` 方法
|
|||
|
|
|
|||
|
|
2. **查询未绑定设备**
|
|||
|
|
- 调用 `/iotDevice/queryList` 接口
|
|||
|
|
- 传递参数:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"type": 1, // 设备类型:1-主机, 2-耳标, 4-项圈
|
|||
|
|
"pageNum": 1,
|
|||
|
|
"pageSize": 9999
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **后端过滤逻辑**
|
|||
|
|
```sql
|
|||
|
|
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`
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
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
|
|||
|
|
|