Files
disknext/routers/api/v1/admin/theme/__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

188 lines
4.7 KiB
Python

from uuid import UUID
from fastapi import APIRouter, Depends, status
from loguru import logger as l
from sqlalchemy import update as sql_update
from middleware.auth import admin_required
from middleware.dependencies import SessionDep
from sqlmodels import (
ThemePreset,
ThemePresetCreateRequest,
ThemePresetUpdateRequest,
ThemePresetResponse,
ThemePresetListResponse,
)
from utils import http_exceptions
admin_theme_router = APIRouter(
prefix="/theme",
tags=["admin", "admin_theme"],
dependencies=[Depends(admin_required)],
)
@admin_theme_router.get(
path='/',
summary='获取主题预设列表',
)
async def router_admin_theme_list(session: SessionDep) -> ThemePresetListResponse:
"""
获取所有主题预设列表
认证:需要管理员权限
响应:
- ThemePresetListResponse: 包含所有主题预设的列表
"""
presets: list[ThemePreset] = await ThemePreset.get(session, fetch_mode="all")
return ThemePresetListResponse(
themes=[ThemePresetResponse.from_preset(p) for p in presets]
)
@admin_theme_router.post(
path='/',
summary='创建主题预设',
status_code=status.HTTP_204_NO_CONTENT,
)
async def router_admin_theme_create(
session: SessionDep,
request: ThemePresetCreateRequest,
) -> None:
"""
创建新的主题预设
认证:需要管理员权限
请求体:
- name: 预设名称(唯一)
- colors: 颜色配置对象
错误处理:
- 409: 名称已存在
"""
# 检查名称唯一性
existing = await ThemePreset.get(session, ThemePreset.name == request.name)
if existing:
http_exceptions.raise_conflict(f"主题预设名称 '{request.name}' 已存在")
preset = ThemePreset(
name=request.name,
**request.colors.model_dump(),
)
preset = await preset.save(session)
l.info(f"管理员创建了主题预设: {request.name}")
@admin_theme_router.patch(
path='/{preset_id}',
summary='更新主题预设',
status_code=status.HTTP_204_NO_CONTENT,
)
async def router_admin_theme_update(
session: SessionDep,
preset_id: UUID,
request: ThemePresetUpdateRequest,
) -> None:
"""
部分更新主题预设
认证:需要管理员权限
路径参数:
- preset_id: 预设UUID
请求体(均可选):
- name: 预设名称
- colors: 颜色配置对象
错误处理:
- 404: 预设不存在
- 409: 名称已被其他预设使用
"""
preset = await ThemePreset.get_exist_one(session, preset_id)
# 检查名称唯一性(排除自身)
if request.name is not None and request.name != preset.name:
existing = await ThemePreset.get(session, ThemePreset.name == request.name)
if existing:
http_exceptions.raise_conflict(f"主题预设名称 '{request.name}' 已存在")
preset.name = request.name
# 更新颜色字段
if request.colors is not None:
color_data = request.colors.model_dump()
for key, value in color_data.items():
setattr(preset, key, value)
preset = await preset.save(session)
l.info(f"管理员更新了主题预设: {preset.name}")
@admin_theme_router.delete(
path='/{preset_id}',
summary='删除主题预设',
status_code=status.HTTP_204_NO_CONTENT,
)
async def router_admin_theme_delete(
session: SessionDep,
preset_id: UUID,
) -> None:
"""
删除主题预设
认证:需要管理员权限
路径参数:
- preset_id: 预设UUID
错误处理:
- 404: 预设不存在
副作用:
- 关联用户的 theme_preset_id 会被数据库 SET NULL
"""
preset = await ThemePreset.get_exist_one(session, preset_id)
await preset.delete(session)
l.info(f"管理员删除了主题预设: {preset.name}")
@admin_theme_router.patch(
path='/{preset_id}/default',
summary='设为默认主题预设',
status_code=status.HTTP_204_NO_CONTENT,
)
async def router_admin_theme_set_default(
session: SessionDep,
preset_id: UUID,
) -> None:
"""
将指定预设设为默认主题
认证:需要管理员权限
路径参数:
- preset_id: 预设UUID
错误处理:
- 404: 预设不存在
逻辑:
- 事务中先清除所有旧默认,再设新默认
"""
preset = await ThemePreset.get_exist_one(session, preset_id)
# 清除所有旧默认
await session.execute(
sql_update(ThemePreset)
.where(ThemePreset.is_default == True) # noqa: E712
.values(is_default=False)
)
# 设新默认
preset.is_default = True
preset = await preset.save(session)
l.info(f"管理员将主题预设 '{preset.name}' 设为默认")