feat: add theme preset system with admin CRUD, public listing, and user theme settings
- Add ChromaticColor (17 Tailwind colors) and NeutralColor (5 grays) enums - Add ThemePreset table with flat color columns and unique name constraint - Add admin theme endpoints (CRUD + set default) at /api/v1/admin/theme - Add public theme listing at /api/v1/site/themes - Add user theme settings (PATCH /theme) with color snapshot on User model - User.color_* columns store per-user overrides; fallback to default preset then builtin - Initialize default theme preset in migration - Remove legacy defaultTheme/themes settings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
117
sqlmodels/theme_preset.py
Normal file
117
sqlmodels/theme_preset.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
|
||||
from sqlmodel import Field
|
||||
|
||||
from .base import SQLModelBase
|
||||
from .color import ChromaticColor, NeutralColor, ThemeColorsBase
|
||||
from .mixin import UUIDTableBaseMixin
|
||||
|
||||
|
||||
class ThemePresetBase(SQLModelBase):
|
||||
"""主题预设基础字段"""
|
||||
|
||||
name: str = Field(max_length=100)
|
||||
"""预设名称"""
|
||||
|
||||
is_default: bool = False
|
||||
"""是否为默认预设"""
|
||||
|
||||
primary: ChromaticColor
|
||||
"""主色调"""
|
||||
|
||||
secondary: ChromaticColor
|
||||
"""辅助色"""
|
||||
|
||||
success: ChromaticColor
|
||||
"""成功色"""
|
||||
|
||||
info: ChromaticColor
|
||||
"""信息色"""
|
||||
|
||||
warning: ChromaticColor
|
||||
"""警告色"""
|
||||
|
||||
error: ChromaticColor
|
||||
"""错误色"""
|
||||
|
||||
neutral: NeutralColor
|
||||
"""中性色"""
|
||||
|
||||
|
||||
class ThemePreset(ThemePresetBase, UUIDTableBaseMixin):
|
||||
"""主题预设表"""
|
||||
|
||||
name: str = Field(max_length=100, unique=True)
|
||||
"""预设名称(唯一约束)"""
|
||||
|
||||
|
||||
# ==================== DTO ====================
|
||||
|
||||
class ThemePresetCreateRequest(SQLModelBase):
|
||||
"""创建主题预设请求 DTO"""
|
||||
|
||||
name: str = Field(max_length=100)
|
||||
"""预设名称"""
|
||||
|
||||
colors: ThemeColorsBase
|
||||
"""颜色配置"""
|
||||
|
||||
|
||||
class ThemePresetUpdateRequest(SQLModelBase):
|
||||
"""更新主题预设请求 DTO"""
|
||||
|
||||
name: str | None = Field(default=None, max_length=100)
|
||||
"""预设名称(可选)"""
|
||||
|
||||
colors: ThemeColorsBase | None = None
|
||||
"""颜色配置(可选)"""
|
||||
|
||||
|
||||
class ThemePresetResponse(SQLModelBase):
|
||||
"""主题预设响应 DTO"""
|
||||
|
||||
id: UUID
|
||||
"""预设UUID"""
|
||||
|
||||
name: str
|
||||
"""预设名称"""
|
||||
|
||||
is_default: bool
|
||||
"""是否为默认预设"""
|
||||
|
||||
colors: ThemeColorsBase
|
||||
"""颜色配置"""
|
||||
|
||||
created_at: datetime
|
||||
"""创建时间"""
|
||||
|
||||
updated_at: datetime
|
||||
"""更新时间"""
|
||||
|
||||
@classmethod
|
||||
def from_preset(cls, preset: ThemePreset) -> 'ThemePresetResponse':
|
||||
"""从数据库模型转换为响应 DTO(平铺列 → 嵌套 colors 对象)"""
|
||||
return cls(
|
||||
id=preset.id,
|
||||
name=preset.name,
|
||||
is_default=preset.is_default,
|
||||
colors=ThemeColorsBase(
|
||||
primary=preset.primary,
|
||||
secondary=preset.secondary,
|
||||
success=preset.success,
|
||||
info=preset.info,
|
||||
warning=preset.warning,
|
||||
error=preset.error,
|
||||
neutral=preset.neutral,
|
||||
),
|
||||
created_at=preset.created_at,
|
||||
updated_at=preset.updated_at,
|
||||
)
|
||||
|
||||
|
||||
class ThemePresetListResponse(SQLModelBase):
|
||||
"""主题预设列表响应 DTO"""
|
||||
|
||||
themes: list[ThemePresetResponse]
|
||||
"""主题预设列表"""
|
||||
Reference in New Issue
Block a user