From 28b73a0bb4c42821c11f619a16e71876453a56ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8E=E5=B0=8F=E4=B8=98?= Date: Wed, 14 Jan 2026 00:00:07 +0800 Subject: [PATCH] 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. --- models/__init__.py | 1 - models/object.py | 2 +- routers/api/v1/object/__init__.py | 31 ++++++++++++++++++------------- tmpclaude-c1f9-cwd | 1 + 4 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 tmpclaude-c1f9-cwd diff --git a/models/__init__.py b/models/__init__.py index e818884..f8431d5 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -94,7 +94,6 @@ from .model_base import ( MetricsSummary, LicenseInfo, VersionInfo, - AdminSummaryData, AdminSummaryResponse, ) diff --git a/models/object.py b/models/object.py index aa2067c..7951702 100644 --- a/models/object.py +++ b/models/object.py @@ -93,7 +93,7 @@ class DirectoryCreateRequest(SQLModelBase): class ObjectMoveRequest(SQLModelBase): """移动对象请求 DTO""" - src_ids: UUID | list[UUID] + src_ids: list[UUID] """源对象UUID列表""" dst_id: UUID diff --git a/routers/api/v1/object/__init__.py b/routers/api/v1/object/__init__.py index 4cf136d..93a10c4 100644 --- a/routers/api/v1/object/__init__.py +++ b/routers/api/v1/object/__init__.py @@ -253,12 +253,13 @@ async def router_object_move( if not dst.is_folder: raise HTTPException(status_code=400, detail="目标不是有效文件夹") + # 存储 dst 的属性,避免后续数据库操作导致 dst 过期后无法访问 + dst_id = dst.id + dst_parent_id = dst.parent_id + moved_count = 0 - # 处理单个 UUID 或 UUID 列表 - src_ids = request.src_ids if isinstance(request.src_ids, list) else [request.src_ids] - - for src_id in src_ids: + for src_id in request.src_ids: src = await Object.get(session, Object.id == src_id) if not src or src.owner_id != user_id: continue @@ -268,18 +269,19 @@ async def router_object_move( continue # 检查是否移动到自身或子目录(防止循环引用) - if src.id == dst.id: + if src.id == dst_id: continue # 检查是否将目录移动到其子目录中(循环检测) if src.is_folder: - current = dst + current_parent_id = dst_parent_id is_cycle = False - while current and current.parent_id: - if current.parent_id == src.id: + while current_parent_id: + if current_parent_id == src.id: is_cycle = True 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: continue @@ -287,20 +289,23 @@ async def router_object_move( existing = await Object.get( session, (Object.owner_id == user_id) & - (Object.parent_id == dst.id) & + (Object.parent_id == dst_id) & (Object.name == src.name) ) if existing: continue # 跳过重名对象 - src.parent_id = dst.id - await src.save(session) + src.parent_id = dst_id + await src.save(session, commit=False, refresh=False) moved_count += 1 + # 统一提交所有更改 + await session.commit() + return ResponseBase( data={ "moved": moved_count, - "total": len(src_ids), + "total": len(request.src_ids), } ) diff --git a/tmpclaude-c1f9-cwd b/tmpclaude-c1f9-cwd new file mode 100644 index 0000000..b6e982b --- /dev/null +++ b/tmpclaude-c1f9-cwd @@ -0,0 +1 @@ +/d/admin/Documents/Code/Server