'json', 'fee_file_ids' => 'json', 'data' => 'json', 'change_data' => 'json']; protected $appends = ['files', 'fee_files', 'status_text', 'fee_status_text']; public static $intToString = [ 'status' => [ 0 => '待审核', 1 => '审核通过', 2 => '审核不通过', 3 => '备选', 4 => '已取消', 5 => '主动放弃', 6 => '黑名单' ], 'fee_status' => [ 0 => '未缴费', 1 => '缴费成功', 2 => '缴费失败', 3 => '待确认' ], ]; public function getStatusTextAttribute($value) { return self::$intToString['status'][$this->status] ?? ''; } public function getFeeStatusTextAttribute($value) { return self::$intToString['fee_status'][$this->fee_status] ?? ''; } public function getFilesAttribute($value) { if (empty($this->file_ids)) return []; return Upload::whereIn('id', $this->file_ids)->get(); } public function getFeeFilesAttribute($value) { if (empty($this->fee_file_ids)) return []; return Upload::whereIn('id', $this->fee_file_ids)->get(); } public function course() { return $this->hasOne(Course::class, 'id', 'course_id'); } public function user() { return $this->hasOne(User::class, 'id', 'user_id'); } /** * 第三方日志记录 * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function thirdAppointmentLogs() { return $this->hasMany(ThirdAppointmentLog::class, 'course_sign_id', 'id'); } /** * 获取学员列表数据 */ public static function getStudentList($start_date = null, $end_date = null, $status = null, $course_ids = null) { $baseQuery = CourseSign::where(function ($query) use ($course_ids, $status) { if ($status) { $query->where('status', $status); } if (isset($course_ids)) { $query->whereIn('course_id', $course_ids); } })->whereHas('course', 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]); } })->whereNotIn('status', [4, 5, 6]); return $baseQuery; } /** * 指定时间内的报名信息(未去重) */ public static function courseSignsTotal($start_date, $end_date, $status = null, $course_ids = null, $retList = false) { $totalQuery = self::getStudentList($start_date, $end_date, $status, $course_ids); if ($retList) { // 返回列表 return $totalQuery->get(); } else { // 基础数据 $baseTotal = $totalQuery->count(); // 历史数据 $historyTotal = 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(function ($query) { $course_type_id = request('course_type_id'); if ($course_type_id) { $course_type_id = explode(',', $course_type_id); $query->whereIn('type', $course_type_id); } })->sum('course_type_signs_pass'); // 返回统计数据 return $historyTotal + $baseTotal; } } /** * 指定时间内的报名信息(去重) */ public static function courseSignsTotalByUnique($start_date, $end_date, $status = null, $course_ids = null, $retList = false) { $totalQuery = self::getStudentList($start_date, $end_date, $status, $course_ids); $user = User::whereIn('id', $totalQuery->get()->pluck('user_id'))->groupBy('mobile')->get(); if ($retList) { // 列表 return $user; } else { $baseTotal = $user->count(); // 历史数据 $historyTotal = 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(function ($query) { $course_type_id = request('course_type_id'); if ($course_type_id) { $course_type_id = explode(',', $course_type_id); $query->whereIn('type', $course_type_id); } })->sum('course_type_signs_pass_unique'); // 统计数据 return $baseTotal + $historyTotal; } } /** * 被投企业统计 * @param string|null $start_date 开始日期 * @param string|null $end_date 结束日期 * @param array|null $course_ids 课程ID(仅在自定义时间时生效) * @param bool $retList 是否返回列表 */ public static function yhInvested($start_date = null, $end_date = null, $course_ids = null, $retList = false) { // 判断是否使用默认时间 $isDefaultDate = (empty($start_date) || $start_date == CourseType::START_DATE) && empty($course_ids); // 获取学员ID列表 if ($isDefaultDate) { // 默认时间:获取所有学员,不限制课程 $userIds = self::getStudentList($start_date, $end_date, 1, null)->get()->pluck('user_id'); } else { // 自定义时间:按课程筛选学员 $userIds = self::getStudentList($start_date, $end_date, 1, $course_ids)->get()->pluck('user_id'); } // 获取这些学员所在的被投企业 $companies = Company::whereHas('users', function ($query) use ($userIds) { $query->whereIn('id', $userIds); })->where('is_yh_invested', 1)->get(); // 自定义时间:需要按被投时间筛选 if (!$isDefaultDate) { $startDate = substr($start_date, 0, 10); $endDate = substr($end_date, 0, 10); // 筛选出被投时间在范围内的企业 $filteredCompanies = []; foreach ($companies as $company) { $projectUsers = $company->project_users ?? []; foreach ($projectUsers as $item) { $investDate = $item['investDate'] ?? null; // 检查被投时间是否在范围内 if ($investDate && $investDate >= $startDate && $investDate <= $endDate) { $filteredCompanies[] = $company; break; // 只要有一条满足就加入 } } } $companies = collect($filteredCompanies); } // 返回结果 if ($retList) { return $companies->values(); } else { return $companies->count(); } } /** * 今年被投企业统计(统计或列表) * @param string|null $start_date 开始日期 * @param string|null $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表(包含学员、课程信息) * @return int|array */ public static function companyInvestedYear($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); $courseSigns = $courseSignsQuery->with(['user.company', 'course.typeDetail'])->get(); // 获取所有被投企业的ID $companyIds = $courseSigns->pluck('user.company.id') ->filter() ->unique() ->toArray(); $year = date('Y'); // 获取这些公司中标记为被投的公司 $allInvestedCompanies = Company::whereIn('id', $companyIds) ->where('is_yh_invested', 1) ->get(); // 筛选出被投时间在今年的企业 $companies = []; foreach ($allInvestedCompanies as $company) { $projectUsers = $company->project_users ?? []; $hasInvestThisYear = false; foreach ($projectUsers as $item) { $investDate = $item['investDate'] ?? null; if ($investDate) { $investYear = date('Y', strtotime($investDate)); if ($investYear == $year) { $hasInvestThisYear = true; break; } } } if ($hasInvestThisYear) { $companies[$company->id] = $company; } } $companies = collect($companies); if ($retList) { // 返回详细列表:主表是公司,子数据是学员信息 $result = []; foreach ($courseSigns as $courseSign) { if (!$courseSign->user || !$courseSign->user->company) { continue; } $companyId = $courseSign->user->company->id; // 只处理今年被投企业的记录 if (!isset($companies[$companyId])) { continue; } $company = $companies[$companyId]; // 如果公司还没有在结果中,初始化 if (!isset($result[$companyId])) { $result[$companyId] = [ 'company' => $company, 'users' => [], ]; } // 按学员分组,收集每个学员的课程信息 $userId = $courseSign->user->id; if (!isset($result[$companyId]['users'][$userId])) { $result[$companyId]['users'][$userId] = [ 'user' => $courseSign->user, 'user_name' => $courseSign->user->name ?? '', 'mobile' => $courseSign->user->mobile ?? '', 'courses' => [], ]; } // 添加该学员的课程信息 $result[$companyId]['users'][$userId]['courses'][] = [ 'course_name' => $courseSign->course->name ?? '', 'course_type' => $courseSign->course->typeDetail->name ?? '', 'course_sign' => $courseSign, ]; } // 将 users 转换为数组(去掉 user_id 作为 key) foreach ($result as $companyId => $item) { $result[$companyId]['users'] = array_values($item['users']); } // 转换为数组并返回 return array_values($result); } else { // 返回统计数据 return $companies->count(); } } /** * 跟班学员(统计或列表) * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表 * @return int|\Illuminate\Database\Eloquent\Collection */ public static function genban($start_date, $end_date, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); // 获取需要统计跟班学员的课程 $genbanCourse = Course::whereHas('typeDetail', function ($query) { $query->where('is_count_genban', 1); })->get(); $courseSigns = $courseSignsQuery->whereHas('user', function ($query) { $query->where('from', 'like', '%跟班学员%'); })->whereIn('course_id', $genbanCourse->pluck('id'))->get(); if ($retList) { return User::with('company')->whereIn('id', $courseSigns->pluck('user_id'))->get(); } else { return User::whereIn('id', $courseSigns->pluck('user_id'))->count(); } } /** * 入学后上市公司数量(在指定时间范围内报名的学员所在公司中,在入学后上市的公司数量) * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表 * @return int|array */ public static function companyMarketAfterEnrollment($start_date, $end_date, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, null, $course_ids); $courseSignsForStock = $courseSignsQuery->with('user.company')->get(); $companiesAfterEnrollment = []; foreach ($courseSignsForStock as $sign) { if ($sign->user && $sign->user->company && $sign->user->company->company_market == 1) { $signDate = \Carbon\Carbon::parse($sign->created_at)->format('Y-m-d'); $stockDate = $sign->user->company->stock_date; if ($stockDate && $stockDate >= $signDate) { $companyId = $sign->user->company->id; if (!isset($companiesAfterEnrollment[$companyId])) { $companiesAfterEnrollment[$companyId] = [ 'company' => $sign->user->company, 'first_sign_date' => $signDate, 'users' => [], ]; } if ($retList) { $companiesAfterEnrollment[$companyId]['users'][] = $sign->user; } } } } if ($retList) { return $companiesAfterEnrollment; } else { return count($companiesAfterEnrollment); } } /** * 入学后被投企业数量(在指定时间范围内报名的学员所在公司中,在入学后被投的公司数量) * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表 * @return int|array */ public static function companyInvestedAfterEnrollment($start_date, $end_date, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); $courseSignsForInvest = $courseSignsQuery->with('user.company')->get(); $companiesAfterEnrollment = []; foreach ($courseSignsForInvest as $sign) { if ($sign->user && $sign->user->company && $sign->user->company->is_yh_invested == 1) { $signDate = \Carbon\Carbon::parse($sign->created_at)->format('Y-m-d'); // 从 project_users 中获取最早的被投时间 $projectUsers = $sign->user->company->project_users; $investDate = null; if (!empty($projectUsers) && is_array($projectUsers)) { foreach ($projectUsers as $projectUser) { if (!empty($projectUser['investDate'])) { if ($investDate === null || $projectUser['investDate'] < $investDate) { $investDate = $projectUser['investDate']; } } } } // 被投时间 >= 报名时间,说明是入学后被投 if ($investDate && $investDate >= $signDate) { $companyId = $sign->user->company->id; if (!isset($companiesAfterEnrollment[$companyId])) { $companiesAfterEnrollment[$companyId] = [ 'company' => $sign->user->company, 'first_sign_date' => $signDate, 'invest_date' => $investDate, 'users' => [], ]; } if ($retList) { $companiesAfterEnrollment[$companyId]['users'][] = $sign->user; } } } } if ($retList) { return $companiesAfterEnrollment; } else { return count($companiesAfterEnrollment); } } /** * 区域统计 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回详情,true返回列表 */ public static function area($start_date, $end_date, $status = null, $course_ids = null, $retList = false) { $courseSignList = self::getStudentList($start_date, $end_date, $status, $course_ids); // 地区 $suzhouArea = Company::where('company_city', '苏州市')->pluck('company_area')->unique(); $list = []; foreach ($suzhouArea as $area) { $sourseSignList2 = (clone $courseSignList)->whereHas('user', function ($query) use ($area) { $query->whereHas('company', function ($query) use ($area) { $query->where('company_area', $area); }); })->get(); $list[] = [ 'area' => $area, // 未去重 'total' => $sourseSignList2->count(), // 已去重 'total_unique' => User::whereIn('id', $sourseSignList2->pluck('user_id'))->groupBy('mobile')->get()->count(), ]; } $courseSignList3 = (clone $courseSignList)->whereHas('user', function ($query) { $query->whereHas('company', function ($query) { $query->where('company_city', '!=', '苏州市'); }); })->get(); $list[] = [ 'area' => '苏州市外', 'total' => $courseSignList3->count(), // 已去重 'total_unique' => User::groupBy('mobile')->whereIn('id', $courseSignList3->pluck('user_id'))->get()->count(), ]; if ($retList) { // 返回列表 return $list; } else { // 返回统计数据 return $courseSignList->get(); } } /** * 元和员工参人员 */ public static function companyJoin($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, null, $course_ids); $courseSignByType = $courseSignsQuery->get(); // 检测关键词 $companyNameKeyword = [ '元禾控股', '元禾原点', '元禾厚望', '元禾重元', '元禾璞华', '元禾谷风', '元禾绿柳', '元禾辰坤', '元禾沙湖', '禾裕集团', '苏州科服', '信诚管理咨询', '集成电路公司', '常州团队', '国企元禾' ]; // $company = Company::where(function ($query) use ($companyNameKeyword) { // foreach ($companyNameKeyword as $item) { // $query->orWhere('company_name', 'like', '%' . $item . '%'); // } // })->get(); $list = User::whereIn('id', $courseSignByType->pluck('user_id')) ->where(function ($query) use ($companyNameKeyword) { foreach ($companyNameKeyword as $item) { $query->orWhere('company_name', 'like', '%' . $item . '%'); } })->get(); if ($retList) { // 返回列表 return $list; } else { // 返回统计数据 return $list->count(); } } /** * 干部参与(统计或列表) * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表 * @return int|\Illuminate\Database\Eloquent\Collection */ public static function ganbu($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); $courseSigns = $courseSignsQuery->whereHas('user', function ($query) { $query->where('from', 'like', '%跟班学员%'); })->get(); if ($retList) { return User::with('company')->whereIn('id', $courseSigns->pluck('user_id'))->get(); } else { return User::whereIn('id', $courseSigns->pluck('user_id'))->count(); } } /** * 头部企业(统计或列表) * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表 * @return int|\Illuminate\Database\Eloquent\Collection */ public static function toubuqiye($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); $courseSignByType = $courseSignsQuery->get(); $list = Company::whereHas('users', function ($query) use ($courseSignByType) { $query->whereIn('id', $courseSignByType->pluck('user_id')); })->where('company_tag', 'like', '%' . '高新技术企业' . '%')->get(); if ($retList) { // 返回列表 return $list; } else { // 返回统计数据 return $list->count(); } } /** * 高层次人才 */ public static function rencai($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); // 条件1:人才培训课程类型的用户 $courseSigns1 = $courseSignsQuery->whereHas('course', function ($query) { $query->whereHas('typeDetail', function ($q) { $q->where('name', '人才培训'); }); })->get(); // 条件2:data 字段中 name="个人荣誉" 且 value != "其他" 的用户 $courseSigns2 = $courseSignsQuery->get()->filter(function ($courseSign) { if (empty($courseSign->data) || !is_array($courseSign->data)) { return false; } foreach ($courseSign->data as $item) { if (isset($item['key']) && $item['key'] === 'type') { if (isset($item['value']) && $item['value'] !== '其他') { return true; } } } return false; }); // 合并两个条件的结果(或关系),并去重 user_id $allUserIds = $courseSigns1->pluck('user_id') ->merge($courseSigns2->pluck('user_id')) ->unique() ->filter(); if ($retList) { return User::whereIn('id', $allUserIds)->get(); } else { return $allUserIds->count(); } } /** * 上市公司(统计或列表) * @param string|null $start_date 开始日期 * @param string|null $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表(包含学员、课程信息) * @return int|array */ public static function shangshi($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); $courseSigns = $courseSignsQuery->with(['user.company', 'course.typeDetail'])->get(); // 获取所有上市公司的ID $companyIds = $courseSigns->pluck('user.company.id') ->filter() ->unique() ->toArray(); // 获取这些公司中标记为上市的公司 $companies = Company::whereIn('id', $companyIds) ->where('company_market', 1) ->get() ->keyBy('id'); if ($retList) { // 返回详细列表:主表是公司,子数据是学员信息 $result = []; foreach ($courseSigns as $courseSign) { if (!$courseSign->user || !$courseSign->user->company) { continue; } $companyId = $courseSign->user->company->id; // 只处理上市公司的记录 if (!isset($companies[$companyId])) { continue; } $company = $companies[$companyId]; // 如果公司还没有在结果中,初始化 if (!isset($result[$companyId])) { $result[$companyId] = [ 'company' => $company, 'users' => [], ]; } // 按学员分组,收集每个学员的课程信息 $userId = $courseSign->user->id; if (!isset($result[$companyId]['users'][$userId])) { $result[$companyId]['users'][$userId] = [ 'user' => $courseSign->user, 'user_name' => $courseSign->user->name ?? '', 'mobile' => $courseSign->user->mobile ?? '', 'courses' => [], ]; } // 添加该学员的课程信息 $result[$companyId]['users'][$userId]['courses'][] = [ 'course_name' => $courseSign->course->name ?? '', 'course_type' => $courseSign->course->typeDetail->name ?? '', 'course_sign' => $courseSign, ]; } // 将 users 转换为数组(去掉 user_id 作为 key) foreach ($result as $companyId => $item) { $result[$companyId]['users'] = array_values($item['users']); } // 转换为数组并返回 return array_values($result); } else { // 返回统计数据 return $companies->count(); } } /** * 今年上市公司(统计或列表) * @param string|null $start_date 开始日期 * @param string|null $end_date 结束日期 * @param array|null $course_ids 课程ID数组,不传则统计所有课程 * @param bool $retList 是否返回列表,false返回数量,true返回列表(包含学员、课程信息) * @return int|array */ public static function companyMarketYear($start_date = null, $end_date = null, $course_ids = null, $retList = false) { $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); $courseSigns = $courseSignsQuery->with(['user.company', 'course.typeDetail'])->get(); // 获取所有上市公司的ID $companyIds = $courseSigns->pluck('user.company.id') ->filter() ->unique() ->toArray(); $year = date('Y'); // 获取这些公司中标记为上市的公司,且上市日期为今年 $companies = Company::whereIn('id', $companyIds) ->where('company_market', 1) ->whereYear('stock_date', $year) ->get() ->keyBy('id'); if ($retList) { // 返回详细列表:主表是公司,子数据是学员信息 $result = []; foreach ($courseSigns as $courseSign) { if (!$courseSign->user || !$courseSign->user->company) { continue; } $companyId = $courseSign->user->company->id; // 只处理上市公司的记录 if (!isset($companies[$companyId])) { continue; } $company = $companies[$companyId]; // 如果公司还没有在结果中,初始化 if (!isset($result[$companyId])) { $result[$companyId] = [ 'company' => $company, 'users' => [], ]; } // 按学员分组,收集每个学员的课程信息 $userId = $courseSign->user->id; if (!isset($result[$companyId]['users'][$userId])) { $result[$companyId]['users'][$userId] = [ 'user' => $courseSign->user, 'user_name' => $courseSign->user->name ?? '', 'mobile' => $courseSign->user->mobile ?? '', 'courses' => [], ]; } // 添加该学员的课程信息 $result[$companyId]['users'][$userId]['courses'][] = [ 'course_name' => $courseSign->course->name ?? '', 'course_type' => $courseSign->course->typeDetail->name ?? '', 'course_sign' => $courseSign, ]; } // 将 users 转换为数组(去掉 user_id 作为 key) foreach ($result as $companyId => $item) { $result[$companyId]['users'] = array_values($item['users']); } // 转换为数组并返回 return array_values($result); } else { // 返回统计数据 return $companies->count(); } } }