配置全面迁移数据库:PromptConfig、TaskConfig动态调度、敏感词/清洗规则/趋势映射/平台标签/痛点模板全部可编辑

- 新增 PromptConfig 模型 + API,支持提示词在线编辑(16条默认)
- 调度器动态读取 TaskConfig.schedule,admin 可调执行时间
- 新增 KeywordDomainMap、SensitiveWord、ContentCleanRule、TrendFieldMapping 表
- DOMAINS、TREND_DOMAIN_MAP、PLATFORM_TAGS、china_pains、RSS关键词、priority_weights 全部迁移到 DB
- tasks.html 重构:卡片网格+配置/产出/历史/提示词四个Tab,折叠显示
- 清理冗余代码:DEFAULT_PROMPTS死代码、collector.py unreachable代码、compliance_checker bug
- strip_thinking_html 改用 DB 规则优先
This commit is contained in:
Yuzhiran Dev
2026-05-22 11:18:23 +08:00
parent a8e0a76e07
commit 1855f190f5
31 changed files with 2927 additions and 1127 deletions
+62 -48
View File
@@ -1,55 +1,82 @@
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy import or_
from typing import List, Optional
from datetime import datetime, timezone
from ..database import get_db
from ..models import TaskLog
from ..schemas import TaskLogBase, TaskLogResponse
from .auth import get_current_admin
router = APIRouter(prefix="/api/admin/tasklogs", tags=["admin"])
router = APIRouter(prefix="/api/admin/task-logs", tags=["admin"])
MODULES = {
"scheduled_refresh_search_cache": "🔍 搜索缓存",
"scheduled_fetch_trends": "🔥 热点趋势",
"scheduled_collect": "📡 内容采集",
"scheduled_generate": "🤖 内容创作",
"scheduled_optimize": "🔍 合规审查",
"scheduled_optimize_sources": "📡 信息源优化",
"scheduled_metrics_sync": "📊 指标同步",
}
@router.get("", response_model=List[TaskLogResponse])
def list_task_logs(
request: Request,
db: Session = Depends(get_db),
admin_user = Depends(get_current_admin),
topic_id: Optional[str] = None,
task_name: Optional[str] = None,
status: Optional[str] = None
admin_user=Depends(get_current_admin),
module_id: Optional[str] = None,
status: Optional[str] = None,
date: Optional[str] = None,
limit: int = 50,
):
"""获取任务日志列表(可过滤)"""
query = db.query(TaskLog)
if topic_id:
query = query.filter(TaskLog.topic_id == topic_id)
if task_name:
query = query.filter(TaskLog.task_name == task_name)
if module_id:
query = query.filter(TaskLog.module_id == module_id)
if status:
query = query.filter(TaskLog.status == status)
logs = query.order_by(TaskLog.started_at.desc()).all()
if date:
try:
dt = datetime.strptime(date, "%Y-%m-%d").replace(tzinfo=timezone.utc)
next_day = datetime(dt.year, dt.month, dt.day + 1, tzinfo=timezone.utc)
query = query.filter(TaskLog.started_at >= dt, TaskLog.started_at < next_day)
except ValueError:
pass
logs = query.order_by(TaskLog.started_at.desc()).limit(limit).all()
return [TaskLogResponse.model_validate(l) for l in logs]
@router.get("/modules")
def list_modules(db: Session = Depends(get_db), admin_user=Depends(get_current_admin)):
today = datetime.now(timezone.utc).date().isoformat()
result = []
for mid, name in MODULES.items():
latest = db.query(TaskLog).filter(TaskLog.module_id == mid).order_by(TaskLog.started_at.desc()).first()
total = db.query(TaskLog).filter(TaskLog.module_id == mid).count()
success = db.query(TaskLog).filter(TaskLog.module_id == mid, TaskLog.status == "success").count()
failed = db.query(TaskLog).filter(TaskLog.module_id == mid, TaskLog.status == "failed").count()
running = db.query(TaskLog).filter(TaskLog.module_id == mid, TaskLog.status == "running").count()
result.append({
"module_id": mid,
"name": name,
"last_run": latest.started_at.isoformat() if latest and latest.started_at else None,
"last_status": latest.status if latest else None,
"last_message": latest.message if latest else None,
"total_runs": total,
"success_runs": success,
"failed_runs": failed,
"running": running,
})
return result
@router.get("/{log_id}", response_model=TaskLogResponse)
def get_task_log(
log_id: int,
request: Request,
db: Session = Depends(get_db),
admin_user = Depends(get_current_admin)
):
"""获取单个任务日志详情"""
def get_task_log(log_id: int, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)):
log = db.query(TaskLog).filter(TaskLog.id == log_id).first()
if not log:
raise HTTPException(status_code=404, detail="日志不存在")
raise HTTPException(status_code=404, detail="记录不存在")
return log
@router.post("", response_model=TaskLogResponse)
def create_task_log(
log_data: TaskLogBase,
request: Request,
db: Session = Depends(get_db),
admin_user = Depends(get_current_admin)
):
"""创建任务日志(用于手动记录)"""
def create_task_log(log_data: TaskLogBase, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)):
log = TaskLog(**log_data.model_dump())
db.add(log)
db.commit()
@@ -57,35 +84,22 @@ def create_task_log(
return log
@router.put("/{log_id}", response_model=TaskLogResponse)
def update_task_log(
log_id: int,
log_update: TaskLogBase,
request: Request,
db: Session = Depends(get_db),
admin_user = Depends(get_current_admin)
):
"""更新任务日志"""
def update_task_log(log_id: int, log_update: TaskLogBase, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)):
log = db.query(TaskLog).filter(TaskLog.id == log_id).first()
if not log:
raise HTTPException(status_code=404, detail="日志不存在")
update_data = log_update.model_dump(exclude_unset=True)
for field, value in update_data.items():
raise HTTPException(status_code=404, detail="记录不存在")
data = log_update.model_dump(exclude_unset=True)
for field, value in data.items():
setattr(log, field, value)
db.commit()
db.refresh(log)
return log
@router.delete("/{log_id}")
def delete_task_log(
log_id: int,
request: Request,
db: Session = Depends(get_db),
admin_user = Depends(get_current_admin)
):
"""删除任务日志"""
def delete_task_log(log_id: int, db: Session = Depends(get_db), admin_user=Depends(get_current_admin)):
log = db.query(TaskLog).filter(TaskLog.id == log_id).first()
if not log:
raise HTTPException(status_code=404, detail="日志不存在")
raise HTTPException(status_code=404, detail="记录不存在")
db.delete(log)
db.commit()
return {"message": "删除成功"}
return {"message": "删除成功"}