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

276 lines
6.5 KiB
Markdown
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.
# 药材名称拼音首字母功能说明
## 概述
系统使用 `overtrue/pinyin` 包自动生成中文药材名称的拼音首字母缩写,存储在 `name_pinyin_abbr` 字段中,用于快速检索。
## 核心实现
### 1. 依赖包
```json
"overtrue/pinyin": "^6.0"
```
已在 `server/composer.json` 中配置。
### 2. 服务类:`MedicineNameAbbrService`
**文件位置:** `server/app/common/service/doctor/MedicineNameAbbrService.php`
```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:当归
```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`
- **应用场景:** 药材快速检索、模糊搜索
这个功能大大提升了中文药材名称的搜索体验,用户可以通过拼音首字母快速找到目标药材。