| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <?php
- namespace App\Module\Task\Commands;
- use App\Module\Task\Enums\RESET_TYPE;
- use App\Module\Task\Enums\TASK_STATUS;
- use App\Module\Task\Models\Task;
- use App\Module\Task\Models\TaskUserTask;
- use Illuminate\Console\Command;
- use Illuminate\Support\Carbon;
- /**
- * 任务重置检查命令
- *
- * 用于诊断任务重置系统,检查哪些任务需要重置,以及重置状态是否正确。
- * 在被动重置机制下,此命令主要用于诊断和调试。
- */
- class TaskResetCheckCommand extends Command
- {
- /**
- * 命令名称
- *
- * @var string
- */
- protected $signature = 'task:reset-check
- {--user-id= : 指定用户ID进行检查}
- {--task-id= : 指定任务ID进行检查}
- {--reset-type= : 指定重置类型(daily, weekly, monthly, seasonal)}
- {--show-all : 显示所有任务,包括不需要重置的任务}
- {--detailed : 显示详细信息}';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = '检查任务重置状态(用于诊断)';
- /**
- * 执行命令
- *
- * @return int
- */
- public function handle()
- {
- $this->info('开始检查任务重置状态...');
-
- // 获取命令选项
- $userId = $this->option('user-id');
- $taskId = $this->option('task-id');
- $resetType = $this->option('reset-type');
- $showAll = $this->option('show-all');
- $detailed = $this->option('detailed');
-
- // 验证重置类型
- if ($resetType && !in_array($resetType, ['daily', 'weekly', 'monthly', 'seasonal', 'none'])) {
- $this->error('无效的重置类型。有效值: daily, weekly, monthly, seasonal, none');
- return 1;
- }
-
- // 构建查询
- $query = TaskUserTask::query();
-
- // 应用过滤条件
- if ($userId) {
- $query->where('user_id', $userId);
- }
-
- if ($taskId) {
- $query->where('task_id', $taskId);
- }
-
- // 获取用户任务
- $userTasks = $query->with('task')->get();
-
- if ($userTasks->isEmpty()) {
- $this->warn('未找到符合条件的用户任务记录');
- return 0;
- }
-
- $this->info("找到 {$userTasks->count()} 条用户任务记录");
-
- // 创建表格头
- $headers = ['用户ID', '任务ID', '任务名称', '重置类型', '下次重置时间', '状态', '需要重置'];
- if ($detailed) {
- $headers = array_merge($headers, ['上次重置时间', '重置次数', '完成时间', '奖励领取时间']);
- }
-
- $rows = [];
- $needResetCount = 0;
- $now = Carbon::now();
-
- foreach ($userTasks as $userTask) {
- // 获取任务
- $task = $userTask->task;
- if (!$task) {
- continue;
- }
-
- // 获取重置类型
- $taskResetType = $task->reset_type ?? 'none';
-
- // 如果指定了重置类型,且不匹配,则跳过
- if ($resetType && $resetType !== $taskResetType) {
- continue;
- }
-
- // 检查是否需要重置
- $needReset = $this->checkNeedReset($userTask, $task, $now);
-
- // 如果不显示所有任务,且不需要重置,则跳过
- if (!$showAll && !$needReset) {
- continue;
- }
-
- if ($needReset) {
- $needResetCount++;
- }
-
- // 准备行数据
- $row = [
- $userTask->user_id,
- $userTask->task_id,
- $task->name ?? "未知任务({$userTask->task_id})",
- $taskResetType,
- $userTask->next_reset_time ? $userTask->next_reset_time->format('Y-m-d H:i:s') : '未设置',
- TASK_STATUS::getDescription(TASK_STATUS::from($userTask->status)),
- $needReset ? '是' : '否'
- ];
-
- if ($detailed) {
- $row = array_merge($row, [
- $userTask->last_reset_time ? $userTask->last_reset_time->format('Y-m-d H:i:s') : '未重置',
- $userTask->reset_count ?? 0,
- $userTask->completed_at ? $userTask->completed_at->format('Y-m-d H:i:s') : '未完成',
- $userTask->rewarded_at ? $userTask->rewarded_at->format('Y-m-d H:i:s') : '未领取'
- ]);
- }
-
- $rows[] = $row;
- }
-
- // 显示表格
- $this->table($headers, $rows);
-
- // 显示统计信息
- $this->info("需要重置的任务数量: {$needResetCount}");
-
- // 显示当前时间
- $this->info("当前系统时间: {$now->format('Y-m-d H:i:s')}");
-
- return 0;
- }
-
- /**
- * 检查任务是否需要重置
- *
- * @param TaskUserTask $userTask 用户任务
- * @param Task $task 任务
- * @param Carbon $now 当前时间
- * @return bool
- */
- protected function checkNeedReset(TaskUserTask $userTask, Task $task, Carbon $now): bool
- {
- // 如果任务不需要重置,则返回false
- if (!$task->reset_type || $task->reset_type === 'none') {
- return false;
- }
-
- // 如果任务状态不是已完成或已领取奖励,则不需要重置
- if (!in_array($userTask->status, [TASK_STATUS::COMPLETED->value, TASK_STATUS::REWARDED->value])) {
- return false;
- }
-
- // 如果下次重置时间未设置,则计算下次重置时间
- if (!$userTask->next_reset_time) {
- // 如果上次重置时间未设置,则使用当前时间
- $lastResetTime = $userTask->last_reset_time ?? $now;
-
- // 计算下次重置时间
- $nextResetTime = $this->calculateNextResetTime($task->reset_type, $lastResetTime);
-
- // 如果下次重置时间已过,则需要重置
- return $now->greaterThanOrEqualTo($nextResetTime);
- }
-
- // 如果当前时间已超过下次重置时间,则需要重置
- return $now->greaterThanOrEqualTo($userTask->next_reset_time);
- }
-
- /**
- * 计算下次重置时间
- *
- * @param string $resetType 重置类型
- * @param Carbon $lastResetTime 上次重置时间
- * @return Carbon
- */
- protected function calculateNextResetTime(string $resetType, Carbon $lastResetTime): Carbon
- {
- $resetType = RESET_TYPE::tryFrom($resetType) ?? RESET_TYPE::NONE;
-
- // 获取重置间隔(秒)
- $interval = RESET_TYPE::getInterval($resetType);
-
- if ($interval === null) {
- // 如果没有重置间隔,则返回一个很远的未来时间
- return Carbon::now()->addYears(100);
- }
-
- // 计算下次重置时间
- return $lastResetTime->copy()->addSeconds($interval);
- }
- }
|