master
lion 5 months ago
commit 2a04a1f0a3

@ -20,7 +20,30 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
public $fields;
public $data;
public $hasUsersField = false;
public $usersColumnIndex = null;
public $hasProjectUsersField = false;
public $totalColumns = 0;
public $totalRows = 0;
public $expandedFields = [];
// 学员信息子列定义
const USERS_SUB_COLUMNS = [
'user_index' => '序号',
'user_no' => '学号',
'user_name' => '姓名',
'user_schoolmate' => '校友',
'user_position' => '职位',
'user_mobile' => '手机',
'user_course' => '报名课程',
'user_sign_date' => '报名时间',
];
// 项目经理信息子列定义
const PROJECT_USERS_SUB_COLUMNS = [
'pm_platform' => '管理平台',
'pm_name' => '项目经理',
'pm_invest_date' => '首次出资时间',
'pm_amount' => '投资金额',
];
public function __construct($data, $exportFields)
{
@ -29,17 +52,49 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
// 数据
$this->data = $data;
// 检查是否有 users 字段
if (is_array($exportFields)) {
$index = 1;
foreach (array_keys($exportFields) as $field) {
if (str_contains($field, 'users')) {
$this->hasUsersField = true;
$this->usersColumnIndex = $this->getColumnLetter($index);
// 构建扩展后的字段列表
$this->buildExpandedFields();
}
/**
* 构建扩展后的字段列表将users和project_users字段展开成多列
*/
private function buildExpandedFields()
{
if (!is_array($this->fields)) {
return;
}
$index = 1;
foreach ($this->fields as $field => $label) {
if (str_contains($field, 'users') && !str_contains($field, 'project_users')) {
$this->hasUsersField = true;
// 展开学员信息为多列
foreach (self::USERS_SUB_COLUMNS as $subField => $subLabel) {
$this->expandedFields[$subField] = $subLabel;
$index++;
}
} elseif (str_contains($field, 'project_users')) {
$this->hasProjectUsersField = true;
// 展开项目经理信息为多列
foreach (self::PROJECT_USERS_SUB_COLUMNS as $subField => $subLabel) {
$this->expandedFields[$subField] = $subLabel;
$index++;
}
} else {
$this->expandedFields[$field] = $label;
$index++;
}
}
$this->totalColumns = count($this->expandedFields);
}
/**
* 是否需要二级表头
*/
private function needsDoubleHeader()
{
return $this->hasUsersField || $this->hasProjectUsersField;
}
/**
@ -63,22 +118,23 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
{
$widths = [];
$index = 1;
foreach (array_keys($this->fields) as $field) {
foreach (array_keys($this->expandedFields) as $field) {
$letter = $this->getColumnLetter($index);
if (str_contains($field, 'users')) {
// 学员信息列设置较宽
$widths[$letter] = 80;
} elseif (str_contains($field, 'partners') || str_contains($field, 'project_users')) {
// 股东和项目经理列
if (in_array($field, ['user_course', 'user_name'])) {
$widths[$letter] = 25;
} elseif (in_array($field, ['user_mobile', 'user_sign_date', 'pm_invest_date', 'pm_amount'])) {
$widths[$letter] = 15;
} elseif (in_array($field, ['user_index', 'user_schoolmate'])) {
$widths[$letter] = 8;
} elseif (in_array($field, ['pm_platform', 'pm_name'])) {
$widths[$letter] = 18;
} elseif (str_contains($field, 'partners')) {
$widths[$letter] = 50;
} elseif (str_contains($field, 'all_course')) {
// 课程列
$widths[$letter] = 40;
} elseif (str_contains($field, 'company_name') || str_contains($field, 'address')) {
// 公司名称和地址
$widths[$letter] = 30;
} else {
// 默认列宽
$widths[$letter] = 15;
}
$index++;
@ -91,13 +147,14 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
*/
public function styles(Worksheet $sheet): array
{
$rowCount = count($this->data) + 1; // 数据行数 + 表头
$colCount = count($this->fields);
$lastCol = $this->getColumnLetter($colCount);
$lastCol = $this->getColumnLetter($this->totalColumns);
$dataStartRow = $this->needsDoubleHeader() ? 3 : 2;
return [
// 表头样式
1 => [
$styles = [];
if ($this->needsDoubleHeader()) {
// 二级表头样式 - 第一行
$styles[1] = [
'font' => ['bold' => true, 'size' => 12],
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
@ -105,23 +162,51 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['rgb' => 'E0E0E0'],
'startColor' => ['rgb' => 'D0D0D0'],
],
],
// 所有数据区域样式
"A1:{$lastCol}{$rowCount}" => [
];
// 二级表头样式 - 第二行
$styles[2] = [
'font' => ['bold' => true, 'size' => 11],
'alignment' => [
'vertical' => Alignment::VERTICAL_TOP,
'wrapText' => true, // 自动换行
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
'borders' => [
'allBorders' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['rgb' => 'CCCCCC'],
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['rgb' => 'E8E8E8'],
],
];
} else {
// 单行表头样式
$styles[1] = [
'font' => ['bold' => true, 'size' => 12],
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['rgb' => 'E0E0E0'],
],
];
}
// 所有数据区域样式
$styles["A1:{$lastCol}" . ($this->totalRows + $dataStartRow - 1)] = [
'alignment' => [
'vertical' => Alignment::VERTICAL_CENTER,
'wrapText' => true,
],
'borders' => [
'allBorders' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['rgb' => 'CCCCCC'],
],
],
];
return $styles;
}
/**
@ -132,34 +217,62 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
return [
AfterSheet::class => function (AfterSheet $event) {
$sheet = $event->sheet->getDelegate();
$rowCount = count($this->data) + 1;
// 设置表头行高
$sheet->getRowDimension(1)->setRowHeight(25);
// 遍历数据行,根据内容设置行高
for ($row = 2; $row <= $rowCount; $row++) {
// 获取该行的最大内容行数
$maxLines = 1;
foreach (array_keys($this->fields) as $index => $field) {
$col = $this->getColumnLetter($index + 1);
$cellValue = $sheet->getCell($col . $row)->getValue();
if ($cellValue) {
$lines = substr_count($cellValue, "\n") + 1;
$maxLines = max($maxLines, $lines);
}
}
// 设置行高每行内容约15像素最小20最大400
$rowHeight = min(400, max(20, $maxLines * 15));
$sheet->getRowDimension($row)->setRowHeight($rowHeight);
if ($this->needsDoubleHeader()) {
// 处理二级表头的单元格合并
$this->mergeHeaderCells($sheet);
// 设置表头行高
$sheet->getRowDimension(1)->setRowHeight(25);
$sheet->getRowDimension(2)->setRowHeight(22);
// 冻结前两行
$sheet->freezePane('A3');
} else {
$sheet->getRowDimension(1)->setRowHeight(25);
$sheet->freezePane('A2');
}
// 冻结首行
$sheet->freezePane('A2');
// 设置数据行高
$dataStartRow = $this->needsDoubleHeader() ? 3 : 2;
for ($row = $dataStartRow; $row <= $this->totalRows + $dataStartRow - 1; $row++) {
$sheet->getRowDimension($row)->setRowHeight(22);
}
},
];
}
/**
* 合并表头单元格
*/
private function mergeHeaderCells(Worksheet $sheet)
{
$index = 1;
foreach ($this->fields as $field => $label) {
if (str_contains($field, 'users') && !str_contains($field, 'project_users')) {
// 学员信息列:合并第一行的多个单元格
$startCol = $this->getColumnLetter($index);
$endCol = $this->getColumnLetter($index + count(self::USERS_SUB_COLUMNS) - 1);
$sheet->mergeCells("{$startCol}1:{$endCol}1");
$sheet->setCellValue("{$startCol}1", $label);
$index += count(self::USERS_SUB_COLUMNS);
} elseif (str_contains($field, 'project_users')) {
// 项目经理信息列:合并第一行的多个单元格
$startCol = $this->getColumnLetter($index);
$endCol = $this->getColumnLetter($index + count(self::PROJECT_USERS_SUB_COLUMNS) - 1);
$sheet->mergeCells("{$startCol}1:{$endCol}1");
$sheet->setCellValue("{$startCol}1", $label);
$index += count(self::PROJECT_USERS_SUB_COLUMNS);
} else {
// 其他列:合并第一行和第二行
$col = $this->getColumnLetter($index);
$sheet->mergeCells("{$col}1:{$col}2");
$sheet->setCellValue("{$col}1", $label);
$index++;
}
}
}
/**
* 数组转集合
* @throws ErrorException
@ -173,65 +286,222 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
if (!is_array($this->fields)) {
throw new ErrorException('导出字段必须是数组');
}
// 获取表头
$header = array_values($this->fields);
$moreFileds = [];
if (empty($clear)) {
// 表头追加附属数据
if (isset($this->data[0]['data']) && is_array($this->data[0]['data'])) {
$moreHeader = array_column($this->data[0]['data'], 'name');
// 获取头信息
$header = array_merge($header, $moreHeader);
// 获取字段信息
$moreFileds = array_column($this->data[0]['data'], 'field');
}
}
// 获取字段指向
$fields = array_keys($this->fields);
$newList = [];
foreach ($this->data as $info) {
$temp = [];
foreach ($fields as $field) {
if (str_contains($field, 'idcard')) {
// 身份证
$temp[$field] = ' ' . $this->getDotValue($info, $field);
} elseif (str_contains($field, 'all_course')) {
// 所有课程
$temp[$field] = $this->allCourse($info);
} elseif (str_contains($field, 'partners')) {
// 股东信息
$temp[$field] = $this->partners($info);
if ($this->needsDoubleHeader()) {
// 有需要展开的字段:创建二级表头
// 第一行表头(主表头)- 在 mergeHeaderCells 中处理
$header1 = [];
foreach ($this->fields as $field => $label) {
if (str_contains($field, 'users') && !str_contains($field, 'project_users')) {
foreach (self::USERS_SUB_COLUMNS as $subLabel) {
$header1[] = '';
}
} elseif (str_contains($field, 'project_users')) {
// 项目经理
$temp[$field] = $this->projectManager($info);
} elseif (str_contains($field, 'users')) {
// 学员信息
$temp[$field] = $this->getUsers($info);
foreach (self::PROJECT_USERS_SUB_COLUMNS as $subLabel) {
$header1[] = '';
}
} else {
$temp[$field] = $this->getDotValue($info, $field);
$header1[] = '';
}
}
// 如果有自定义数据,全部附件上去
$t2 = [];
$newList[] = $header1;
// 第二行表头(子表头)
$header2 = [];
foreach ($this->fields as $field => $label) {
if (str_contains($field, 'users') && !str_contains($field, 'project_users')) {
foreach (self::USERS_SUB_COLUMNS as $subLabel) {
$header2[] = $subLabel;
}
} elseif (str_contains($field, 'project_users')) {
foreach (self::PROJECT_USERS_SUB_COLUMNS as $subLabel) {
$header2[] = $subLabel;
}
} else {
$header2[] = '';
}
}
$newList[] = $header2;
// 数据行:每个展开记录占一行
foreach ($this->data as $info) {
$expandedRows = $this->getExpandedRows($info);
if (empty($expandedRows)) {
// 没有展开数据,输出一行空数据
$row = $this->buildExpandedRow($info, [], []);
$newList[] = $row;
} else {
foreach ($expandedRows as $expandedRow) {
$row = $this->buildExpandedRow($info, $expandedRow['users'] ?? [], $expandedRow['project_users'] ?? []);
$newList[] = $row;
}
}
}
} else {
// 没有需要展开的字段:使用原有逻辑
$header = array_values($this->fields);
$moreFileds = [];
if (empty($clear)) {
if (isset($info['data']) && $info['data'] && !empty($moreFileds)) {
$dataCollect = collect($info['data']);
foreach ($moreFileds as $moreFiled) {
$value = ($dataCollect->where('field', $moreFiled)->first()['value']) ?? '';
if (str_contains($moreFiled, 'idcard')) {
$t2[$moreFiled] = ' ' . $value;
} else {
$t2[$moreFiled] = $value;
if (isset($this->data[0]['data']) && is_array($this->data[0]['data'])) {
$moreHeader = array_column($this->data[0]['data'], 'name');
$header = array_merge($header, $moreHeader);
$moreFileds = array_column($this->data[0]['data'], 'field');
}
}
$newList[] = $header;
foreach ($this->data as $info) {
$temp = [];
foreach (array_keys($this->fields) as $field) {
if (str_contains($field, 'idcard')) {
$temp[$field] = ' ' . $this->getDotValue($info, $field);
} elseif (str_contains($field, 'all_course')) {
$temp[$field] = $this->allCourse($info);
} elseif (str_contains($field, 'partners')) {
$temp[$field] = $this->partners($info);
} else {
$temp[$field] = $this->getDotValue($info, $field);
}
}
$t2 = [];
if (empty($clear)) {
if (isset($info['data']) && $info['data'] && !empty($moreFileds)) {
$dataCollect = collect($info['data']);
foreach ($moreFileds as $moreFiled) {
$value = ($dataCollect->where('field', $moreFiled)->first()['value']) ?? '';
if (str_contains($moreFiled, 'idcard')) {
$t2[$moreFiled] = ' ' . $value;
} else {
$t2[$moreFiled] = $value;
}
}
}
}
$newList[] = array_values($temp + $t2);
}
$newList[] = $temp + $t2;
}
array_unshift($newList, $header); //插入表头
$this->totalRows = count($newList) - ($this->needsDoubleHeader() ? 2 : 1);
return new Collection($newList);
}
/**
* 获取展开后的所有行数据
*/
private function getExpandedRows($info)
{
$usersData = $this->hasUsersField ? $this->getUsersExpanded($info) : [];
$projectUsersData = $this->hasProjectUsersField ? $this->getProjectUsersExpanded($info) : [];
// 计算最大行数
$maxRows = max(count($usersData), count($projectUsersData), 1);
$result = [];
for ($i = 0; $i < $maxRows; $i++) {
$result[] = [
'users' => $usersData[$i] ?? [],
'project_users' => $projectUsersData[$i] ?? [],
];
}
return $result;
}
/**
* 获取展开的项目经理数据(每条记录一行)
*/
private function getProjectUsersExpanded($info)
{
if (empty($info['project_users'])) {
return [];
}
$result = [];
foreach ($info['project_users'] as $item) {
$result[] = [
'pm_platform' => $item['groupName'] ?? '-',
'pm_name' => $item['userName'] ?? '-',
'pm_invest_date' => $item['investDate'] ?? '-',
'pm_amount' => $item['amount'] ?? '-',
];
}
return $result;
}
/**
* 获取展开的学员数据(每个学员每条课程一行)
*/
private function getUsersExpanded($info)
{
if (empty($info['users'])) {
return [];
}
$result = [];
$userIndex = 1;
foreach ($info['users'] as $user) {
if (!empty($user['course_signs'])) {
foreach ($user['course_signs'] as $signIndex => $sign) {
$result[] = [
'user_index' => $signIndex === 0 ? $userIndex : '',
'user_no' => $signIndex === 0 ? ($user['no'] ?? '-') : '',
'user_name' => $signIndex === 0 ? ($user['username'] ?? '-') : '',
'user_schoolmate' => $signIndex === 0 ? ($user['is_schoolmate_text'] ?? '-') : '',
'user_position' => $signIndex === 0 ? ($user['company_position'] ?? '-') : '',
'user_mobile' => $signIndex === 0 ? ($user['mobile'] ?? '-') : '',
'user_course' => $sign['course']['name'] ?? '-',
'user_sign_date' => isset($sign['created_at']) ? substr($sign['created_at'], 0, 10) : '-',
];
}
} else {
$result[] = [
'user_index' => $userIndex,
'user_no' => $user['no'] ?? '-',
'user_name' => $user['username'] ?? '-',
'user_schoolmate' => $user['is_schoolmate_text'] ?? '-',
'user_position' => $user['company_position'] ?? '-',
'user_mobile' => $user['mobile'] ?? '-',
'user_course' => '-',
'user_sign_date' => '-',
];
}
$userIndex++;
}
return $result;
}
/**
* 构建包含展开数据的行
*/
private function buildExpandedRow($info, $userData, $projectUserData)
{
$row = [];
foreach ($this->fields as $field => $label) {
if (str_contains($field, 'users') && !str_contains($field, 'project_users')) {
// 填充学员信息列
foreach (array_keys(self::USERS_SUB_COLUMNS) as $subField) {
$row[] = $userData[$subField] ?? '';
}
} elseif (str_contains($field, 'project_users')) {
// 填充项目经理信息列
foreach (array_keys(self::PROJECT_USERS_SUB_COLUMNS) as $subField) {
$row[] = $projectUserData[$subField] ?? '';
}
} elseif (str_contains($field, 'idcard')) {
$row[] = ' ' . $this->getDotValue($info, $field);
} elseif (str_contains($field, 'all_course')) {
$row[] = $this->allCourse($info);
} elseif (str_contains($field, 'partners')) {
$row[] = $this->partners($info);
} else {
$row[] = $this->getDotValue($info, $field);
}
}
return $row;
}
/**
* .号转数组层级并返回对应的值
* @param $key
@ -293,49 +563,9 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
{
$list = [];
foreach ($data['project_users'] as $item) {
$list[] = $item['groupName'] . '-' . ($item['userName'] ?? '') . '-' . ($item['investDate'] ?? '');
$list[] = $item['groupName'] . '-' . ($item['userName'] ?? '') . '-' . ($item['investDate'] ?? '') . '-' . ($item['amount'] ?? '');
}
return implode("、\r\n", $list);
}
/**
* 获取学员信息(优化显示格式)
* @param $data
*/
function getUsers($data)
{
if (empty($data['users'])) {
return '';
}
$list = [];
$index = 1;
foreach ($data['users'] as $item) {
// 基本信息行
$userInfo = [];
$userInfo[] = "【学员{$index}】";
$userInfo[] = "学号: " . ($item['no'] ?? '-');
$userInfo[] = "姓名: " . ($item['username'] ?? '-');
$userInfo[] = "校友: " . ($item['is_schoolmate_text'] ?? '-');
$userInfo[] = "职位: " . ($item['company_position'] ?? '-');
$userInfo[] = "手机: " . ($item['mobile'] ?? '-');
// 课程报名信息
if (!empty($item['course_signs'])) {
$userInfo[] = "报名课程:";
foreach ($item['course_signs'] as $signIndex => $sign) {
$courseName = $sign['course']['name'] ?? '-';
$signDate = $sign['created_at'] ?? '-';
$userInfo[] = " " . ($signIndex + 1) . ". {$courseName} ({$signDate})";
}
}
$list[] = implode("\n", $userInfo);
$index++;
}
// 用分隔线分隔不同学员
return implode("\n" . str_repeat("-", 40) . "\n", $list);
}
}

@ -50,7 +50,7 @@ class CalendarsController extends BaseController
public function index()
{
$all = \request()->all();
$list = Calendar::with('course', 'courseContent','historyCourses')
$list = Calendar::with('course', 'courseContent', 'historyCourses')
->where(function ($query) use ($all) {
if (isset($all['month'])) {
$query->where('start_time', 'like', $all['month'] . '%');
@ -61,7 +61,21 @@ class CalendarsController extends BaseController
$list = $list->toArray();
return Excel::download(new CommonExport($list, $all['export_fields'] ?? ''), ($all['file_name'] ?? '') . date('YmdHis') . '.xlsx');
}
return $this->success($list);
// 本月日历天数
$monthDayCalendar = Calendar::where(function ($query) use ($all) {
if (isset($all['month'])) {
$query->where('start_time', 'like', $all['month'] . '%');
}
})->where('is_count_days', 1)->sum('days');
// 本年日历天数
$yearDayCalendar = Calendar::where(function ($query) use ($all) {
if (isset($all['month'])) {
// 获取$all['month']的年份部分
$year = date('Y', strtotime($all['month']));
$query->where('start_time', 'like', $year . '%');
}
})->where('is_count_days', 1)->sum('days');
return $this->success(compact('list', 'monthDayCalendar', 'yearDayCalendar'));
}
/**

@ -141,7 +141,7 @@ class OtherController extends CommonController
// 重点上市公司
$list['cover_stock_total'] = CourseSign::shangshi();
// 本月课程
$monthCourses = Calendar::with('course.teacher')->where('type', 1)
$monthCourses = Calendar::with('course.teacher')
->where('date', 'like', '%' . date('Y-m') . '%')
->get();
// 课程统计
@ -222,7 +222,7 @@ class OtherController extends CommonController
$course_type_id = $params['course_type_id'];
$courses = $params['courses'];
// 被投企业数
$list['course_signs_invested'] = CourseSign::yhInvested($start_date, $end_date);
// $list['course_signs_invested'] = CourseSign::yhInvested($start_date, $end_date, $courses->pluck('id')->toArray());
// 报名人数
$list['course_signs_total'] = CourseSign::courseSignsTotal($start_date, $end_date, null, $courses->pluck('id'));
// 审核通过人数
@ -233,10 +233,14 @@ class OtherController extends CommonController
$calendar = Calendar::where(function ($query) use ($start_date, $end_date) {
$query->whereBetween('start_time', [$start_date, $end_date])
->orWhereBetween('end_time', [$start_date, $end_date]);
})->whereIn('course_id', $courses->pluck('id'));
})->where(function ($query) use ($courses) {
if (request('course_type_id')) {
$query->whereIn('course_id', $courses->pluck('id'));
}
});
$list['course_total'] = (clone $calendar)->count();
// 开课天数
$list['course_day_total'] = (clone $calendar)->sum('days');
$list['course_day_total'] = (clone $calendar)->where('is_count_days', 1)->sum('days');
// 上市公司数(所有上市公司)
$list['company_market_total'] = Company::companyMarket($start_date, $end_date);
@ -272,7 +276,7 @@ class OtherController extends CommonController
foreach ($courseTypes as $courseType) {
// 获取课程
$courses2 = Course::where('type', $courseType->id)
->whereHas('course', function ($query) use ($start_date, $end_date) {
->where(function ($query) use ($start_date, $end_date) {
// 开始结束日期的筛选。or查询
if ($start_date && $end_date) {
$query->whereBetween('start_date', [$start_date, $end_date])
@ -288,11 +292,19 @@ class OtherController extends CommonController
'course_type_signs_pass_unique' => CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $courses2->pluck('id'), null),
'course_name' => $course->name,
'course_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, [$course->id]),
// 跟班学员数量
'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id]),
// 被投企业数
'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]),
// 元禾同事数
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id]),
];
}
}
// 附加历史课程数据
$historyCourses = HistoryCourse::where(function ($query) use ($start_date, $end_date) {
$historyCourses = 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]);
@ -353,7 +365,7 @@ class OtherController extends CommonController
switch ($export_type) {
case 'course_signs_invested':
// 被投企业明细 - 使用与coursesHome相同的算法
$companies = CourseSign::yhInvested($start_date, $end_date, true);
$companies = CourseSign::yhInvested($start_date, $end_date, $course_ids, true);
foreach ($companies as $company) {
$data[] = [
'company_name' => $company->company_name,
@ -493,6 +505,9 @@ class OtherController extends CommonController
'course_type_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, $courses2->pluck('id')),
'course_type_signs_pass_unique' => CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, $courses2->pluck('id'), null),
'course_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, [$course->id]),
'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id]),
'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]),
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id]),
];
}
}
@ -502,6 +517,9 @@ class OtherController extends CommonController
'course_type_signs_pass' => '课程体系培养人数',
'course_type_signs_pass_unique' => '课程体系去重培养人数',
'course_signs_pass' => '课程培养人数',
'genban_total' => '跟班学员数',
'yh_invested_total' => '被投企业数',
'company_join_total' => '元禾同事数',
];
$filename = '课程分类明细';
break;
@ -573,6 +591,7 @@ class OtherController extends CommonController
'mobile' => $user->mobile ?? '',
'company_name' => $user->company_name ?? '',
'company_position' => $user->company_position ?? '',
'from' => $user->from ?? '',
];
}
$fields = [
@ -581,6 +600,7 @@ class OtherController extends CommonController
'mobile' => '手机号',
'company_name' => '企业名称',
'company_position' => '职位',
'from' => '标签',
];
$filename = '跟班学员明细';
break;
@ -677,8 +697,12 @@ class OtherController extends CommonController
case 'course_total':
// 开课场次明细 - 与coursesHome算法一致
$calendars = Calendar::whereIn('course_id', $course_ids)
->whereBetween('date', [$start_date, $end_date])
$calendars = Calendar::whereBetween('date', [$start_date, $end_date])
->where(function ($query) use ($course_ids) {
if (request('course_type_id')) {
$query->whereIn('course_id', $course_ids);
}
})
->with('course')
->get();
@ -705,8 +729,12 @@ class OtherController extends CommonController
case 'course_day_total':
// 开课天数明细 - 与coursesHome算法一致
$calendars = Calendar::whereIn('course_id', $course_ids)
->whereBetween('date', [$start_date, $end_date])
$calendars = Calendar::whereBetween('date', [$start_date, $end_date])
->where(function ($query) use ($course_ids) {
if (request('course_type_id')) {
$query->whereIn('course_id', $course_ids);
}
})->where('is_count_days', 1)
->with('course')
->get();

@ -110,7 +110,9 @@ class CourseSign extends SoftDeletesModel
// 基础数据
$baseTotal = $totalQuery->count();
// 历史数据
$historyTotal = HistoryCourse::where(function ($query) use ($start_date, $end_date) {
$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]);
@ -133,7 +135,9 @@ class CourseSign extends SoftDeletesModel
} else {
$baseTotal = $user->count();
// 历史数据
$historyTotal = HistoryCourse::where(function ($query) use ($start_date, $end_date) {
$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]);
@ -144,20 +148,57 @@ class CourseSign extends SoftDeletesModel
}
/**
* 指定时间内的被投企业
* 被投企业统计
* @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, $retList = false)
public static function yhInvested($start_date = null, $end_date = null, $course_ids = null, $retList = false)
{
$courseSignByTypeQuery = self::getStudentList($start_date, $end_date, 1, null);
$list = Company::whereHas('users', function ($query) use ($courseSignByTypeQuery) {
$query->whereIn('id', $courseSignByTypeQuery->get()->pluck('user_id'));
// 判断是否使用默认时间
$isDefaultDate = empty($start_date) || $start_date == CourseType::START_DATE || empty($course_ids);
dd(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 $list;
return $companies->values();
} else {
// 返回统计数据
return $list->count();
return $companies->count();
}
}
@ -173,7 +214,7 @@ class CourseSign extends SoftDeletesModel
{
$courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids);
$courseSigns = $courseSignsQuery->whereHas('user', function ($query) {
$query->where('from', '%' . '跟班学员' . '%');
$query->where('from', 'like', '%跟班学员%');
})->get();
if ($retList) {
@ -337,10 +378,21 @@ class CourseSign extends SoftDeletesModel
// 检测关键词
$companyNameKeyword = [
'元禾控股', '元禾原点', '元禾厚望', '元禾重元',
'元禾璞华', '元禾谷风', '元禾绿柳', '元禾辰坤', '元禾沙湖',
'禾裕集团', '苏州科服', '信诚管理咨询',
'集成电路公司', '常州团队', '国企元禾'
'元禾控股',
'元禾原点',
'元禾厚望',
'元禾重元',
'元禾璞华',
'元禾谷风',
'元禾绿柳',
'元禾辰坤',
'元禾沙湖',
'禾裕集团',
'苏州科服',
'信诚管理咨询',
'集成电路公司',
'常州团队',
'国企元禾'
];
$company = Company::where(function ($query) use ($companyNameKeyword) {
foreach ($companyNameKeyword as $item) {
@ -372,7 +424,7 @@ class CourseSign extends SoftDeletesModel
{
$courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids);
$courseSigns = $courseSignsQuery->whereHas('user', function ($query) {
$query->where('from', '%' . '跟班学员' . '%');
$query->where('from', 'like', '%跟班学员%');
})->get();
if ($retList) {
return User::with('company')->whereIn('id', $courseSigns->pluck('user_id'))->get();

@ -13,8 +13,8 @@ return new class extends Migration {
public function up()
{
Schema::table('calendars', function (Blueprint $table) {
$table->tinyInteger('is_count_days')->default(1)->comment('是否统计天数 0否 1是');
$table->tinyInteger('is_count_people')->default(1)->comment('是否统计人数 0否 1是');
$table->tinyInteger('is_count_days')->nullable()->comment('是否统计天数 0否 1是');
$table->tinyInteger('is_count_people')->nullable()->comment('是否统计人数 0否 1是');
});
}

Loading…
Cancel
Save