8.5 KiB
8.5 KiB
模板参数可模糊查询(±容差)功能需求文档
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_searchableTINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否允许模糊查询(仅数值型)'fuzzy_toleranceDECIMAL(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. 后端实现要点(建议方案)
当前实现(精确匹配),示意:
-- 现状(等值):
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); - 条件:
CAST(JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.<key>')) AS DECIMAL(18,6)) BETWEEN :lower AND :upper
- 下限截断:
- 否则:执行等值匹配:
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. 实施清单(参考)
- 数据库:为
part_template_params增列fuzzy_searchable、fuzzy_tolerance;(变更需通过 MysqlMCP,成功后同步更新doc/database_documentation.md与backend/db/db.sql) - 配置:新增
search.fuzzy.*配置项并给出默认值(全局生效,无租户级覆盖); - 管理端:模板参数编辑 UI 新增开关与容差输入;
- 后端:按 8 节改造查询 SQL 构建逻辑(无
templateId也启用模糊,行级按模板判定); - 文档:在功能开发完成后更新
doc/openapi.yaml中模板参数 schema 与GET /api/products的查询规则说明,并标注实现状态; - 发布:前后端同步上线;无需灰度与回滚开关;
- 验收:按 10 节用例覆盖单测/集成测试与手工回归。