99 lines
3.3 KiB
PHP
99 lines
3.3 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace app\common\command;
|
||
|
||
use app\common\model\doctor\Medicine;
|
||
use app\common\service\doctor\MedicineNameAbbrService;
|
||
use think\console\Command;
|
||
use think\console\Input;
|
||
use think\console\input\Option;
|
||
use think\console\Output;
|
||
|
||
/**
|
||
* 批量回填药材库 name_pinyin_abbr(拼音首字母,供检索)
|
||
*
|
||
* 用法:
|
||
* php think sync_medicine_pinyin_abbr # 仅更新 abbr 为空的记录
|
||
* php think sync_medicine_pinyin_abbr --all # 全部按当前名称重算
|
||
* php think sync_medicine_pinyin_abbr --dry # 只打印将更新多少条,不写库
|
||
*/
|
||
class SyncMedicinePinyinAbbr extends Command
|
||
{
|
||
protected function configure()
|
||
{
|
||
$this->setName('sync_medicine_pinyin_abbr')
|
||
->setDescription('回填/刷新药材表 name_pinyin_abbr(需已执行迁移并 composer 安装 overtrue/pinyin)')
|
||
->addOption('all', null, Option::VALUE_NONE, '重算全部记录(默认只处理 abbr 为空的)')
|
||
->addOption('dry', null, Option::VALUE_NONE, '仅统计/预览,不写入数据库');
|
||
}
|
||
|
||
protected function execute(Input $input, Output $output)
|
||
{
|
||
if (!class_exists(\Overtrue\Pinyin\Pinyin::class)) {
|
||
$output->writeln('<error>未检测到 overtrue/pinyin,请在 server 目录执行: composer update</error>');
|
||
|
||
return 1;
|
||
}
|
||
|
||
$all = (bool) $input->getOption('all');
|
||
$dry = (bool) $input->getOption('dry');
|
||
|
||
$makeQuery = function () use ($all) {
|
||
$q = Medicine::order('id', 'asc');
|
||
if (!$all) {
|
||
$q->where('name_pinyin_abbr', '');
|
||
}
|
||
|
||
return $q;
|
||
};
|
||
|
||
$total = $makeQuery()->count();
|
||
if ($total === 0) {
|
||
$output->writeln('没有需要处理的记录。');
|
||
|
||
return 0;
|
||
}
|
||
|
||
$output->writeln(($all ? '模式: 全部重算' : '模式: 仅空 abbr') . ",待处理 {$total} 条" . ($dry ? '(dry-run)' : ''));
|
||
|
||
$updated = 0;
|
||
$skipped = 0;
|
||
|
||
$makeQuery()->chunk(200, function ($rows) use (&$updated, &$skipped, $dry) {
|
||
foreach ($rows as $row) {
|
||
$data = $row instanceof \think\Model ? $row->toArray() : (array) $row;
|
||
$id = (int) ($data['id'] ?? 0);
|
||
$name = trim((string) ($data['name'] ?? ''));
|
||
if ($id <= 0 || $name === '') {
|
||
++$skipped;
|
||
continue;
|
||
}
|
||
$abbr = MedicineNameAbbrService::build($name);
|
||
if ($abbr === '') {
|
||
++$skipped;
|
||
continue;
|
||
}
|
||
if ($dry) {
|
||
++$updated;
|
||
continue;
|
||
}
|
||
Medicine::where('id', $id)->update([
|
||
'name_pinyin_abbr' => $abbr,
|
||
'update_time' => time(),
|
||
]);
|
||
++$updated;
|
||
}
|
||
});
|
||
|
||
if ($dry) {
|
||
$output->writeln("[预览] 将写入/覆盖拼音首字母: {$updated} 条,跳过(空名或无法生成): {$skipped} 条");
|
||
} else {
|
||
$output->writeln("完成: 已更新 {$updated} 条,跳过 {$skipped} 条。");
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
}
|