128 lines
8.5 KiB
Markdown
128 lines
8.5 KiB
Markdown
## 模板参数可模糊查询(±容差)功能需求文档
|
||
|
||
### 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`(number,nullable)
|
||
- 若前端暂未改造,后端默认按 `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)
|
||
- 单参数-模糊:模板字段 `内径`(number,fuzzy=true,tolerance=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` 作为下限;不支持负数参数匹配。
|
||
- 非法输入:当参数在模板中开启模糊但请求值非数字时,返回 400(Bad 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 节用例覆盖单测/集成测试与手工回归。
|
||
|
||
|