You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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(); // 避免因多表连接产生重复数据
}

核心逻辑说明

  1. 部门权限保留:原有的hasManyThrough关联确保Job所属部门是用户已关联的部门
  2. 库存权限校验:通过关联车辆和库存表,检查库存的DEPARTMENT_IDS是否包含用户的任意部门ID
  3. 存储格式适配:必须根据STOCKS.department_ids的实际存储方式(字符串/JSON)选择对应的查询语法,否则筛选逻辑会失效

内容的提问来源于stack exchange,提问作者Dean Hooper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:57:20