This commit is contained in:
2025-09-29 21:38:32 +08:00
parent ed26244cdb
commit 19117de6c8
182 changed files with 11590 additions and 2156 deletions

View File

@@ -0,0 +1,127 @@
## 模板参数可模糊查询(±容差)功能需求文档
### 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 节用例覆盖单测/集成测试与手工回归