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

Laravel出勤统计API自定义JSON响应结构实现方案

Laravel出勤汇总API结构调整方案

问题原因

当前逻辑把聚合统计字段通过addSelect附加到每条出勤明细查询上,返回结果自然是带重复统计值的明细数组,本质是混淆了「明细查询」和「聚合统计」的查询场景,统计类接口不需要查询单条学生记录,直接用SQL聚合函数计算全局值即可。

实现代码

直接替换原getAttendanceReport方法内的逻辑即可,注意如果你的表结构、关联关系和示例有出入,对应调整字段名即可:

public function getAttendanceReport(Request $request)
{
    // 先做入参校验,根据自身业务调整校验规则
    $validated = $request->validate([
        'date' => 'required|date',
        'grade_id' => 'required|integer'
    ]);
    $targetDate = $validated['date'];
    $gradeId = $validated['grade_id'];

    // 统计出勤数据 对应attendance_id=1
    $presentData = AttendanceStudent::where('date', $targetDate)
        ->where('grade_id', $gradeId)
        ->where('attendance_id', 1)
        ->selectRaw('
            COUNT(*) as total_present_students,
            SUM(CASE WHEN s.gender = "男" THEN 1 ELSE 0 END) as total_boys_present,
            SUM(CASE WHEN s.gender = "女" THEN 1 ELSE 0 END) as total_girls_present,
            MAX(attendance_students.created_at) as created_at
        ')
        // 如果AttendanceStudent表本身存了gender字段,去掉join逻辑直接统计本表字段即可
        ->leftJoin('students as s', 'attendance_students.student_id', '=', 's.id')
        ->first();

    // 统计缺勤数据 对应attendance_id=2
    $absentData = AttendanceStudent::where('date', $targetDate)
        ->where('grade_id', $gradeId)
        ->where('attendance_id', 2)
        ->selectRaw('
            COUNT(*) as total_absent_students,
            SUM(CASE WHEN s.gender = "男" THEN 1 ELSE 0 END) as total_boys_absent,
            SUM(CASE WHEN s.gender = "女" THEN 1 ELSE 0 END) as total_girls_absent,
            MAX(attendance_students.created_at) as created_at
        ')
        ->leftJoin('students as s', 'attendance_students.student_id', '=', 's.id')
        ->first();

    // 统计对应年级总人数
    $totalGradeStudents = Student::where('grade_id', $gradeId)->count();

    // 组装要求的响应结构
    return response()->json([
        'message' => '出勤汇总数据获取成功',
        'Present' => [
            'total_present_students' => $presentData->total_present_students ?? 0,
            'total_boys_present' => $presentData->total_boys_present ?? 0,
            'total_girls_present' => $presentData->total_girls_present ?? 0,
            'created_at' => $presentData->created_at ?? null
        ],
        'Absent' => [
            'total_absent_students' => $absentData->total_absent_students ?? 0,
            'total_boys_absent' => $absentData->total_boys_absent ?? 0,
            'total_girls_absent' => $absentData->total_girls_absent ?? 0,
            'created_at' => $absentData->created_at ?? null
        ],
        'total_students_in_grade' => $totalGradeStudents
    ]);
}

返回结构参考

接口最终返回的JSON格式完全匹配业务需求:

{
    "message": "出勤汇总数据获取成功",
    "Present": {
        "total_present_students": 126,
        "total_boys_present": 65,
        "total_girls_present": 61,
        "created_at": "2024-05-20 08:30:00"
    },
    "Absent": {
        "total_absent_students": 8,
        "total_boys_absent": 5,
        "total_girls_absent": 3,
        "created_at": "2024-05-20 08:32:00"
    },
    "total_students_in_grade": 134
}

优化说明

  • 去掉了全量学生明细查询,直接返回聚合结果,数据量越大性能提升越明显
  • 增加空值兜底,当天无出勤/缺勤记录时对应统计值默认返回0,不会出现类型错误
  • 不存在重复挂载全局统计字段的问题,结构完全匹配前端展示需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:36:19