feat: 内容数据迁移至数据库,合规审查全链路打通
- 文章 HTML 存储从文件系统迁移至 articles 表,删除 releases 目录 - 合规审查从 DB 读取 HTML,审查结果写回 DB,通过后自动推进至待发布 - 新增 todayCount 筛选按钮,与系统概览统计数据一致 - 全屏预览修复:提升 z-index 超过侧边栏,添加退出全屏/关闭按钮 - 统一 '优化' → '审查' 命名,消除前后端术语不一致 - 调度器创作完成后自动触发审查(生成 → 审查 → 待发布) - 清理旧备份/调试文件、过期大纲和研究笔记
This commit is contained in:
+136
-3
@@ -80,11 +80,50 @@ def update_topic_status(topic_id: str, status: str, db: Optional[Session] = None
|
||||
if close_db:
|
||||
db.close()
|
||||
|
||||
def get_active_llm_config(db: Optional[Session] = None) -> Optional[Dict]:
|
||||
"""获取启用的 LLM 配置,优先读取 system_configs 中的 review_llm_id
|
||||
|
||||
返回格式: { "model", "temperature", "max_tokens", "system_prompt", "name" }
|
||||
无配置时返回 None(调用方应使用环境变量默认值)
|
||||
"""
|
||||
close_db = False
|
||||
if db is None:
|
||||
db = SessionLocal()
|
||||
close_db = True
|
||||
try:
|
||||
from app.models import LLMConfig, SystemConfig
|
||||
# 先查系统配置中指定的 review_llm_id
|
||||
sc = db.query(SystemConfig).filter(SystemConfig.key == 'review_llm_id').first()
|
||||
target_id = None
|
||||
if sc and sc.value and sc.value.isdigit():
|
||||
target_id = int(sc.value)
|
||||
query = db.query(LLMConfig)
|
||||
if target_id:
|
||||
query = query.filter(LLMConfig.id == target_id)
|
||||
query = query.filter(LLMConfig.is_active == True)
|
||||
cfg = query.first()
|
||||
if not cfg:
|
||||
cfg = db.query(LLMConfig).filter(LLMConfig.is_active == True).first()
|
||||
if cfg:
|
||||
return {
|
||||
"id": cfg.id,
|
||||
"name": cfg.name,
|
||||
"model": cfg.model,
|
||||
"temperature": cfg.temperature,
|
||||
"max_tokens": cfg.max_tokens,
|
||||
"system_prompt": cfg.system_prompt,
|
||||
"user_prompt_template": cfg.user_prompt_template,
|
||||
}
|
||||
return None
|
||||
finally:
|
||||
if close_db:
|
||||
db.close()
|
||||
|
||||
def topic_to_dict(topic: Topic) -> Dict:
|
||||
return {
|
||||
'id': topic.id,
|
||||
'title': topic.title,
|
||||
'field': topic.field.name if topic.field else None,
|
||||
'field': topic.field_name,
|
||||
'format': topic.format,
|
||||
'core_concept': topic.core_concept,
|
||||
'audience_pain': topic.audience_pain,
|
||||
@@ -131,7 +170,7 @@ def save_topics_to_db(topics_data: List[Dict]):
|
||||
existing = db.query(Topic).filter(Topic.id == t['id']).first()
|
||||
if existing:
|
||||
# 更新字段
|
||||
for field in ['title', 'field', 'format', 'core_concept', 'audience_pain', 'unique_angle', 'priority', 'priority_score', 'total_score', 'status', 'cases', 'source_file', 'compliance_score', 'platform_urls']:
|
||||
for field in ['title', 'field_name', 'format', 'core_concept', 'audience_pain', 'unique_angle', 'priority', 'priority_score', 'total_score', 'status', 'cases', 'source_file', 'compliance_score', 'platform_urls']:
|
||||
setattr(existing, field, t.get(field, getattr(existing, field)))
|
||||
if t.get('ready_at'):
|
||||
try:
|
||||
@@ -148,7 +187,7 @@ def save_topics_to_db(topics_data: List[Dict]):
|
||||
new_topic = Topic(
|
||||
id=t['id'],
|
||||
title=t['title'],
|
||||
field=t.get('field', '可持续生活系统'),
|
||||
field_name=t.get('field_name') or t.get('field', '可持续生活系统'),
|
||||
format=t.get('format'),
|
||||
core_concept=t.get('core_concept'),
|
||||
audience_pain=t.get('audience_pain'),
|
||||
@@ -173,3 +212,97 @@ def save_topics_to_db(topics_data: List[Dict]):
|
||||
raise
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def save_article(topic_id: str, platform: str, html_content: str, db: Optional[Session] = None) -> Dict:
|
||||
"""保存/更新文章到 articles 表"""
|
||||
close_db = False
|
||||
if db is None:
|
||||
db = SessionLocal()
|
||||
close_db = True
|
||||
try:
|
||||
from app.models import Article
|
||||
article_id = f"{platform}_{topic_id}"
|
||||
existing = db.query(Article).filter(Article.id == article_id).first()
|
||||
now = datetime.now()
|
||||
if existing:
|
||||
existing.html_content = html_content
|
||||
existing.compliance_score = existing.compliance_score
|
||||
else:
|
||||
article = Article(
|
||||
id=article_id,
|
||||
topic_id=topic_id,
|
||||
platform=platform,
|
||||
file_path=f"db:{article_id}",
|
||||
html_content=html_content,
|
||||
status="draft",
|
||||
compliance_score=None
|
||||
)
|
||||
db.add(article)
|
||||
db.commit()
|
||||
return {"id": article_id, "topic_id": topic_id, "platform": platform}
|
||||
except Exception:
|
||||
db.rollback()
|
||||
raise
|
||||
finally:
|
||||
if close_db:
|
||||
db.close()
|
||||
|
||||
def get_article(topic_id: str, platform: str, db: Optional[Session] = None) -> Optional[Dict]:
|
||||
"""从 articles 表获取文章 HTML"""
|
||||
close_db = False
|
||||
if db is None:
|
||||
db = SessionLocal()
|
||||
close_db = True
|
||||
try:
|
||||
from app.models import Article
|
||||
article_id = f"{platform}_{topic_id}"
|
||||
article = db.query(Article).filter(Article.id == article_id).first()
|
||||
if not article:
|
||||
return None
|
||||
return {
|
||||
"id": article.id,
|
||||
"topic_id": article.topic_id,
|
||||
"platform": article.platform,
|
||||
"html_content": article.html_content,
|
||||
"status": article.status,
|
||||
"compliance_score": article.compliance_score,
|
||||
"created_at": article.created_at.isoformat() if article.created_at else None,
|
||||
}
|
||||
finally:
|
||||
if close_db:
|
||||
db.close()
|
||||
|
||||
def get_articles_by_topic(topic_id: str, db: Optional[Session] = None) -> List[Dict]:
|
||||
"""获取某选题在所有平台的文章"""
|
||||
close_db = False
|
||||
if db is None:
|
||||
db = SessionLocal()
|
||||
close_db = True
|
||||
try:
|
||||
from app.models import Article
|
||||
articles = db.query(Article).filter(Article.topic_id == topic_id).all()
|
||||
return [{
|
||||
"id": a.id,
|
||||
"topic_id": a.topic_id,
|
||||
"platform": a.platform,
|
||||
"html_content": a.html_content,
|
||||
"status": a.status,
|
||||
"compliance_score": a.compliance_score,
|
||||
} for a in articles]
|
||||
finally:
|
||||
if close_db:
|
||||
db.close()
|
||||
|
||||
def delete_articles_by_topic(topic_id: str, db: Optional[Session] = None):
|
||||
"""删除某选题的所有文章"""
|
||||
close_db = False
|
||||
if db is None:
|
||||
db = SessionLocal()
|
||||
close_db = True
|
||||
try:
|
||||
from app.models import Article
|
||||
db.query(Article).filter(Article.topic_id == topic_id).delete()
|
||||
db.commit()
|
||||
finally:
|
||||
if close_db:
|
||||
db.close()
|
||||
|
||||
Reference in New Issue
Block a user