diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index 0537abd..23b6186 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -230,37 +230,53 @@ class OtherController extends CommonController ->orderBy('sort', 'asc') ->get(); - // 2. 查询对应的 CourseType + // 2. 查询对应的 CourseType(仅一层归集:overview_parent_id 指向根体系) $allCourseTypes = CourseType::where('is_chart', 1) - ->orderBy('sort', 'asc') ->where('is_history', 0) + ->orderBy('sort', 'asc') ->get(); + // 根体系:没有归集到其他体系的类型 + $rootCourseTypes = $allCourseTypes->whereNull('overview_parent_id')->values(); + // 子体系:归集到某个根体系(仅一层) + $childrenByRootId = $allCourseTypes + ->whereNotNull('overview_parent_id') + ->groupBy('overview_parent_id'); + // 3. 循环所有配置,对每个配置进行统计 foreach ($yearConfigs as $config) { // 根据配置获取日期范围 $configStartDate = $config->start_date; $configEndDate = $config->end_date ? $config->end_date : date('Y-m-d', strtotime('+10 year')); - // 复制 CourseType 集合(避免引用问题) - $courseTypes = $allCourseTypes->map(function ($item) { + // 复制根 CourseType 集合(避免引用问题) + $courseTypes = $rootCourseTypes->map(function ($item) { return clone $item; - }); + })->values(); // 汇总本配置下全部 Course id,用于 course_signs_unique_total 与 courses-home 口径一致(courseSignsTotalByUnique) $configCourseIds = collect(); // 对每个 CourseType 进行统计 foreach ($courseTypes as $courseType) { + $includedTypeIds = collect([$courseType->id]); + $children = $childrenByRootId->get($courseType->id); + if ($children && $children->count() > 0) { + $includedTypeIds = $includedTypeIds->merge($children->pluck('id')); + } + $includedTypeIds = $includedTypeIds->unique()->values(); + // 历史课程数据(添加时间范围限制;仅统计 type 为 is_history=0 的,is_history=1 的由下方「与 courses-home 口径一致」块统计,避免重复) - $historyCourse = HistoryCourse::whereHas('typeDetail', function ($query) use ($courseType) { - $query->where('name', 'like', '%' . $courseType->name . '%')->where('is_history', 0); - })->where(function ($query) use ($configStartDate, $configEndDate) { + // 口径升级:history_courses.type 存的是课程体系ID字符串,直接按 includedTypeIds 归集(避免名称匹配漂移) + $historyCourse = HistoryCourse::whereIn('type', $includedTypeIds) + ->whereHas('typeDetail', function ($query) { + $query->where('is_history', 0); + })->where(function ($query) use ($configStartDate, $configEndDate) { $query->whereBetween('start_time', [$configStartDate, $configEndDate]) ->orWhereBetween('end_time', [$configStartDate, $configEndDate]); })->get(); // 实际课程数据(添加时间范围限制) - $courses = Course::where('type', $courseType->id)->where('is_chart', 1) + $courses = Course::whereIn('type', $includedTypeIds)->where('is_chart', 1) ->where(function ($query) use ($configStartDate, $configEndDate) { $query->whereBetween('start_date', [$configStartDate, $configEndDate]) ->orWhereBetween('end_date', [$configStartDate, $configEndDate]); diff --git a/database/migrations/2026_04_09_120000_add_overview_parent_id_to_course_types_table.php b/database/migrations/2026_04_09_120000_add_overview_parent_id_to_course_types_table.php new file mode 100644 index 0000000..64db5c0 --- /dev/null +++ b/database/migrations/2026_04_09_120000_add_overview_parent_id_to_course_types_table.php @@ -0,0 +1,30 @@ +unsignedInteger('overview_parent_id')->nullable()->index()->comment('数据总览归集到的课程体系ID(仅一层)'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('course_types', function (Blueprint $table) { + $table->dropIndex(['overview_parent_id']); + $table->dropColumn('overview_parent_id'); + }); + } +}; +