This commit is contained in:
Your Name
2026-04-15 16:31:25 +08:00
parent 906684c1ed
commit 3d9c5dd8f5
47 changed files with 7963 additions and 10 deletions
+275
View File
@@ -0,0 +1,275 @@
# 药材名称拼音首字母功能说明
## 概述
系统使用 `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`
- **应用场景:** 药材快速检索、模糊搜索
这个功能大大提升了中文药材名称的搜索体验,用户可以通过拼音首字母快速找到目标药材。