# 绑定车辆部门过滤功能说明 ## 功能概述 用户绑定车辆时,系统自动限制只能绑定与自己同一分公司的车辆,确保车辆管理的规范性和数据隔离。 ## 实现状态 ### ✅ 已实现功能 #### 1. 前端部门过滤 **文件**: [`app/pages/bind-vehicle.vue`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\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](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysTask.java#L95-L96) - ✅ [deptId](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysTask.java#L95-L96) 为空时,给出友好提示 - ✅ 无可用车辆时,显示明确提示信息 - ✅ 记录详细日志便于调试 #### 2. 后端部门过滤 **接口**: `GET /task/vehicle/available` **文件**: [`SysTaskVehicleController.java`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-admin\src\main\java\com\ruoyi\web\controller\task\SysTaskVehicleController.java) ```java @GetMapping("/available") public AjaxResult getAvailableVehicles( @RequestParam Long deptId, // ✅ 必填参数 @RequestParam(required = false) String taskType) { List list = sysTaskService.getAvailableVehicles(deptId, taskType); return success(list); } ``` **Service层过滤**: - ✅ 根据 [deptId](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysTask.java#L95-L96) 查询车辆 - ✅ 过滤 `status='0'` 的正常车辆 - ✅ 过滤 `car_id` 和 `dept_id` 不为空的车辆 ## 业务流程 ### 场景1:深圳分公司用户绑定车辆 ``` 用户登录 (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 (深圳分公司) ↓ 前端显示: 仅显示深圳分公司的车辆 ↓ 用户选择并绑定 ``` ### 场景2:用户无部门信息 ``` 用户登录 (deptId: null) ↓ 打开绑定车辆页面 ↓ 系统检查 deptId = null ↓ ❌ 终止加载,显示提示:"无法获取用户部门信息" ↓ 车辆列表为空,用户无法绑定 ``` ### 场景3:分公司暂无车辆 ``` 用户登录 (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 (无部门) | (无) | (全部) | ## 安全性保障 ### 1. 前端验证 - ✅ 检查用户部门信息是否存在 - ✅ 不使用默认值 100 - ✅ 空值时终止加载 ### 2. 后端验证 - ✅ [deptId](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysTask.java#L95-L96) 作为必填参数 - ✅ 数据库查询时强制添加部门条件 - ✅ 过滤无效车辆(car_id、dept_id 为空) ### 3. 建议增强(可选) 可以在后端Controller中添加权限校验: ```java @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 list = sysTaskService.getAvailableVehicles(deptId, taskType); return success(list); } ``` ## 相关接口 ### 1. 查询可用车辆 **接口**: `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": [] } ``` ### 2. 绑定车辆 **接口**: `POST /system/vehicle/bind` **请求体**: ```json { "userId": 1, "vehicleId": 123 } ``` ### 3. 查询用户绑定车辆 **接口**: `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 吗?" | ### 日志记录 ```javascript // 成功加载 console.log(`加载了 ${vehicleList.length} 辆车辆(部门ID: ${deptId})`) // 无部门信息 console.error('无法获取用户部门信息') // 无可用车辆 console.log('当前分公司暂无可用车辆') // 加载失败 console.error('加载车辆列表失败:', error) ``` ## 测试场景 ### 1. 正常绑定 - [x] 深圳用户只能看到深圳的车辆 - [x] 广州用户只能看到广州的车辆 - [x] 用户可以成功绑定本分公司的车辆 ### 2. 边界情况 - [x] 用户无部门信息,显示提示 - [x] 分公司无车辆,显示提示 - [x] 网络异常,显示错误提示 ### 3. 数据隔离 - [x] 深圳用户看不到广州的车辆 - [x] 广州用户看不到深圳的车辆 - [x] 不同分公司用户数据完全隔离 ### 4. 重复绑定 - [x] 绑定同一车辆,提示已绑定 - [x] 绑定其他车辆,提示是否解绑旧车辆 ## 相关文件 ### 前端 - [`app/pages/bind-vehicle.vue`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\app\pages\bind-vehicle.vue) - 绑定车辆页面 - [`app/api/vehicle.js`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\app\api\vehicle.js) - 车辆API ### 后端 - [`SysTaskVehicleController.java`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-admin\src\main\java\com\ruoyi\web\controller\task\SysTaskVehicleController.java) - 车辆Controller - [`SysTaskServiceImpl.java`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\service\impl\SysTaskServiceImpl.java) - 任务Service - [`VehicleInfoMapper.xml`](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\resources\mapper\system\VehicleInfoMapper.xml) - 车辆Mapper ### 文档 - [绑定车辆部门过滤优化.md](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\prd\绑定车辆部门过滤优化.md) - [车辆绑定解绑功能说明.md](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\prd\车辆绑定解绑功能说明.md) ## 总结 ✅ **已完成**: 绑定车辆时已经实现了部门过滤功能 ✅ **前端验证**: 严格检查用户部门信息,不使用默认值 ✅ **后端过滤**: 根据部门ID查询车辆,确保数据隔离 ✅ **用户体验**: 提供友好的提示信息和日志记录 💡 **建议**: 可以在后端增加权限校验,验证请求的 [deptId](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysTask.java#L95-L96) 是否与用户的 [deptId](file://d:\project\急救转运\code\Api\RuoYi-Vue-master\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysTask.java#L95-L96) 一致,进一步提高安全性。 --- **更新时间**: 2025-10-25 **版本**: v1.0 **状态**: ✅ 已实现