Files
zyt/PINYIN_ABBREVIATION_GUIDE.md
T
2026-04-15 16:31:25 +08:00

6.5 KiB
Raw Blame History

药材名称拼音首字母功能说明

概述

系统使用 overtrue/pinyin 包自动生成中文药材名称的拼音首字母缩写,存储在 name_pinyin_abbr 字段中,用于快速检索。

核心实现

1. 依赖包

"overtrue/pinyin": "^6.0"

已在 server/composer.json 中配置。

2. 服务类:MedicineNameAbbrService

文件位置: server/app/common/service/doctor/MedicineNameAbbrService.php

<?php

namespace app\common\service\doctor;

use Overtrue\Pinyin\Pinyin;

class MedicineNameAbbrService
{
    public static function build(string $name): string
    {
        $name = trim($name);
        if ($name === '') {
            return '';
        }
        if (!class_exists(Pinyin::class)) {
            return '';
        }
        $abbr = (string) Pinyin::abbr($name)->join('');

        return strtolower($abbr);
    }
}

功能说明:

  • 输入:中文药材名称(如 "当归")
  • 输出:拼音首字母小写连写(如 "dg"
  • 自动处理:去除空格、转小写
  • 容错:如果 Pinyin 类不存在,返回空字符串

3. 使用示例

示例 1:当归

MedicineNameAbbrService::build('当归');
// 输出: "dg"

示例 2:黄芪

MedicineNameAbbrService::build('黄芪');
// 输出: "hq"

示例 3:党参

MedicineNameAbbrService::build('党参');
// 输出: "ds"

示例 4:白术

MedicineNameAbbrService::build('白术');
// 输出: "bs"

自动生成时机

1. 创建药材时

文件: server/app/adminapi/logic/doctor/MedicineLogic.php

Medicine::create([
    'name' => $params['name'],
    'name_pinyin_abbr' => MedicineNameAbbrService::build($params['name']),
    // ... 其他字段
]);

2. 编辑药材时

Medicine::update([
    'id' => $params['id'],
    'name' => $params['name'],
    'name_pinyin_abbr' => MedicineNameAbbrService::build($params['name']),
    // ... 其他字段
]);

批量回填命令

命令:sync_medicine_pinyin_abbr

文件: server/app/common/command/SyncMedicinePinyinAbbr.php

用于批量生成或更新已有药材的拼音首字母。

使用方法

1. 仅更新空字段(默认)

cd server
php think sync_medicine_pinyin_abbr

只处理 name_pinyin_abbr 为空的记录。

2. 重算全部记录

php think sync_medicine_pinyin_abbr --all

重新计算所有药材的拼音首字母(覆盖现有值)。

3. 预览模式(不写入数据库)

php think sync_medicine_pinyin_abbr --dry

只统计将更新多少条,不实际写入。

4. 组合使用

php think sync_medicine_pinyin_abbr --all --dry

预览全部重算的结果。

命令输出示例

模式: 仅空 abbr,待处理 150 条
完成: 已更新 145 条,跳过 5 条。

检索功能

列表搜索

文件: server/app/adminapi/lists/doctor/MedicineLists.php

$query->where(function ($q) use ($kw, $keyword) {
    $q->where('name_pinyin_abbr', 'like', '%' . $kw . '%')
        ->whereOr('name', 'like', '%' . $keyword . '%');
});

功能说明:

  • 用户输入 "dg" 可以搜索到 "当归"
  • 用户输入 "当归" 也可以搜索到
  • 支持模糊匹配(LIKE 查询)

搜索示例

用户输入 匹配药材
dg 当归
hq 黄芪
ds 党参、丹参
bs 白术、白芍
当归 当归

数据库字段

表:zyt_doctor_medicine

`name_pinyin_abbr` varchar(64) DEFAULT NULL COMMENT '名称拼音首字母缩写(小写连写)'

索引建议

如果药材数量很大(>10000条),建议添加索引:

ALTER TABLE `zyt_doctor_medicine` 
ADD INDEX `idx_name_pinyin_abbr` (`name_pinyin_abbr`);

常见问题

Q1: 如何安装 overtrue/pinyin

cd server
composer require overtrue/pinyin

(已在项目中安装,无需手动执行)

Q2: 多音字如何处理?

overtrue/pinyin 会自动选择最常用的读音。例如:

  • "重" → "z" (重量) 或 "c" (重复)
  • 默认使用最常见的读音

Q3: 如何处理英文或数字?

  • 英文字母:保留原样并转小写
  • 数字:保留原样
  • 示例:"维生素B12""wssbB12""wssbb12"

Q4: 为什么有些药材搜索不到?

可能原因:

  1. name_pinyin_abbr 字段为空 → 运行批量回填命令
  2. 药材名称包含特殊字符 → 检查数据质量
  3. 索引未生效 → 检查数据库索引

Q5: 如何在其他模块使用?

use app\common\service\doctor\MedicineNameAbbrService;

// 生成拼音首字母
$abbr = MedicineNameAbbrService::build('当归');
echo $abbr; // 输出: dg

性能优化建议

1. 批量处理

命令使用 chunk(200) 分批处理,避免内存溢出:

$makeQuery()->chunk(200, function ($rows) {
    // 每次处理 200 条
});

2. 异步生成

对于大量数据,建议:

  • 使用队列异步处理
  • 在低峰期运行批量命令
  • 使用 --dry 先预览再执行

3. 缓存策略

如果药材数据不常变动,可以:

  • 缓存常用药材的拼音首字母
  • 使用 Redis 存储热门搜索词

相关文件

文件 说明
server/app/common/service/doctor/MedicineNameAbbrService.php 拼音首字母生成服务
server/app/common/command/SyncMedicinePinyinAbbr.php 批量回填命令
server/app/adminapi/logic/doctor/MedicineLogic.php 药材增删改逻辑
server/app/adminapi/lists/doctor/MedicineLists.php 药材列表搜索
server/app/common/model/doctor/Medicine.php 药材模型

扩展应用

此功能可以扩展到其他需要中文检索的模块:

1. 患者姓名检索

use app\common\service\doctor\MedicineNameAbbrService;

$patientName = '张三';
$abbr = MedicineNameAbbrService::build($patientName); // "zs"

2. 医生姓名检索

$doctorName = '李医生';
$abbr = MedicineNameAbbrService::build($doctorName); // "lys"

3. 诊断名称检索

$diagnosis = '感冒';
$abbr = MedicineNameAbbrService::build($diagnosis); // "gm"

总结

  • 核心类: MedicineNameAbbrService::build()
  • 依赖包: overtrue/pinyin
  • 存储字段: name_pinyin_abbr
  • 批量命令: php think sync_medicine_pinyin_abbr
  • 应用场景: 药材快速检索、模糊搜索

这个功能大大提升了中文药材名称的搜索体验,用户可以通过拼音首字母快速找到目标药材。