master
cody 4 months ago
parent c888a9ad58
commit 9863a23eb9

@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
use App\Exports\BaseExport;
use App\Helpers\ResponseCode;
use App\Models\Course;
use App\Models\CustomForm;
use App\Models\CustomFormField;
use App\Models\EmployeeParticipation;
@ -245,28 +246,58 @@ class EmployeeParticipationController extends BaseController
$tempFile = $file->getRealPath();
$dataArray = (new FastExcel)->import($tempFile)->toArray();
// 固定的字段映射Excel表头中文 => 数据库字段名)
$fieldMapping = [
'类型' => 'type',
'开始日期' => 'start_date',
'结束日期' => 'end_date',
'数量' => 'total',
'课程类型ID' => 'course_type_id',
'课程ID' => 'course_id',
'课程名称' => 'course_name',
'公司名字' => 'company_name',
'姓名' => 'name',
'部门' => 'department',
// 类型映射:中文 => 数字
$typeMapping = [
'元和员工参与' => 1,
'干部培训' => 2,
];
// 类型名称映射:数字 => 中文
$typeNameMapping = [
1 => '元和员工参与',
2 => '干部培训',
];
$list = [];
foreach ($dataArray as $key => $value) {
$list[$key] = [];
// 根据固定字段映射转换数据
foreach ($fieldMapping as $excelHeader => $dbField) {
if (isset($value[$excelHeader])) {
$list[$key][$dbField] = $value[$excelHeader];
}
// 只读取 Excel 中的字段:类型、课程名称、公司名称、姓名、部门
$courseName = $value['课程名称'] ?? null;
$typeText = $value['类型'] ?? null;
// 转换类型:中文 -> 数字
$type = null;
if ($typeText) {
$type = $typeMapping[$typeText] ?? null;
}
// 根据课程名称查找课程信息
$course = null;
if ($courseName) {
$course = Course::where('name', $courseName)->first();
}
// 填充基础字段
$list[$key]['type'] = $type;
$list[$key]['type_name'] = $type ? ($typeNameMapping[$type] ?? '') : '';
$list[$key]['course_name'] = $courseName;
$list[$key]['company_name'] = $value['公司名称'] ?? null;
$list[$key]['name'] = $value['姓名'] ?? null;
$list[$key]['department'] = $value['部门'] ?? null;
// 根据课程信息填充其他字段
if ($course) {
$list[$key]['start_date'] = $course->start_date;
$list[$key]['end_date'] = $course->end_date;
$list[$key]['course_type_id'] = $course->type;
$list[$key]['course_id'] = $course->id;
} else {
// 如果找不到课程,字段设为 null
$list[$key]['start_date'] = null;
$list[$key]['end_date'] = null;
$list[$key]['course_type_id'] = null;
$list[$key]['course_id'] = null;
}
}
return $this->success($list);

@ -134,8 +134,8 @@ class OtherController extends CommonController
// 校友总数
$list['schoolmate_total'] = User::where('is_schoolmate', 1)->count();
// 今年新增校友数
$list['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->count();
// 今年新增校友数根据schoolmate_time字段统计
$list['schoolmate_year'] = User::where('is_schoolmate', 1)->whereYear('schoolmate_time', date('Y'))->count();
// 投后企业
$list['company_invested_total'] = CourseSign::yhInvestedTotal(CourseType::START_DATE, date('Y-m-d'), null);
// 元和员工参与人数
@ -318,20 +318,25 @@ class OtherController extends CommonController
// 跟班学员数在指定时间范围内报名的学员中from为'跟班学员'的数量)
$list['ganbu_total'] = CourseSign::genban($start_date, $end_date, $course_ids);
// 今年上市公司数量从stock_companys表获取stock_date在今年
$currentYear = date('Y');
$list['company_market_year_total'] = StockCompany::whereYear('stock_date', $currentYear)->count();
// 当前上市公司数量从stock_companys表获取stock_date在指定时间范围内
$list['company_market_year_total'] = StockCompany::getByDateRange($start_date, $end_date);
// 入学后上市公司数量从stock_companys表获取is_after_enrollment = 1
$list['company_market_after_enrollment_total'] = StockCompany::where('is_after_enrollment', 1)->count();
// 入学后上市公司数量从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);
// 元和员工参与人数
@ -1101,8 +1106,7 @@ class OtherController extends CommonController
case 'company_market_year_total':
// 今年上市公司明细 - 从stock_companys表获取与coursesHome统计逻辑保持一致
$currentYear = date('Y');
$stockCompanies = StockCompany::with('company')->whereYear('stock_date', $currentYear)->get();
$stockCompanies = StockCompany::getByDateRange($start_date, $end_date, true)->load('company');
foreach ($stockCompanies as $stockCompany) {
// 通过company_id关联到Company表获取详细信息
@ -1222,7 +1226,7 @@ class OtherController extends CommonController
case 'company_market_after_enrollment_total':
// 入学后上市公司明细 - 从stock_companys表获取与coursesHome统计逻辑保持一致
$stockCompanies = StockCompany::with('company')->where('is_after_enrollment', 1)->get();
$stockCompanies = StockCompany::getAfterEnrollment($start_date, $end_date, true)->load('company');
foreach ($stockCompanies as $stockCompany) {
// 通过company_id关联到Company表获取详细信息

@ -188,33 +188,6 @@ class CourseSign extends SoftDeletesModel
$companies = Company::approvedStudents()->whereHas('users', function ($query) use ($userIds) {
$query->whereIn('id', $userIds);
})->where('is_yh_invested', 1)->get();
// 自定义时间:需要按被投时间筛选
// 筛选出被投时间在范围内的企业
$filteredCompanies = [];
foreach ($companies as $company) {
$projectUsers = $company->project_users ?? [];
$hasValidInvestDate = false;
$allInvestDatesNull = true;
foreach ($projectUsers as $item) {
$investDate = $item['investDate'] ?? null;
// 检查是否有有效的被投时间
if ($investDate) {
$allInvestDatesNull = false;
// 检查被投时间是否在范围内
if ($investDate <= $end_date) {
$hasValidInvestDate = true;
break; // 只要有一条满足就加入
}
}
}
// 如果有有效的被投时间在范围内或者所有被投时间都是null则加入结果
if ($hasValidInvestDate || $allInvestDatesNull) {
$filteredCompanies[] = $company;
}
}
$companies = collect($filteredCompanies);
// 返回结果
if ($retList) {
@ -482,63 +455,84 @@ class CourseSign extends SoftDeletesModel
}
/**
* 入学后被投企业数量(在指定时间范围内报名的学员所在公司中,在入学后被投的公司数量)
* 当前入学后被投企业数量(被投时间在指定时间范围内,且学员入学时间小于等于被投时间的公司数量)
* @param string $start_date 开始日期
* @param string $end_date 结束日期
* @param array|null $course_ids 课程ID数组,不传则统计所有课程
* @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', 'course'])->get();
// 获取所有被投企业
$companies = Company::approvedStudents()->where('is_yh_invested', 1)->get();
$companiesAfterEnrollment = [];
foreach ($courseSignsForInvest as $sign) {
if ($sign->user && $sign->user->company && $sign->user->company->is_yh_invested == 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;
}
foreach ($companies as $company) {
$projectUsers = $company->project_users ?? [];
// 从 project_users 中检查是否有任何一个被投时间 >= 课程开始时间(入学时间)
$projectUsers = $sign->user->company->project_users;
$hasInvestAfterEnrollment = false;
$investDate = null;
if (!empty($projectUsers) && is_array($projectUsers)) {
foreach ($projectUsers as $projectUser) {
if (!empty($projectUser['investDate'])) {
$currentInvestDate = $projectUser['investDate'];
// 只要有一个被投时间 >= 课程开始时间(入学时间),就满足条件
if ($currentInvestDate >= $enrollmentDate) {
$hasInvestAfterEnrollment = true;
// 记录满足条件的被投时间(如果有多个,记录最早的)
if ($investDate === null || $currentInvestDate < $investDate) {
$investDate = $currentInvestDate;
// 遍历被投时间,找到在指定时间范围内的被投时间
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 ($hasInvestAfterEnrollment && $investDate) {
$companyId = $sign->user->company->id;
if (!isset($companiesAfterEnrollment[$companyId])) {
$companiesAfterEnrollment[$companyId] = [
'company' => $sign->user->company,
'first_enrollment_date' => $enrollmentDate, // 首次入学时间(课程开始时间)
'invest_date' => $investDate,
'users' => [],
];
}
if ($retList) {
$companiesAfterEnrollment[$companyId]['users'][] = $sign->user;
// 如果有学员的入学时间小于等于被投时间,则计入统计
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; // 只要有一个被投时间满足条件即可
}
}
}
@ -630,18 +624,22 @@ class CourseSign extends SoftDeletesModel
}
}
// 如果 config 中没有数据,使用空数组(避免 SQL 错误)
// 如果 config 中没有数据,直接返回空
if (empty($companyNameKeyword)) {
$list = collect([]);
} else {
$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 collect([]);
} else {
return 0;
}
}
$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;
@ -708,10 +706,7 @@ class CourseSign extends SoftDeletesModel
*/
public static function isSuzhou($user = null, $company = null)
{
// 判断是否为苏州地区user表的company_address包含"苏州"或关联公司的company_address包含"苏州"或company_city包含"苏州"
if ($user && $user->company_address && strpos($user->company_address, '苏州') !== false) {
return true;
}
// 判断是否为苏州地区关联公司的company_address包含"苏州"或company_city包含"苏州"
if ($company && $company->company_address && strpos($company->company_address, '苏州') !== false) {
return true;
}

@ -27,5 +27,46 @@ class StockCompany extends SoftDeletesModel
{
return $this->belongsTo(Company::class, 'company_id', 'id');
}
/**
* 获取指定时间范围内的上市公司数量(统计或列表)
* @param string|null $start_date 开始日期
* @param string|null $end_date 结束日期
* @param bool $retList 是否返回列表false返回数量true返回列表
* @return int|\Illuminate\Database\Eloquent\Collection
*/
public static function getByDateRange($start_date = null, $end_date = null, $retList = false)
{
$query = self::when($start_date && $end_date, function ($query) use ($start_date, $end_date) {
$query->whereBetween('stock_date', [$start_date, $end_date]);
});
if ($retList) {
return $query->get();
} else {
return $query->count();
}
}
/**
* 获取入学后上市的公司数量(统计或列表)
* @param string|null $start_date 开始日期
* @param string|null $end_date 结束日期
* @param bool $retList 是否返回列表false返回数量true返回列表
* @return int|\Illuminate\Database\Eloquent\Collection
*/
public static function getAfterEnrollment($start_date = null, $end_date = null, $retList = false)
{
$query = self::where('is_after_enrollment', 1)
->when($start_date && $end_date, function ($query) use ($start_date, $end_date) {
$query->whereBetween('stock_date', [$start_date, $end_date]);
});
if ($retList) {
return $query->get();
} else {
return $query->count();
}
}
}

Loading…
Cancel
Save