Laravel 获取按项目结束日期排序的最新项目
P粉773659687
P粉773659687 2023-09-11 21:38:55
0
1
496

我需要编写一个范围来为当前登录的用户获取项目。如果当前登录的用户具有查看所有项目权限,那么我想列出系统中的所有项目,否则我想列出登录用户创建的项目或登录的项目在用户中通过任务分配。我尝试在 Project 模型中编写以下范围:

public function scopeForUser($query, User $user)
  {
    if ($user->can('view-all-projects')) {
      return $query->withBudget()
        ->with(['customer:id,company_id' => ['company:id,name']])
        ->latest()
        ->orderBy('end_date', 'desc');
    }

    return $query->withBudget()
      ->with(['customer:id,company_id' => ['company:id,name']])
      ->where(function ($query) use ($user) {
        $query->where('user_id', $user->id)
          ->orWhereHas('users', function ($query) use ($user) {
            $query->where('users.id', $user->id);
          })
          ->orWhereHas('tasks', function ($query) use ($user) {
            $query->where('user_id', $user->id);
          });
      })
      ->latest()
      ->orderBy('end_date', 'desc');
  }

withBudget 的范围如下

public function scopeWithBudget($query)
  {
    return $query->addSelect(['budget' => function ($subQuery) {
      $subQuery->selectRaw('sum(cost)')
        ->from('tasks')
        ->whereColumn('project_id', 'projects.id');
    }]);
}

到目前为止,它确实有效,但不准确。有时,当我知道登录的用户是管理员并拥有所有权限时,它只会获取几个项目,而且项目也会按降序排列,我认为 created_at 而不是 end_date< /代码>

有什么想法可以解决这个问题吗?如果您需要更多信息,请告诉我

编辑 如果我删除一些查询,以下代码片段将起作用:

if ($user->hasPermissionTo('view-all-projects')) {
      return $query->latest();
    } else {
      return $query->where(function ($query) use ($user) {
        $query->where('user_id', $user->id)
          ->orWhereIn('id', function ($query) use ($user) {
            $query->select('project_id')
              ->from('tasks')
              ->where('user_id', $user->id);
          });
      });
    }

然后我通过以下操作获取项目:

<?php

namespace App\Actions;

use App\Models\Project;
// use Illuminate\Support\Collection;
use Illuminate\View\View;

class ListProjects
{

  public function __invoke(): View
  {
    $projects = Project::forUser(auth()->user())->get();

    return view('projects.index', ['projects' => $projects, 'projectsCount' => $projects->count()]);
  }
}

虽然上面的代码片段有效,但它没有做一件事(暂时忘记急切加载),但我需要根据截止日期之前的剩余时间列出项目。因此,它应该按顺序列出即将到期的项目、有更多时间的项目、已经到期的项目

P粉773659687
P粉773659687

全部回复(1)
P粉258788831

我认为排序问题可能是您调用 latest() 以及 orderBy('end_date', 'desc') 作为 latest() 工作于 created_at。您可能根本不需要 latest() 调用,因为您无论如何都要添加自己的排序。

至于用户范围问题,我想知道您是否使用两个 orWhereHas 调用而不是 whereHasorWhereHas 可能会在 scopeForUser 中引起问题。

也许另一种方法可能如下所示:

public function scopeForUser($query, User $user)
  {
    if ($user->can('view-all-projects')) {
      return $query->withBudget()
        ->with(['customer:id,company_id' => ['company:id,name']])
        ->orderBy('end_date', 'desc');
    }

    return $query->withBudget()
      ->with(['customer:id,company_id' => ['company:id,name']])
      ->where('user_id', $user->id)
      ->orWhere(function ($query) use ($user) {
        $query->whereHas('users', function ($query) use ($user) {
            $query->where('users.id', $user->id);
          })
          ->orWhereHas('tasks', function ($query) use ($user) {
            $query->where('user_id', $user->id);
          });
      })
      ->orderBy('end_date', 'desc');
  }
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板