Files
PartsInquiry/doc/模板参数可模糊查询_功能需求文档.md
2025-09-29 21:38:32 +08:00

128 lines
8.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.

## 模板参数可模糊查询(±容差)功能需求文档
### 1. 背景与目标
当前用户端「按模板参数查询」要求参数值与数据库完全相同才能命中,实际使用中数值类参数(如内径、外径、长度等)存在测量/录入微小误差,严格等值导致命中率偏低。新增能力:在管理端创建模板时,为每个参数提供「可模糊查询」选项;开启后,用户搜索该参数时按数值区间匹配(±容差);未开启的参数继续精确等值。
### 2. 业务范围
- 场景:用户端/管理端的商品列表查询(含「按模板参数查询」模式)。
- 对象:模板参数定义(仅限数值型参数生效)。
- 不影响:名称/品牌/型号/规格关键字搜索逻辑;非数值类型参数的等值匹配逻辑。
### 3. 术语与约束
- 模板参数类型string/number/boolean/enum/date。
- 模糊查询仅对 type=number 生效;其他类型不展示该选项或忽略配置。
- 容差tolerance对搜索入参 v匹配区间为 \[v - tolerance, v + tolerance](闭区间)。默认容差为 1见配置项可在参数层级单独覆盖。
- 组合关系:多参数为 AND 关系;每个参数根据其「可模糊查询」与容差独立计算。
### 4. 交互与流程
- 管理端-模板配置:
- 新建/编辑模板参数时,新增选项:
- 可模糊查询(开关,仅当类型为 number 显示)
- 容差值number>0显示单位提示`unit` 字段;当开关开启时必填,否则置空)
- 校验:
- type≠number 时禁止开启;
- 容差必须为正数,支持小数;
- 可保存为“使用平台默认容差”,当字段留空时后端落默认(见配置)。
- 用户端/管理端-按模板参数查询:
- 入参与现状一致:仍以 `templateId` + 多个 `param_*` 传参;
- 行为变化:
- 对应参数若开启可模糊查询:按区间 \[v - tol, v + tol] 比较;
- 否则:仍为精确等值比较。
### 5. 数据模型变更(待实施)
- 表:`part_template_params`
- 新增列:
- `fuzzy_searchable` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否允许模糊查询(仅数值型)'
- `fuzzy_tolerance` DECIMAL(18,6) NULL COMMENT '容差NULL 表示使用平台默认容差'
- 说明:
- 仅当 `type='number' AND fuzzy_searchable=1` 时才使用容差;
- 初始迁移将全部历史记录置为 `fuzzy_searchable=0, fuzzy_tolerance=NULL`,保持现有行为不变。
### 6. 配置项(后端)
- `search.fuzzy.enabled`bool默认 true是否启用模糊查询全局开关
- `search.fuzzy.defaultTolerance`decimal默认 1.0):当参数未设置 `fuzzy_tolerance` 时使用;
- 读取途径Spring 配置application.properties/yaml或环境变量。禁止在代码中硬编码数字 1。
- 仅全局配置,不支持租户级(`system_parameters`)覆盖;无需设置小数精度上限/最大容差限制。
### 7. 接口协议与兼容性
- 查询接口:`GET /api/products`(已存在)
- 入参保持不变:`templateId``param_*`
- 语义扩展(无须 `templateId` 也启用模糊):后端将基于商品行的 `template_id` 与参数定义逐行判定某个 `param_*` 是否启用 ±容差;若该参数在对应模板中未开启模糊或非数值型,则对该条件执行等值匹配。
- 模板接口:`POST /api/admin/part-templates``PUT /api/admin/part-templates/{id}`(已存在)
- 参数定义对象新增字段:
- `fuzzySearchable`boolean
- `fuzzyTolerance`numbernullable
- 若前端暂未改造,后端默认按 `fuzzySearchable=false` 处理,兼容旧请求体。
(根据「接口规范生效条件」,待功能开发完成后更新 `doc/openapi.yaml` 中对应 schema 与描述,并在 summary/description 标注实现状态)
### 8. 后端实现要点(建议方案)
当前实现(精确匹配),示意:
```sql
-- 现状(等值):
AND JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.内径')) = '10'
```
推荐实现:
- 行级判定方案(支持无 `templateId` 也启用模糊):
- 对每个传入的 `param_<key>=v`
-`EXISTS` 子查询或 `JOIN part_template_params ptp ON ptp.template_id=p.template_id AND ptp.field_key='<key>'` 获取参数定义;
-`ptp.type='number' AND ptp.fuzzy_searchable=1`:对 `v` 解析为数值,计算 `tol = COALESCE(ptp.fuzzy_tolerance, :defaultTolerance)`
- 下限截断:`lower = GREATEST(0, v - tol)`
- 条件:
```sql
CAST(JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.<key>')) AS DECIMAL(18,6)) BETWEEN :lower AND :upper
```
- 否则:执行等值匹配:
```sql
JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.<key>')) = :val
```
- 快路径(可选):当请求携带 `templateId` 时,可先一次性加载该模板参数定义映射到内存,按映射决定每个条件构造,以减少 `JOIN/EXISTS` 次数。
- 容差取值:优先 `ptp.fuzzy_tolerance`,否则全局 `search.fuzzy.defaultTolerance`。
性能建议:
- 初期:允许全表扫描 + JSON_EXTRACT观察真实 QPS 与延迟;
- 进阶(可选):对热点参数引入“生成列 + 索引”Generated Column例如
- 在 `products` 增加 `attr_<key> DECIMAL(18,6) GENERATED ALWAYS AS (CAST(JSON_UNQUOTE(JSON_EXTRACT(attributes_json, '$.<key>')) AS DECIMAL(18,6))) STORED` 并建索引,以支持范围查询;
- 仅对访问量高的少数参数启用,避免列爆炸。
### 9. 管理端实现要点UI/校验)
- `admin/src/views/parts/Templates.vue`
- 参数编辑行新增:
- 开关:可模糊查询(仅 type=number 显示)
- 数值输入:容差(显示单位,>0支持小数留空表示使用平台默认
- 保存/加载兼容:与后端新增字段映射,历史数据默认显示为关闭态。
- 校验:当参数开启模糊时,对应值在 UI 侧仅允许数字输入;单位提示与 `unit` 一致。
### 10. 验收标准Test Cases
- 单参数-模糊:模板字段 `内径`numberfuzzy=truetolerance=1商品 A/B/C 分别取值 9/10/11搜索 `param_内径=10` 命中 A/B/C。
- 单参数-精确:同上但 fuzzy=false搜索 `param_内径=10` 仅命中 B。
- 多参数组合:`内径`fuzzy=true, tol=0.5)、`长度`fuzzy=false搜索 `param_内径=10`、`param_长度=20` 仅命中满足区间与等值的交集。
- 无 templateId也启用模糊后端逐行按 `p.template_id` 与参数定义判定是否应用容差。
- 容差来源:当 `fuzzy_tolerance=NULL` 时,生效平台默认容差;覆盖值生效优先级高于默认。
- 非数值参数:即使请求携带 `param_颜色=黑`,也严格等值。
- 下限截断:当 `v - tol < 0` 时,以 `0` 作为下限;不支持负数参数匹配。
- 非法输入:当参数在模板中开启模糊但请求值非数字时,返回 400Bad Request
### 11. 兼容与回退
- 不改动现有请求入参与返回体,历史客户端无需升级亦可按原精确逻辑使用;
- 新能力由模板参数配置显式开启,可随时在模板中关闭;
- 如需全局关闭,可通过 `search.fuzzy.enabled=false` 临时禁用(后端配置)。
### 12. 风险与注意事项
- 数据质量:历史 `attributes_json` 中数值可能以字符串存储;需统一以 `CAST(JSON_UNQUOTE(...))` 解析。
- 单位与容差UI 需提示单位;容差与单位一一对应,避免“毫米 vs 厘米”误解。
- 性能:范围查询较等值更难走索引;必要时引入“生成列+索引”优化热点字段。
- 负数与边界:不支持负数参数;区间采用闭区间,且下限截断为 `0`。
### 13. 实施清单(参考)
1) 数据库:为 `part_template_params` 增列 `fuzzy_searchable`、`fuzzy_tolerance`;(变更需通过 MysqlMCP成功后同步更新 `doc/database_documentation.md` 与 `backend/db/db.sql`
2) 配置:新增 `search.fuzzy.*` 配置项并给出默认值(全局生效,无租户级覆盖);
3) 管理端:模板参数编辑 UI 新增开关与容差输入;
4) 后端:按 8 节改造查询 SQL 构建逻辑(无 `templateId` 也启用模糊,行级按模板判定);
5) 文档:在功能开发完成后更新 `doc/openapi.yaml` 中模板参数 schema 与 `GET /api/products` 的查询规则说明并标注实现状态
6) 发布前后端同步上线无需灰度与回滚开关
7) 验收 10 节用例覆盖单测/集成测试与手工回归