Some checks failed
Test / test (push) Failing after 3m47s
- 替换 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>
188 lines
4.7 KiB
Python
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}' 设为默认")
|