You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2426 lines
123 KiB

10 months ago
<?php
namespace App\Http\Controllers\Admin;
use App\Helpers\ResponseCode;
use App\Jobs\CancelAppointMeet;
10 months ago
use App\Models\Admin;
use App\Models\Appointment;
use App\Models\AppointmentConfig;
5 months ago
use App\Models\Article;
8 months ago
use App\Models\Calendar;
10 months ago
use App\Models\CarparkLog;
9 months ago
use App\Models\Company;
9 months ago
use App\Models\CourseSign;
use App\Models\CourseType;
3 months ago
use App\Models\CourseTypeDataOverviewConfig;
10 months ago
use App\Models\CustomFormField;
use App\Models\Department;
5 months ago
use App\Models\HistoryCourse;
3 months ago
use App\Models\EmployeeParticipation;
9 months ago
use App\Models\ParameterDetail;
3 months ago
use App\Models\StockCompany;
5 months ago
use App\Models\SupplyDemand;
5 months ago
use App\Models\TimeEvent;
10 months ago
use App\Models\User;
use App\Repositories\DoorRepository;
use App\Repositories\EntranceRepository;
8 months ago
use Illuminate\Support\Carbon;
3 months ago
use Illuminate\Support\Facades\Cache;
9 months ago
use Illuminate\Support\Facades\DB;
10 months ago
use Illuminate\Support\Facades\Validator;
use App\Models\Course;
use EasyWeChat\Factory;
use Illuminate\Filesystem\Filesystem;
5 months ago
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\CommonExport;
3 months ago
use App\Exports\MultiSheetExport;
use App\Exports\SheetExport;
10 months ago
class OtherController extends CommonController
{
9 months ago
/**
* @OA\Get(
* path="/api/admin/other/home",
* tags={"其他"},
* summary="驾驶舱",
* description="",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function home()
{
// 校友总数
8 months ago
$schoolmate['schoolmate_total'] = User::where('is_schoolmate', 1)->count();
9 months ago
// 2025年校友数
8 months ago
$schoolmate['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->count();
8 months ago
// 开课场次(全部)
$calendar = Calendar::get();
$company['course_total'] = $calendar->count();
$company['course_day_total'] = $calendar->sum(function ($course) {
$start = Carbon::parse($course->start_time);
$end = Carbon::parse($course->end_time);
return $end->diffInDays($start) + 1; // 包含起始和结束日期
});
// 开课场次(当年)
$calendarYear = Calendar::where('date', 'like', '%' . date('Y') . '%')->get();
$company['course_total_year'] = $calendarYear->count();
$company['course_day_total_year'] = $calendarYear->sum(function ($course) {
$start = Carbon::parse($course->start_time);
$end = Carbon::parse($course->end_time);
return $end->diffInDays($start) + 1; // 包含起始和结束日期
});
9 months ago
// 校友企业总融资额
3 months ago
$company['company_fund'] = Company::approvedStudents()->where('is_schoolmate', 1)->sum('company_fund');
9 months ago
// 校友企业总估值
3 months ago
$company['valuation'] = Company::approvedStudents()->where('is_schoolmate', 1)->sum('valuation');
8 months ago
9 months ago
// 校友企业所属领域
$industryTotal = [];
$industries = ParameterDetail::where('parameter_id', 4)->get();
foreach ($industries as $item) {
$level2Names = ParameterDetail::where('parameter_id', 10)->where('remark', $item->value)->pluck('value');
$industryTotal[] = [
'industry' => $item->value,
'total' => User::whereIn('company_industry', $level2Names)->count()
];
}
9 months ago
// 课程统计
9 months ago
$courseTypes = CourseType::where('is_chart', 1)->get();
9 months ago
foreach ($courseTypes as $courseType) {
9 months ago
$courseIds = Course::where('type', $courseType->id)->pluck('id');
$courseType->course_signs_total = CourseSign::whereIn('course_id', $courseIds)
9 months ago
->where('status', 1)
->count();
}
9 months ago
// 苏州区域数据
3 months ago
$suzhou = Company::approvedStudents()->where('company_city', '苏州市')
9 months ago
// 根据company_area分组查询公司数量
->select('company_area', DB::raw('count(*) as company_total'))
->groupBy('company_area')
->get();
// 全国数据
3 months ago
$country = Company::approvedStudents()->select('company_city', DB::raw('count(*) as company_total'))
9 months ago
->groupBy('company_city')
->get();
return $this->success(compact('courseTypes', 'schoolmate', 'company', 'industryTotal', 'suzhou', 'country'));
9 months ago
}
5 months ago
/**
* @OA\Get(
* path="/api/admin/other/home-v2",
* tags={"其他"},
* summary="驾驶舱V2",
* description="",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function homeV2()
{
3 months ago
// 生成缓存键(该方法无参数,使用固定键名)
$cacheKey = 'home_v2_data';
3 months ago
// 尝试从缓存获取数据,使用 CourseSign 模型定义的缓存时间
$data = Cache::remember($cacheKey, CourseSign::CACHE_TIME_STATISTICS, function () {
3 months ago
// 默认开始时间
$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']
];
3 months ago
}
5 months ago
3 months ago
// 全国数据(与 study 口径一致address 用 company_address/company_city 的 like且须有 courseSigns 且 course.is_chart=1is_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,
];
3 months ago
}
3 months ago
// 时间轴
$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;
}
// 与 courses-home 口径一致:附加 is_history=1 的 HistoryCoursewhereHas calendar is_count_people=1type=体系 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);
}
// 统计 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);
3 months ago
}
3 months ago
// 返回数据数组
return compact('list', 'suzhou', 'country', 'monthCourses', 'time_axis', 'article', 'yearConfigs');
});
5 months ago
3 months ago
// 返回响应
return $this->success($data);
5 months ago
}
8 months ago
/**
* @OA\Get(
* path="/api/admin/other/courses-home",
* tags={"其他"},
* summary="课程统计",
* description="",
* @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=true, description="开始日期"),
* @OA\Parameter(name="end_date", in="query", @OA\Schema(type="string"), required=true, description="结束日期"),
8 months ago
* @OA\Parameter(name="course_type_id", in="query", @OA\Schema(type="string"), required=true, description="课程体系id多个英文逗号"),
8 months ago
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function coursesHome()
{
5 months ago
// 获取公共参数
$params = $this->getCoursesHomeParams();
$start_date = $params['start_date'];
$end_date = $params['end_date'];
$course_type_id = $params['course_type_id'];
$courses = $params['courses'];
5 months ago
3 months ago
// 生成缓存键(基于参数)
$cacheKey = 'courses_home_' . md5($start_date . '_' . $end_date . '_' . implode(',', $course_type_id));
3 months ago
// 尝试从缓存获取数据,使用 CourseSign 模型定义的缓存时间
$data = Cache::remember($cacheKey, CourseSign::CACHE_TIME_STATISTICS, function () use ($start_date, $end_date, $course_type_id, $courses) {
3 months ago
// 报名人数
$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在指定时间范围内
3 months ago
$year_start_date = Carbon::now()->startOfYear()->format('Y-m-d');
$year_end_date = Carbon::now()->endOfYear()->format('Y-m-d');
$list['company_market_year_total'] = StockCompany::getByDateRange($year_start_date, $year_end_date);
3 months ago
// 入学后上市公司数量从stock_companys表获取is_after_enrollment = 1stock_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),
// 跟班学员数量
3 months ago
'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id], false, false),
3 months ago
// 被投企业数
'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]),
// 元禾同事数
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id], false, false),
];
}
8 months ago
}
3 months ago
// 附加历史课程数据(与 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,
];
}
5 months ago
}
5 months ago
3 months ago
// 区域明细统计
$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);
3 months ago
3 months ago
// 获取统计项元数据
$statistics_metadata = Course::getStatisticsMetadata();
3 months ago
3 months ago
// 返回数据数组
return compact('list', 'courseTypesSum', 'areas', 'areas_schoolmate', 'statistics_metadata');
});
3 months ago
3 months ago
// 返回响应
return $this->success($data);
8 months ago
}
5 months ago
/**
* @OA\Get(
* path="/api/admin/other/courses-home-export",
* tags={"其他"},
* summary="课程统计明细导出",
* description="导出课程统计数据的明细",
5 months ago
* @OA\Parameter(name="export_type", in="query", @OA\Schema(type="string"), required=true, description="导出类型course_signs_invested-被投企业明细, course_signs_total-报名人数明细, course_signs_pass-审核通过人数明细, course_signs_pass_unique-审核通过人数去重明细, courseTypesSum-课程分类明细, areas-区域明细, company_market_total-上市公司明细, ganbu_total-跟班学员明细, company_market_year_total-今年上市公司明细, company_market_after_enrollment_total-入学后上市公司明细, company_invested_after_enrollment_total-入学后被投企业明细, company_invested_year_total-年份范围内被投企业明细, course_total-开课场次明细, course_day_total-开课天数明细, company_join_total-元和员工参与企业明细, company_ganbu_total-全市干部参与企业明细, cover_head_total-苏州头部企业明细, cover_rencai_total-高层次人才明细, cover_stock_total-重点上市公司明细"),
5 months ago
* @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=false, description="开始日期"),
* @OA\Parameter(name="end_date", in="query", @OA\Schema(type="string"), required=false, description="结束日期"),
* @OA\Parameter(name="course_type_id", in="query", @OA\Schema(type="string"), required=false, description="课程体系id多个英文逗号"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="导出Excel文件"
* )
* )
*/
public function coursesHomeExport()
{
$export_type = request('export_type');
if (!$export_type) {
return $this->fail([ResponseCode::ERROR_PARAMETER, '导出类型不能为空']);
}
// 获取参数与coursesHome保持一致
$params = $this->getCoursesHomeParams();
$start_date = $params['start_date'];
$end_date = $params['end_date'];
$course_type_id = $params['course_type_id'];
$courses = $params['courses'];
$course_ids = $courses->pluck('id');
$data = [];
$fields = [];
$filename = '';
switch ($export_type) {
5 months ago
case 'course_signs_invested':
5 months ago
// 被投企业明细 - 使用与coursesHome相同的算法
3 months ago
// 确保 $course_ids 是数组格式
$courseIdsArray = $course_ids ? (is_array($course_ids) ? $course_ids : $course_ids->toArray()) : null;
3 months ago
3 months ago
// 辅助函数:构建被投企业数据
$buildInvestedCompanyData = function ($start_date, $end_date, $courseIdsArray) {
$data = [];
$companies = CourseSign::yhInvestedTotal($start_date, $end_date, $courseIdsArray, true);
foreach ($companies as $company) {
// 获取该公司的学员信息
$userIds = User::where('company_id', $company->id)->pluck('id')->toArray();
// 公司基本信息
$companyInfo = [
'company_name' => $company->company_name,
'company_legal_representative' => $company->company_legal_representative ?? '',
'company_date' => $company->company_date ?? '',
'company_address' => $company->company_address ?? '',
'business_scope' => $company->business_scope ?? '',
'contact_phone' => $company->contact_phone ?? '',
'contact_mail' => $company->contact_mail ?? '',
'company_tag' => $company->company_tag ?? '',
];
3 months ago
3 months ago
if (empty($userIds)) {
// 如果没有学员,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
} else {
$userCourseSigns = CourseSign::getStudentList($start_date, $end_date, 1, $courseIdsArray)
->whereIn('user_id', $userIds)
->with(['user', 'course.typeDetail'])
->get();
// 按学员分组
$usersData = [];
foreach ($userCourseSigns as $sign) {
if (!$sign->user) {
continue;
}
$userId = $sign->user_id;
if (!isset($usersData[$userId])) {
$usersData[$userId] = [
'user' => $sign->user,
'courseSigns' => [],
];
}
$usersData[$userId]['courseSigns'][] = $sign;
3 months ago
}
3 months ago
// 每个学员一行,公司信息只在第一行显示,后续行公司信息为空
$isFirstRow = true;
foreach ($usersData as $userData) {
$user = $userData['user'];
$courseSigns = collect($userData['courseSigns']);
if ($courseSigns->isNotEmpty()) {
// 获取课程名称列表,用中文顿号分隔
$courseNames = $courseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $courseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 报名课程数
$courseCount = $courseSigns->count();
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'company_address' => '',
'business_scope' => '',
'contact_phone' => '',
'contact_mail' => '',
'company_tag' => '',
'credit_code' => '',
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
}
}
3 months ago
}
3 months ago
}
3 months ago
}
3 months ago
3 months ago
return $data;
};
3 months ago
3 months ago
// 第一个 sheet累计被投企业覆盖数从 CourseType::START_DATE 开始)
$cumulativeData = $buildInvestedCompanyData(CourseType::START_DATE, $end_date, $courseIdsArray);
3 months ago
3 months ago
// 第二个 sheet当前被投企业覆盖数从传入的开始日期开始
$currentData = $buildInvestedCompanyData($start_date, $end_date, $courseIdsArray);
3 months ago
5 months ago
$fields = [
'company_name' => '企业名称',
5 months ago
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'company_address' => '地址',
'business_scope' => '营业范围',
'contact_phone' => '联系电话',
5 months ago
'contact_mail' => '联系邮箱',
'company_tag' => '企业资质',
3 months ago
'user_name' => '学员姓名',
3 months ago
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
3 months ago
// 创建多 sheet 导出
$sheets = [
new SheetExport($cumulativeData, $fields, '被投企业覆盖数'),
new SheetExport($currentData, $fields, '当前被投企业覆盖数'),
];
5 months ago
$filename = '被投企业明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
case 'course_signs_total':
// 报名人数明细 - 使用courseSignsTotal方法获取列表与coursesHome算法一致
5 months ago
$courseSigns = CourseSign::courseSignsTotal($start_date, $end_date, null, $course_ids, true);
5 months ago
// 加载关联关系
$courseSigns->load(['user', 'course']);
foreach ($courseSigns as $sign) {
$data[] = [
'user_name' => $sign->user->name ?? '',
'mobile' => $sign->user->mobile ?? '',
'company_name' => $sign->user->company_name ?? '',
'company_area' => $sign->user->company_area ?? '',
'course_name' => $sign->course->name ?? '',
'status_text' => $sign->status_text ?? '',
'created_at' => $sign->created_at ? $sign->created_at->format('Y-m-d H:i:s') : '',
];
}
$fields = [
'user_name' => '学员姓名',
'mobile' => '手机号',
'company_name' => '企业名称',
'company_area' => '所在区域',
'course_name' => '课程名称',
'status_text' => '审核状态',
'created_at' => '报名时间',
];
$filename = '报名人数明细';
break;
case 'course_signs_pass':
// 审核通过人数明细 - 使用courseSignsTotal方法获取列表与coursesHome算法一致
5 months ago
$courseSigns = CourseSign::courseSignsTotal($start_date, $end_date, 1, $course_ids, true);
5 months ago
// 加载关联关系
3 months ago
$courseSigns->load(['user.company', 'course.typeDetail']);
5 months ago
3 months ago
// 当前课程数据
$currentData = [];
5 months ago
foreach ($courseSigns as $sign) {
3 months ago
$currentData[] = [
5 months ago
'user_name' => $sign->user->name ?? '',
'mobile' => $sign->user->mobile ?? '',
4 months ago
'company_name' => $sign->user->company->company_name ?? '',
3 months ago
'user_company_name' => $sign->user->company_name ?? '',
4 months ago
'company_area' => $sign->user->company->company_area ?? '',
'company_industry' => $sign->user->company->company_industry ?? '',
5 months ago
'course_name' => $sign->course->name ?? '',
5 months ago
'course_type' => $sign->course->typeDetail->name ?? '',
5 months ago
];
}
3 months ago
$currentFields = [
5 months ago
'user_name' => '学员姓名',
'mobile' => '手机号',
'company_name' => '企业名称',
3 months ago
'user_company_name' => '用户填写企业',
5 months ago
'company_area' => '所在区域',
3 months ago
'company_industry' => '所在行业',
5 months ago
'course_name' => '课程名称',
5 months ago
'course_type' => '课程类型',
5 months ago
];
3 months ago
// 历史课程数据
$historyData = [];
$course_type_id_array = $course_type_id ? (is_array($course_type_id) ? $course_type_id : explode(',', $course_type_id)) : [];
$historyCourses = HistoryCourse::whereHas('calendar', function ($query) {
$query->where('is_count_people', 1);
})->whereHas('typeDetail', function ($query) {
$query->where('is_history', 1);
})->where(function ($query) use ($start_date, $end_date) {
if ($start_date && $end_date) {
$query->whereBetween('start_time', [$start_date, $end_date])
->orWhereBetween('end_time', [$start_date, $end_date]);
}
})->where(function ($query) use ($course_type_id_array) {
if (!empty($course_type_id_array)) {
$query->whereIn('type', $course_type_id_array);
}
})->with('typeDetail')->get();
foreach ($historyCourses as $historyCourse) {
$historyData[] = [
'course_type' => $historyCourse->typeDetail->name ?? '',
'course_name' => $historyCourse->course_name ?? '',
'start_time' => $historyCourse->start_time ?? '',
'end_time' => $historyCourse->end_time ?? '',
'course_type_signs_pass' => $historyCourse->course_type_signs_pass ?? 0,
'course_type_signs_pass_unique' => $historyCourse->course_type_signs_pass_unique ?? 0,
'course_signs_pass' => $historyCourse->course_signs_pass ?? 0,
];
}
$historyFields = [
'course_type' => '课程体系',
'course_name' => '课程名称',
'start_time' => '开始时间',
'end_time' => '结束时间',
3 months ago
'course_type_signs_pass' => '培养人次未去重',
3 months ago
'course_type_signs_pass_unique' => '培养人数去重',
'course_signs_pass' => '课程培养人数',
];
// 创建多 sheet 导出
$sheets = [
new SheetExport($currentData, $currentFields, '当前课程数据'),
new SheetExport($historyData, $historyFields, '历史课程数据'),
];
5 months ago
$filename = '审核通过人数明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
case 'course_signs_pass_unique':
3 months ago
// 审核通过人数去重明细 - 使用courseSignsTotalByUnique方法获取列表与coursesHome保持一致
5 months ago
$users = CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $course_ids, true);
3 months ago
// 预加载 company 关系,避免 N+1 查询问题
$users->load('company');
3 months ago
// 当前课程数据(已去重)
$currentData = [];
5 months ago
foreach ($users as $user) {
3 months ago
// 获取该学员报名的课程列表 - 使用getStudentList方法确保与统计逻辑一致
$userCourseSigns = CourseSign::getStudentList($start_date, $end_date, 1, $course_ids)
3 months ago
->where('user_id', $user->id)
3 months ago
->with(['course.typeDetail'])
5 months ago
->get();
3 months ago
// 获取课程名称列表,用中文顿号分隔
$courseNames = $userCourseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $userCourseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 企查查企业(来自 company 表)
$qccCompanyName = $user->company && $user->company->company_name
3 months ago
? $user->company->company_name
3 months ago
: '';
// 用户填写企业(来自 user 表)
$userCompanyName = $user->company_name ?? '';
// 优先使用 company 关系的企业信息,如果不存在则使用 User 表的字段
3 months ago
$companyArea = $user->company && $user->company->company_area
? $user->company->company_area
: ($user->company_area ?? '');
$companyIndustry = $user->company && $user->company->company_industry
? $user->company->company_industry
: ($user->company_industry ?? '');
3 months ago
$currentData[] = [
5 months ago
'user_name' => $user->name ?? '',
'mobile' => $user->mobile ?? '',
3 months ago
'qcc_company_name' => $qccCompanyName,
'user_company_name' => $userCompanyName,
'company_position' => $user->company_position ?? '',
3 months ago
'company_area' => $companyArea,
'company_industry' => $companyIndustry,
3 months ago
'course_types' => $courseTypes,
5 months ago
'course_names' => $courseNames,
'course_count' => $userCourseSigns->count(),
];
}
3 months ago
$currentFields = [
5 months ago
'user_name' => '学员姓名',
'mobile' => '手机号',
3 months ago
'qcc_company_name' => '企查查企业',
'user_company_name' => '用户填写企业',
'company_position' => '职务',
5 months ago
'company_area' => '所在区域',
'company_industry' => '所属行业',
3 months ago
'course_types' => '课程体系',
5 months ago
'course_names' => '报名课程',
'course_count' => '报名课程数',
];
3 months ago
// 历史课程数据
$historyData = [];
$course_type_id_array = $course_type_id ? (is_array($course_type_id) ? $course_type_id : explode(',', $course_type_id)) : [];
$historyCourses = HistoryCourse::whereHas('calendar', function ($query) {
$query->where('is_count_people', 1);
})->whereHas('typeDetail', function ($query) {
$query->where('is_history', 1);
})->where(function ($query) use ($start_date, $end_date) {
if ($start_date && $end_date) {
$query->whereBetween('start_time', [$start_date, $end_date])
->orWhereBetween('end_time', [$start_date, $end_date]);
}
})->where(function ($query) use ($course_type_id_array) {
if (!empty($course_type_id_array)) {
$query->whereIn('type', $course_type_id_array);
}
})->with('typeDetail')->get();
foreach ($historyCourses as $historyCourse) {
$historyData[] = [
'course_type' => $historyCourse->typeDetail->name ?? '',
'course_name' => $historyCourse->course_name ?? '',
'start_time' => $historyCourse->start_time ?? '',
'end_time' => $historyCourse->end_time ?? '',
'course_type_signs_pass' => $historyCourse->course_type_signs_pass ?? 0,
'course_type_signs_pass_unique' => $historyCourse->course_type_signs_pass_unique ?? 0,
'course_signs_pass' => $historyCourse->course_signs_pass ?? 0,
];
}
$historyFields = [
'course_type' => '课程体系',
'course_name' => '课程名称',
'start_time' => '开始时间',
'end_time' => '结束时间',
3 months ago
'course_type_signs_pass' => '培养人次未去重',
3 months ago
'course_type_signs_pass_unique' => '培养人数去重',
'course_signs_pass' => '课程培养人数',
];
// 创建多 sheet 导出
$sheets = [
new SheetExport($currentData, $currentFields, '当前课程数据'),
new SheetExport($historyData, $historyFields, '历史课程数据'),
];
5 months ago
$filename = '审核通过人数去重明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
5 months ago
case 'courseTypesSum':
5 months ago
// 课程分类明细 - 与coursesHome中的courseTypesSum逻辑保持一致
$courseTypes = CourseType::whereIn('id', $course_type_id)->get();
foreach ($courseTypes as $courseType) {
5 months ago
// 获取课程 - 添加日期筛选逻辑
$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]);
}
3 months ago
})->where('is_chart', 1)->orderBy('start_date', 'asc')->get();
5 months ago
foreach ($courses2 as $course) {
$data[] = [
'course_type' => $courseType->name,
'course_name' => $course->name,
5 months ago
'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_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, [$course->id], false, false),
5 months ago
'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id]),
'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]),
4 months ago
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id], false, false),
5 months ago
];
}
}
3 months ago
// 附加历史课程数据
5 months ago
$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) {
$data[] = [
'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,
];
}
}
5 months ago
$fields = [
'course_type' => '课程体系',
'course_name' => '课程名称',
'course_type_signs_pass' => '课程体系培养人数',
'course_type_signs_pass_unique' => '课程体系去重培养人数',
'course_signs_pass' => '课程培养人数',
5 months ago
'genban_total' => '跟班学员数',
'yh_invested_total' => '被投企业数',
'company_join_total' => '元禾同事数',
5 months ago
];
$filename = '课程分类明细';
break;
case 'areas':
3 months ago
// 区域明细 - 使用 CourseSign::getAreaData 方法,统一统计和导出逻辑
3 months ago
// 第一个sheet普通学员区域明细
3 months ago
$areasData = CourseSign::getAreaData($start_date, $end_date, 1, $courses->pluck('id'), false, 'export');
3 months ago
5 months ago
$fields = [
5 months ago
'company_name' => '企业名称',
'company_area' => '公司区域',
'company_city' => '公司城市',
'company_province' => '公司省份',
3 months ago
'company_address' => '公司地址',
5 months ago
'user_name' => '学员姓名',
'mobile' => '手机号',
3 months ago
'course_type' => '课程体系',
5 months ago
'course_name' => '课程名称',
5 months ago
];
3 months ago
3 months ago
// 第二个sheet校友区域明细
$areasSchoolmateData = CourseSign::getAreaData($start_date, $end_date, 1, $courses->pluck('id'), true, 'export');
3 months ago
$sheets = [
new SheetExport($areasData, $fields, '区域明细'),
new SheetExport($areasSchoolmateData, $fields, '校友区域明细'),
];
5 months ago
$filename = '区域明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
5 months ago
case 'company_market_total':
3 months ago
// 上市公司明细 - 与coursesHome统计逻辑保持一致
// 使用CourseSign::shangshi方法获取数据确保与统计逻辑一致
$shangshiList = CourseSign::shangshi($start_date, $end_date, $course_ids, true);
foreach ($shangshiList as $item) {
$company = $item['company'] ?? null;
$users = $item['users'] ?? [];
3 months ago
if (!$company) {
3 months ago
continue;
3 months ago
}
5 months ago
3 months ago
// 获取StockCompany信息如果有
$stockCompany = StockCompany::where('company_id', $company->id)
->orWhere('company_name', $company->company_name)
->first();
// 公司基本信息
5 months ago
$companyInfo = [
3 months ago
'company_name' => $company->company_name ?? '',
5 months ago
'company_legal_representative' => $company->company_legal_representative ?? '',
'company_date' => $company->company_date ?? '',
3 months ago
'stock_date' => $stockCompany->stock_date ?? '',
3 months ago
'is_after_enrollment' => $stockCompany && $stockCompany->is_after_enrollment == 1 ? '是' : '否',
5 months ago
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
'company_area' => $company->company_area ?? '',
5 months ago
'company_tag' => $company->company_tag ?? '',
5 months ago
];
3 months ago
if (empty($users)) {
// 如果没有学员,仍然导出公司基本信息
5 months ago
$data[] = array_merge($companyInfo, [
5 months ago
'user_name' => '',
3 months ago
'course_names' => '',
3 months ago
'course_types' => '',
'course_count' => 0,
5 months ago
]);
3 months ago
} else {
3 months ago
// 每个学员一行,公司信息只在第一行显示,后续行公司信息为空
$isFirstRow = true;
3 months ago
foreach ($users as $userData) {
$user = $userData['user'] ?? null;
$courses = $userData['courses'] ?? [];
if (!$user) {
continue;
}
// 获取课程名称列表,用中文顿号分隔
$courseNames = collect($courses)->pluck('course_name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = collect($courses)->pluck('course_type')->filter()->unique()->values()->implode('、');
// 报名课程数
$courseCount = count($courses);
3 months ago
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $userData['user_name'] ?? $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'stock_date' => '',
'is_after_enrollment' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'company_tag' => '',
'user_name' => $userData['user_name'] ?? $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
}
3 months ago
}
5 months ago
}
5 months ago
}
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'stock_date' => '上市日期',
3 months ago
'is_after_enrollment' => '是否入学后上市',
5 months ago
'company_address' => '地址',
5 months ago
'company_city' => '所在城市',
'company_area' => '所在区域',
5 months ago
'company_tag' => '企业资质',
5 months ago
'user_name' => '学员姓名',
3 months ago
'course_names' => '课程名称',
3 months ago
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
$filename = '上市公司明细';
break;
5 months ago
case 'ganbu_total':
5 months ago
// 跟班学员明细 - 使用模型方法
5 months ago
$users = CourseSign::genban($start_date, $end_date, $course_ids, true);
5 months ago
foreach ($users as $user) {
3 months ago
// 获取该学员的课程报名记录 - 使用getStudentList方法确保与统计逻辑一致
$userCourseSigns = CourseSign::getStudentList($start_date, $end_date, 1, $course_ids)
3 months ago
->where('user_id', $user->id)
->with(['course.typeDetail'])
->get();
// 获取课程名称列表,用中文顿号分隔
$courseNames = $userCourseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $userCourseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 报名课程数
$courseCount = $userCourseSigns->count();
5 months ago
$data[] = [
5 months ago
'name' => $user->username ?? '',
'sex' => $user->sex ?? '',
5 months ago
'mobile' => $user->mobile ?? '',
'company_name' => $user->company_name ?? '',
5 months ago
'company_position' => $user->company_position ?? '',
5 months ago
'from' => $user->from ?? '',
3 months ago
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
5 months ago
];
}
$fields = [
5 months ago
'name' => '姓名',
5 months ago
'sex' => '性别',
5 months ago
'mobile' => '手机号',
'company_name' => '企业名称',
5 months ago
'company_position' => '职位',
5 months ago
'from' => '标签',
3 months ago
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
$filename = '跟班学员明细';
break;
5 months ago
case 'company_market_year_total':
3 months ago
// 今年上市公司明细 - 从stock_companys表获取与coursesHome统计逻辑保持一致
3 months ago
$stockCompanies = StockCompany::getByDateRange($start_date, $end_date, true)->load('company');
5 months ago
3 months ago
foreach ($stockCompanies as $stockCompany) {
3 months ago
// 通过company_id关联到Company表获取详细信息
$company = $stockCompany->company_id ? $stockCompany->company : null;
if (!$company) {
// 如果没有company_id尝试通过公司名称关联
$company = Company::where('company_name', $stockCompany->company_name)->first();
}
5 months ago
3 months ago
// 公司基本信息(只在第一行使用)
$companyInfo = [
3 months ago
'company_name' => $stockCompany->company_name,
5 months ago
'company_legal_representative' => $company->company_legal_representative ?? '',
3 months ago
'stock_date' => $stockCompany->stock_date ?? '',
3 months ago
'is_after_enrollment' => $stockCompany->is_after_enrollment == 1 ? '是' : '否',
5 months ago
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
'company_area' => $company->company_area ?? '',
5 months ago
'company_tag' => $company->company_tag ?? '',
5 months ago
];
3 months ago
// 获取该公司的学员信息
if ($company) {
$users = $company->users()
->whereHas('courseSigns', function ($q) {
$q->where('status', 1);
})
->with([
'courseSigns' => function ($query) {
$query->where('status', 1)
->with(['course.typeDetail']);
}
])
->get();
if ($users->isEmpty()) {
// 如果没有学员,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
} else {
// 每个学员一行
$isFirstRow = true;
foreach ($users as $user) {
$courseSigns = $user->courseSigns ?? collect([]);
// 获取课程名称列表,用中文顿号分隔
$courseNames = $courseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $courseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 报名课程数
$courseCount = $courseSigns->count();
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'stock_date' => '',
'is_after_enrollment' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'company_tag' => '',
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
}
}
}
} else {
// 如果没有关联的公司,只导出基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
}
5 months ago
}
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'stock_date' => '上市日期',
3 months ago
'is_after_enrollment' => '是否入学后上市',
5 months ago
'company_address' => '地址',
5 months ago
'company_city' => '所在城市',
'company_area' => '所在区域',
'company_tag' => '企业资质',
3 months ago
'user_name' => '学员姓名',
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
$filename = '今年上市公司明细';
break;
5 months ago
case 'company_market_after_enrollment_total':
3 months ago
// 入学后上市公司明细 - 从stock_companys表获取与coursesHome统计逻辑保持一致
3 months ago
$stockCompanies = StockCompany::getAfterEnrollment($start_date, $end_date, true)->load('company');
3 months ago
foreach ($stockCompanies as $stockCompany) {
3 months ago
// 通过company_id关联到Company表获取详细信息
$company = $stockCompany->company_id ? $stockCompany->company : null;
if (!$company) {
// 如果没有company_id尝试通过公司名称关联
$company = Company::where('company_name', $stockCompany->company_name)->first();
}
5 months ago
3 months ago
// 公司基本信息(只在第一行使用)
$companyInfo = [
3 months ago
'company_name' => $stockCompany->company_name,
5 months ago
'company_legal_representative' => $company->company_legal_representative ?? '',
3 months ago
'stock_date' => $stockCompany->stock_date ?? '',
'enrollment_date' => $stockCompany->enrollment_date ?? '',
3 months ago
'is_after_enrollment' => $stockCompany->is_after_enrollment == 1 ? '是' : '否',
5 months ago
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
3 months ago
'company_area' => $company->company_area ?? '',
'company_tag' => $company->company_tag ?? '',
5 months ago
];
3 months ago
// 获取该公司的学员信息
if ($company) {
$users = $company->users()
->whereHas('courseSigns', function ($q) {
$q->where('status', 1);
})
->with([
'courseSigns' => function ($query) {
$query->where('status', 1)
->with(['course.typeDetail']);
}
])
->get();
if ($users->isEmpty()) {
// 如果没有学员,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
} else {
// 每个学员一行
$isFirstRow = true;
foreach ($users as $user) {
$courseSigns = $user->courseSigns ?? collect([]);
// 获取课程名称列表,用中文顿号分隔
$courseNames = $courseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $courseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 报名课程数
$courseCount = $courseSigns->count();
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'stock_date' => '',
'enrollment_date' => '',
'is_after_enrollment' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'company_tag' => '',
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
}
}
}
} else {
// 如果没有关联的公司,只导出基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
}
5 months ago
}
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'stock_date' => '上市日期',
3 months ago
'enrollment_date' => '入学时间',
3 months ago
'is_after_enrollment' => '是否入学后上市',
5 months ago
'company_address' => '地址',
'company_city' => '所在城市',
3 months ago
'company_area' => '所在区域',
'company_tag' => '企业资质',
'user_name' => '学员姓名',
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
$filename = '入学后上市公司明细';
break;
5 months ago
case 'company_invested_after_enrollment_total':
3 months ago
// 入学后被投企业明细 - 使用模型方法,与其他导出学员信息保持一致
3 months ago
// 辅助函数:构建入学后被投企业数据
$buildAfterEnrollmentData = function ($start_date, $end_date, $course_ids) {
$data = [];
$companiesAfterEnrollment = CourseSign::companyInvestedAfterEnrollment($start_date, $end_date, $course_ids, true);
foreach ($companiesAfterEnrollment as $item) {
$company = $item['company'];
3 months ago
$users = $item['users'] ?? [];
// 公司基本信息(只在第一行使用)
$companyInfo = [
3 months ago
'company_name' => $company->company_name,
'company_legal_representative' => $company->company_legal_representative ?? '',
'company_date' => $company->company_date ?? '',
'invest_date' => $item['invest_date'] ?? '',
'first_sign_date' => $item['first_enrollment_date'] ?? '',
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
'company_area' => $company->company_area ?? '',
];
3 months ago
if (empty($users)) {
// 如果没有学员,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
} else {
// 获取该公司的学员ID列表
$userIds = collect($users)->pluck('id')->toArray();
// 使用getStudentList获取学员的课程报名记录与统计逻辑一致
$userCourseSigns = CourseSign::getStudentList($start_date, $end_date, 1, $course_ids)
->whereIn('user_id', $userIds)
->with(['user', 'course.typeDetail'])
->get();
// 按学员分组
$usersData = [];
foreach ($userCourseSigns as $sign) {
if (!$sign->user) {
continue;
}
$userId = $sign->user_id;
if (!isset($usersData[$userId])) {
$usersData[$userId] = [
'user' => $sign->user,
'courseSigns' => [],
];
}
$usersData[$userId]['courseSigns'][] = $sign;
}
// 如果没有找到课程报名记录,仍然导出学员基本信息
if (empty($usersData)) {
foreach ($users as $user) {
$data[] = array_merge($companyInfo, [
'user_name' => $user->name ?? '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
// 后续行的公司信息为空
$companyInfo = array_fill_keys(array_keys($companyInfo), '');
}
} else {
// 每个学员一行,公司信息只在第一行显示,后续行公司信息为空
$isFirstRow = true;
foreach ($usersData as $userData) {
$user = $userData['user'];
$courseSigns = collect($userData['courseSigns']);
// 获取课程名称列表,用中文顿号分隔
$courseNames = $courseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $courseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 报名课程数
$courseCount = $courseSigns->count();
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'invest_date' => '',
'first_sign_date' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
}
}
// 处理没有课程报名记录的学员(如果有)
$processedUserIds = array_keys($usersData);
foreach ($users as $user) {
if (!in_array($user->id, $processedUserIds)) {
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'invest_date' => '',
'first_sign_date' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'user_name' => $user->name ?? '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
];
}
}
}
}
3 months ago
}
return $data;
};
// 第一个 sheet当前入学后被投企业从传入的开始日期开始
$currentData = $buildAfterEnrollmentData($start_date, $end_date, $course_ids);
// 第二个 sheet累计入学后被投企业从 CourseType::START_DATE 开始)
$cumulativeData = $buildAfterEnrollmentData(CourseType::START_DATE, $end_date, $course_ids);
5 months ago
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'invest_date' => '被投日期',
'first_sign_date' => '首次报名时间',
'company_address' => '地址',
'company_city' => '所在城市',
'company_area' => '所在区域',
3 months ago
'user_name' => '学员姓名',
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
3 months ago
// 创建多 sheet 导出
$sheets = [
new SheetExport($currentData, $fields, '当前入学后被投企业'),
new SheetExport($cumulativeData, $fields, '累计入学后被投企业'),
];
5 months ago
$filename = '入学后被投企业明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
5 months ago
case 'company_invested_year_total':
// 年份范围内被投企业明细 - 所有年份范围内被投企业,关联学员、课程信息
// 数据结构:主表是公司,子数据是学员信息
// 导出时:公司信息只在第一行显示,后续行公司信息为空
5 months ago
$companiesData = CourseSign::companyInvestedYear($start_date, $end_date, $course_ids, true);
5 months ago
foreach ($companiesData as $item) {
$company = $item['company'];
$users = $item['users'] ?? [];
// 公司基本信息(只在第一行使用)
$companyInfo = [
'company_name' => $company->company_name,
'company_legal_representative' => $company->company_legal_representative ?? '',
'company_date' => $company->company_date ?? '',
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
'company_area' => $company->company_area ?? '',
'company_tag' => $company->company_tag ?? '',
];
if (empty($users)) {
// 如果没有学员报名记录,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_name' => '',
'course_type' => '',
]);
} else {
// 每个学员一行,多个课程合并显示
$isFirstRow = true;
foreach ($users as $userInfo) {
$courses = $userInfo['courses'] ?? [];
// 合并同一学员的多个课程:格式为"课程体系-课程名称,课程体系-课程名称"
$courseList = [];
foreach ($courses as $courseInfo) {
$courseType = $courseInfo['course_type'] ?? '';
$courseName = $courseInfo['course_name'] ?? '';
if ($courseType && $courseName) {
$courseList[] = $courseType . '-' . $courseName;
} elseif ($courseName) {
$courseList[] = $courseName;
}
}
$courseDisplay = implode("\r\n", $courseList);
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $userInfo['user_name'] ?? '',
'course_name' => $courseDisplay,
'course_type' => '', // 课程类型已合并到课程名称中
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'company_tag' => '',
'user_name' => $userInfo['user_name'] ?? '',
'course_name' => $courseDisplay,
];
}
}
}
}
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'company_address' => '地址',
'company_city' => '所在城市',
'company_area' => '所在区域',
'company_tag' => '企业资质',
'user_name' => '学员姓名',
'course_name' => '课程信息',
];
$filename = '年份范围内被投企业明细';
break;
5 months ago
case 'course_total':
// 开课场次明细 - 与coursesHome算法一致
5 months ago
$calendars = Calendar::getCalendarsByDateRange($start_date, $end_date, $course_type_id)
->with('course')
5 months ago
->get();
foreach ($calendars as $calendar) {
$data[] = [
'course_name' => $calendar->course->name ?? '',
'title' => $calendar->title ?? '',
'date' => $calendar->date ?? '',
'start_time' => $calendar->start_time,
'end_time' => $calendar->end_time,
'address' => $calendar->address ?? '',
];
}
$fields = [
'course_name' => '课程名称',
'title' => '标题',
'date' => '日期',
'start_time' => '开始时间',
'end_time' => '结束时间',
'address' => '地址',
];
$filename = '开课场次明细';
break;
case 'course_day_total':
// 开课天数明细 - 与coursesHome算法一致
5 months ago
$calendars = Calendar::getCalendarsByDateRange($start_date, $end_date, $course_type_id)
->where('is_count_days', 1)
5 months ago
->with('course')
->get();
foreach ($calendars as $calendar) {
$data[] = [
'course_name' => $calendar->course->name ?? '',
'title' => $calendar->title ?? '',
'date' => $calendar->date ?? '',
'start_time' => $calendar->start_time ? date('Y-m-d H:i:s', strtotime($calendar->start_time)) : '',
'end_time' => $calendar->end_time ? date('Y-m-d H:i:s', strtotime($calendar->end_time)) : '',
'days' => $calendar->days ?? 0,
'address' => $calendar->address ?? '',
];
}
$fields = [
'course_name' => '课程名称',
'title' => '标题',
'date' => '日期',
'start_time' => '开始时间',
'end_time' => '结束时间',
'days' => '天数',
'address' => '地址',
];
$filename = '开课天数明细';
break;
5 months ago
case 'company_join_total':
5 months ago
// 元和员工参与人员明细 - 使用模型方法(现在返回的是用户列表)
3 months ago
// 注意第5个参数 $needHistory 需要与 coursesHome 方法保持一致true
$users = CourseSign::companyJoin($start_date, $end_date, $course_ids, true, true);
5 months ago
// 加载关联关系
$users->load('company');
3 months ago
// 当前学员数据
$currentData = [];
5 months ago
foreach ($users as $user) {
3 months ago
// 获取该学员的课程报名记录
3 months ago
// 使用与 companyJoin 方法完全相同的 getStudentList 逻辑,确保数据一致
$userCourseSigns = CourseSign::getStudentList($start_date, $end_date, null, $course_ids)
3 months ago
->where('user_id', $user->id)
->with(['course.typeDetail'])
->get();
// 获取课程名称列表,用中文顿号分隔
$courseNames = $userCourseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $userCourseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
// 报名课程数
$courseCount = $userCourseSigns->count();
3 months ago
$currentData[] = [
5 months ago
'user_name' => $user->name ?? '',
'mobile' => $user->mobile ?? '',
5 months ago
'company_name' => $user->company->company_name ?? $user->company_name,
5 months ago
'company_position' => $user->company_position ?? '',
'company_city' => $user->company->company_city ?? '',
'company_area' => $user->company->company_area ?? '',
'company_legal_representative' => $user->company->company_legal_representative ?? '',
'company_date' => $user->company->company_date ?? '',
'company_address' => $user->company->company_address ?? '',
3 months ago
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
5 months ago
];
}
3 months ago
$currentFields = [
5 months ago
'user_name' => '学员姓名',
'mobile' => '手机号',
5 months ago
'company_name' => '企业名称',
5 months ago
'company_position' => '职位',
'company_city' => '所在城市',
'company_area' => '所在区域',
5 months ago
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'company_address' => '地址',
3 months ago
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
3 months ago
// 自定义数据EmployeeParticipation type=1 员工参与数)
$customData = [];
$employeeParticipations = EmployeeParticipation::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('type', 1)->with('courseType')->get();
foreach ($employeeParticipations as $participation) {
$customData[] = [
'course_type' => $participation->courseType->name ?? '',
'course_name' => $participation->course_name ?? '',
'start_date' => $participation->start_date ?? '',
'end_date' => $participation->end_date ?? '',
'total' => $participation->total ?? 0,
];
}
$customFields = [
'course_type' => '课程体系',
'course_name' => '课程名称',
'start_date' => '开始日期',
'end_date' => '结束日期',
'total' => '参与数量',
];
// 创建多 sheet 导出
$sheets = [
new SheetExport($currentData, $currentFields, '学员数据'),
new SheetExport($customData, $customFields, '自定义数据'),
];
5 months ago
$filename = '元和员工参与企业明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
case 'company_ganbu_total':
// 全市干部参与企业明细 - 使用模型方法
$users = CourseSign::ganbu($start_date, $end_date, $course_ids, true);
3 months ago
// 当前学员数据
$currentData = [];
5 months ago
foreach ($users as $user) {
3 months ago
$currentData[] = [
5 months ago
'user_name' => $user->name ?? '',
'mobile' => $user->mobile ?? '',
'company_name' => $user->company->company_name ?? '',
'company_area' => $user->company->company_area ?? '',
'company_city' => $user->company->company_city ?? '',
'company_position' => $user->company_position ?? '',
];
}
3 months ago
$currentFields = [
5 months ago
'user_name' => '学员姓名',
'mobile' => '手机号',
'company_name' => '企业名称',
'company_area' => '所在区域',
'company_city' => '所在城市',
'company_position' => '职位',
];
3 months ago
// 自定义数据EmployeeParticipation type=2 干部培训数)
$customData = [];
$employeeParticipations = EmployeeParticipation::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('type', 2)->with('courseType')->get();
foreach ($employeeParticipations as $participation) {
$customData[] = [
'course_type' => $participation->courseType->name ?? '',
'course_name' => $participation->course_name ?? '',
'start_date' => $participation->start_date ?? '',
'end_date' => $participation->end_date ?? '',
'total' => $participation->total ?? 0,
];
}
$customFields = [
'course_type' => '课程体系',
'course_name' => '课程名称',
'start_date' => '开始日期',
'end_date' => '结束日期',
'total' => '参与数量',
];
// 创建多 sheet 导出
$sheets = [
new SheetExport($currentData, $currentFields, '学员数据'),
new SheetExport($customData, $customFields, '自定义数据'),
];
5 months ago
$filename = '全市干部参与企业明细';
3 months ago
// 直接返回多 sheet 导出
return Excel::download(
new MultiSheetExport($sheets),
$filename . '_' . date('YmdHis') . '.xlsx'
);
5 months ago
break;
case 'cover_head_total':
// 苏州头部企业明细 - 使用模型方法
3 months ago
// 确保 $course_ids 是数组格式
$courseIdsArray = $course_ids ? (is_array($course_ids) ? $course_ids : $course_ids->toArray()) : null;
$companies = CourseSign::toubuqiye($start_date, $end_date, $courseIdsArray, true);
3 months ago
// 预先获取所有符合条件的课程报名记录与toubuqiye方法逻辑一致
$courseSignsQuery = CourseSign::getStudentList($start_date, $end_date, 1, $courseIdsArray);
$allCourseSigns = $courseSignsQuery->with(['user', 'course.typeDetail'])->get();
// 按公司ID分组课程报名记录
$companyCourseSigns = [];
foreach ($allCourseSigns as $sign) {
if (!$sign->user || !$sign->user->company) {
continue;
}
$companyId = $sign->user->company->id;
if (!isset($companyCourseSigns[$companyId])) {
$companyCourseSigns[$companyId] = [];
}
$companyCourseSigns[$companyId][] = $sign;
}
5 months ago
foreach ($companies as $company) {
3 months ago
// 获取该公司的学员信息(只包含有课程报名的学员)
$userCourseSigns = collect($companyCourseSigns[$company->id] ?? []);
3 months ago
3 months ago
// 公司基本信息(只在第一行使用)
$companyInfo = [
'company_name' => $company->company_name,
'company_legal_representative' => $company->company_legal_representative ?? '',
'company_date' => $company->company_date ?? '',
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
'company_area' => $company->company_area ?? '',
'company_tag' => $company->company_tag ?? '',
'business_scope' => $company->business_scope ?? '',
'contact_phone' => $company->contact_phone ?? '',
'contact_mail' => $company->contact_mail ?? '',
];
3 months ago
if ($userCourseSigns->isEmpty()) {
3 months ago
// 如果没有学员,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
3 months ago
} else {
// 按学员分组
$usersData = [];
foreach ($userCourseSigns as $sign) {
if (!$sign->user) {
continue;
}
$userId = $sign->user_id;
if (!isset($usersData[$userId])) {
$usersData[$userId] = [
'user' => $sign->user,
'courseSigns' => [],
];
}
$usersData[$userId]['courseSigns'][] = $sign;
}
3 months ago
// 每个学员一行
$isFirstRow = true;
3 months ago
foreach ($usersData as $userData) {
$user = $userData['user'];
$courseSigns = collect($userData['courseSigns']);
3 months ago
if ($courseSigns->isEmpty()) {
continue;
}
3 months ago
3 months ago
// 获取课程名称列表,用中文顿号分隔
$courseNames = $courseSigns->pluck('course.name')->filter()->unique()->values()->implode('、');
3 months ago
3 months ago
// 获取课程体系列表,用中文顿号分隔
$courseTypes = $courseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->implode('、');
3 months ago
3 months ago
// 报名课程数
$courseCount = $courseSigns->count();
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'company_tag' => '',
'business_scope' => '',
'contact_phone' => '',
'contact_mail' => '',
'user_name' => $user->name ?? '',
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
3 months ago
}
}
}
5 months ago
}
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'company_address' => '地址',
'company_city' => '所在城市',
'company_area' => '所在区域',
'company_tag' => '企业资质',
'business_scope' => '营业范围',
'contact_phone' => '联系电话',
'contact_mail' => '联系邮箱',
3 months ago
'user_name' => '学员姓名',
3 months ago
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
$filename = '苏州头部企业明细';
break;
case 'cover_rencai_total':
// 高层次人才明细 - 使用模型方法
3 months ago
// 确保 $course_ids 是数组格式
$courseIdsArray = $course_ids ? (is_array($course_ids) ? $course_ids : $course_ids->toArray()) : null;
$users = CourseSign::rencai($start_date, $end_date, $courseIdsArray, true);
5 months ago
// 加载关联关系
$users->load('company');
3 months ago
// 获取所有用户的课程报名记录使用与rencai相同的筛选条件
$userIds = $users->pluck('id')->toArray();
$userCourseSigns = CourseSign::getStudentList($start_date, $end_date, 1, $courseIdsArray)
->whereIn('user_id', $userIds)
->with(['user', 'course.typeDetail'])
->get();
// 按用户ID分组课程报名记录
$userCourseSignsMap = [];
foreach ($userCourseSigns as $sign) {
if (!$sign->user) {
continue;
}
$userId = $sign->user_id;
if (!isset($userCourseSignsMap[$userId])) {
$userCourseSignsMap[$userId] = [];
}
$userCourseSignsMap[$userId][] = $sign;
}
5 months ago
foreach ($users as $user) {
3 months ago
// 获取该用户的课程报名记录
$courseSigns = collect($userCourseSignsMap[$user->id] ?? []);
if ($courseSigns->isEmpty()) {
// 如果没有课程报名记录,设置空值
$courseNamesStr = '';
$courseTypesStr = '';
$totalCourseCount = 0;
} else {
// 收集课程名称
$courseNames = $courseSigns->pluck('course.name')->filter()->unique()->values()->toArray();
$courseNamesStr = implode('、', array_filter($courseNames));
// 收集课程体系
$courseTypes = $courseSigns->pluck('course.typeDetail.name')
->filter()
->unique()
->values()
->toArray();
$courseTypesStr = implode('、', array_filter($courseTypes));
// 统计报名课程数
$totalCourseCount = $courseSigns->count();
}
5 months ago
$data[] = [
'user_name' => $user->name ?? '',
'mobile' => $user->mobile ?? '',
'company_name' => $user->company_name ?? '',
'company_area' => $user->company_area ?? '',
'company_city' => $user->company->company_city ?? '',
'company_position' => $user->company_position ?? '',
'education' => $user->education ?? '',
3 months ago
'geren_rongyu' => $user->type ?? '',
3 months ago
'course_names' => $courseNamesStr,
'course_types' => $courseTypesStr,
'course_count' => $totalCourseCount,
5 months ago
];
}
$fields = [
'user_name' => '学员姓名',
'mobile' => '手机号',
'company_name' => '企业名称',
'company_area' => '所在区域',
'company_city' => '所在城市',
'company_position' => '职位',
'education' => '学历',
3 months ago
'geren_rongyu' => '个人荣誉',
3 months ago
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
$filename = '高层次人才明细';
break;
case 'cover_stock_total':
3 months ago
// 重点上市公司明细 - 使用模型方法,与统计逻辑保持一致
$companiesData = CourseSign::suzhoushangshi($start_date, $end_date, $course_ids, true);
5 months ago
foreach ($companiesData as $item) {
$company = $item['company'];
3 months ago
$users = $item['users'] ?? [];
3 months ago
// 公司基本信息(只在第一行使用)
3 months ago
$companyInfo = [
5 months ago
'company_name' => $company->company_name,
'company_legal_representative' => $company->company_legal_representative ?? '',
'company_date' => $company->company_date ?? '',
'stock_date' => $company->stock_date ?? '',
'company_address' => $company->company_address ?? '',
'company_city' => $company->company_city ?? '',
'company_area' => $company->company_area ?? '',
3 months ago
'company_tag' => $company->company_tag ?? '',
5 months ago
'business_scope' => $company->business_scope ?? '',
'contact_phone' => $company->contact_phone ?? '',
'contact_mail' => $company->contact_mail ?? '',
];
3 months ago
if (empty($users)) {
// 如果没有学员,仍然导出公司基本信息
$data[] = array_merge($companyInfo, [
'user_name' => '',
'course_names' => '',
'course_types' => '',
'course_count' => 0,
]);
} else {
3 months ago
// 每个学员一行
$isFirstRow = true;
3 months ago
foreach ($users as $userInfo) {
$user = $userInfo['user'] ?? null;
$courses = $userInfo['courses'] ?? [];
if (empty($courses)) {
// 如果没有课程,仍然显示学员信息
$courseNames = '';
$courseTypes = '';
$courseCount = 0;
} else {
// 收集课程名称
$courseNames = collect($courses)->pluck('course_name')->filter()->unique()->values()->implode('、');
// 收集课程体系
$courseTypes = collect($courses)->pluck('course_type')->filter()->unique()->values()->implode('、');
// 报名课程数
$courseCount = count($courses);
}
3 months ago
if ($isFirstRow) {
// 第一行:显示公司信息
$data[] = array_merge($companyInfo, [
'user_name' => $userInfo['user_name'] ?? ($user->name ?? ''),
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
]);
$isFirstRow = false;
} else {
// 后续行:公司信息为空
$data[] = [
'company_name' => '',
'company_legal_representative' => '',
'company_date' => '',
'stock_date' => '',
'company_address' => '',
'company_city' => '',
'company_area' => '',
'company_tag' => '',
'business_scope' => '',
'contact_phone' => '',
'contact_mail' => '',
'user_name' => $userInfo['user_name'] ?? ($user->name ?? ''),
'course_names' => $courseNames,
'course_types' => $courseTypes,
'course_count' => $courseCount,
];
}
3 months ago
}
}
5 months ago
}
$fields = [
'company_name' => '企业名称',
'company_legal_representative' => '法人',
'company_date' => '成立时间',
'stock_date' => '上市日期',
'company_address' => '地址',
'company_city' => '所在城市',
'company_area' => '所在区域',
3 months ago
'company_tag' => '企业资质',
5 months ago
'business_scope' => '营业范围',
'contact_phone' => '联系电话',
'contact_mail' => '联系邮箱',
3 months ago
'user_name' => '学员姓名',
'course_names' => '课程名称',
'course_types' => '课程体系',
'course_count' => '报名课程数',
5 months ago
];
3 months ago
$filename = '重点上市公司明细';
5 months ago
break;
5 months ago
default:
return $this->fail([ResponseCode::ERROR_PARAMETER, '不支持的导出类型']);
}
if (empty($data)) {
return $this->fail([ResponseCode::ERROR_PARAMETER, '暂无数据可导出']);
}
return Excel::download(
new CommonExport($data, $fields),
$filename . '_' . date('YmdHis') . '.xlsx'
);
}
/**
* 获取coursesHome方法的公共参数提取公共逻辑
* @return array
*/
private function getCoursesHomeParams()
{
$start_date = request('start_date', CourseType::START_DATE);
5 months ago
// 默认结束日期一年以后
5 months ago
$end_date = request('end_date', date('Y-m-d', strtotime('+10 year')));
5 months ago
$course_type_id = request('course_type_id', '');
if ($course_type_id) {
// 部分
5 months ago
$course_type_id = explode(',', $course_type_id);
5 months ago
} else {
// 全部
$course_type_id = CourseType::pluck('id')->toArray();
}
// 课程
$courses = Course::whereIn('type', $course_type_id)->get();
return [
'start_date' => $start_date,
'end_date' => $end_date,
'course_type_id' => $course_type_id,
'courses' => $courses,
];
}
10 months ago
/**
* @OA\Post(
* path="/api/admin/other/admin-user-list",
* tags={"其他"},
* summary="后台用户列表",
* description="",
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
* @OA\Parameter(name="department_id", in="query", @OA\Schema(type="int"), required=false, description="部门id"),
* @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="关键词"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function adminUserList()
{
$all = \request()->all();
$list = Admin::where(function ($query) use ($all) {
if (isset($all['department_id'])) {
$query->where('department_id', $all['department_id']);
}
if (isset($all['keyword'])) {
$query->where('name', 'like', '%' . $all['keyword'] . '%')->orWhere('username', 'like', '%' . $all['keyword'] . '%')->orWhere('mobile', 'like', '%' . $all['keyword'] . '%');
}
})->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc')
->paginate($all['page_size'] ?? 20);
return $this->success($list);
}
/**
* @OA\Post(
* path="/api/admin/other/admin-department-list",
* tags={"其他"},
* summary="后台部门列表",
* description="",
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码。不传则全部,传入则分页"),
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
* @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="关键词"),
* @OA\Parameter(name="show_tree", in="query", @OA\Schema(type="string"), required=false, description="是否显示树形结构 0否1是"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function adminDepartmentList()
{
$all = \request()->all();
$list = Department::with('users')->where(function ($query) use ($all) {
if (isset($all['keyword'])) {
$query->where('name', 'like', '%' . $all['keyword'] . '%');
}
});
if (isset($all['show_tree']) && $all['show_tree']) {
// 显示树形结构
$list = array2tree($list->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc')->get()->toArray());
} else {
$list = $list->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc')->paginate($all['page_size'] ?? 20);
}
return $this->success($list);
}
/**
* @OA\Get(
* path="/api/admin/other/table-fileds",
* tags={"其他"},
* summary="获取表字段",
* description="",
* @OA\Parameter(name="table_name", in="query", @OA\Schema(type="string"), required=true, description="table_name"),
* @OA\Parameter(name="except", in="query", @OA\Schema(type="string"), required=true, description="排除的字段数组"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="暂无"
* )
* )
*/
public function tableFileds()
{
$all = \request()->all();
$messages = [
'table_name.required' => '表名必填',
];
$validator = Validator::make($all, [
'table_name' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$except = request('except');
$detail = (new CustomFormField())->getRowTableFieldsByComment($all['table_name']);
$list = [];
if ($except) {
foreach ($detail as $key => $item) {
if (in_array($key, $except)) {
continue;
}
$list[] = $item;
}
} else {
$list = $detail;
}
return $this->success($list);
}
public function test()
{
6 months ago
$model = new DoorRepository();
$result = $model->getAllDoorInfo();
5 months ago
dd(json_encode($result, JSON_UNESCAPED_UNICODE));
10 months ago
}
/**
* 车辆进出场日志
*/
public function postCarInInfo()
{
$all = request()->all();
CarparkLog::add(1, $all, $all['plateNo']);
return $this->success($all);
}
/**
* 车辆出场日志
*/
public function postCarOutInfo()
{
$all = request()->all();
CarparkLog::add(2, $all, $all['plateNo']);
return $this->success($all);
}
3 months ago
/**
* @OA\Post(
* path="/api/admin/other/clear-cache",
* tags={"其他"},
* summary="清除缓存",
* description="清除系统所有缓存",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="清除缓存成功"
* )
* )
*/
public function clearCache()
{
try {
// 清除所有缓存
Cache::flush();
return $this->success(['message' => '缓存清除成功']);
} catch (\Exception $exception) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '清除缓存失败:' . $exception->getMessage()]);
}
}
10 months ago
}