feat: 内容数据迁移至数据库,合规审查全链路打通

- 文章 HTML 存储从文件系统迁移至 articles 表,删除 releases 目录
- 合规审查从 DB 读取 HTML,审查结果写回 DB,通过后自动推进至待发布
- 新增 todayCount 筛选按钮,与系统概览统计数据一致
- 全屏预览修复:提升 z-index 超过侧边栏,添加退出全屏/关闭按钮
- 统一 '优化' → '审查' 命名,消除前后端术语不一致
- 调度器创作完成后自动触发审查(生成 → 审查 → 待发布)
- 清理旧备份/调试文件、过期大纲和研究笔记
This commit is contained in:
Yuzhiran Dev
2026-05-13 17:33:56 +08:00
parent bc6a302e59
commit 233e23016c
234 changed files with 5670 additions and 10651 deletions
+70 -7
View File
@@ -69,18 +69,37 @@ def trigger_generation(topic_id: str = Body(None, embed=True), db: Session = Dep
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/optimize/run", dependencies=[Depends(get_current_user)])
def trigger_optimization(topic_ids: List[str] = Body(None, embed=True), db: Session = Depends(get_db)):
@router.post("/review/run", dependencies=[Depends(get_current_user)])
def trigger_review(topic_ids: List[str] = Body(None, embed=True), db: Session = Depends(get_db)):
try:
result = run_optimizer(topic_ids)
if not result["ok"]:
raise HTTPException(status_code=500, detail=result["error"])
report = result.get("report")
if report:
sync_all_topics()
return {"message": "Optimization completed", "summary": report["summary"]}
if report and report["summary"]["total_articles"] > 0:
s = report["summary"]
passed = s["passed_auto"]
manual = s["need_manual"]
total = s["total_articles"]
avg = s["average_score"]
msg = f"审查完成: {total} 篇, {passed} 篇通过 ({avg:.0f}分)"
if manual:
msg += f", {manual} 篇需人工处理"
return {"message": msg, "summary": s}
else:
return {"message": "Optimization completed", "stdout": result.get("stdout", "")}
if topic_ids:
updated = 0
for tid in topic_ids:
topic = db.query(Topic).filter(Topic.id == tid).first()
if topic and topic.status in ('review', '待审查'):
topic.status = 'ready'
if not topic.generated_at:
topic.generated_at = datetime.utcnow()
updated += 1
db.commit()
if updated:
logger.info(f"Review: {updated} topics advanced to 'ready' (no release files)")
return {"message": "审查完成(未找到 release 文件,仅推进状态)", "stdout": result.get("stdout", "")}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@@ -152,4 +171,48 @@ def refresh_all():
@router.get("/scheduler/status", dependencies=[Depends(get_current_user)])
def get_scheduler_status():
return {"jobs": scheduler.get_jobs()}
return {"running": scheduler._started, "jobs": scheduler.get_jobs()}
@router.get("/modules/status", dependencies=[Depends(get_current_user)])
def get_modules_status():
today_str = date.today().isoformat()
module_logs = {
"creator": {
"key": "🤖 内容创作引擎",
"log": LOGS_DIR / f"creator_{today_str}.log",
"config_file": PROJECT_ROOT / "automation" / "data" / "outlines" / today_str,
},
"optimizer": {
"key": "🔍 内容优化器",
"log": LOGS_DIR / f"optimizer_{today_str}.log",
"config_file": PROJECT_ROOT / "automation" / "data" / "drafts" / today_str,
},
"collector": {
"key": "📡 内容收集器",
"log": LOGS_DIR / f"collector_{today_str}.log",
"config_file": PROJECT_ROOT / "automation" / "data",
},
}
modules = []
for mod_id, cfg in module_logs.items():
log_file = cfg["log"]
last_run = None
task_count = 0
success_rate = None
if log_file.exists():
mtime = datetime.fromtimestamp(log_file.stat().st_mtime)
last_run = mtime.strftime("%Y-%m-%d %H:%M")
content = log_file.read_text(encoding="utf-8", errors="ignore")
task_count = content.count("完成") + content.count("success") + content.count("SUCCESS")
total = task_count + content.count("失败") + content.count("failed") + content.count("ERROR")
success_rate = round(task_count / total * 100) if total > 0 else None
modules.append({
"id": mod_id,
"title": cfg["key"],
"status": "running" if log_file.exists() else "stopped",
"last_run": last_run or "从未运行",
"task_count": task_count,
"success_rate": success_rate,
})
return {"modules": modules, "scheduler": {"running": scheduler._started, "jobs": scheduler.get_jobs()}}