fix: PR#164审查修复 - P1 count_by_user status参数 + P2 内存分页优化
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 170h11m59s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 170h12m4s
Deploy / Deploy Staging (push) Failing after 170h14m34s
CI/CD Pipeline / Frontend Lint (push) Failing after 170h15m9s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 170h15m14s

P1修复:
- voice_library_repository.count_by_user() 增加可选 status 参数
- 修复 list_voices_unified 中 TypeError: count_by_user got unexpected keyword argument 'status'

P2修复:
- 移除 limit=1000 全量拉取,改为直接传递 skip/limit 到仓储层
- 删除冗余的 clone_repository_count() 辅助函数
- 优化统一列表分页逻辑,代码更清晰

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
灵应
2026-07-02 10:39:15 +08:00
parent 44dc89360a
commit 5584df3d55
2 changed files with 24 additions and 36 deletions
+19 -33
View File
@@ -137,56 +137,42 @@ def list_voices_unified(
preset_count = 0
clone_count = 0
has_preset = type is None or type == "preset"
has_clone = type is None or type == "clone"
# 获取预置音色
if type is None or type == "preset":
if has_preset:
preset_items = [_preset_to_unified_response(p) for p in PRESET_VOICES]
preset_count = len(preset_items)
if type == "preset":
# 仅预置:应用分页
items = preset_items[skip : skip + limit]
else:
items.extend(preset_items)
# 获取克隆音色
if type is None or type == "clone":
if has_clone:
use_case = ListVoiceLibraryUseCase(voice_repository)
clone_items_raw = use_case.execute(user_id, status=status_filter, skip=0, limit=1000)
clone_items_raw = use_case.execute(user_id, status=status_filter, skip=skip, limit=limit)
clone_items = [_to_unified_response(i) for i in clone_items_raw]
clone_count = len(clone_items)
if type == "clone":
# 仅克隆:应用分页
items = clone_items[skip : skip + limit]
else:
items.extend(clone_items)
clone_count = voice_repository.count_by_user(user_id, status=status_filter) if status_filter else voice_repository.count_by_user(user_id)
# 全量模式:应用分页
if type is None:
total = preset_count + clone_count
items = items[skip : skip + limit]
elif type == "preset":
# 组装结果
if type == "preset":
items = preset_items[skip : skip + limit]
total = preset_count
elif type == "clone":
items = clone_items
total = clone_count
else:
total = clone_repository_count(voice_repository, user_id, status_filter)
# 全量模式:预置在前,克隆补位
all_items = preset_items + clone_items
total = preset_count + clone_count
items = all_items[skip : skip + limit]
return UnifiedVoiceListResponse(
items=items,
total=total,
preset_count=preset_count if type != "clone" else 0,
clone_count=clone_count if type != "preset" else 0,
preset_count=preset_count if has_preset else 0,
clone_count=clone_count if has_clone else 0,
)
def clone_repository_count(
voice_repository: SQLAlchemyVoiceLibraryRepository,
user_id: str,
status_filter: Optional[str],
) -> int:
"""获取克隆音色数量。"""
if status_filter:
return voice_repository.count_by_user(user_id, status=status_filter)
return voice_repository.count_by_user(user_id)
# ==================== 预置音色专用端点 ====================
@@ -110,15 +110,17 @@ class SQLAlchemyVoiceLibraryRepository:
self.session.commit()
return True
def count_by_user(self, user_id: str) -> int:
return (
def count_by_user(self, user_id: str, *, status: Optional[str] = None) -> int:
query = (
self.session.query(VoiceLibraryModel)
.filter(
VoiceLibraryModel.user_id == user_id,
VoiceLibraryModel.status != "deleted",
)
.count()
)
if status:
query = query.filter(VoiceLibraryModel.status == status)
return query.count()
@staticmethod
def _model_to_entity(model: VoiceLibraryModel) -> VoiceLibraryItem: