feat: 创作工作台统一 + AI味检测/白标 + 移动端补全 + 合规发布闭环
- 新增创作工作台 studio.html:合并选题/内容工厂/文章管理为单一 tab 入口(iframe embed 模式) - 新增 AI味检测模块(ai_slop API + 页面,合规软硬问题分级) - 新增白标品牌配置(branding API + 页面 + deploy 私有化交付包) - 发布闭环:publishing 放宽至 editor + records/mark-published 接口 - 移动端响应式补全(admin/calendar/ai-slop 表格卡片兜底) - 修复菜单幂等播种缺陷(按 path 对齐,避免功能页孤立) - 新增短视频脚本 shortvideo.py 与 2026 市场调研简报
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
from ..database import get_db
|
||||
from ..models import SystemConfig
|
||||
from .auth import get_current_admin
|
||||
|
||||
router = APIRouter(prefix="/api/branding", tags=["branding"])
|
||||
|
||||
BRAND_KEYS = {
|
||||
"brand_name": "宇之然内容创作平台",
|
||||
"brand_logo": "",
|
||||
"brand_primary_color": "#2563eb",
|
||||
"brand_support_email": "",
|
||||
}
|
||||
|
||||
PUBLIC_RESP_DESC = "白标实例公开信息(供前端运行时应用品牌)"
|
||||
|
||||
|
||||
class BrandingResponse(BaseModel):
|
||||
brand_name: str
|
||||
brand_logo: str
|
||||
brand_primary_color: str
|
||||
brand_support_email: str
|
||||
version: str
|
||||
|
||||
|
||||
class BrandingUpdate(BaseModel):
|
||||
brand_name: Optional[str] = None
|
||||
brand_logo: Optional[str] = None
|
||||
brand_primary_color: Optional[str] = None
|
||||
brand_support_email: Optional[str] = None
|
||||
|
||||
|
||||
def _get(db: Session, key: str) -> str:
|
||||
cfg = db.query(SystemConfig).filter(SystemConfig.key == key).first()
|
||||
if not cfg or cfg.value is None:
|
||||
return BRAND_KEYS.get(key, "")
|
||||
return cfg.value
|
||||
|
||||
|
||||
@router.get("", response_model=BrandingResponse)
|
||||
def get_branding(db: Session = Depends(get_db)):
|
||||
"""公开接口:返回当前实例的白标配置(无需登录),用于前端运行时渲染品牌"""
|
||||
try:
|
||||
from ..main import app
|
||||
version = getattr(app, "version", "0.1.0")
|
||||
except Exception:
|
||||
version = "0.1.0"
|
||||
return BrandingResponse(
|
||||
brand_name=_get(db, "brand_name"),
|
||||
brand_logo=_get(db, "brand_logo"),
|
||||
brand_primary_color=_get(db, "brand_primary_color"),
|
||||
brand_support_email=_get(db, "brand_support_email"),
|
||||
version=version,
|
||||
)
|
||||
|
||||
|
||||
@router.put("", response_model=BrandingResponse)
|
||||
def update_branding(
|
||||
payload: BrandingUpdate,
|
||||
db: Session = Depends(get_db),
|
||||
admin_user=Depends(get_current_admin),
|
||||
):
|
||||
"""管理员接口:更新白标配置(品牌名/Logo/主色/支持邮箱)"""
|
||||
data = payload.model_dump(exclude_unset=True)
|
||||
for key, value in data.items():
|
||||
if key not in BRAND_KEYS:
|
||||
continue
|
||||
if value is None:
|
||||
continue
|
||||
cfg = db.query(SystemConfig).filter(SystemConfig.key == key).first()
|
||||
if cfg:
|
||||
cfg.value = str(value)
|
||||
else:
|
||||
db.add(SystemConfig(key=key, value=str(value), description="白标配置"))
|
||||
db.commit()
|
||||
return get_branding(db)
|
||||
Reference in New Issue
Block a user