option('days'); $dryRun = $this->option('dry-run'); if ($days <= 0) { $this->error('天数必须大于0'); return 1; } $cutoffDate = Carbon::now()->subDays($days); $this->info("开始清理 {$cutoffDate} 之前结束的活动..."); if ($dryRun) { $this->warn('当前为演示模式,不会实际执行清理操作'); } // 查找过期活动 $expiredActivities = ActivityConfig::where('end_time', '<', $cutoffDate) ->whereIn('status', [ACTIVITY_STATUS::ENDED, ACTIVITY_STATUS::CLOSED]) ->get(); $this->info("找到 " . count($expiredActivities) . " 个过期活动"); if ($expiredActivities->isEmpty()) { $this->info('没有需要清理的过期活动'); return 0; } // 显示将要清理的活动 $this->table( ['ID', '名称', '结束时间', '状态'], $expiredActivities->map(function ($activity) { return [ $activity->id, $activity->name, $activity->end_time, ACTIVITY_STATUS::getName($activity->status) ]; }) ); if (!$dryRun && !$this->confirm('确定要清理这些活动吗?此操作不可撤销')) { $this->info('操作已取消'); return 0; } // 清理过期活动 $expiredActivityIds = $expiredActivities->pluck('id')->toArray(); $expiredRewardsCount = 0; if (!$dryRun) { DB::beginTransaction(); try { // 标记未领取的奖励为已过期 $expiredRewardsCount = ActivityParticipation::whereIn('activity_id', $expiredActivityIds) ->where('reward_status', REWARD_STATUS::NOT_CLAIMED) ->update(['reward_status' => REWARD_STATUS::EXPIRED]); // 更新活动状态为已关闭 ActivityConfig::whereIn('id', $expiredActivityIds) ->where('status', ACTIVITY_STATUS::ENDED) ->update(['status' => ACTIVITY_STATUS::CLOSED]); DB::commit(); $this->info("成功清理 " . count($expiredActivityIds) . " 个过期活动"); $this->info("标记 {$expiredRewardsCount} 个未领取的奖励为已过期"); // 记录日志 Log::info("清理过期活动完成", [ 'activity_count' => count($expiredActivityIds), 'expired_rewards_count' => $expiredRewardsCount, 'cutoff_date' => $cutoffDate ]); } catch (\Exception $e) { DB::rollBack(); $this->error("清理过期活动失败: " . $e->getMessage()); // 记录日志 Log::error("清理过期活动失败", [ 'error' => $e->getMessage(), 'cutoff_date' => $cutoffDate ]); return 1; } } else { // 演示模式,显示将要执行的操作 $expiredRewardsCount = ActivityParticipation::whereIn('activity_id', $expiredActivityIds) ->where('reward_status', REWARD_STATUS::NOT_CLAIMED) ->count(); $this->info("将会清理 " . count($expiredActivityIds) . " 个过期活动"); $this->info("将会标记 {$expiredRewardsCount} 个未领取的奖励为已过期"); } return 0; } }