Laravel获取最新的项目,按项目结束日期排序,最先排序的项目

6mzjoqzu  于 2023-04-07  发布在  其他
关注(0)|答案(1)|浏览(81)

我需要为当前登录的用户编写一个提取项目的范围。如果当前登录的用户具有view-all-projects权限,则我希望列出系统中的所有项目,否则我希望列出登录用户创建的项目或登录用户通过任务分配到的项目。我尝试在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()]);
  }
}

虽然上面的代码段的作品,但它不做一件事(忘记了急于加载现在),但我需要的项目,根据截止日期前剩余的时间列出。所以它应该列出的项目几乎即将到期,项目有更多的时间已经到期的项目,在该顺序

tvmytwxo

tvmytwxo1#

我认为排序的问题很可能是你调用了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');
  }

相关问题