chore: 清理 Docker 相关文件并优化前端布局

- 删除 Docker 相关文件 (docker-compose, Dockerfile, nginx.conf, init.sql 等)
- 优化 platforms.html 卡片布局和响应式样式
- 优化 users.html 格式和移动端卡片设计
- 优化 admin.html 页面结构和表格布局
- 修复各页面 min-height 和溢出问题
- 更新导航组件样式
This commit is contained in:
lt
2026-05-09 19:41:59 +08:00
parent e77a1aa4d9
commit 71cb4c35a8
80 changed files with 142574 additions and 3900 deletions
+3 -3
View File
@@ -100,7 +100,7 @@ def login(login_data: LoginRequest, request: Request, db: Session = Depends(get_
user_agent=user_agent,
db=db
)
return TokenResponse(token=token, role=user.role, user=UserResponse.from_orm(user))
return TokenResponse(token=token, role=user.role, user=UserResponse.model_validate(user))
# 从数据库查询其他用户
user = db.query(User).filter(User.username == login_data.username).first()
@@ -136,7 +136,7 @@ def login(login_data: LoginRequest, request: Request, db: Session = Depends(get_
user_agent=user_agent,
db=db
)
return TokenResponse(token=token, role=user.role, user=UserResponse.from_orm(user))
return TokenResponse(token=token, role=user.role, user=UserResponse.model_validate(user))
def get_current_user(request: Request, db: Session = Depends(get_db)) -> User:
"""依赖项:验证用户登录"""
@@ -159,5 +159,5 @@ def get_me(
current_user: User = Depends(get_current_user)
):
"""获取当前登录用户信息"""
return {"user": UserResponse.from_orm(current_user)}
return {"user": UserResponse.model_validate(current_user)}
+3 -6
View File
@@ -28,7 +28,7 @@ def list_cases(
):
"""获取案例列表(管理员)"""
cases = db.query(Case).all()
return [CaseResponse.from_orm(c) for c in cases]
return [CaseResponse.model_validate(c) for c in cases]
@router.get("/{case_id}", response_model=CaseResponse)
def get_case(
@@ -51,10 +51,7 @@ def create_case(
admin_user = Depends(get_current_admin)
):
"""创建新案例"""
existing = db.query(Case).filter(Case.id == case_data.id).first()
if existing:
raise HTTPException(status_code=400, detail="案例ID已存在")
case = Case(**case_data.dict())
case = Case(**case_data.model_dump())
db.add(case)
db.commit()
db.refresh(case)
@@ -72,7 +69,7 @@ def update_case(
case = db.query(Case).filter(Case.id == case_id).first()
if not case:
raise HTTPException(status_code=404, detail="案例不存在")
update_data = case_update.dict(exclude_unset=True)
update_data = case_update.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(case, field, value)
db.commit()
+3 -3
View File
@@ -28,7 +28,7 @@ def list_llm_configs(
):
"""获取 LLM 配置列表"""
configs = db.query(LLMConfig).all()
return [LLMConfigResponse.from_orm(c) for c in configs]
return [LLMConfigResponse.model_validate(c) for c in configs]
@router.get("/{config_id}", response_model=LLMConfigResponse)
def get_llm_config(
@@ -51,7 +51,7 @@ def create_llm_config(
admin_user = Depends(get_current_admin)
):
"""创建 LLM 配置"""
config = LLMConfig(**config_data.dict())
config = LLMConfig(**config_data.model_dump())
db.add(config)
db.commit()
db.refresh(config)
@@ -69,7 +69,7 @@ def update_llm_config(
config = db.query(LLMConfig).filter(LLMConfig.id == config_id).first()
if not config:
raise HTTPException(status_code=404, detail="配置不存在")
update_data = config_update.dict(exclude_unset=True)
update_data = config_update.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(config, field, value)
db.commit()
+2 -2
View File
@@ -11,7 +11,7 @@ router = APIRouter(prefix="/api", tags=["optimizer_logs"])
PROJECT_ROOT = Path(__file__).parent.parent.parent.parent.parent
@router.post("/optimizer/run")
def run_optimizer(
async def run_optimizer(
request: Request,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_admin)
@@ -20,7 +20,7 @@ def run_optimizer(
触发合规优化器运行(管理员)
"""
try:
body = request.json()
body = await request.json()
except Exception:
raise HTTPException(status_code=400, detail="Invalid JSON")
topic_id = body.get("topic_id")
+5 -5
View File
@@ -31,7 +31,7 @@ def list_system_configs(
# 将 value 解析为 JSON(如果是 JSON 字符串)
result = []
for c in configs:
resp = SystemConfigResponse.from_orm(c)
resp = SystemConfigResponse.model_validate(c)
# 尝试解析 value 为 JSON
if c.value:
try:
@@ -53,7 +53,7 @@ def get_system_config(
config = db.query(SystemConfig).filter(SystemConfig.key == config_key).first()
if not config:
raise HTTPException(status_code=404, detail="配置不存在")
resp = SystemConfigResponse.from_orm(config)
resp = SystemConfigResponse.model_validate(config)
if config.value:
try:
import json
@@ -85,7 +85,7 @@ def create_system_config(
existing.description = config_data.description
db.commit()
db.refresh(existing)
resp = SystemConfigResponse.from_orm(existing)
resp = SystemConfigResponse.model_validate(existing)
if existing.value:
try:
import json
@@ -95,7 +95,7 @@ def create_system_config(
return resp
else:
# 新建
data = config_data.dict()
data = config_data.model_dump()
# 将 value 转为字符串(如果是复杂类型则 JSON)
if isinstance(data.get('value'), (dict, list)):
import json
@@ -104,7 +104,7 @@ def create_system_config(
db.add(config)
db.commit()
db.refresh(config)
resp = SystemConfigResponse.from_orm(config)
resp = SystemConfigResponse.model_validate(config)
if config.value:
try:
import json
+3 -3
View File
@@ -38,7 +38,7 @@ def list_task_logs(
if status:
query = query.filter(TaskLog.status == status)
logs = query.order_by(TaskLog.started_at.desc()).all()
return [TaskLogResponse.from_orm(l) for l in logs]
return [TaskLogResponse.model_validate(l) for l in logs]
@router.get("/{log_id}", response_model=TaskLogResponse)
def get_task_log(
@@ -61,7 +61,7 @@ def create_task_log(
admin_user = Depends(get_current_admin)
):
"""创建任务日志(用于手动记录)"""
log = TaskLog(**log_data.dict())
log = TaskLog(**log_data.model_dump())
db.add(log)
db.commit()
db.refresh(log)
@@ -79,7 +79,7 @@ def update_task_log(
log = db.query(TaskLog).filter(TaskLog.id == log_id).first()
if not log:
raise HTTPException(status_code=404, detail="日志不存在")
update_data = log_update.dict(exclude_unset=True)
update_data = log_update.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(log, field, value)
db.commit()
+8
View File
@@ -38,6 +38,14 @@ Base = declarative_base()
def init_db():
Base.metadata.create_all(bind=engine)
# 迁移:为已有表添加 last_login 列
try:
from sqlalchemy import text
with engine.connect() as conn:
conn.execute(text("ALTER TABLE users ADD COLUMN IF NOT EXISTS last_login TIMESTAMP"))
conn.commit()
except Exception:
pass # SQLite 不支持 IF NOT EXISTS,但 create_all 对 SQLite 够用
def get_db():
db = SessionLocal()
+13 -1
View File
@@ -41,7 +41,7 @@ def import_initial_data():
### 选题信息
标题:{topic.get('title')}
领域:{topic.get('field')}
领域:{topic.get('field_name')}
核心观点:{topic.get('core_concept', '')}
受众痛点:{topic.get('audience_pain', '')}
独特视角:{topic.get('unique_angle', '')}
@@ -209,6 +209,18 @@ def import_initial_data():
db.commit()
print(f"✅ 导入 {len(cases_data)} 条案例")
# 同步 PostgreSQL 自增序列
if os.getenv('USE_POSTGRES', 'true').lower() == 'true':
try:
from sqlalchemy import text
tables = ["cases", "users", "content_calendar", "media_assets", "content_metrics", "content_tasks", "audit_logs", "task_logs", "topic_config_fields"]
for table in tables:
db.execute(text(f"SELECT setval(pg_get_serial_sequence('{table}', 'id'), COALESCE((SELECT MAX(id) FROM {table}), 0) + 1, false)"))
db.commit()
print("✅ PostgreSQL 自增序列已同步")
except Exception as e:
print(f"⚠️ 序列同步警告: {e}")
print("✅ 初始化完成")
except Exception as e:
+2
View File
@@ -41,6 +41,7 @@ class User(Base):
username = Column(String, unique=True, nullable=False, index=True)
password_hash = Column(String, nullable=False)
role = Column(String, default="user", nullable=False)
last_login = Column(DateTime(timezone=True), nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
@@ -49,6 +50,7 @@ class User(Base):
"id": self.id,
"username": self.username,
"role": self.role,
"last_login": self.last_login.isoformat() if self.last_login else None,
"created_at": self.created_at.isoformat() if self.created_at else None
}
+2 -1
View File
@@ -441,7 +441,7 @@ class TaskLogBase(BaseModel):
message: Optional[str] = None
started_at: Optional[datetime] = None
finished_at: Optional[datetime] = None
duration_seconds: Optional[int] = None
duration: Optional[int] = None
class TaskLogResponse(TaskLogBase):
@@ -475,6 +475,7 @@ class SystemConfigBase(BaseModel):
class SystemConfigResponse(SystemConfigBase):
value: Optional[Any] = None
updated_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)