diff --git a/app/Console/Commands/AutoSchoolmate.php b/app/Console/Commands/AutoSchoolmate.php index d648524..2015621 100755 --- a/app/Console/Commands/AutoSchoolmate.php +++ b/app/Console/Commands/AutoSchoolmate.php @@ -4,12 +4,8 @@ namespace App\Console\Commands; use App\Models\Course; use App\Models\CourseSign; -use App\Models\EmailRecord; -use App\Models\EmailRecordUser; use App\Models\User; -use App\Repositories\MeetRepository; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Mail; class AutoSchoolmate extends Command @@ -67,14 +63,10 @@ class AutoSchoolmate extends Command continue; } - // 只更新还不是校友的学员,避免重复处理 - // 注意:is_schoolmate != 1 不会匹配 NULL 值,需要显式包含 NULL - $updated = User::whereIn('id', $courseSigns->pluck('user_id')) - ->where(function ($query) { - $query->where('is_schoolmate', '!=', 1) - ->orWhereNull('is_schoolmate'); - }) - //->where('is_black',0) + // 只更新还不是校友的学员;从 非校友→校友 时顺带写入 schoolmate_time + $userIds = $courseSigns->pluck('user_id')->unique()->values(); + $updated = User::whereIn('id', $userIds) + ->whereRaw('COALESCE(is_schoolmate, 0) != 1') ->update(['is_schoolmate' => 1, 'schoolmate_time' => now()]); $totalUpdated += $updated; diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index 8dba8d6..2c7e97e 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -377,22 +377,11 @@ class OtherController extends CommonController ]; } } - // 附加历史课程数据(与 home-v2 yearConfigs 口径一致:仅统计 typeDetail.name 能匹配某个 is_chart=1 且 is_history=0 的 CourseType 的 HistoryCourse) - $chartHistoryTypeNames = CourseType::where('is_chart', 1)->where('is_history', 0)->pluck('name')->toArray(); + // 附加历史课程数据(与 course_signs_pass 口径一致:与 needHistory 的 HistoryCourse 条件一致,calendar+日期+type in course_type_id) $courseTypesHistory = CourseType::where('is_history', 1)->whereIn('id', $course_type_id)->get(); foreach ($courseTypesHistory as $historyCourse) { $courses3 = HistoryCourse::whereHas('calendar', function ($query) { $query->where('is_count_people', 1); - })->whereHas('typeDetail', function ($query) use ($chartHistoryTypeNames) { - if (empty($chartHistoryTypeNames)) { - $query->whereRaw('1=0'); - return; - } - $query->where(function ($q) use ($chartHistoryTypeNames) { - foreach ($chartHistoryTypeNames as $n) { - $q->orWhere('name', 'like', '%' . $n . '%'); - } - }); })->where(function ($query) use ($start_date, $end_date) { // 开始结束日期的筛选。or查询 $query->whereBetween('start_time', [$start_date, $end_date]) @@ -874,22 +863,11 @@ class OtherController extends CommonController ]; } } - // 附加历史课程数据(与 home-v2 yearConfigs 口径一致:仅统计 typeDetail.name 能匹配某个 is_chart=1 且 is_history=0 的 CourseType 的 HistoryCourse) - $chartHistoryTypeNames = CourseType::where('is_chart', 1)->where('is_history', 0)->pluck('name')->toArray(); + // 附加历史课程数据(与 course_signs_pass 口径一致:与 needHistory 的 HistoryCourse 条件一致,calendar+日期+type in course_type_id) $courseTypesHistory = CourseType::where('is_history', 1)->whereIn('id', $course_type_id)->get(); foreach ($courseTypesHistory as $historyCourse) { $courses3 = HistoryCourse::whereHas('calendar', function ($query) { $query->where('is_count_people', 1); - })->whereHas('typeDetail', function ($query) use ($chartHistoryTypeNames) { - if (empty($chartHistoryTypeNames)) { - $query->whereRaw('1=0'); - return; - } - $query->where(function ($q) use ($chartHistoryTypeNames) { - foreach ($chartHistoryTypeNames as $n) { - $q->orWhere('name', 'like', '%' . $n . '%'); - } - }); })->where(function ($query) use ($start_date, $end_date) { // 开始结束日期的筛选。or查询 $query->whereBetween('start_time', [$start_date, $end_date]) @@ -2054,6 +2032,7 @@ class OtherController extends CommonController 'company_position' => $user->company_position ?? '', 'education' => $user->education ?? '', 'geren_rongyu' => $user->type ?? '', + 'talent_tags' => $user->talent_tags ?? '', 'course_names' => $courseNamesStr, 'course_types' => $courseTypesStr, 'course_count' => $totalCourseCount, @@ -2068,6 +2047,7 @@ class OtherController extends CommonController 'company_position' => '职位', 'education' => '学历', 'geren_rongyu' => '个人荣誉', + 'talent_tags' => '人才标签', 'course_names' => '课程名称', 'course_types' => '课程体系', 'course_count' => '报名课程数', diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index a7512cc..38fd6ab 100755 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -161,7 +161,7 @@ class UserController extends BaseController * @OA\Parameter(name="name", in="query", @OA\Schema(type="string"), required=false, description="名字"), * @OA\Parameter(name="company_name", in="query", @OA\Schema(type="string"), required=false, description="公司名字"), * @OA\Parameter(name="company_position", in="query", @OA\Schema(type="string"), required=false, description="职务"), - * @OA\Parameter(name="company_area", in="query", @OA\Schema(type="string"), required=false, description="所属区域"), + * @OA\Parameter(name="company_area", in="query", @OA\Schema(type="string"), required=false, description="所在区域,多个英文逗号分隔,like 匹配关联 company 的 company_area(or 关系)"), * @OA\Parameter(name="company_type", in="query", @OA\Schema(type="string"), required=false, description="企业性质"), * @OA\Parameter(name="company_industry", in="query", @OA\Schema(type="string"), required=false, description="所属行业"), * @OA\Parameter(name="courses_start_date", in="query", @OA\Schema(type="string"), required=false, description="课程开始时间"), @@ -191,6 +191,7 @@ class UserController extends BaseController * @OA\Parameter(name="company_tag", in="query", @OA\Schema(type="string"), required=false, description="企业标签"), * @OA\Parameter(name="talent_tags", in="query", @OA\Schema(type="string"), required=false, description="人才标签,多个英文逗号分隔"), * @OA\Parameter(name="address", in="query", @OA\Schema(type="string"), required=false, description="公司地址,模糊匹配关联 company 的 company_address 或 company_city"), + * @OA\Parameter(name="is_rencai", in="query", @OA\Schema(type="string"), required=false, description="是否人才,1=是时筛选;满足任一条即为人才:报名过人才培训课程(typeDetail.name=人才培训) 或 user.type/talent_tags 含「人才」"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", @@ -366,9 +367,18 @@ class UserController extends BaseController if (isset($all['company_position'])) { $query->where('company_position', $all['company_position']); } - if (isset($all['company_area'])) { - $company_area = explode(',', $all['company_area']); - $query->whereIn('company_area', $company_area); + // 所在区域:like 匹配关联 company 的 company_area,多个英文逗号分隔为 or + if (isset($all['company_area']) && $all['company_area'] !== '') { + $company_area = array_filter(array_map('trim', explode(',', $all['company_area']))); + if (!empty($company_area)) { + $query->whereHas('company', function ($c) use ($company_area) { + $c->where(function ($q) use ($company_area) { + foreach ($company_area as $v) { + $q->orWhere('company_area', 'like', '%' . $v . '%'); + } + }); + }); + } } // 公司地址:模糊匹配关联 company 的 company_address 或 company_city if (isset($all['address']) && $all['address'] !== '') { @@ -426,6 +436,18 @@ class UserController extends BaseController } }); } + // 是否人才(与 CourseSign::rencai 条件一致):1=是时筛选。任一条即视为人才:报名过人才培训课程 或 type/talent_tags 含「人才」 + if (isset($all['is_rencai']) && (int) $all['is_rencai'] === 1) { + $query->where(function ($q) { + $q->whereHas('courseSigns', function ($cs) { + $cs->where('status', 1)->whereHas('course', function ($c) { + $c->whereHas('typeDetail', function ($t) { + $t->where('name', '人才培训'); + }); + }); + })->orWhere('type', 'like', '%人才%')->orWhere('talent_tags', 'like', '%人才%'); + }); + } })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); if (isset($all['is_export']) && !empty($all['is_export'])) { $list = $list->limit(5000)->get()->toArray(); @@ -746,13 +768,23 @@ class UserController extends BaseController if ($validator->fails()) { return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } - $idsArray = explode(',', $all['ids']); - $data = []; + $idsArray = array_filter(array_map('trim', explode(',', $all['ids']))); + if (empty($idsArray)) { + return $this->fail([StarterResponseCode::START_ERROR_PARAMETER, '编号不能为空']); + } if (isset($all['is_schoolmate'])) { - $data['is_schoolmate'] = $all['is_schoolmate']; - $data['schoolmate_time'] = ($all['is_schoolmate'] == 1) ? now() : null; + if ($all['is_schoolmate'] == 1) { + // 仅当 非校友→校友 时写入 schoolmate_time;已是校友的不更新,避免覆盖 + $this->model->whereIn('id', $idsArray) + ->whereRaw('COALESCE(is_schoolmate, 0) != 1') + ->update(['is_schoolmate' => 1, 'schoolmate_time' => now()]); + } else { + $this->model->whereIn('id', $idsArray)->update([ + 'is_schoolmate' => $all['is_schoolmate'], + 'schoolmate_time' => null, + ]); + } } - $this->model->whereIn('id', $idsArray)->update($data); return $this->success('批量更新成功'); } diff --git a/app/Models/CourseSign.php b/app/Models/CourseSign.php index c114c73..f89682e 100755 --- a/app/Models/CourseSign.php +++ b/app/Models/CourseSign.php @@ -798,14 +798,14 @@ class CourseSign extends SoftDeletesModel $courseSignsQuery = self::getStudentList($start_date, $end_date, 1, $course_ids); // 条件1:人才培训课程类型的用户 - $courseSigns1 = $courseSignsQuery->whereHas('course', function ($query) { + $courseSigns1 = (clone ($courseSignsQuery))->whereHas('course', function ($query) { $query->whereHas('typeDetail', function ($q) { $q->where('name', '人才培训'); }); })->with(['user.company'])->get(); // 条件2:user.type 包含「人才」的用户 - $courseSigns2 = $courseSignsQuery->whereHas('user', function ($q) { + $courseSigns2 = (clone ($courseSignsQuery))->whereHas('user', function ($q) { $q->where('type', 'like', '%人才%')->orWhere('talent_tags', 'like', '%人才%'); })->with(['user.company'])->get();