Files
disknext/routers/api/v1/admin/share/__init__.py
于小丘 6c96c43bea
Some checks failed
Test / test (push) Failing after 3m47s
refactor: 统一 sqlmodel_ext 用法至官方推荐模式
- 替换 Field(max_length=X) 为 StrX/TextX 类型别名(21 个 sqlmodels 文件)
- 替换 get + 404 检查为 get_exist_one()(17 个路由文件,约 50 处)
- 替换 save + session.refresh 为 save(load=...)
- 替换 session.add + commit 为 save()(dav/provider.py)
- 更新所有依赖至最新版本

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:13:16 +08:00

162 lines
3.9 KiB
Python

from datetime import datetime
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from loguru import logger as l
from middleware.auth import admin_required
from middleware.dependencies import SessionDep, TableViewRequestDep
from sqlmodels import (
ListResponse,
Share, AdminShareListItem,
)
from sqlmodel_ext import SQLModelBase
class ShareDetailResponse(SQLModelBase):
"""分享详情响应"""
id: UUID
"""分享UUID"""
code: str
"""分享码"""
views: int
"""浏览次数"""
downloads: int
"""下载次数"""
remain_downloads: int | None
"""剩余下载次数"""
expires: datetime | None
"""过期时间"""
preview_enabled: bool
"""是否启用预览"""
score: int
"""评分"""
has_password: bool
"""是否有密码"""
user_id: str
"""用户UUID"""
username: str | None
"""用户名"""
object: dict | None
"""关联对象信息"""
created_at: str
"""创建时间"""
admin_share_router = APIRouter(
prefix='/share',
tags=['admin', 'admin_share']
)
@admin_share_router.get(
path='/list',
summary='获取分享列表',
description='Get share list',
dependencies=[Depends(admin_required)]
)
async def router_admin_get_share_list(
session: SessionDep,
table_view: TableViewRequestDep,
user_id: UUID | None = None,
) -> ListResponse[AdminShareListItem]:
"""
获取分享列表。
:param session: 数据库会话
:param table_view: 分页排序参数依赖
:param user_id: 按用户筛选
:return: 分页分享列表
"""
condition = Share.user_id == user_id if user_id else None
result = await Share.get_with_count(session, condition, table_view=table_view, load=Share.user)
items: list[AdminShareListItem] = []
for s in result.items:
user = await s.awaitable_attrs.user
obj = await s.awaitable_attrs.object
items.append(AdminShareListItem.from_share(s, user, obj))
return ListResponse(items=items, count=result.count)
@admin_share_router.get(
path='/{share_id}',
summary='获取分享详情',
description='Get share detail by ID',
dependencies=[Depends(admin_required)]
)
async def router_admin_get_share(
session: SessionDep,
share_id: UUID,
) -> ShareDetailResponse:
"""
获取分享详情。
:param session: 数据库会话
:param share_id: 分享ID
:return: 分享详情
"""
share = await Share.get(session, Share.id == share_id, load=Share.object)
if not share:
raise HTTPException(status_code=404, detail="分享不存在")
obj = await share.awaitable_attrs.object
user = await share.awaitable_attrs.user
return ShareDetailResponse(
id=share.id,
code=share.code,
views=share.views,
downloads=share.downloads,
remain_downloads=share.remain_downloads,
expires=share.expires,
preview_enabled=share.preview_enabled,
score=share.score,
has_password=bool(share.password),
user_id=str(share.user_id),
username=user.email if user else None,
object={
"id": str(obj.id),
"name": obj.name,
"type": obj.type.value,
"size": obj.size,
} if obj else None,
created_at=share.created_at.isoformat(),
)
@admin_share_router.delete(
path='/{share_id}',
summary='删除分享',
description='Delete share by ID',
dependencies=[Depends(admin_required)],
status_code=204,
)
async def router_admin_delete_share(
session: SessionDep,
share_id: UUID,
) -> None:
"""
删除分享。
:param session: 数据库会话
:param share_id: 分享ID
:return: 删除结果
"""
share = await Share.get_exist_one(session, share_id)
await Share.delete(session, share)
l.info(f"管理员删除了分享: {share.code}")