Laravel 9:筛选登录用户可访问部门且符合库存条件的Job列表
带库存权限的Job列表筛选实现
需求
仅展示同时满足以下条件的Job列表:
- 用户隶属于该Job对应的部门
- Job关联的车辆所属库存组,允许用户所在部门访问(库存表的
DEPARTMENT_IDS包含用户所属部门ID)
完整表结构(中文)
- 用户表(USER):
ID - 部门表(DEPARTMENT):
ID - 用户-部门关联表(DEPARTMENT_USER):
ID、USER_ID、DEPARTMENT_ID - 任务表(JOBS):
ID、DEPARTMENT_ID、VEHICLE_ID - 车辆表(VEHICLE):
ID、STOCK_ID - 库存表(STOCKS):
ID、DEPARTMENT_IDS(有权访问该库存的部门ID集合)
现有代码(已实现部门权限过滤)
public function jobs_active() { return $this->hasManyThrough(Job::class, DepartmentUser::class, 'user_id', 'department_id', 'id', 'department_id'); }
修改后的实现方案
方案1:基于现有关联追加库存筛选(推荐)
利用whereHas嵌套关联,在原有部门权限过滤基础上,新增库存权限校验:
public function jobs_active() { // 获取当前用户的所有部门ID $userDeptIds = $this->departments->pluck('id')->toArray(); return $this->hasManyThrough(Job::class, DepartmentUser::class, 'user_id', 'department_id', 'id', 'department_id') ->whereHas('vehicle.stock', function ($query) use ($userDeptIds) { // 根据STOCKS.department_ids的存储格式选择对应逻辑 // 场景1:DEPARTMENT_IDS是逗号分隔字符串(如"1,3,5") foreach ($userDeptIds as $deptId) { $query->orWhereRaw('FIND_IN_SET(?, department_ids)', [$deptId]); } // 场景2:DEPARTMENT_IDS是JSON数组(如[1,3,5]),根据数据库调整 // MySQL 5.7+:$query->whereJsonContains('department_ids', $userDeptIds); // PostgreSQL:$query->whereRaw('? <@ department_ids', [$userDeptIds]); }); }
注意:需确保
Job模型已定义vehicle关联,Vehicle模型已定义stock关联。
方案2:手动多表连接实现(更灵活)
如果需要更直观的多表关联逻辑,可以直接构建查询:
public function jobs_active() { $userDeptIds = $this->departments->pluck('id')->toArray(); return Job::query() ->join('department_user', 'jobs.department_id', '=', 'department_user.department_id') ->join('vehicles', 'jobs.vehicle_id', '=', 'vehicles.id') ->join('stocks', 'vehicles.stock_id', '=', 'stocks.id') ->where('department_user.user_id', $this->id) ->where(function ($query) use ($userDeptIds) { // 同方案1的存储格式适配逻辑 foreach ($userDeptIds as $deptId) { $query->orWhereRaw('FIND_IN_SET(?, stocks.department_ids)', [$deptId]); } }) ->select('jobs.*') ->distinct(); // 避免因多表连接产生重复数据 }
核心逻辑说明
- 部门权限保留:原有的
hasManyThrough关联确保Job所属部门是用户已关联的部门 - 库存权限校验:通过关联车辆和库存表,检查库存的
DEPARTMENT_IDS是否包含用户的任意部门ID - 存储格式适配:必须根据
STOCKS.department_ids的实际存储方式(字符串/JSON)选择对应的查询语法,否则筛选逻辑会失效
内容的提问来源于stack exchange,提问作者Dean Hooper
相关产品推荐
相关产品推荐

