Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions backend/apps/system/api/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,31 @@ async def pager(

# 相似度排序:精确匹配 > 前缀匹配 > 包含匹配
# 当有 keyword 时,将 similarity_score 加入 SELECT 列以满足 DISTINCT 约束
# 对 account、name、email 三个字段分别计算相似度,取最高(最小值)
similarity_score = None
if keyword:
similarity_score = case(
from sqlalchemy import func
# 每个字段的相似度分数
account_score = case(
(UserModel.account == keyword, 0),
(UserModel.account.startswith(keyword), 1),
(UserModel.account.contains(keyword), 2),
else_=3
)
name_score = case(
(UserModel.name == keyword, 0),
(UserModel.name.startswith(keyword), 1),
(UserModel.name.contains(keyword), 2),
else_=3
)
email_score = case(
(UserModel.email == keyword, 0),
(UserModel.email.startswith(keyword), 1),
(UserModel.email.contains(keyword), 2),
else_=3
)
# 取三个字段中的最小值(最高匹配度)
similarity_score = func.LEAST(account_score, name_score, email_score)
select_columns.append(similarity_score.label('similarity_score'))

origin_stmt = (
Expand Down Expand Up @@ -133,12 +150,26 @@ async def pager(
)
# 第二次查询也需要应用相同的相似度排序
if keyword:
similarity_score = case(
from sqlalchemy import func
account_score = case(
(UserModel.account == keyword, 0),
(UserModel.account.startswith(keyword), 1),
(UserModel.account.contains(keyword), 2),
else_=3
)
name_score = case(
(UserModel.name == keyword, 0),
(UserModel.name.startswith(keyword), 1),
(UserModel.name.contains(keyword), 2),
else_=3
)
email_score = case(
(UserModel.email == keyword, 0),
(UserModel.email.startswith(keyword), 1),
(UserModel.email.contains(keyword), 2),
else_=3
)
similarity_score = func.LEAST(account_score, name_score, email_score)
stmt = stmt.order_by(similarity_score, sort_clause)
else:
stmt = stmt.order_by(sort_clause)
Expand Down
Loading