4(已过号) * - 预约时间已过超过8小时:status -> 2(已取消) * - 不处理:status=3(已完成)、未到时间的单子 */ class UpdateAppointmentStatus extends Command { protected function configure() { $this->setName('update_appointment_status') ->setDescription('自动更新挂号单状态:过号->4,超8小时->2(已取消)') ->addOption('dry', null, Option::VALUE_NONE, '仅预览不执行'); } protected function execute(Input $input, Output $output) { $dryRun = $input->getOption('dry'); $now = time(); $table = (new Appointment())->getTable(); // 1. 超过8小时 -> 已取消(status=2) $cancelWhere = "status = 1 AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) <= DATE_SUB(NOW(), INTERVAL 8 HOUR)"; $cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}"; $cancelCount = $dryRun ? 0 : Db::execute($cancelSql, [$now]); // 2. 已过时间但未超8小时 -> 已过号(status=4) $missedWhere = "status = 1 AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) < NOW() AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) > DATE_SUB(NOW(), INTERVAL 8 HOUR)"; $missedSql = "UPDATE {$table} SET status = 4, update_time = ? WHERE {$missedWhere}"; $missedCount = $dryRun ? 0 : Db::execute($missedSql, [$now]); if ($dryRun) { $cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}"); $missedPreview = Db::query("SELECT id FROM {$table} WHERE {$missedWhere}"); $output->writeln('[预览] 将改为已取消: ' . count($cancelPreview) . ' 条'); $output->writeln('[预览] 将改为已过号: ' . count($missedPreview) . ' 条'); return; } $output->writeln("已取消(超8小时): {$cancelCount} 条"); $output->writeln("已过号: {$missedCount} 条"); Log::info("update_appointment_status: 已取消 {$cancelCount}, 已过号 {$missedCount}"); } }