Files
zyt/server/app/common/command/UpdateAppointmentStatus.php
T
2026-10-15 11:03:54 +08:00

67 lines
2.9 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\command;
use app\common\model\doctor\Appointment;
use app\common\service\tcm\RevisitDueHook;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;
/**
* 挂号单状态自动更新
* - 已预约(status=1) 且预约时间已过超过 35 分钟 → status=4(已过号)
* - 已过号(status=4) 且预约时间已过超过 8 小时 → status=2(已取消)
* - 不处理:status=3(已完成)、未到预约时间、距预约未满 35 分钟的单子
*/
class UpdateAppointmentStatus extends Command
{
protected function configure()
{
$this->setName('update_appointment_status')
->setDescription('挂号单:已预约过号35分钟→已过号;已过号超8小时→已取消')
->addOption('dry', null, Option::VALUE_NONE, '仅预览不执行');
}
protected function execute(Input $input, Output $output)
{
$dryRun = $input->getOption('dry');
$now = time();
$table = (new Appointment())->getTable();
$dtExpr = "CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00'))";
// 1. 已预约 → 已过号:预约时间早于「当前 − 35 分钟」
$missedWhere = "status = 1 AND {$dtExpr} < DATE_SUB(NOW(), INTERVAL 35 MINUTE)";
$missedSql = "UPDATE {$table} SET status = 4, update_time = ? WHERE {$missedWhere}";
// 2. 已过号 → 已取消:预约时间早于或等于「当前 − 8 小时」
$cancelWhere = "status = 4 AND {$dtExpr} <= DATE_SUB(NOW(), INTERVAL 8 HOUR)";
$cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}";
if ($dryRun) {
$missedPreview = Db::query("SELECT id FROM {$table} WHERE {$missedWhere}");
$cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}");
$output->writeln('[预览] 将改为已过号(1→4): ' . count($missedPreview) . ' 条');
$output->writeln('[预览] 将改为已取消(4→2,过号超8小时): ' . count($cancelPreview) . ' 条');
$output->writeln('[说明] 真实执行时先执行 1→4,再执行 4→2;同一次内刚由 1 变 4 且已超 8 小时的会再被改为 2。');
return;
}
$missedCount = Db::execute($missedSql, [$now]);
$cancelCount = Db::execute($cancelSql, [$now]);
// 过号/取消落库后重评复诊到期快照中「已约」行(当天过号即进标红/弹窗;钩子内部已 try/catch)
RevisitDueHook::onAppointmentStatusCronDone();
$output->writeln("已过号(1→4): {$missedCount} 条");
$output->writeln("已取消(4→2,过号超8小时): {$cancelCount} 条");
Log::info("update_appointment_status: 已过号 {$missedCount}, 已取消 {$cancelCount}");
}
}