From 3587559a87f166626ed17167f6baf0f9b44670c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=B1=BC=E5=BC=80=E5=8F=91?= Date: Tue, 2 Jun 2026 15:51:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=B4=A0=E6=9D=90=E5=9B=9E=E9=80=80?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E6=94=AF=E6=8C=81=E6=A8=A1=E7=B3=8A=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E4=BA=8C=E7=BA=A7=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 broll_category.get_by_name_like_and_level() 模糊匹配方法 - _try_fallback_to_parent 增加三级降级策略: 1. 精确匹配 2. 模糊匹配 LIKE %parent_name%(兼容'电路施工'→'电路施工镜') 3. 自动补后缀'镜'/'阶段'再精确匹配 - 解决 scene 中 parent_name 与数据库二级分类 name 不一致导致回退失败的问题 --- python-api/app/crud/broll_category.py | 13 +++++++++++ python-api/app/services/material_service.py | 24 +++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/python-api/app/crud/broll_category.py b/python-api/app/crud/broll_category.py index 8fa1ad3..f1155e1 100644 --- a/python-api/app/crud/broll_category.py +++ b/python-api/app/crud/broll_category.py @@ -57,6 +57,19 @@ class BrollCategoryCRUD(CRUDBase[BrollCategory]): ) return list(result.scalars().all()) + async def get_by_name_like_and_level( + self, db: AsyncSession, *, name: str, level: int + ) -> BrollCategory | None: + """根据名称模糊匹配和层级获取启用的分类(LIKE %name%)""" + result = await db.execute( + select(BrollCategory).where( + BrollCategory.name.like(f"%{name}%"), + BrollCategory.level == level, + BrollCategory.status == "active", + ) + ) + return result.scalar_one_or_none() + # 导出实例 broll_category = BrollCategoryCRUD() diff --git a/python-api/app/services/material_service.py b/python-api/app/services/material_service.py index d6fe5a4..7aac534 100644 --- a/python-api/app/services/material_service.py +++ b/python-api/app/services/material_service.py @@ -69,6 +69,11 @@ async def _try_fallback_to_parent( - 若 scene 含 '-',取后半部分作为 parent_name(如 '电路施工-电路施工' -> '电路施工') - 若不含 '-',直接以整个 scene 作为 parent_name + 匹配策略(逐级降级): + 1. 精确匹配 level=2 分类 name + 2. 模糊匹配(LIKE %parent_name%),兼容 "电路施工" → "电路施工镜" + 3. 去掉常见后缀(镜、阶段等)再精确匹配 + 返回: 随机选中的一个 level=3 子分类,或 None """ @@ -77,9 +82,28 @@ async def _try_fallback_to_parent( else: parent_name = normalized_scene + # 1. 精确匹配 parent = await broll_category.get_by_name_and_level( db, name=parent_name, level=2 ) + + # 2. 模糊匹配(兼容 "电路施工" → "电路施工镜") + if parent is None: + parent = await broll_category.get_by_name_like_and_level( + db, name=parent_name, level=2 + ) + + # 3. 去掉常见后缀再试 + if parent is None: + for suffix in ("镜", "阶段"): + if not parent_name.endswith(suffix): + candidate = parent_name + suffix + parent = await broll_category.get_by_name_and_level( + db, name=candidate, level=2 + ) + if parent: + break + if parent is None: return None