diff --git a/app/Console/Commands/UpdateUserNo.php b/app/Console/Commands/UpdateUserNo.php index 408f2cf..4e56e31 100755 --- a/app/Console/Commands/UpdateUserNo.php +++ b/app/Console/Commands/UpdateUserNo.php @@ -23,7 +23,7 @@ class UpdateUserNo extends Command * * @var string */ - protected $description = '批量更新学号'; + protected $description = '批量更新学号/打元和同事标签'; /** * Create a new command instance. @@ -42,6 +42,21 @@ class UpdateUserNo extends Command */ public function handle() { + // 1. 批量更新学号 + $this->updateUserNo(); + + // 2. 给元和同事打标签 + $this->tagYuanheColleague(); + + return $this->info('更新完成'); + } + + /** + * 批量更新学号 + */ + protected function updateUserNo() + { + $this->info('开始更新学号...'); // 已经开始的课程日期(所有历史数据处理) // $dateList = Course::whereNotNull('start_date') // ->where('start_date', '<=', date('Y-m-d')) @@ -52,9 +67,11 @@ class UpdateUserNo extends Command // 当日数据处理(日常定时任务) $dateList = [date('Y-m-d')]; foreach ($dateList as $date) { - $courses = Course::with(['courseSigns' => function ($query) { - $query->where('status', 1); - }])->where('start_date', $date) + $courses = Course::with([ + 'courseSigns' => function ($query) { + $query->where('status', 1); + } + ])->where('start_date', $date) ->whereNotNull('student_prefix') ->orderBy('start_date') ->get(); @@ -70,12 +87,50 @@ class UpdateUserNo extends Command // 更新用户编号 $user->no = $no; $user->save(); - $this->info($no); + $this->info('学号: ' . $no); $i++; } } } - return $this->info('更新完成'); + $this->info('学号更新完成'); + } + + /** + * 给元和同事打标签 + */ + protected function tagYuanheColleague() + { + $this->info('开始给元和同事打标签...'); + $tag = '元禾同事'; + + // 获取元和员工用户列表 + $users = CourseSign::companyJoin(null, null, null, true); + + $count = 0; + foreach ($users as $user) { + // 获取当前的 from 字段 + $from = $user->from ?? ''; + + // 将 from 字段按逗号分隔成数组 + $fromArray = array_filter(array_map('trim', explode(',', $from))); + + // 检查是否已存在该标签 + if (in_array($tag, $fromArray)) { + continue; + } + + // 追加标签 + $fromArray[] = $tag; + + // 更新 from 字段 + $user->from = implode(',', $fromArray); + $user->save(); + + $this->info('已为用户 ' . $user->name . '(' . $user->mobile . ') 添加标签: ' . $tag); + $count++; + } + + $this->info('元和同事标签更新完成,共更新 ' . $count . ' 人'); } } diff --git a/app/Exports/CommonExport.php b/app/Exports/CommonExport.php index 97daf33..c90a038 100755 --- a/app/Exports/CommonExport.php +++ b/app/Exports/CommonExport.php @@ -8,11 +8,19 @@ namespace App\Exports; use App\Exceptions\ErrorException; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\FromCollection; +use Maatwebsite\Excel\Concerns\WithStyles; +use Maatwebsite\Excel\Concerns\WithColumnWidths; +use Maatwebsite\Excel\Concerns\WithEvents; +use Maatwebsite\Excel\Events\AfterSheet; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; +use PhpOffice\PhpSpreadsheet\Style\Alignment; -class CommonExport implements FromCollection +class CommonExport implements FromCollection, WithStyles, WithColumnWidths, WithEvents { public $fields; public $data; + public $hasUsersField = false; + public $usersColumnIndex = null; public function __construct($data, $exportFields) { @@ -20,8 +28,137 @@ class CommonExport implements FromCollection $this->fields = $exportFields; // 数据 $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); + } + $index++; + } + } + } + + /** + * 获取列字母 + */ + private function getColumnLetter($columnNumber) + { + $letter = ''; + while ($columnNumber > 0) { + $columnNumber--; + $letter = chr(65 + ($columnNumber % 26)) . $letter; + $columnNumber = intval($columnNumber / 26); + } + return $letter; + } + + /** + * 设置列宽 + */ + public function columnWidths(): array + { + $widths = []; + $index = 1; + foreach (array_keys($this->fields) as $field) { + $letter = $this->getColumnLetter($index); + if (str_contains($field, 'users')) { + // 学员信息列设置较宽 + $widths[$letter] = 80; + } elseif (str_contains($field, 'partners') || str_contains($field, 'project_users')) { + // 股东和项目经理列 + $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++; + } + return $widths; + } + + /** + * 设置样式 + */ + public function styles(Worksheet $sheet): array + { + $rowCount = count($this->data) + 1; // 数据行数 + 表头 + $colCount = count($this->fields); + $lastCol = $this->getColumnLetter($colCount); + + return [ + // 表头样式 + 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'], + ], + ], + // 所有数据区域样式 + "A1:{$lastCol}{$rowCount}" => [ + 'alignment' => [ + 'vertical' => Alignment::VERTICAL_TOP, + 'wrapText' => true, // 自动换行 + ], + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => ['rgb' => 'CCCCCC'], + ], + ], + ], + ]; } + /** + * 注册事件 + */ + public function registerEvents(): array + { + 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); + } + + // 冻结首行 + $sheet->freezePane('A2'); + }, + ]; + } /** * 数组转集合 @@ -162,20 +299,43 @@ class CommonExport implements FromCollection } /** - * 获取手机号 + * 获取学员信息(优化显示格式) * @param $data */ function getUsers($data) { + if (empty($data['users'])) { + return ''; + } + $list = []; + $index = 1; foreach ($data['users'] as $item) { - $base = $item['no'] . '-' . $item['username'] . '-' . $item['is_schoolmate_text'] . '-' . $item['company_position'] . '-' . ($item['mobile'] ?? ''); - foreach ($item['course_signs'] as $i) { - $base .= '-' . $i['course']['name'] . '-' . ($i['created_at'] ?? ''); + // 基本信息行 + $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[] = $base; + + $list[] = implode("\n", $userInfo); + $index++; } - return implode("、\r\n", $list); + + // 用分隔线分隔不同学员 + return implode("\n" . str_repeat("-", 40) . "\n", $list); } } diff --git a/app/Http/Controllers/Admin/CalendarsController.php b/app/Http/Controllers/Admin/CalendarsController.php index 7130029..1490dbf 100644 --- a/app/Http/Controllers/Admin/CalendarsController.php +++ b/app/Http/Controllers/Admin/CalendarsController.php @@ -50,7 +50,7 @@ class CalendarsController extends BaseController public function index() { $all = \request()->all(); - $list = Calendar::with('course', 'courseContent') + $list = Calendar::with('course', 'courseContent','historyCourses') ->where(function ($query) use ($all) { if (isset($all['month'])) { $query->where('start_time', 'like', $all['month'] . '%'); diff --git a/app/Http/Controllers/Admin/CourseSignController.php b/app/Http/Controllers/Admin/CourseSignController.php index 66f8c75..60e5a09 100755 --- a/app/Http/Controllers/Admin/CourseSignController.php +++ b/app/Http/Controllers/Admin/CourseSignController.php @@ -86,7 +86,9 @@ class CourseSignController extends BaseController $query->where('is_vip', $all['is_vip']); } if (isset($all['company_name'])) { - $query->where('company_name', 'like', '%' . $all['company_name'] . '%'); + $query->whereHas('company', function ($query) use ($all) { + $query->where('company_name', 'like', '%' . $all['company_name'] . '%'); + }); } if (isset($all['company_position'])) { $query->where('company_position', $all['company_position']); diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index 183f67e..f8ca8b9 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -128,7 +128,7 @@ class OtherController extends CommonController $list['schoolmate_year'] = User::where('is_schoolmate', 1)->where('created_at', 'like', '%' . date('Y') . '%')->count(); // 投后企业 $list['company_invested_total'] = CourseSign::yhInvested(); - // 元和员工参与企业 + // 元和员工参与人数 $list['company_join_total'] = CourseSign::companyJoin(); // 全市干部参与企业 $list['company_ganbu_total'] = CourseSign::ganbu(); @@ -254,7 +254,7 @@ class OtherController extends CommonController // 入学后被投企业数量(在指定时间范围内报名的学员所在公司中,在入学后被投的公司数量) $list['company_invested_after_enrollment_total'] = CourseSign::companyInvestedAfterEnrollment($start_date, $end_date, $course_ids); - // 元和员工参与企业 + // 元和员工参与人数 $list['company_join_total'] = CourseSign::companyJoin($start_date, $end_date, $course_ids); // 全市干部参与企业 $list['company_ganbu_total'] = CourseSign::ganbu($start_date, $end_date, $course_ids); @@ -271,7 +271,14 @@ class OtherController extends CommonController $courseTypes = CourseType::whereIn('id', $course_type_id)->get(); foreach ($courseTypes as $courseType) { // 获取课程 - $courses2 = Course::where('type', $courseType->id)->orderBy('start_date', 'asc')->get(); + $courses2 = Course::where('type', $courseType->id) + ->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]); + } + })->orderBy('start_date', 'asc')->get(); foreach ($courses2 as $course) { $courseTypesSum[] = [ 'course_type' => $courseType->name, @@ -727,35 +734,33 @@ class OtherController extends CommonController break; case 'company_join_total': - // 元和员工参与企业明细 - 使用模型方法 - $companies = CourseSign::companyJoin($start_date, $end_date, $course_ids, true); - foreach ($companies as $company) { + // 元和员工参与人员明细 - 使用模型方法(现在返回的是用户列表) + $users = CourseSign::companyJoin($start_date, $end_date, $course_ids, true); + // 加载关联关系 + $users->load('company'); + foreach ($users as $user) { $data[] = [ - 'company_name' => $company->company_name, - 'company_legal_representative' => $company->company_legal_representative ?? '', - 'company_date' => $company->company_date ?? '', - 'company_address' => $company->company_address ?? '', - 'company_city' => $company->company_city ?? '', - 'company_area' => $company->company_area ?? '', - 'business_scope' => $company->business_scope ?? '', - 'contact_phone' => $company->contact_phone ?? '', - 'contact_mail' => $company->contact_mail ?? '', - 'company_tag' => $company->company_tag ?? '', - 'credit_code' => ' ' . $company->credit_code ?? '', + 'user_name' => $user->name ?? '', + 'mobile' => $user->mobile ?? '', + 'company_name' => $user->company->company_name ?? '', + 'company_position' => $user->company_position ?? '', + 'company_city' => $user->company->company_city ?? '', + 'company_area' => $user->company->company_area ?? '', + 'company_legal_representative' => $user->company->company_legal_representative ?? '', + 'company_date' => $user->company->company_date ?? '', + 'company_address' => $user->company->company_address ?? '', ]; } $fields = [ + 'user_name' => '学员姓名', + 'mobile' => '手机号', 'company_name' => '企业名称', + 'company_position' => '职位', + 'company_city' => '所在城市', + 'company_area' => '所在区域', 'company_legal_representative' => '法人', 'company_date' => '成立时间', 'company_address' => '地址', - 'company_city' => '所在城市', - 'company_area' => '所在区域', - 'business_scope' => '营业范围', - 'contact_phone' => '联系电话', - 'contact_mail' => '联系邮箱', - 'company_tag' => '企业资质', - 'credit_code' => '统一社会信用代码', ]; $filename = '元和员工参与企业明细'; break; diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 9c1bf21..6d1438a 100755 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -291,7 +291,9 @@ class UserController extends BaseController $query->where('name', 'like', '%' . $all['name'] . '%'); } if (isset($all['company_name'])) { - $query->where('company_name', 'like', '%' . $all['company_name'] . '%'); + $query->whereHas('company', function ($query) use ($all) { + $query->where('company_name', 'like', '%' . $all['company_name'] . '%'); + }); } if (isset($all['company_position'])) { $query->where('company_position', $all['company_position']); diff --git a/app/Models/CourseSign.php b/app/Models/CourseSign.php index 2efc70f..3938c4b 100755 --- a/app/Models/CourseSign.php +++ b/app/Models/CourseSign.php @@ -173,7 +173,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', '%' . '跟班学员' . '%'); })->get(); if ($retList) { @@ -328,11 +328,11 @@ class CourseSign extends SoftDeletesModel } /** - * 元和员工参与企业 + * 元和员工参人员 */ public static function companyJoin($start_date = null, $end_date = null, $course_ids = null, $retList = false) { - $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); + $courseSignsQuery = self::getStudentList($start_date, $end_date, null, $course_ids); $courseSignByType = $courseSignsQuery->get(); // 检测关键词 @@ -342,13 +342,15 @@ class CourseSign extends SoftDeletesModel '禾裕集团', '苏州科服', '信诚管理咨询', '集成电路公司', '常州团队', '国企元禾' ]; - $list = Company::whereHas('users', function ($query) use ($courseSignByType, $companyNameKeyword) { - $query->whereIn('id', $courseSignByType->pluck('user_id')); - })->where(function ($query) use ($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')) + ->whereIn('company_id', $company->pluck('id')) + ->get(); + if ($retList) { // 返回列表 return $list; @@ -370,7 +372,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', '%' . '跟班学员' . '%'); })->get(); if ($retList) { return User::with('company')->whereIn('id', $courseSigns->pluck('user_id'))->get();