用户绑定车辆时,系统自动限制只能绑定与自己同一分公司的车辆,确保车辆管理的规范性和数据隔离。
文件: app/pages/bind-vehicle.vue
核心逻辑:
```javascript
loadVehicleList() {
this.loading = true
// ✅ 获取当前用户的部门ID
const deptId = this.currentUser.deptId
// ✅ 严格验证:部门ID不存在时,不加载车辆
if (!deptId) {
this.loading = false
console.error('无法获取用户部门信息')
this.$modal.showToast('无法获取用户部门信息')
return
}
// ✅ 使用用户实际部门ID查询车辆
listAvailableVehicles(deptId, 'GENERAL').then(response => {
// ...
})
}
```
关键特性:
- ✅ 不使用默认值,严格检查 deptId
- ✅ deptId 为空时,给出友好提示
- ✅ 无可用车辆时,显示明确提示信息
- ✅ 记录详细日志便于调试
接口: GET /task/vehicle/available
文件: SysTaskVehicleController.java
@GetMapping("/available")
public AjaxResult getAvailableVehicles(
@RequestParam Long deptId, // ✅ 必填参数
@RequestParam(required = false) String taskType) {
List<SysTaskVehicle> list = sysTaskService.getAvailableVehicles(deptId, taskType);
return success(list);
}
Service层过滤:
- ✅ 根据 deptId 查询车辆
- ✅ 过滤 status='0' 的正常车辆
- ✅ 过滤 car_id 和 dept_id 不为空的车辆
用户登录 (deptId: 101)
↓
打开绑定车辆页面
↓
系统检查 deptId = 101
↓
调用 API: /task/vehicle/available?deptId=101&taskType=GENERAL
↓
后端查询: SELECT * FROM tb_vehicle_info WHERE dept_id=101 AND status='0'
↓
返回结果:
- 粤A12345 (深圳分公司)
- 粤A67890 (深圳分公司)
↓
前端显示: 仅显示深圳分公司的车辆
↓
用户选择并绑定
用户登录 (deptId: null)
↓
打开绑定车辆页面
↓
系统检查 deptId = null
↓
❌ 终止加载,显示提示:"无法获取用户部门信息"
↓
车辆列表为空,用户无法绑定
用户登录 (deptId: 103)
↓
打开绑定车辆页面
↓
系统检查 deptId = 103
↓
调用 API: /task/vehicle/available?deptId=103&taskType=GENERAL
↓
后端查询: SELECT * FROM tb_vehicle_info WHERE dept_id=103 AND status='0'
↓
返回结果: [] (空数组)
↓
前端显示提示:"当前分公司暂无可用车辆"
100 (总公司)
├── 101 (深圳分公司)
│ ├── 粤A12345
│ ├── 粤A67890
│ └── 粤A11111
├── 102 (广州分公司)
│ ├── 粤B12345
│ ├── 粤B67890
│ └── 粤B22222
└── 103 (北京分公司)
├── 京A12345
└── 京A67890
| 用户 | 部门ID | 可见车辆 | 不可见车辆 |
|---|---|---|---|
| 张三 | 101 (深圳) | 粤A12345, 粤A67890, 粤A11111 | 粤B*, 京A* |
| 李四 | 102 (广州) | 粤B12345, 粤B67890, 粤B22222 | 粤A*, 京A* |
| 王五 | 103 (北京) | 京A12345, 京A67890 | 粤A*, 粤B* |
| 赵六 | null (无部门) | (无) | (全部) |
可以在后端Controller中添加权限校验:
@GetMapping("/available")
public AjaxResult getAvailableVehicles(@RequestParam Long deptId, @RequestParam(required = false) String taskType) {
// ✅ 验证请求的 deptId 是否与用户的 deptId 一致
LoginUser loginUser = SecurityUtils.getLoginUser();
Long userDeptId = loginUser.getUser().getDeptId();
if (!deptId.equals(userDeptId)) {
return error("无权查询其他部门的车辆");
}
List<SysTaskVehicle> list = sysTaskService.getAvailableVehicles(deptId, taskType);
return success(list);
}
接口: GET /task/vehicle/available
请求参数: deptId: 101 (必填) 部门ID taskType: GENERAL (可选) 任务类型
响应示例:json { "code": 200, "msg": "查询成功", "data": [ { "vehicleId": 1, "vehicleNo": "粤A12345", "vehicleType": "救护车", "vehicleBrand": "福特", "vehicleModel": "全顺", "deptId": 101, "status": "0" } ] }
无车辆时:json { "code": 200, "msg": "查询成功", "data": [] }
接口: POST /system/vehicle/bind
请求体:json { "userId": 1, "vehicleId": 123 }
接口: GET /system/vehicle/user/bound/{userId}
响应示例:json { "code": 200, "msg": "查询成功", "data": { "vehicleId": 123, "vehicleNumber": "粤A12345", "deptId": 101, "bindTime": "2025-10-25 10:30:00" } }
| 场景 | 提示内容 |
|---|---|
| 无部门信息 | "无法获取用户部门信息" |
| 无可用车辆 | "当前分公司暂无可用车辆" |
| 加载失败 | "加载车辆列表失败" |
| 重复绑定 | "当前已绑定此车辆,无需重复绑定" |
| 强制绑定确认 | "您当前已绑定车辆:粤A12345,确认要解绑旧车辆并绑定新车辆:粤A67890 吗?" |
// 成功加载
console.log(`加载了 ${vehicleList.length} 辆车辆(部门ID: ${deptId})`)
// 无部门信息
console.error('无法获取用户部门信息')
// 无可用车辆
console.log('当前分公司暂无可用车辆')
// 加载失败
console.error('加载车辆列表失败:', error)
app/pages/bind-vehicle.vue - 绑定车辆页面app/api/vehicle.js - 车辆APISysTaskVehicleController.java - 车辆ControllerSysTaskServiceImpl.java - 任务ServiceVehicleInfoMapper.xml - 车辆Mapper✅ 已完成: 绑定车辆时已经实现了部门过滤功能
✅ 前端验证: 严格检查用户部门信息,不使用默认值
✅ 后端过滤: 根据部门ID查询车辆,确保数据隔离
✅ 用户体验: 提供友好的提示信息和日志记录
💡 建议: 可以在后端增加权限校验,验证请求的 deptId 是否与用户的 deptId 一致,进一步提高安全性。
更新时间: 2025-10-25
版本: v1.0
状态: ✅ 已实现