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.

1309 lines
53 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Models;
use Illuminate\Support\Facades\Log;
use OwenIt\Auditing\Models\Audit;
class CourseSign extends SoftDeletesModel
{
protected $casts = ['file_ids' => '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) {
$query->where('is_chart', 1);
// 开始结束日期的筛选。or查询
if ($start_date && $end_date) {
$query->where(function ($query) use ($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, $needHistory = true)
{
$totalQuery = self::getStudentList($start_date, $end_date, $status, $course_ids);
if ($retList) {
// 返回列表
return $totalQuery->get();
} else {
// 基础数据
$baseTotal = $totalQuery->count();
// 历史数据
$historyTotal = 0;
if ($needHistory) {
$historyTotal = 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) {
// 开始结束日期的筛选。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, $needHistory = true)
{
$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 = 0;
if ($needHistory) {
// 历史数据
$historyTotal = 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) {
// 开始结束日期的筛选。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 yhInvestedTotal($start_date = null, $end_date = null, $course_ids = null, $retList = false)
{
// 默认时间:获取所有学员
$userIds = self::getStudentList($start_date, $end_date, 1, $course_ids)->get()->pluck('user_id');
// 获取这些学员所在的被投企业
$companies = Company::approvedStudents()->whereHas('users', function ($query) use ($userIds) {
$query->whereIn('id', $userIds);
})->where('is_yh_invested', 1)->get();
// 返回结果
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 是否返回列表
*/
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::approvedStudents()->whereHas('users', function ($query) use ($userIds) {
$query->whereIn('id', $userIds);
})->where('is_yh_invested', 1)->get();
// 返回结果
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();
// 计算年份范围
$years = [];
if ($start_date && $end_date) {
// 从开始和结束日期中提取年份范围
$startYear = (int) date('Y', strtotime($start_date));
$endYear = (int) date('Y', strtotime($end_date));
// 生成所有年份的数组
for ($year = $startYear; $year <= $endYear; $year++) {
$years[] = $year;
}
} else {
// 如果没有提供日期,使用当前年份
$years[] = (int) date('Y');
}
// 获取这些公司中标记为被投的公司
$allInvestedCompanies = Company::approvedStudents()->whereIn('id', $companyIds)
->where('is_yh_invested', 1)
->get();
// 筛选出被投时间在年份范围内的企业
$companies = [];
foreach ($allInvestedCompanies as $company) {
$projectUsers = $company->project_users ?? [];
$hasInvestInYears = false;
foreach ($projectUsers as $item) {
$investDate = $item['investDate'] ?? null;
if ($investDate) {
$investYear = (int) date('Y', strtotime($investDate));
if (in_array($investYear, $years)) {
$hasInvestInYears = true;
break;
}
}
}
if ($hasInvestInYears) {
$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 = null, $end_date = null, $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 {
$baseCount = User::whereIn('id', $courseSigns->pluck('user_id'))->count();
// 额外数据:从 TraineeStudent 模型中统计
$traineeStudentTotal = TraineeStudent::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]);
}
})->sum('total');
return $baseCount + $traineeStudentTotal;
}
}
/**
* 入学后上市公司数量(在指定时间范围内报名的学员所在公司中,在入学后上市的公司数量)
* @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', 'course'])->get();
$companiesAfterEnrollment = [];
foreach ($courseSignsForStock as $sign) {
if ($sign->user && $sign->user->company && $sign->user->company->company_market == 1) {
// 入学时间使用参与课程的课程开始时间course->start_date不使用报名时间created_at
$enrollmentDate = null;
if ($sign->course && $sign->course->start_date) {
$enrollmentDate = \Carbon\Carbon::parse($sign->course->start_date)->format('Y-m-d');
}
// 如果没有课程开始时间,跳过这条记录
if (!$enrollmentDate) {
continue;
}
$stockDate = $sign->user->company->stock_date;
// 上市时间 >= 课程开始时间(入学时间),说明是入学后上市
if ($stockDate && $stockDate >= $enrollmentDate) {
$companyId = $sign->user->company->id;
if (!isset($companiesAfterEnrollment[$companyId])) {
$companiesAfterEnrollment[$companyId] = [
'company' => $sign->user->company,
'first_enrollment_date' => $enrollmentDate, // 首次入学时间(课程开始时间)
'stock_date' => $stockDate,
'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)
{
// 获取所有被投企业
$companies = Company::approvedStudents()->where('is_yh_invested', 1)->get();
$companiesAfterEnrollment = [];
foreach ($companies as $company) {
$projectUsers = $company->project_users ?? [];
// 遍历被投时间,找到在指定时间范围内的被投时间
foreach ($projectUsers as $projectUser) {
$investDate = $projectUser['investDate'] ?? null;
// 检查被投时间是否在指定时间范围内
if ($investDate && $investDate >= $start_date && $investDate <= $end_date) {
// 获取该公司的所有学员
$users = $company->users()->get();
// 检查是否有学员的入学时间(课程开始时间)小于等于被投时间
$hasValidEnrollment = false;
$firstEnrollmentDate = null;
$matchedUsers = [];
foreach ($users as $user) {
// 获取该学员的所有审核通过的课程报名记录
$courseSigns = self::where('user_id', $user->id)
->where('status', 1)
->with('course')
->get();
foreach ($courseSigns as $courseSign) {
if ($courseSign->course && $courseSign->course->start_date) {
$enrollmentDate = \Carbon\Carbon::parse($courseSign->course->start_date)->format('Y-m-d');
// 检查入学时间是否小于等于被投时间
if ($enrollmentDate <= $investDate) {
$hasValidEnrollment = true;
// 记录最早的入学时间
if ($firstEnrollmentDate === null || $enrollmentDate < $firstEnrollmentDate) {
$firstEnrollmentDate = $enrollmentDate;
}
if ($retList) {
$matchedUsers[] = $user;
}
break; // 只要有一个课程满足条件即可
}
}
}
}
// 如果有学员的入学时间小于等于被投时间,则计入统计
if ($hasValidEnrollment) {
$companyId = $company->id;
if (!isset($companiesAfterEnrollment[$companyId])) {
$companiesAfterEnrollment[$companyId] = [
'company' => $company,
'first_enrollment_date' => $firstEnrollmentDate,
'invest_date' => $investDate,
'users' => [],
];
}
if ($retList) {
// 合并用户列表(去重)
$existingUserIds = array_column($companiesAfterEnrollment[$companyId]['users'], 'id');
foreach ($matchedUsers as $user) {
if (!in_array($user->id, $existingUserIds)) {
$companiesAfterEnrollment[$companyId]['users'][] = $user;
}
}
}
break; // 只要有一个被投时间满足条件即可
}
}
}
}
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返回列表
* @param bool $is_schoolmate 是否只统计校友false统计所有true只统计校友
*/
public static function area($start_date, $end_date, $status = null, $course_ids = null, $retList = false, $is_schoolmate = false)
{
$courseSignList = self::getStudentList($start_date, $end_date, $status, $course_ids);
// 如果只统计校友,添加校友筛选条件
if ($is_schoolmate) {
$courseSignList->whereHas('user', function ($query) {
$query->where('is_schoolmate', 1);
});
}
// 地区 - 从数据字典获取
$suzhouAreas = ParameterDetail::where('parameter_id', 5)
->where('status', 1)
->orderBy('sort', 'asc')
->pluck('value')
->toArray();
$list = [];
foreach ($suzhouAreas as $area) {
// 特殊处理:高新区需要统计高新区+虎丘区
if ($area === '高新区') {
$sourseSignList2 = (clone $courseSignList)->whereHas('user', function ($query) {
$query->whereHas('company', function ($query) {
$query->where('company_city', '苏州市')
->where(function ($q) {
$q->where('company_area', '高新区')
->orWhere('company_area', '虎丘区');
});
});
})->get();
} elseif ($area === '苏州市外') {
// 苏州市外:统计除了苏州之外的所有数据
$sourseSignList2 = (clone $courseSignList)->whereHas('user', function ($query) {
$query->whereHas('company', function ($query) {
$query->where('company_city', '!=', '苏州市');
});
})->get();
} else {
// 其他区域:正常统计
$sourseSignList2 = (clone $courseSignList)->whereHas('user', function ($query) use ($area) {
$query->whereHas('company', function ($query) use ($area) {
$query->where('company_city', '苏州市')
->where('company_area', 'like', '%' . $area . '%');
});
})->get();
}
$list[] = [
'area' => $area,
// 未去重
'total' => $sourseSignList2->count(),
// 已去重
'total_unique' => User::whereIn('id', $sourseSignList2->pluck('user_id'))->groupBy('mobile')->get()->count(),
];
}
if ($retList) {
// 返回列表
return $list;
} else {
// 返回统计数据
return $courseSignList->get();
}
}
/**
* 获取区域数据(统计或导出)
* @param string $start_date 开始日期
* @param string $end_date 结束日期
* @param int|null $status 状态1表示审核通过
* @param array|null $course_ids 课程ID数组
* @param bool $is_schoolmate 是否只统计校友
* @param string $returnType 返回类型:'statistics' 返回统计数据,'export' 返回导出数据
* @return array
*/
public static function getAreaData($start_date, $end_date, $status = 1, $course_ids = null, $is_schoolmate = false, $returnType = 'statistics')
{
$courseSignList = self::getStudentList($start_date, $end_date, $status, $course_ids);
// 如果只统计校友,添加校友筛选条件
if ($is_schoolmate) {
$courseSignList->whereHas('user', function ($query) {
$query->where('is_schoolmate', 1);
});
}
// 从数据字典获取区域列表
$suzhouAreas = ParameterDetail::where('parameter_id', 5)
->where('status', 1)
->orderBy('sort', 'asc')
->pluck('value')
->toArray();
$result = [];
foreach ($suzhouAreas as $area) {
// 根据区域获取对应的CourseSign记录
if ($area === '高新区') {
// 高新区:统计高新区+虎丘区
$areaCourseSigns = (clone $courseSignList)->whereHas('user', function ($query) {
$query->whereHas('company', function ($query) {
$query->where('company_city', '苏州市')
->where(function ($q) {
$q->where('company_area', '高新区')
->orWhere('company_area', '虎丘区');
});
});
})->get();
} elseif ($area === '苏州市外') {
// 苏州市外:统计除了苏州之外的所有数据
$areaCourseSigns = (clone $courseSignList)->whereHas('user', function ($query) {
$query->whereHas('company', function ($query) {
$query->where('company_city', '!=', '苏州市');
});
})->get();
} else {
// 其他区域:正常统计
$areaCourseSigns = (clone $courseSignList)->whereHas('user', function ($query) use ($area) {
$query->whereHas('company', function ($query) use ($area) {
$query->where('company_city', '苏州市')
->where('company_area', 'like', '%' . $area . '%');
});
})->get();
}
if ($returnType === 'statistics') {
// 返回统计数据
$result[] = [
'area' => $area,
// 未去重
'total' => $areaCourseSigns->count(),
// 已去重
'total_unique' => User::whereIn('id', $areaCourseSigns->pluck('user_id'))->groupBy('mobile')->get()->count(),
];
} else {
// 返回导出数据(详细的学员列表)
// 加载关联关系
$areaCourseSigns->load(['user.company', 'course.typeDetail']);
// 将该区域下的学员明细添加到结果(一行一个学员)
foreach ($areaCourseSigns as $sign) {
$result[] = [
'company_name' => $sign->user->company->company_name ?? '',
'company_area' => $sign->user->company->company_area ?? '',
'company_city' => $sign->user->company->company_city ?? '',
'company_province' => $sign->user->company->company_province ?? '',
'company_address' => $sign->user->company->company_address ?? '',
'user_name' => $sign->user->name ?? '',
'mobile' => $sign->user->mobile ?? '',
'course_type' => $sign->course->typeDetail->name ?? '',
'course_name' => $sign->course->name ?? '',
];
}
}
}
return $result;
}
/**
* 元和员工参与人员user.from 包含「元和同事」的用户)
*/
public static function companyJoin($start_date = null, $end_date = null, $course_ids = null, $retList = false, $needHistory = true)
{
$courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids);
$courseSignByType = $courseSignsQuery->get();
$list = User::whereIn('id', $courseSignByType->pluck('user_id'))
->where('from', 'like', '%' . User::FROM_TAG_YUANHE_COLLEAGUE . '%')
->get();
if ($retList) {
// 返回列表
return $list;
} else {
// 基础数据
$baseCount = $list->count();
$employeeParticipations = 0;
if ($needHistory) {
// 额外数据
$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)->sum('total');
}
// 返回统计数据
return $baseCount + $employeeParticipations;
}
}
/**
* 干部参与(统计或列表)
* @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);
// 获取需要统计跟班学员的课程
$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 {
$baseCount = User::whereIn('id', $courseSigns->pluck('user_id'))->count();
// 额外数据
$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)->sum('total');
return $baseCount + $employeeParticipations;
}
}
/**
* 判断是否为苏州地区
* @param \App\Models\User|null $user 用户对象
* @param \App\Models\Company|null $company 公司对象
* @return bool
*/
public static function isSuzhou($user = null, $company = null)
{
// 判断是否为苏州地区关联公司的company_address包含"苏州"或company_city包含"苏州"
if ($company && $company->company_address && strpos($company->company_address, '苏州') !== false) {
return true;
}
if ($company && $company->company_city && strpos($company->company_city, '苏州') !== false) {
return true;
}
return false;
}
/**
* 头部企业(统计或列表)
* @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);
$courseSigns = $courseSignsQuery->with(['user.company'])->get();
// 获取所有高新技术企业的公司ID
$companyIds = $courseSigns->pluck('user.company.id')
->filter()
->unique()
->toArray();
// 获取这些公司中标记为高新技术企业的公司
$companies = Company::approvedStudents()->whereIn('id', $companyIds)
->where('company_tag', 'like', '%' . '高新技术企业' . '%')
->get()
->keyBy('id');
// 筛选苏州地区的公司
$suzhouCompanyIds = [];
foreach ($courseSigns as $courseSign) {
if (!$courseSign->user || !$courseSign->user->company) {
continue;
}
$companyId = $courseSign->user->company->id;
// 只处理高新技术企业的记录
if (!isset($companies[$companyId])) {
continue;
}
$user = $courseSign->user;
$company = $user->company;
// 使用通用方法判断是否为苏州地区
if (self::isSuzhou($user, $company)) {
$suzhouCompanyIds[$companyId] = true;
}
}
// 只保留苏州地区的高新技术企业
$suzhouCompanies = $companies->filter(function ($company) use ($suzhouCompanyIds) {
return isset($suzhouCompanyIds[$company->id]);
});
if ($retList) {
// 返回列表
return $suzhouCompanies->values();
} else {
// 返回统计数据
return count($suzhouCompanyIds);
}
}
/**
* 高层次人才
*/
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', '人才培训');
});
})->with(['user.company'])->get();
// 条件2data 字段中 name="个人荣誉" 且 value != "其他" 的用户
$courseSigns2 = $courseSignsQuery->with(['user.company'])->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();
// 筛选苏州地区的用户
$suzhouUserIds = [];
$allCourseSigns = $courseSigns1->merge($courseSigns2);
foreach ($allCourseSigns as $courseSign) {
if (!$courseSign->user) {
continue;
}
$userId = $courseSign->user->id;
// 只处理符合条件的用户
if (!in_array($userId, $allUserIds->toArray())) {
continue;
}
$user = $courseSign->user;
$company = $user->company;
// 使用通用方法判断是否为苏州地区
if (self::isSuzhou($user, $company)) {
$suzhouUserIds[$userId] = true;
}
}
// 只保留苏州地区的用户ID
$suzhouUserIds = array_keys($suzhouUserIds);
if ($retList) {
return User::whereIn('id', $suzhouUserIds)->get();
} else {
return count($suzhouUserIds);
}
}
/**
* 上市公司(统计或列表)
* @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::approvedStudents()->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 suzhoushangshi($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::approvedStudents()->whereIn('id', $companyIds)
->where('company_market', 1)
->get()
->keyBy('id');
// 筛选苏州地区的公司
$suzhouCompanyIds = [];
foreach ($courseSigns as $courseSign) {
if (!$courseSign->user || !$courseSign->user->company) {
continue;
}
$companyId = $courseSign->user->company->id;
// 只处理上市公司的记录
if (!isset($companies[$companyId])) {
continue;
}
$user = $courseSign->user;
$company = $user->company;
// 使用通用方法判断是否为苏州地区
if (self::isSuzhou($user, $company)) {
$suzhouCompanyIds[$companyId] = true;
}
}
// 只保留苏州地区的上市公司
$suzhouCompanies = $companies->filter(function ($company) use ($suzhouCompanyIds) {
return isset($suzhouCompanyIds[$company->id]);
});
if ($retList) {
// 返回详细列表:主表是公司,子数据是学员信息
$result = [];
foreach ($courseSigns as $courseSign) {
if (!$courseSign->user || !$courseSign->user->company) {
continue;
}
$companyId = $courseSign->user->company->id;
// 只处理苏州上市公司的记录
if (!isset($suzhouCompanyIds[$companyId])) {
continue;
}
$company = $suzhouCompanies[$companyId] ?? $courseSign->user->company;
// 如果公司还没有在结果中,初始化
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 count($suzhouCompanyIds);
}
}
/**
* 苏州重点上市公司(统计或列表)
* 在上市公司基础上,限定为苏州地区的公司
* 条件user表的company_address包含"苏州"或关联公司的company_address包含"苏州"或company_city包含"苏州"
* @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 suzhouStock($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::approvedStudents()->whereIn('id', $companyIds)
->where('company_market', 1)
->get()
->keyBy('id');
// 筛选苏州地区的公司
$suzhouCompanyIds = [];
foreach ($courseSigns as $courseSign) {
if (!$courseSign->user || !$courseSign->user->company) {
continue;
}
$companyId = $courseSign->user->company->id;
// 只处理上市公司的记录
if (!isset($companies[$companyId])) {
continue;
}
$user = $courseSign->user;
$company = $user->company;
// 判断是否为苏州地区user表的company_address包含"苏州"或关联公司的company_address包含"苏州"或company_city包含"苏州"
$isSuzhou = false;
if ($user->company_address && strpos($user->company_address, '苏州') !== false) {
$isSuzhou = true;
} elseif ($company->company_address && strpos($company->company_address, '苏州') !== false) {
$isSuzhou = true;
} elseif ($company->company_city && strpos($company->company_city, '苏州') !== false) {
$isSuzhou = true;
}
if ($isSuzhou) {
$suzhouCompanyIds[$companyId] = true;
}
}
// 只保留苏州地区的上市公司
$suzhouCompanies = $companies->filter(function ($company) use ($suzhouCompanyIds) {
return isset($suzhouCompanyIds[$company->id]);
});
if ($retList) {
// 返回详细列表:主表是公司,子数据是学员信息
$result = [];
foreach ($courseSigns as $courseSign) {
if (!$courseSign->user || !$courseSign->user->company) {
continue;
}
$companyId = $courseSign->user->company->id;
// 只处理苏州上市公司的记录
if (!isset($suzhouCompanyIds[$companyId])) {
continue;
}
$company = $suzhouCompanies[$companyId] ?? $courseSign->user->company;
// 如果公司还没有在结果中,初始化
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 count($suzhouCompanyIds);
}
}
/**
* 今年上市公司(统计或列表)
* @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();
}
}
}