You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.9 KiB

2 weeks ago
<?php
namespace App\Console\Commands;
use App\Models\Venue;
use App\Support\HtmlToPlainText;
use Illuminate\Console\Command;
/**
* 历史数据中「预约方式」曾用富文本,现改为单行 input 后需去掉 HTML 标签。
* 先执行: php artisan venue:strip-booking-method-html --dry-run
*/
class StripVenueBookingMethodHtmlCommand extends Command
{
protected $signature = 'venue:strip-booking-method-html
{--dry-run : 只列出将更新的场馆 ID不写库}
{--with-snapshot : 同时清理 last_approved_snapshot 内 booking_method}';
protected $description = '批量将 venues.booking_method 从 HTML 转为纯文本(单行)';
public function handle(): int
{
$dry = (bool) $this->option('dry-run');
$withSnapshot = (bool) $this->option('with-snapshot');
$n = 0;
Venue::query()->orderBy('id')->chunkById(100, function ($venues) use ($dry, $withSnapshot, &$n) {
foreach ($venues as $venue) {
if ($this->processVenue($venue, $dry, $withSnapshot)) {
$n++;
}
}
});
if ($dry) {
$this->info("dry-run将更新 {$n} 条记录,未写入数据库。去掉 --dry-run 后执行写入。");
} else {
$this->info("已更新 {$n} 条记录。");
}
return self::SUCCESS;
}
private function processVenue(Venue $venue, bool $dry, bool $withSnapshot): bool
{
$newMethod = HtmlToPlainText::toSingleLine($venue->booking_method);
$methodChanged = (string) ($venue->booking_method ?? '') !== (string) ($newMethod ?? '');
$snapChanged = false;
$newSnapMethod = null;
if ($withSnapshot && is_array($venue->last_approved_snapshot) && array_key_exists('booking_method', $venue->last_approved_snapshot)) {
$raw = $venue->last_approved_snapshot['booking_method'];
if (is_string($raw) || $raw === null) {
$newSnapMethod = HtmlToPlainText::toSingleLine($raw);
$snapChanged = (string) ($raw ?? '') !== (string) ($newSnapMethod ?? '');
}
}
if (! $methodChanged && ! $snapChanged) {
return false;
}
if ($methodChanged) {
$this->line("venue_id={$venue->id} booking_method: 去除 HTML/实体");
}
if ($snapChanged) {
$this->line("venue_id={$venue->id} last_approved_snapshot.booking_method: 去除 HTML/实体");
}
if ($dry) {
return true;
}
if ($methodChanged) {
$venue->booking_method = $newMethod;
}
if ($snapChanged) {
$snap = $venue->last_approved_snapshot;
$snap['booking_method'] = $newSnapMethod;
$venue->last_approved_snapshot = $snap;
}
$venue->save();
return true;
}
}