# 药材名称拼音首字母功能说明 ## 概述 系统使用 `overtrue/pinyin` 包自动生成中文药材名称的拼音首字母缩写,存储在 `name_pinyin_abbr` 字段中,用于快速检索。 ## 核心实现 ### 1. 依赖包 ```json "overtrue/pinyin": "^6.0" ``` 已在 `server/composer.json` 中配置。 ### 2. 服务类:`MedicineNameAbbrService` **文件位置:** `server/app/common/service/doctor/MedicineNameAbbrService.php` ```php join(''); return strtolower($abbr); } } ``` **功能说明:** - 输入:中文药材名称(如 "当归") - 输出:拼音首字母小写连写(如 "dg") - 自动处理:去除空格、转小写 - 容错:如果 Pinyin 类不存在,返回空字符串 ### 3. 使用示例 #### 示例 1:当归 ```php MedicineNameAbbrService::build('当归'); // 输出: "dg" ``` #### 示例 2:黄芪 ```php MedicineNameAbbrService::build('黄芪'); // 输出: "hq" ``` #### 示例 3:党参 ```php MedicineNameAbbrService::build('党参'); // 输出: "ds" ``` #### 示例 4:白术 ```php MedicineNameAbbrService::build('白术'); // 输出: "bs" ``` ## 自动生成时机 ### 1. 创建药材时 **文件:** `server/app/adminapi/logic/doctor/MedicineLogic.php` ```php Medicine::create([ 'name' => $params['name'], 'name_pinyin_abbr' => MedicineNameAbbrService::build($params['name']), // ... 其他字段 ]); ``` ### 2. 编辑药材时 ```php 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. 仅更新空字段(默认) ```bash cd server php think sync_medicine_pinyin_abbr ``` 只处理 `name_pinyin_abbr` 为空的记录。 #### 2. 重算全部记录 ```bash php think sync_medicine_pinyin_abbr --all ``` 重新计算所有药材的拼音首字母(覆盖现有值)。 #### 3. 预览模式(不写入数据库) ```bash php think sync_medicine_pinyin_abbr --dry ``` 只统计将更新多少条,不实际写入。 #### 4. 组合使用 ```bash php think sync_medicine_pinyin_abbr --all --dry ``` 预览全部重算的结果。 ### 命令输出示例 ``` 模式: 仅空 abbr,待处理 150 条 完成: 已更新 145 条,跳过 5 条。 ``` ## 检索功能 ### 列表搜索 **文件:** `server/app/adminapi/lists/doctor/MedicineLists.php` ```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` ```sql `name_pinyin_abbr` varchar(64) DEFAULT NULL COMMENT '名称拼音首字母缩写(小写连写)' ``` ### 索引建议 如果药材数量很大(>10000条),建议添加索引: ```sql ALTER TABLE `zyt_doctor_medicine` ADD INDEX `idx_name_pinyin_abbr` (`name_pinyin_abbr`); ``` ## 常见问题 ### Q1: 如何安装 overtrue/pinyin? ```bash cd server composer require overtrue/pinyin ``` (已在项目中安装,无需手动执行) ### Q2: 多音字如何处理? `overtrue/pinyin` 会自动选择最常用的读音。例如: - "重" → "z" (重量) 或 "c" (重复) - 默认使用最常见的读音 ### Q3: 如何处理英文或数字? - 英文字母:保留原样并转小写 - 数字:保留原样 - 示例:`"维生素B12"` → `"wssbB12"` → `"wssbb12"` ### Q4: 为什么有些药材搜索不到? 可能原因: 1. `name_pinyin_abbr` 字段为空 → 运行批量回填命令 2. 药材名称包含特殊字符 → 检查数据质量 3. 索引未生效 → 检查数据库索引 ### Q5: 如何在其他模块使用? ```php use app\common\service\doctor\MedicineNameAbbrService; // 生成拼音首字母 $abbr = MedicineNameAbbrService::build('当归'); echo $abbr; // 输出: dg ``` ## 性能优化建议 ### 1. 批量处理 命令使用 `chunk(200)` 分批处理,避免内存溢出: ```php $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. 患者姓名检索 ```php use app\common\service\doctor\MedicineNameAbbrService; $patientName = '张三'; $abbr = MedicineNameAbbrService::build($patientName); // "zs" ``` ### 2. 医生姓名检索 ```php $doctorName = '李医生'; $abbr = MedicineNameAbbrService::build($doctorName); // "lys" ``` ### 3. 诊断名称检索 ```php $diagnosis = '感冒'; $abbr = MedicineNameAbbrService::build($diagnosis); // "gm" ``` ## 总结 - **核心类:** `MedicineNameAbbrService::build()` - **依赖包:** `overtrue/pinyin` - **存储字段:** `name_pinyin_abbr` - **批量命令:** `php think sync_medicine_pinyin_abbr` - **应用场景:** 药材快速检索、模糊搜索 这个功能大大提升了中文药材名称的搜索体验,用户可以通过拼音首字母快速找到目标药材。