feat: 宇之然平台 v2.0 - 完整重构版
核心功能: - 新增 JWT 认证系统,支持管理员登录/登出 - 前后端合并为单一 FastAPI 应用 (端口 8001) - 系统概览页:6 个统计卡片,点击跳转筛选 - 选题管理页:批量操作 (刷新/创作/优化),时间列展示 - 系统日志页:整合日志查看功能 - 用户管理页:管理员可创建/删除用户 - 移动端适配:响应式布局,底部导航栏 - 标题居中显示 技术改进: - 添加 generated_at 字段支持创作时间记录 - 状态更新时自动同步 updated_at - 所有 API 路由添加 JWT 认证保护 - 前端 authFetch 封装自动附加 Token - 升级 FastAPI 0.136, Pydantic 2.13 等依赖 修复: - 修复 API 500 错误 (数据库列缺失) - 修复 formatRelativeTime 未定义错误 - 修复登录 Token 存储和自动附加逻辑
This commit is contained in:
@@ -1,7 +1,51 @@
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from datetime import datetime, date
|
||||
from typing import Optional, List, Dict, Any
|
||||
|
||||
class AuditLogBase(BaseModel):
|
||||
user_id: Optional[int] = None
|
||||
username: str
|
||||
action: str
|
||||
resource_type: Optional[str] = None
|
||||
resource_id: Optional[str] = None
|
||||
details: Optional[Dict[str, Any]] = None
|
||||
ip_address: Optional[str] = None
|
||||
user_agent: Optional[str] = None
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
class AuditLogResponse(AuditLogBase):
|
||||
id: int
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class UserBase(BaseModel):
|
||||
username: str
|
||||
role: str = "user"
|
||||
|
||||
class UserCreate(UserBase):
|
||||
password: str
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
username: Optional[str] = None
|
||||
password: Optional[str] = None
|
||||
role: Optional[str] = None
|
||||
|
||||
class UserResponse(UserBase):
|
||||
id: int
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
token: str
|
||||
role: str
|
||||
user: UserResponse
|
||||
|
||||
class TopicBase(BaseModel):
|
||||
id: str
|
||||
title: str
|
||||
@@ -11,14 +55,14 @@ class TopicBase(BaseModel):
|
||||
compliance_score: Optional[int] = None
|
||||
ready_at: Optional[date] = None
|
||||
published_at: Optional[date] = None
|
||||
generated_at: Optional[datetime] = None
|
||||
platform_urls: Optional[Dict[str, str]] = None
|
||||
|
||||
class TopicResponse(TopicBase):
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class ArticleBase(BaseModel):
|
||||
id: str
|
||||
@@ -30,8 +74,7 @@ class ArticleBase(BaseModel):
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
class ArticleResponse(ArticleBase):
|
||||
class Config:
|
||||
from_attributes = True
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class SystemStatus(BaseModel):
|
||||
total_topics: int
|
||||
@@ -40,14 +83,55 @@ class SystemStatus(BaseModel):
|
||||
today_articles: int
|
||||
compliance_rate: float
|
||||
last_optimization: Optional[datetime] = None
|
||||
execution_time: Optional[float] = None # 任务执行耗时(秒)
|
||||
execution_time: Optional[float] = None
|
||||
|
||||
class OptimizationRequest(BaseModel):
|
||||
topic_ids: Optional[List[str]] = None # None表示全部
|
||||
topic_ids: Optional[List[str]] = None
|
||||
|
||||
class PublishRequest(BaseModel):
|
||||
topic_id: str
|
||||
platform_urls: Dict[str, str] # {"zhihu": "...", "wechat": "...", "xiaohongshu": "..."}
|
||||
platform_urls: Dict[str, str]
|
||||
|
||||
class PublishActionRequest(BaseModel):
|
||||
action: str
|
||||
platform: Optional[str] = None
|
||||
status: str
|
||||
operator: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
suggestion: Optional[str] = None
|
||||
url: Optional[str] = None
|
||||
error_msg: Optional[str] = None
|
||||
|
||||
class PublishRecordResponse(BaseModel):
|
||||
id: int
|
||||
topic_id: str
|
||||
platform: str
|
||||
action: str
|
||||
status: str
|
||||
operator: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
suggestion: Optional[str] = None
|
||||
url: Optional[str] = None
|
||||
error_msg: Optional[str] = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class BatchPublishRequest(BaseModel):
|
||||
date: str # YYYY-MM-DD
|
||||
date: str
|
||||
|
||||
|
||||
class AuditLogResponse(BaseModel):
|
||||
id: int
|
||||
user_id: Optional[int] = None
|
||||
username: str
|
||||
action: str
|
||||
resource_type: Optional[str] = None
|
||||
resource_id: Optional[str] = None
|
||||
details: Optional[Dict[str, Any]] = None
|
||||
ip_address: Optional[str] = None
|
||||
user_agent: Optional[str] = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user