docs: add design for CRM product/customer pinyin initial search.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
05350a99a6
commit
65ea371d5f
1 file changed
+143
@@ -0,0 +1,143 @@
|
||||
# CRM 产品/客户名称拼音首字母检索
|
||||
|
||||
**日期:** 2026-08-07
|
||||
**状态:** 设计已确认
|
||||
**选定方案:** 表内冗余字段 `name_pinyin_abbr` + 后端 `pypinyin` 统一生成;列表与业务选择器 keyword 增加不区分大小写的拼音模糊匹配
|
||||
**相关模块:** 产品管理 `/#/crm/product`、客户管理 `/#/crm/customer`;合同/报价等产品选择器与客户选择器
|
||||
|
||||
## 1. 目标
|
||||
|
||||
1. 为产品名称、客户全称维护 **拼音首字母缩写**(库内存小写),支持多音字/特殊简称时人工纠正。
|
||||
2. 前台列表筛选、快速搜索,以及合同/报价等业务选择器的远程搜索,支持用拼音首字母 **模糊检索**,且输入大小写混合均可命中。
|
||||
3. 新增/保存时默认按名称自动生成;名称变更时 **仅当拼音字段为空才自动填**;已有值(含手改)不覆盖;表单提供「按名称重新生成」。
|
||||
4. 上线时对存量数据跑一次批量回填(仅填空字段)。
|
||||
|
||||
## 2. 非目标
|
||||
|
||||
- 不维护客户 `short_name` 的独立拼音字段(简称仍走现有中文 `LIKE`)。
|
||||
- 不存全拼、不做独立别名表、不做全文检索引擎。
|
||||
- 本期不改客户公海、小程序客户列表等其它入口的检索(可二期复用同一字段与工具函数)。
|
||||
- 不提供管理端「强制全量重算」入口(仅上线脚本一次回填)。
|
||||
- 不为 `LIKE '%xx%'` 强依赖新建索引(可按数据量后续评估)。
|
||||
|
||||
## 3. 背景与现状
|
||||
|
||||
- web-admin 已有 CRM **产品管理**(`crm_product`)与 **客户管理**(`crm_customer`)。
|
||||
- 当前检索均为名称/编号等字段的 `LIKE` 中文模糊匹配,无拼音相关列。
|
||||
- 业务痛点:打汉字检索偏慢,希望用拼音首字母快速定位。
|
||||
|
||||
## 4. 数据模型
|
||||
|
||||
| 表 | 新字段 | 类型 | 说明 |
|
||||
|----|--------|------|------|
|
||||
| `crm_product` | `name_pinyin_abbr` | `varchar(100)` DEFAULT NULL | 产品名称拼音首字母,存小写 |
|
||||
| `crm_customer` | `name_pinyin_abbr` | `varchar(100)` DEFAULT NULL | 客户全称拼音首字母,存小写 |
|
||||
|
||||
- 字段位置:业务字段区,紧挨 `product_name` / `customer_name` 之后;公共字段之前。
|
||||
- API / 前端驼峰:`namePinyinAbbr`。
|
||||
- DDL 同步维护:`docs/sql/` 基线及迁移脚本;符合 `database-conventions` 字段顺序约定。
|
||||
- `_row_to_dict`、Create/Update Body、前端 form **字段一致性** 必须包含该可写字段(见 `docs/dev-field-consistency.md`)。
|
||||
|
||||
## 5. 生成规则
|
||||
|
||||
后端统一工具函数(建议 `backend/app/utils/pinyin_abbr.py` 或同等位置),依赖 `pypinyin`(写入 `requirements.txt`)。
|
||||
|
||||
**算法:**
|
||||
|
||||
1. 输入字符串 trim;空则返回空串。
|
||||
2. 逐字符:
|
||||
- 汉字 → 取拼音首字母(`pypinyin` 默认读音),转小写;
|
||||
- `a-zA-Z0-9` → 转小写后保留;
|
||||
- 其余(空格、括号、%、中英文标点等)→ 丢弃。
|
||||
3. 拼接为连续小写串;若超过字段长度则截断至 100。
|
||||
|
||||
**示例(以实际 `pypinyin` 结果为准,下列为期望形态):**
|
||||
|
||||
| 名称 | `name_pinyin_abbr` |
|
||||
|------|-------------------|
|
||||
| `55% 工业硫酸` | `55gylls` |
|
||||
| `苯骈三氮唑BTA` | `bstnzbta` |
|
||||
| `PAC` | `pac` |
|
||||
| `安徽金浔新能源材料有限公司` | 按库结果连续小写首字母 |
|
||||
|
||||
**写入时机:**
|
||||
|
||||
| 场景 | 行为 |
|
||||
|------|------|
|
||||
| 新增且拼音为空 | 按名称自动生成 |
|
||||
| 编辑改名称,拼音仍为空 | 自动生成 |
|
||||
| 编辑改名称,拼音已有值 | **不覆盖** |
|
||||
| 用户点「按名称重新生成」 | 前端用当前名称覆盖表单拼音字段;保存时提交 |
|
||||
| 用户手改拼音 | 保存时 `strip` 后转小写入库 |
|
||||
| 上线回填脚本 | 仅空 / NULL 字段按名称生成 |
|
||||
|
||||
名称本身有必填校验;名称为空时不生成、不因拼音阻塞保存。
|
||||
|
||||
## 6. 检索语义
|
||||
|
||||
在现有 keyword / 名称类条件上 **OR** 拼音字段,大小写不敏感:
|
||||
|
||||
```text
|
||||
-- 伪代码;kw_lower = keyword.strip().lower()
|
||||
(名称 LIKE %keyword%)
|
||||
OR (编号等其它既有条件…)
|
||||
OR (LOWER(name_pinyin_abbr) LIKE %kw_lower%)
|
||||
```
|
||||
|
||||
- 中文检索行为保持不变。
|
||||
- 纯字母数字输入可命中拼音缩写(如 `GYlls` / `gylls` / `GYLLS` 等价)。
|
||||
- 客户列表既有 `customer_name` / `customer_no` / `short_name` / `mobile` 等条件保留,再 OR 拼音。
|
||||
|
||||
**本期必须改造的查询入口:**
|
||||
|
||||
| 入口 | 说明 |
|
||||
|------|------|
|
||||
| 产品列表 keyword | 筛选区 + 快速搜索 |
|
||||
| 产品 options / 选择器 | `fetchProductOptions`、`product-selector`、`DbCrmProductSelect` 等远程搜 |
|
||||
| 客户列表 keyword / customerName | 筛选区客户名称、快速搜索 |
|
||||
| 客户 options / 选择器 | `fetchCustomerOptions`、`DbCrmCustomerSelect` 等远程搜 |
|
||||
|
||||
合同/报价等使用上述 options/list 的选择器 **不新增独立查询参数**。
|
||||
|
||||
## 7. API 与后端改动要点
|
||||
|
||||
- CRUD create/update:接受 `namePinyinAbbr`;服务端按第 5 节规则归一化/补全。
|
||||
- list / options:keyword 条件并入拼音 OR。
|
||||
- detail / `_row_to_dict`:返回 `namePinyinAbbr`。
|
||||
- 回填:一次性脚本(如 `backend/scripts/backfill_name_pinyin_abbr.py`),按租户或全表扫描,仅更新空字段;失败行记日志,按批提交避免长事务。
|
||||
|
||||
## 8. 前端 UI
|
||||
|
||||
| 位置 | 改动 |
|
||||
|------|------|
|
||||
| 产品新增/编辑表单(含公共 `ProductFormDialog`) | 「拼音首字母」可编辑输入 + 「重新生成」按钮 |
|
||||
| 客户新增/编辑表单 | 同上 |
|
||||
| 产品/客户查看弹窗 | 只读展示拼音首字母,便于核对手改 |
|
||||
| 列表筛选 / 快速搜索 | placeholder / hint 提示可搜名称、编号、拼音首字母 |
|
||||
| 选择器搜索框 | 同步更新 placeholder(若有文案) |
|
||||
|
||||
UI 遵守 Fresh Mint:`label-position="top"`、按钮带图标、「重新生成」为中性描边;表单注释用 `#label` + `.form-label-tip`(如有需要)。
|
||||
|
||||
## 9. 上线步骤
|
||||
|
||||
1. 执行 DDL:两表增加 `name_pinyin_abbr`。
|
||||
2. 部署后端(含 `pypinyin`)与前端。
|
||||
3. 运行回填脚本(仅空字段)。
|
||||
4. 抽检:列表与选择器用中文、小写拼音、大小写混合拼音检索若干已知样例。
|
||||
|
||||
## 10. 测试要点
|
||||
|
||||
- 新增产品/客户:不填拼音 → 自动生成小写缩写。
|
||||
- 手改拼音后改名称保存 → 拼音不被覆盖。
|
||||
- 「重新生成」→ 表单拼音被名称规则覆盖,保存后生效。
|
||||
- 列表 / options:`gylls`、`GYLLS`、`GYlls` 均可命中对应产品;中文名称检索仍可用。
|
||||
- 回填:已有手改值的行不被脚本覆盖;空行被填上。
|
||||
- 字段一致性脚本:`python scripts/check_field_consistency.py`(若覆盖 product/customer)通过。
|
||||
|
||||
## 11. 风险与缓解
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|------|------|
|
||||
| 多音字默认读音不准 | 表单可手改 + 重新生成 |
|
||||
| 化工名含括号、百分比、英文缩写 | 生成规则保留字母数字、丢弃符号(见第 5 节) |
|
||||
| 存量未回填则拼音搜不到 | 上线必跑一次回填脚本 |
|
||||
Reference in new issue
Block a user