From 805731963a81d5fcec72295136dd8daea0cda32a Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Thu, 22 Jan 2026 17:14:27 +0800 Subject: [PATCH 1/2] update --- app/Http/Controllers/Admin/UserController.php | 13 ++--- app/Models/Company.php | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 1c6cd7e..1efdf1e 100755 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -369,16 +369,9 @@ class UserController extends BaseController } // 所在区域:like 匹配关联 company 的 company_area,多个英文逗号分隔为 or if (isset($all['company_area']) && $all['company_area'] !== '') { - $company_area = array_filter(array_map('trim', explode(',', $all['company_area']))); - if (!empty($company_area)) { - $query->whereHas('company', function ($c) use ($company_area) { - $c->where(function ($q) use ($company_area) { - foreach ($company_area as $v) { - $q->orWhere('company_area', 'like', '%' . $v . '%'); - } - }); - }); - } + $query->whereHas('company', function ($c) use ($all) { + $c->filterByArea($all['company_area']); + }); } // 公司地址:模糊匹配关联 company 的 company_address 或 company_city if (isset($all['address']) && $all['address'] !== '') { diff --git a/app/Models/Company.php b/app/Models/Company.php index 28990b5..eb076ae 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -38,6 +38,57 @@ class Company extends SoftDeletesModel }); } + /** + * 根据区域名称筛选公司 + * 支持区域名称映射和特殊逻辑(如"苏州市外") + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string|array $companyArea 区域名称,多个用英文逗号分隔或传入数组 + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeFilterByArea($query, $companyArea) + { + if (empty($companyArea)) { + return $query; + } + + // 如果是字符串,转换为数组 + if (is_string($companyArea)) { + $company_area = array_filter(array_map('trim', explode(',', $companyArea))); + } else { + $company_area = array_filter(array_map('trim', (array) $companyArea)); + } + + if (empty($company_area)) { + return $query; + } + + // 区域名称映射:搜索参数 -> 数据库值 + $areaMapping = [ + '高新区' => '虎丘', + ]; + + // 检查是否包含"苏州市外" + $hasSuzhouOut = in_array('苏州市外', $company_area); + + if ($hasSuzhouOut) { + // 如果包含"苏州市外",查询所有不等于"苏州"的记录 + return $query->where('company_area', '!=', '苏州') + ->whereNotNull('company_area') + ->where('company_area', '!=', ''); + } else { + // 将搜索参数转换为数据库值 + $company_area = array_map(function ($v) use ($areaMapping) { + return isset($areaMapping[$v]) ? $areaMapping[$v] : $v; + }, $company_area); + + return $query->where(function ($q) use ($company_area) { + foreach ($company_area as $v) { + $q->orWhere('company_area', 'like', '%' . $v . '%'); + } + }); + } + } + /** * 地址转经纬度 */ From 0c352fc7eef967bcacc426de98ee1cdb29139db7 Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Thu, 22 Jan 2026 17:22:46 +0800 Subject: [PATCH 2/2] update --- .../Controllers/Admin/OtherController.php | 581 +++++++++--------- 1 file changed, 301 insertions(+), 280 deletions(-) diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index 4ca66fb..bad4cc9 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -26,6 +26,7 @@ use App\Models\User; use App\Repositories\DoorRepository; use App\Repositories\EntranceRepository; use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; use App\Models\Course; @@ -127,181 +128,191 @@ class OtherController extends CommonController */ public function homeV2() { - // 默认开始时间 - $start_date = CourseType::START_DATE; - // 默认结束日期一年以后 - $end_date = date('Y-m-d', strtotime('+10 year')); - - // 校友总数(与 study 口径一致:仅统计有课程报名记录的校友) - $list['schoolmate_total'] = User::where('is_schoolmate', 1)->whereHas('courseSigns')->count(); - // 今年新增校友数(根据schoolmate_time字段统计,口径同上) - $list['schoolmate_year'] = User::where('is_schoolmate', 1)->whereHas('courseSigns')->whereYear('schoolmate_time', date('Y'))->count(); - // 投后企业 - $list['company_invested_total'] = CourseSign::yhInvestedTotal(CourseType::START_DATE, date('Y-m-d'), null); - // 元和员工参与人数 - $list['company_join_total'] = CourseSign::companyJoin(); - // 全市干部参与企业 - $list['company_ganbu_total'] = CourseSign::ganbu(); - // 三个全覆盖 - // 苏州苏州头部企业 - $list['cover_head_total'] = CourseSign::toubuqiye(); - // 苏州高层次人才 - $list['cover_rencai_total'] = CourseSign::rencai(); - // 苏州重点上市公司 - $list['cover_stock_total'] = CourseSign::shangshi(); - // 培养人次 - $start_date = CourseType::START_DATE; - // 默认结束日期一年以后 - $end_date = date('Y-m-d', strtotime('+10 year')); - // 培养人次 - $list['course_signs_pass'] = CourseSign::courseSignsTotal($start_date, $end_date, 1); - // 培养人数 - $list['course_signs_pass_unique'] = CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, null, null); - // 跟班学员数 - $list['genban_total'] = CourseSign::genban($start_date, $end_date); - // 本月课程 - $monthCourses = Calendar::with('course.teacher') - ->where('start_time', 'like', '%' . date('Y-m') . '%') - ->get(); - - // 苏州区域数据 - 使用 CourseSign::getAreaData 方法实现数据一致 - $areasData = CourseSign::getAreaData($start_date, $end_date, 1, null, true, 'statistics'); - $suzhou = []; - foreach ($areasData as $item) { - $suzhou[] = [ - 'area' => $item['area'], - 'total' => $item['total_unique'] ?? $item['total'] - ]; - } - - // 全国数据(与 study 口径一致:address 用 company_address/company_city 的 like;且须有 courseSigns 且 course.is_chart=1,is_schoolmate=1) - $countryArea = Company::approvedStudents()->groupBy('company_city')->whereNotNull('company_city')->get(['company_city']); - $country = []; - foreach ($countryArea as $item) { - $term = preg_replace('/市$/', '', $item->company_city) ?: $item->company_city; - $total = User::query() - ->where('is_schoolmate', 1) - ->whereHas('company', function ($query) use ($term) { - $query->where(function ($q) use ($term) { - $q->where('company_address', 'like', '%' . $term . '%') - ->orWhere('company_city', 'like', '%' . $term . '%'); - }); - }) - ->whereHas('courseSigns', function ($cs) { - $cs->whereHas('course', function ($c) { - $c->where('is_chart', 1); - }); - }) - ->count(); - if (empty($total)) { - continue; + // 生成缓存键(该方法无参数,使用固定键名) + $cacheKey = 'home_v2_data'; + + // 尝试从缓存获取数据,缓存5分钟(300秒) + $data = Cache::remember($cacheKey, 300, function () { + // 默认开始时间 + $start_date = CourseType::START_DATE; + // 默认结束日期一年以后 + $end_date = date('Y-m-d', strtotime('+10 year')); + + // 校友总数(与 study 口径一致:仅统计有课程报名记录的校友) + $list['schoolmate_total'] = User::where('is_schoolmate', 1)->whereHas('courseSigns')->count(); + // 今年新增校友数(根据schoolmate_time字段统计,口径同上) + $list['schoolmate_year'] = User::where('is_schoolmate', 1)->whereHas('courseSigns')->whereYear('schoolmate_time', date('Y'))->count(); + // 投后企业 + $list['company_invested_total'] = CourseSign::yhInvestedTotal(CourseType::START_DATE, date('Y-m-d'), null); + // 元和员工参与人数 + $list['company_join_total'] = CourseSign::companyJoin(); + // 全市干部参与企业 + $list['company_ganbu_total'] = CourseSign::ganbu(); + // 三个全覆盖 + // 苏州苏州头部企业 + $list['cover_head_total'] = CourseSign::toubuqiye(); + // 苏州高层次人才 + $list['cover_rencai_total'] = CourseSign::rencai(); + // 苏州重点上市公司 + $list['cover_stock_total'] = CourseSign::shangshi(); + // 培养人次 + $start_date = CourseType::START_DATE; + // 默认结束日期一年以后 + $end_date = date('Y-m-d', strtotime('+10 year')); + // 培养人次 + $list['course_signs_pass'] = CourseSign::courseSignsTotal($start_date, $end_date, 1); + // 培养人数 + $list['course_signs_pass_unique'] = CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, null, null); + // 跟班学员数 + $list['genban_total'] = CourseSign::genban($start_date, $end_date); + // 本月课程 + $monthCourses = Calendar::with('course.teacher') + ->where('start_time', 'like', '%' . date('Y-m') . '%') + ->get(); + + // 苏州区域数据 - 使用 CourseSign::getAreaData 方法实现数据一致 + $areasData = CourseSign::getAreaData($start_date, $end_date, 1, null, true, 'statistics'); + $suzhou = []; + foreach ($areasData as $item) { + $suzhou[] = [ + 'area' => $item['area'], + 'total' => $item['total_unique'] ?? $item['total'] + ]; } - $country[] = [ - 'area' => $item->company_city, - 'total' => $total, - ]; - } - // 时间轴 - $time_axis = TimeEvent::orderBy('sort', 'asc')->get(); - // 动态信息 - $article['xiaoyou'] = Article::where('type', 1)->limit(7)->orderBy('sort', 'desc')->get(); - $article['yejie'] = Article::where('type', 2)->limit(7)->orderBy('sort', 'desc')->get(); - $article['supply_demands'] = SupplyDemand::limit(7)->orderBy('created_at', 'desc')->get(); - - // 课程体系筛选 - // 1. 从配置表读取配置列表 - $yearConfigs = CourseTypeDataOverviewConfig::where('status', true) - ->orderBy('sort', 'asc') - ->get(); + // 全国数据(与 study 口径一致:address 用 company_address/company_city 的 like;且须有 courseSigns 且 course.is_chart=1,is_schoolmate=1) + $countryArea = Company::approvedStudents()->groupBy('company_city')->whereNotNull('company_city')->get(['company_city']); + $country = []; + foreach ($countryArea as $item) { + $term = preg_replace('/市$/', '', $item->company_city) ?: $item->company_city; + $total = User::query() + ->where('is_schoolmate', 1) + ->whereHas('company', function ($query) use ($term) { + $query->where(function ($q) use ($term) { + $q->where('company_address', 'like', '%' . $term . '%') + ->orWhere('company_city', 'like', '%' . $term . '%'); + }); + }) + ->whereHas('courseSigns', function ($cs) { + $cs->whereHas('course', function ($c) { + $c->where('is_chart', 1); + }); + }) + ->count(); + if (empty($total)) { + continue; + } + $country[] = [ + 'area' => $item->company_city, + 'total' => $total, + ]; + } - // 2. 查询对应的 CourseType - $allCourseTypes = CourseType::where('is_chart', 1) - ->orderBy('sort', 'asc') - ->where('is_history', 0) - ->get(); + // 时间轴 + $time_axis = TimeEvent::orderBy('sort', 'asc')->get(); + // 动态信息 + $article['xiaoyou'] = Article::where('type', 1)->limit(7)->orderBy('sort', 'desc')->get(); + $article['yejie'] = Article::where('type', 2)->limit(7)->orderBy('sort', 'desc')->get(); + $article['supply_demands'] = SupplyDemand::limit(7)->orderBy('created_at', 'desc')->get(); + + // 课程体系筛选 + // 1. 从配置表读取配置列表 + $yearConfigs = CourseTypeDataOverviewConfig::where('status', true) + ->orderBy('sort', 'asc') + ->get(); + + // 2. 查询对应的 CourseType + $allCourseTypes = CourseType::where('is_chart', 1) + ->orderBy('sort', 'asc') + ->where('is_history', 0) + ->get(); + + // 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) { + return clone $item; + }); + + // 汇总本配置下全部 Course id,用于 course_signs_unique_total 与 courses-home 口径一致(courseSignsTotalByUnique) + $configCourseIds = collect(); + + // 对每个 CourseType 进行统计 + foreach ($courseTypes as $courseType) { + // 历史课程数据(添加时间范围限制;仅统计 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) { + $query->whereBetween('start_time', [$configStartDate, $configEndDate]) + ->orWhereBetween('end_time', [$configStartDate, $configEndDate]); + })->get(); + // 实际课程数据(添加时间范围限制) + $courses = Course::where('type', $courseType->id)->where('is_chart', 1) + ->where(function ($query) use ($configStartDate, $configEndDate) { + $query->whereBetween('start_date', [$configStartDate, $configEndDate]) + ->orWhereBetween('end_date', [$configStartDate, $configEndDate]); + })->get(); + $configCourseIds = $configCourseIds->merge($courses->pluck('id')); + // 历史课程期数 + $courseType->history_course_periods_total = $historyCourse->count(); + // 现在课程期数(添加时间范围限制) + $courseType->now_course_periods_total = $courses->count(); + + // 历史课程培养人数去重 + $courseType->history_course_signs_total = $historyCourse->sum('course_type_signs_pass_unique'); + // 现在课程培养人数(使用配置的日期范围) + $courseType->now_course_signs_total = CourseSign::courseSignsTotalByUnique($configStartDate, $configEndDate, 1, $courses->pluck('id'), false, false); + + // 已开设期数 + $courseType->course_periods_total = $courseType->now_course_periods_total + $courseType->history_course_periods_total; + // 培养人数去重 + $courseType->course_signs_total = $courseType->history_course_signs_total + $courseType->now_course_signs_total; + } - // 3. 循环所有配置,对每个配置进行统计 - foreach ($yearConfigs as $config) { - // 根据配置获取日期范围 - $configStartDate = $config->start_date; - $configEndDate = $config->end_date ? $config->end_date : date('Y-m-d', strtotime('+10 year')); + // 与 courses-home 口径一致:附加 is_history=1 的 HistoryCourse(whereHas calendar is_count_people=1,type=体系 id,日期在配置范围内) + $courseTypesHistory = CourseType::where('is_history', 1)->get(); + foreach ($courseTypesHistory as $hc) { + $historyList = HistoryCourse::whereHas('calendar', function ($query) { + $query->where('is_count_people', 1); + })->where(function ($query) use ($configStartDate, $configEndDate) { + $query->whereBetween('start_time', [$configStartDate, $configEndDate]) + ->orWhereBetween('end_time', [$configStartDate, $configEndDate]); + })->where('type', $hc->id)->get(); + $hc->history_course_periods_total = $historyList->count(); + $hc->now_course_periods_total = 0; + $hc->history_course_signs_total = $historyList->sum('course_type_signs_pass_unique'); + $hc->now_course_signs_total = 0; + $hc->course_periods_total = $hc->history_course_periods_total; + $hc->course_signs_total = $hc->history_course_signs_total; + $courseTypes->push(clone $hc); + } - // 复制 CourseType 集合(避免引用问题) - $courseTypes = $allCourseTypes->map(function ($item) { - return clone $item; - }); + // 统计 is_chart=0 的课程类型数据,组成"其他"统计项 + $otherCourseType = CourseType::getOtherStatistics($configStartDate, $configEndDate); - // 汇总本配置下全部 Course id,用于 course_signs_unique_total 与 courses-home 口径一致(courseSignsTotalByUnique) - $configCourseIds = collect(); + // 将"其他"添加到 courseTypes 集合中 + $courseTypes->push($otherCourseType); - // 对每个 CourseType 进行统计 - foreach ($courseTypes as $courseType) { - // 历史课程数据(添加时间范围限制;仅统计 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) { - $query->whereBetween('start_time', [$configStartDate, $configEndDate]) - ->orWhereBetween('end_time', [$configStartDate, $configEndDate]); - })->get(); - // 实际课程数据(添加时间范围限制) - $courses = Course::where('type', $courseType->id)->where('is_chart', 1) - ->where(function ($query) use ($configStartDate, $configEndDate) { - $query->whereBetween('start_date', [$configStartDate, $configEndDate]) - ->orWhereBetween('end_date', [$configStartDate, $configEndDate]); - })->get(); - $configCourseIds = $configCourseIds->merge($courses->pluck('id')); - // 历史课程期数 - $courseType->history_course_periods_total = $historyCourse->count(); - // 现在课程期数(添加时间范围限制) - $courseType->now_course_periods_total = $courses->count(); - - // 历史课程培养人数去重 - $courseType->history_course_signs_total = $historyCourse->sum('course_type_signs_pass_unique'); - // 现在课程培养人数(使用配置的日期范围) - $courseType->now_course_signs_total = CourseSign::courseSignsTotalByUnique($configStartDate, $configEndDate, 1, $courses->pluck('id'), false, false); - - // 已开设期数 - $courseType->course_periods_total = $courseType->now_course_periods_total + $courseType->history_course_periods_total; - // 培养人数去重 - $courseType->course_signs_total = $courseType->history_course_signs_total + $courseType->now_course_signs_total; - } + $configCourseIds = $configCourseIds->merge(CourseType::getOtherCourseIds($configStartDate, $configEndDate)); - // 与 courses-home 口径一致:附加 is_history=1 的 HistoryCourse(whereHas calendar is_count_people=1,type=体系 id,日期在配置范围内) - $courseTypesHistory = CourseType::where('is_history', 1)->get(); - foreach ($courseTypesHistory as $hc) { - $historyList = HistoryCourse::whereHas('calendar', function ($query) { - $query->where('is_count_people', 1); - })->where(function ($query) use ($configStartDate, $configEndDate) { - $query->whereBetween('start_time', [$configStartDate, $configEndDate]) - ->orWhereBetween('end_time', [$configStartDate, $configEndDate]); - })->where('type', $hc->id)->get(); - $hc->history_course_periods_total = $historyList->count(); - $hc->now_course_periods_total = 0; - $hc->history_course_signs_total = $historyList->sum('course_type_signs_pass_unique'); - $hc->now_course_signs_total = 0; - $hc->course_periods_total = $hc->history_course_periods_total; - $hc->course_signs_total = $hc->history_course_signs_total; - $courseTypes->push(clone $hc); + // 将统计数据直接组合到配置对象中 + $config->courseTypes = $courseTypes; + // 总期数(包含"其他") + $config->course_periods_total = $courseTypes->sum('course_periods_total'); + // 总去重人数(与 courses-home 的 course_signs_pass_unique 口径一致:courseSignsTotalByUnique) + $config->course_signs_unique_total = CourseSign::courseSignsTotalByUnique($configStartDate, $configEndDate, 1, $configCourseIds->unique()->values(), false); } - // 统计 is_chart=0 的课程类型数据,组成"其他"统计项 - $otherCourseType = CourseType::getOtherStatistics($configStartDate, $configEndDate); - - // 将"其他"添加到 courseTypes 集合中 - $courseTypes->push($otherCourseType); - - $configCourseIds = $configCourseIds->merge(CourseType::getOtherCourseIds($configStartDate, $configEndDate)); - - // 将统计数据直接组合到配置对象中 - $config->courseTypes = $courseTypes; - // 总期数(包含"其他") - $config->course_periods_total = $courseTypes->sum('course_periods_total'); - // 总去重人数(与 courses-home 的 course_signs_pass_unique 口径一致:courseSignsTotalByUnique) - $config->course_signs_unique_total = CourseSign::courseSignsTotalByUnique($configStartDate, $configEndDate, 1, $configCourseIds->unique()->values(), false); - } + // 返回数据数组 + return compact('list', 'suzhou', 'country', 'monthCourses', 'time_axis', 'article', 'yearConfigs'); + }); - return $this->success(compact('list', 'suzhou', 'country', 'monthCourses', 'time_axis', 'article', 'yearConfigs')); + // 返回响应 + return $this->success($data); } /** @@ -329,128 +340,138 @@ class OtherController extends CommonController $course_type_id = $params['course_type_id']; $courses = $params['courses']; - // 报名人数 - $list['course_signs_total'] = CourseSign::courseSignsTotal($start_date, $end_date, null, $courses->pluck('id')); - // 审核通过人数 - $list['course_signs_pass'] = CourseSign::courseSignsTotal($start_date, $end_date, 1, $courses->pluck('id')); - // 审核通过人数去重 - $list['course_signs_pass_unique'] = CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $courses->pluck('id'), false); - // 开课场次 - $list['course_total'] = Calendar::getCourseTotal($start_date, $end_date, $course_type_id); - // 开课天数 - $list['course_day_total'] = Calendar::getCourseDayTotal($start_date, $end_date, $course_type_id); - - $course_ids = $courses->pluck('id'); - - // 上市公司覆盖数(所有上市公司) - $list['company_market_total'] = CourseSign::shangshi($start_date, $end_date, $course_ids); - // 跟班学员数(在指定时间范围内报名的学员中,from为'跟班学员'的数量) - $list['ganbu_total'] = CourseSign::genban($start_date, $end_date, $course_ids); - - // 当前上市公司数量(从stock_companys表获取,stock_date在指定时间范围内) - $list['company_market_year_total'] = StockCompany::getByDateRange($start_date, $end_date); - - // 入学后上市公司数量(从stock_companys表获取,is_after_enrollment = 1,stock_date在指定时间范围内) - $list['company_market_after_enrollment_total'] = StockCompany::getAfterEnrollment($start_date, $end_date); - - // 累计被投企业数,被投企业覆盖数 - $list['course_signs_invested'] = CourseSign::yhInvestedTotal(CourseType::START_DATE, $end_date, $course_ids); - - // 当前被投企业覆盖数(根据传入的开始结束时间统计) - $list['course_signs_invested_current'] = CourseSign::yhInvestedTotal($start_date, $end_date, $course_ids); - - // 当前入学后被投企业数量(在指定时间范围内报名的学员所在公司中,在入学后被投的公司数量) - $list['company_invested_after_enrollment_total'] = CourseSign::companyInvestedAfterEnrollment($start_date, $end_date, $course_ids); - - // 累计入学后被投企业数量(从CourseType::START_DATE开始的入学后被投企业数量) - $list['company_invested_after_enrollment_total_cumulative'] = CourseSign::companyInvestedAfterEnrollment(CourseType::START_DATE, $end_date, $course_ids); - - // 当前被投企业数 - $list['company_invested_year_total'] = CourseSign::companyInvestedYear($start_date, $end_date, $course_ids); - - // 元和员工参与人数 - $list['company_join_total'] = CourseSign::companyJoin($start_date, $end_date, $course_ids, false, true); - // 全市干部参与企业 - $list['company_ganbu_total'] = CourseSign::ganbu($start_date, $end_date, $course_ids); - // 苏州头部企业 - $list['cover_head_total'] = CourseSign::toubuqiye($start_date, $end_date, $course_ids); - // 苏州高层次人才 - $list['cover_rencai_total'] = CourseSign::rencai($start_date, $end_date, $course_ids); - // 苏州重点上市公司 - $list['cover_stock_total'] = CourseSign::suzhoushangshi($start_date, $end_date, $course_ids); - - - // 课程分类明细统计 - $courseTypesSum = []; - $courseTypes = CourseType::whereIn('id', $course_type_id)->get(); - foreach ($courseTypes as $courseType) { - // 获取课程 - $courses2 = Course::where('type', $courseType->id) - ->where(function ($query) use ($start_date, $end_date) { - // 开始结束日期的筛选。or查询 - if ($start_date && $end_date) { - $query->whereBetween('start_date', [$start_date, $end_date]) - ->orWhereBetween('end_date', [$start_date, $end_date]); - } - })->where('is_chart', 1)->orderBy('start_date', 'asc')->get(); - foreach ($courses2 as $course) { - $courseTypesSum[] = [ - 'course_type' => $courseType->name, - // 培养人数 - 'course_type_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, $courses2->pluck('id'), false, false), - // 去重培养人数 - 'course_type_signs_pass_unique' => CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $courses2->pluck('id'), false, false), - 'course_name' => $course->name, - 'course_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, [$course->id], false, false), - // 跟班学员数量 - 'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id]), - // 被投企业数 - 'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]), - // 元禾同事数 - 'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id], false, false), - ]; + // 生成缓存键(基于参数) + $cacheKey = 'courses_home_' . md5($start_date . '_' . $end_date . '_' . implode(',', $course_type_id)); + + // 尝试从缓存获取数据,缓存5分钟(300秒) + $data = Cache::remember($cacheKey, 300, function () use ($start_date, $end_date, $course_type_id, $courses) { + // 报名人数 + $list['course_signs_total'] = CourseSign::courseSignsTotal($start_date, $end_date, null, $courses->pluck('id')); + // 审核通过人数 + $list['course_signs_pass'] = CourseSign::courseSignsTotal($start_date, $end_date, 1, $courses->pluck('id')); + // 审核通过人数去重 + $list['course_signs_pass_unique'] = CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $courses->pluck('id'), false); + // 开课场次 + $list['course_total'] = Calendar::getCourseTotal($start_date, $end_date, $course_type_id); + // 开课天数 + $list['course_day_total'] = Calendar::getCourseDayTotal($start_date, $end_date, $course_type_id); + + $course_ids = $courses->pluck('id'); + + // 上市公司覆盖数(所有上市公司) + $list['company_market_total'] = CourseSign::shangshi($start_date, $end_date, $course_ids); + // 跟班学员数(在指定时间范围内报名的学员中,from为'跟班学员'的数量) + $list['ganbu_total'] = CourseSign::genban($start_date, $end_date, $course_ids); + + // 当前上市公司数量(从stock_companys表获取,stock_date在指定时间范围内) + $list['company_market_year_total'] = StockCompany::getByDateRange($start_date, $end_date); + + // 入学后上市公司数量(从stock_companys表获取,is_after_enrollment = 1,stock_date在指定时间范围内) + $list['company_market_after_enrollment_total'] = StockCompany::getAfterEnrollment($start_date, $end_date); + + // 累计被投企业数,被投企业覆盖数 + $list['course_signs_invested'] = CourseSign::yhInvestedTotal(CourseType::START_DATE, $end_date, $course_ids); + + // 当前被投企业覆盖数(根据传入的开始结束时间统计) + $list['course_signs_invested_current'] = CourseSign::yhInvestedTotal($start_date, $end_date, $course_ids); + + // 当前入学后被投企业数量(在指定时间范围内报名的学员所在公司中,在入学后被投的公司数量) + $list['company_invested_after_enrollment_total'] = CourseSign::companyInvestedAfterEnrollment($start_date, $end_date, $course_ids); + + // 累计入学后被投企业数量(从CourseType::START_DATE开始的入学后被投企业数量) + $list['company_invested_after_enrollment_total_cumulative'] = CourseSign::companyInvestedAfterEnrollment(CourseType::START_DATE, $end_date, $course_ids); + + // 当前被投企业数 + $list['company_invested_year_total'] = CourseSign::companyInvestedYear($start_date, $end_date, $course_ids); + + // 元和员工参与人数 + $list['company_join_total'] = CourseSign::companyJoin($start_date, $end_date, $course_ids, false, true); + // 全市干部参与企业 + $list['company_ganbu_total'] = CourseSign::ganbu($start_date, $end_date, $course_ids); + // 苏州头部企业 + $list['cover_head_total'] = CourseSign::toubuqiye($start_date, $end_date, $course_ids); + // 苏州高层次人才 + $list['cover_rencai_total'] = CourseSign::rencai($start_date, $end_date, $course_ids); + // 苏州重点上市公司 + $list['cover_stock_total'] = CourseSign::suzhoushangshi($start_date, $end_date, $course_ids); + + + // 课程分类明细统计 + $courseTypesSum = []; + $courseTypes = CourseType::whereIn('id', $course_type_id)->get(); + foreach ($courseTypes as $courseType) { + // 获取课程 + $courses2 = Course::where('type', $courseType->id) + ->where(function ($query) use ($start_date, $end_date) { + // 开始结束日期的筛选。or查询 + if ($start_date && $end_date) { + $query->whereBetween('start_date', [$start_date, $end_date]) + ->orWhereBetween('end_date', [$start_date, $end_date]); + } + })->where('is_chart', 1)->orderBy('start_date', 'asc')->get(); + foreach ($courses2 as $course) { + $courseTypesSum[] = [ + 'course_type' => $courseType->name, + // 培养人数 + 'course_type_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, $courses2->pluck('id'), false, false), + // 去重培养人数 + 'course_type_signs_pass_unique' => CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $courses2->pluck('id'), false, false), + 'course_name' => $course->name, + 'course_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, [$course->id], false, false), + // 跟班学员数量 + 'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id]), + // 被投企业数 + 'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]), + // 元禾同事数 + 'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id], false, false), + ]; + } } - } - // 附加历史课程数据(与 courses-home 口径一致:统计所有 is_history=1 的 HistoryCourse) - $courseTypesHistory = CourseType::where('is_history', 1)->whereIn('id', $course_type_id)->get(); - foreach ($courseTypesHistory as $historyCourse) { - $courses3 = HistoryCourse::whereHas('calendar', function ($query) { - $query->where('is_count_people', 1); - })->where(function ($query) use ($start_date, $end_date) { - // 开始结束日期的筛选。or查询 - $query->whereBetween('start_time', [$start_date, $end_date]) - ->orWhereBetween('end_time', [$start_date, $end_date]); - })->where('type', $historyCourse->id)->get(); - foreach ($courses3 as $course) { - $courseTypesSum[] = [ - 'course_type' => $historyCourse->name, - 'course_name' => $course->course_name, - // 课程类型培养人数 - 'course_type_signs_pass' => $courses3->sum('course_type_signs_pass'), - // 课程类型去重培养人数 - 'course_type_signs_pass_unique' => $courses3->sum('course_type_signs_pass_unique'), - // 课程人数 - 'course_signs_pass' => $course->course_signs_pass, - // 跟班学员数量 - 'genban_total' => 0, - // 被投企业数 - 'yh_invested_total' => 0, - // 元禾同事数 - 'company_join_total' => 0, - ]; + // 附加历史课程数据(与 courses-home 口径一致:统计所有 is_history=1 的 HistoryCourse) + $courseTypesHistory = CourseType::where('is_history', 1)->whereIn('id', $course_type_id)->get(); + foreach ($courseTypesHistory as $historyCourse) { + $courses3 = HistoryCourse::whereHas('calendar', function ($query) { + $query->where('is_count_people', 1); + })->where(function ($query) use ($start_date, $end_date) { + // 开始结束日期的筛选。or查询 + $query->whereBetween('start_time', [$start_date, $end_date]) + ->orWhereBetween('end_time', [$start_date, $end_date]); + })->where('type', $historyCourse->id)->get(); + foreach ($courses3 as $course) { + $courseTypesSum[] = [ + 'course_type' => $historyCourse->name, + 'course_name' => $course->course_name, + // 课程类型培养人数 + 'course_type_signs_pass' => $courses3->sum('course_type_signs_pass'), + // 课程类型去重培养人数 + 'course_type_signs_pass_unique' => $courses3->sum('course_type_signs_pass_unique'), + // 课程人数 + 'course_signs_pass' => $course->course_signs_pass, + // 跟班学员数量 + 'genban_total' => 0, + // 被投企业数 + 'yh_invested_total' => 0, + // 元禾同事数 + 'company_join_total' => 0, + ]; + } } - } - // 区域明细统计 - $areas = CourseSign::area($start_date, $end_date, 1, $courses->pluck('id'), true); + // 区域明细统计 + $areas = CourseSign::area($start_date, $end_date, 1, $courses->pluck('id'), true); - // 校友的区域明细统计 - $areas_schoolmate = CourseSign::area($start_date, $end_date, 1, $courses->pluck('id'), true, true); + // 校友的区域明细统计 + $areas_schoolmate = CourseSign::area($start_date, $end_date, 1, $courses->pluck('id'), true, true); - // 获取统计项元数据 - $statistics_metadata = Course::getStatisticsMetadata(); + // 获取统计项元数据 + $statistics_metadata = Course::getStatisticsMetadata(); + + // 返回数据数组 + return compact('list', 'courseTypesSum', 'areas', 'areas_schoolmate', 'statistics_metadata'); + }); - return $this->success(compact('list', 'courseTypesSum', 'areas', 'areas_schoolmate', 'statistics_metadata')); + // 返回响应 + return $this->success($data); } /**