| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- <?php
- namespace App\Module\Activity\Commands;
- use App\Module\Activity\Enums\ACTIVITY_STATUS;
- use App\Module\Activity\Enums\REWARD_STATUS;
- use App\Module\Activity\Models\ActivityConfig;
- use App\Module\Activity\Models\ActivityParticipation;
- use Carbon\Carbon;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- /**
- * 清理过期活动命令
- */
- class CleanExpiredActivitiesCommand extends Command
- {
- /**
- * 命令名称
- *
- * @var string
- */
- protected $signature = 'activity:clean-expired {--days=30 : 清理多少天前结束的活动} {--dry-run : 仅显示将要清理的内容,不实际执行}';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = '清理过期活动和未领取的奖励';
- /**
- * 执行命令
- *
- * @return int
- */
- public function handle()
- {
- $days = (int)$this->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;
- }
- }
|