Refactor object move API and fix src_ids type

Changed ObjectMoveRequest.src_ids to always be a list of UUIDs for consistency. Refactored the object move API to simplify src_ids handling, optimize cycle detection, and batch commit database changes for efficiency. Also removed unused AdminSummaryData import.
This commit is contained in:
2026-01-14 00:00:07 +08:00
parent 3059f9c259
commit 28b73a0bb4
4 changed files with 20 additions and 15 deletions

View File

@@ -94,7 +94,6 @@ from .model_base import (
MetricsSummary, MetricsSummary,
LicenseInfo, LicenseInfo,
VersionInfo, VersionInfo,
AdminSummaryData,
AdminSummaryResponse, AdminSummaryResponse,
) )

View File

@@ -93,7 +93,7 @@ class DirectoryCreateRequest(SQLModelBase):
class ObjectMoveRequest(SQLModelBase): class ObjectMoveRequest(SQLModelBase):
"""移动对象请求 DTO""" """移动对象请求 DTO"""
src_ids: UUID | list[UUID] src_ids: list[UUID]
"""源对象UUID列表""" """源对象UUID列表"""
dst_id: UUID dst_id: UUID

View File

@@ -253,12 +253,13 @@ async def router_object_move(
if not dst.is_folder: if not dst.is_folder:
raise HTTPException(status_code=400, detail="目标不是有效文件夹") raise HTTPException(status_code=400, detail="目标不是有效文件夹")
# 存储 dst 的属性,避免后续数据库操作导致 dst 过期后无法访问
dst_id = dst.id
dst_parent_id = dst.parent_id
moved_count = 0 moved_count = 0
# 处理单个 UUID 或 UUID 列表 for src_id in request.src_ids:
src_ids = request.src_ids if isinstance(request.src_ids, list) else [request.src_ids]
for src_id in src_ids:
src = await Object.get(session, Object.id == src_id) src = await Object.get(session, Object.id == src_id)
if not src or src.owner_id != user_id: if not src or src.owner_id != user_id:
continue continue
@@ -268,18 +269,19 @@ async def router_object_move(
continue continue
# 检查是否移动到自身或子目录(防止循环引用) # 检查是否移动到自身或子目录(防止循环引用)
if src.id == dst.id: if src.id == dst_id:
continue continue
# 检查是否将目录移动到其子目录中(循环检测) # 检查是否将目录移动到其子目录中(循环检测)
if src.is_folder: if src.is_folder:
current = dst current_parent_id = dst_parent_id
is_cycle = False is_cycle = False
while current and current.parent_id: while current_parent_id:
if current.parent_id == src.id: if current_parent_id == src.id:
is_cycle = True is_cycle = True
break break
current = await Object.get(session, Object.id == current.parent_id) current = await Object.get(session, Object.id == current_parent_id)
current_parent_id = current.parent_id if current else None
if is_cycle: if is_cycle:
continue continue
@@ -287,20 +289,23 @@ async def router_object_move(
existing = await Object.get( existing = await Object.get(
session, session,
(Object.owner_id == user_id) & (Object.owner_id == user_id) &
(Object.parent_id == dst.id) & (Object.parent_id == dst_id) &
(Object.name == src.name) (Object.name == src.name)
) )
if existing: if existing:
continue # 跳过重名对象 continue # 跳过重名对象
src.parent_id = dst.id src.parent_id = dst_id
await src.save(session) await src.save(session, commit=False, refresh=False)
moved_count += 1 moved_count += 1
# 统一提交所有更改
await session.commit()
return ResponseBase( return ResponseBase(
data={ data={
"moved": moved_count, "moved": moved_count,
"total": len(src_ids), "total": len(request.src_ids),
} }
) )

1
tmpclaude-c1f9-cwd Normal file
View File

@@ -0,0 +1 @@
/d/admin/Documents/Code/Server