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

Laravel API返回结构调整:嵌套对象转对象数组问题排查

Laravel接口grades字段结构调整问题

我开发了Laravel框架下的TODreport方法,调用API后返回的JSON里grades字段是嵌套对象结构,但需要改成对象数组结构,每个数组元素要包含grade_name字段。以下是相关代码和结果,请帮忙修正。

实现代码

public function TODreport($school_id, $date)
{
    $school = School::where('id', $school_id)->first();
    $school_education_level = $school->educationLevel;
    $result =['message' => 'Attendance Report in School'];

    $levels = [
        'Standard One', 'Standard Two', 'Standard Three', 'Standard Four',
        'Standard Five', 'Standard Six', 'Standard Seven',
    ];

    if($school_education_level == 'Secondary') {
        $levels = ['Form One', 'Form Two', 'Form Three', 'Form Four'];
    }
    foreach($levels as $level) {
       $result['grades'][$level] = [];

        $result['grades'][$level]['total_students'] = AttendanceStudent::where('dateofattendance', $date)
            ->where('school_id', $school_id)
            ->where('grade', $level )
            ->count();

        $result['grades'][$level]['total_boys_present_in_class'] = AttendanceStudent::where('dateofattendance', $date)
            ->where('school_id', $school_id)
            ->where('attendance_id', "1")
            ->where('grade', $level )
            ->whereHas('student' , function($query){
                return $query->where('gender', 'male');
            })
            ->count();

        $result['grades'][$level]['total_girls_present_in_class'] = AttendanceStudent::where('dateofattendance', $date)
            ->where('school_id', $school_id)
            ->where('attendance_id', "1")
            ->where('grade', $level )
            ->whereHas('student' , function($query){
                return $query->where('gender', 'female');
            })
            ->count();

        $result['grades'][$level]['total_boys_absent_in_class'] = AttendanceStudent::where('dateofattendance', $date)
            ->where('school_id', $school_id)
            ->where('attendance_id', "2")
            ->where('grade', $level )
            ->whereHas('student' , function($query){
                return $query->where('gender', 'male');
            })
            ->count();

        $result['grades'][$level]['total_girls_absent_in_class'] = AttendanceStudent::where('dateofattendance', $date)
            ->where('school_id', $school_id)
            ->where('attendance_id', "2")
            ->where('grade', $level )
            ->whereHas('student' , function($query){
                return $query->where('gender', 'female');
            })
            ->count();
    }
}

当前返回结果

{
   "message": "Attendance Report in School",
"grades": {
    "Form One": {
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    },
    "Form Two": {
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    },
    "Form Three": {
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    },
    "Form Four": {
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    }
},
"total_students_in_school": 0,
"total_present_students": 0,
"total_boys_present": 0,
"total_girls_present": 0,
"total_absent_students": 0,
"total_boys_absent": 0,
"total_girls_absent": 0
}

期望返回结果

{
"message": "Attendance Report in School",
"grades": [
    {
        "grade_name": "Form One",
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    },
    {
        "grade_name": "Form Two",
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    },
    {
        "grade_name": "Form Three",
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    },
    {
        "grade_name": "Form Four",
        "total_students": 0,
        "total_boys_present_in_class": 0,
        "total_girls_present_in_class": 0,
        "total_boys_absent_in_class": 0,
        "total_girls_absent_in_class": 0
    }
],
"total_students_in_school": 0,
"total_present_students": 0,
"total_boys_present": 0,
"total_girls_present": 0,
"total_absent_students": 0,
"total_boys_absent": 0,
"total_girls_absent": 0
}

解决方案

问题出在循环里的数组赋值方式:原来的代码把$result['grades']作为关联数组,用年级名称作为键;现在需要改成索引数组,每个元素是包含grade_name的对象。

修改步骤:

  1. 先初始化$result['grades']为空数组:在循环前添加$result['grades'] = [];
  2. 循环内不再用年级名称作为键,而是创建一个临时数组,加入grade_name字段,再把这个临时数组push到$result['grades']中

修改后的代码:

public function TODreport($school_id, $date)
{
    $school = School::where('id', $school_id)->first();
    $school_education_level = $school->educationLevel;
    $result =['message' => 'Attendance Report in School'];

    // 初始化grades为索引数组
    $result['grades'] = [];

    $levels = [
        'Standard One', 'Standard Two', 'Standard Three', 'Standard Four',
        'Standard Five', 'Standard Six', 'Standard Seven',
    ];

    if($school_education_level == 'Secondary') {
        $levels = ['Form One', 'Form Two', 'Form Three', 'Form Four'];
    }

    foreach($levels as $level) {
        // 创建当前年级的统计数组,包含grade_name
        $gradeData = [
            'grade_name' => $level,
            'total_students' => AttendanceStudent::where('dateofattendance', $date)
                ->where('school_id', $school_id)
                ->where('grade', $level )
                ->count(),
            'total_boys_present_in_class' => AttendanceStudent::where('dateofattendance', $date)
                ->where('school_id', $school_id)
                ->where('attendance_id', "1")
                ->where('grade', $level )
                ->whereHas('student' , function($query){
                    return $query->where('gender', 'male');
                })
                ->count(),
            'total_girls_present_in_class' => AttendanceStudent::where('dateofattendance', $date)
                ->where('school_id', $school_id)
                ->where('attendance_id', "1")
                ->where('grade', $level )
                ->whereHas('student' , function($query){
                    return $query->where('gender', 'female');
                })
                ->count(),
            'total_boys_absent_in_class' => AttendanceStudent::where('dateofattendance', $date)
                ->where('school_id', $school_id)
                ->where('attendance_id', "2")
                ->where('grade', $level )
                ->whereHas('student' , function($query){
                    return $query->where('gender', 'male');
                })
                ->count(),
            'total_girls_absent_in_class' => AttendanceStudent::where('dateofattendance', $date)
                ->where('school_id', $school_id)
                ->where('attendance_id', "2")
                ->where('grade', $level )
                ->whereHas('student' , function($query){
                    return $query->where('gender', 'female');
                })
                ->count(),
        ];

        // 将当前年级数据加入grades数组
        $result['grades'][] = $gradeData;
    }

    // 记得返回$result(原代码缺失返回逻辑,这里补上)
    return response()->json($result);
}

额外优化建议

当前代码每个年级要执行5次数据库查询,性能较差。可以通过一次查询获取该学校当天所有年级的考勤数据,再分组统计,减少数据库交互次数:

// 获取该学校当天所有考勤记录,预加载student关联
$attendanceRecords = AttendanceStudent::with('student')
    ->where('dateofattendance', $date)
    ->where('school_id', $school_id)
    ->get();

foreach($levels as $level) {
    // 筛选当前年级的记录
    $levelRecords = $attendanceRecords->where('grade', $level);

    $gradeData = [
        'grade_name' => $level,
        'total_students' => $levelRecords->count(),
        'total_boys_present_in_class' => $levelRecords->where('attendance_id', 1)->where('student.gender', 'male')->count(),
        'total_girls_present_in_class' => $levelRecords->where('attendance_id', 1)->where('student.gender', 'female')->count(),
        'total_boys_absent_in_class' => $levelRecords->where('attendance_id', 2)->where('student.gender', 'male')->count(),
        'total_girls_absent_in_class' => $levelRecords->where('attendance_id', 2)->where('student.gender', 'female')->count(),
    ];

    $result['grades'][] = $gradeData;
}

内容的提问来源于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.13 11:25:37