diff --git a/app/Console/Commands/AutoSchoolmate.php b/app/Console/Commands/AutoSchoolmate.php index 2015621..c08343a 100755 --- a/app/Console/Commands/AutoSchoolmate.php +++ b/app/Console/Commands/AutoSchoolmate.php @@ -41,38 +41,67 @@ class AutoSchoolmate extends Command */ public function handle() { - // 获取所有已开始且需要自动加入校友库的课程 + // 获取所有已开始且需要自动加入校友库的课程(只处理存在 start_date 的课程) $today = date('Y-m-d'); $courses = Course::where('auto_schoolmate', 1) - ->where(function ($query) use ($today) { - // 方式1: start_date 已填写且 <= 今天 - $query->where(function ($q) use ($today) { - $q->whereNotNull('start_date') - ->where('start_date', '<=', $today); - }) - // 方式2: 或者课程状态为进行中(即使 start_date 未及时填写) - ->orWhere('course_status', 10); - }) + ->whereNotNull('start_date') + ->where('start_date', '<=', $today) ->get(); + if ($courses->isEmpty()) { + return $this->info('没有需要处理的课程'); + } + + $this->info("找到 {$courses->count()} 个需要处理的课程"); + $totalUpdated = 0; + $totalSkipped = 0; + $processedUserIds = []; // 记录已处理的用户ID,避免重复处理 + foreach ($courses as $course) { - // 获取报名通过的学员 - $courseSigns = CourseSign::where('course_id', $course->id)->where('status', 1)->get(); + // 获取报名通过的学员,并排除已经是校友的用户 + $courseSigns = CourseSign::where('course_id', $course->id) + ->where('status', 1) + ->whereHas('user', function ($query) { + // 排除已经是校友的用户(is_schoolmate = 1) + $query->whereRaw('COALESCE(is_schoolmate, 0) != 1'); + })->get(); + if ($courseSigns->isEmpty()) { continue; } - // 只更新还不是校友的学员;从 非校友→校友 时顺带写入 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()]); + // 获取需要更新的用户ID,并排除已经在本脚本中处理过的用户 + $userIds = $courseSigns->pluck('user_id') + ->unique() + ->filter(function ($userId) use (&$processedUserIds) { + // 如果已经处理过,跳过 + if (in_array($userId, $processedUserIds)) { + return false; + } + $processedUserIds[] = $userId; + return true; + }) + ->values() + ->toArray(); + + if (empty($userIds)) { + continue; + } + + // 批量更新:只更新还不是校友的学员;使用课程开课时间作为 schoolmate_time + $updated = User::batchUpdateToSchoolmate($userIds, $course->start_date); $totalUpdated += $updated; + $skipped = count($userIds) - $updated; + $totalSkipped += $skipped; + + if ($updated > 0) { + $this->info("课程【{$course->name}】: 更新 {$updated} 位学员,跳过 {$skipped} 位已处理学员"); + } } - return $this->info("更新完成,共处理 {$totalUpdated} 位学员"); + return $this->info("更新完成,共处理 {$totalUpdated} 位学员,跳过 {$totalSkipped} 位已处理学员"); } } diff --git a/app/Models/User.php b/app/Models/User.php index 5c6d362..f0266a4 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -243,4 +243,28 @@ class User extends Authenticatable implements Auditable return $user->appointment_total - $useTotal >= 0 ? $user->appointment_total - $useTotal : 0; } + /** + * 批量将用户更新为校友 + * @param array $userIds 用户ID数组 + * @param string $courseStartDate 课程开课时间(用于设置 schoolmate_time) + * @return int 更新的用户数量 + */ + public static function batchUpdateToSchoolmate(array $userIds, string $courseStartDate) + { + if (empty($userIds)) { + return 0; + } + + // 将课程开课时间转换为 datetime 格式 + $schoolmateTime = Carbon::parse($courseStartDate)->format('Y-m-d H:i:s'); + + // 批量更新:只更新还不是校友的学员;从 非校友→校友 时使用课程开课时间作为 schoolmate_time + return self::whereIn('id', $userIds) + ->whereRaw('COALESCE(is_schoolmate, 0) != 1') + ->update([ + 'is_schoolmate' => 1, + 'schoolmate_time' => $schoolmateTime + ]); + } + }