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

Laravel考勤系统:如何按用户ID统计各类请假时长并展示详情

解决方案:按请假类型合并统计已休天数

你可以通过Laravel Eloquent的分组聚合查询实现按请假类型合并统计的需求,以下是具体实现步骤:

1. 完善模型关联

首先在Leave模型中添加与LeaveApplication的一对多关联(对应现有belongsTo反向关联):

// app/Models/Leave.php
public function leaveApplications()
{
    return $this->hasMany(LeaveApplication::class, 'leave_id', 'id');
}

2. 修改Controller查询语句

替换你当前的两段查询,用一条语句直接获取按请假类型分组的统计数据:

// Dashboard Controller
use Illuminate\Support\Facades\Auth;
use App\Models\Leave;

$userLeaveStats = Leave::whereHas('leaveApplications', function ($query) {
    $query->where('user_id', Auth::user()->id)
          ->where('statuses_id', 2); // 仅统计已批准的请假
})
->withSum(['leaveApplications' => function ($query) {
    $query->where('user_id', Auth::user()->id)
          ->where('statuses_id', 2);
}], 'leave_taken_days')
->select('id', 'leave_name', 'total_leave_days')
->get();

代码说明:

  • whereHas:过滤出当前用户有已批准请假记录的请假类型
  • withSum:聚合计算该类型下用户已休天数的总和
  • select:只获取需要展示的字段,提升查询效率

如果你更倾向于使用join写法,也可以用以下语句:

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\LeaveApplication;

$userLeaveStats = LeaveApplication::where('user_id', Auth::user()->id)
    ->where('statuses_id', 2)
    ->join('leaves', 'leave_applications.leave_id', '=', 'leaves.id')
    ->select(
        'leaves.leave_name',
        'leaves.total_leave_days',
        DB::raw('SUM(leave_applications.leave_taken_days) as total_taken')
    )
    ->groupBy('leaves.id', 'leaves.leave_name', 'leaves.total_leave_days')
    ->get();

3. 调整视图展示代码

循环遍历统计后的集合,展示每个请假类型的汇总数据:

{{-- 视图文件 --}}
@foreach($userLeaveStats as $stat)
    <p>{{ $stat->leave_name }} ==> {{ $stat->leave_taken_days_sum ?? $stat->total_taken }} / {{ $stat->total_leave_days }}</p>
@endforeach

注:如果用withSum写法,总和字段是leave_taken_days_sum;如果用join写法,总和字段是total_taken

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:55:41