feat: Phase 4 多租户隔离 + 四阶段升级测试 + CSS 统一化

Phase 4: org_id 注入 JWT/API 过滤/组织管理 CRUD/前端组织列
测试: tests/test_phase_upgrades.py 97项全覆盖
CSS: theme-modern.css 共享 mobile-card-list/status-dot/search-bar 等模式
修复: initial_data.py LLM配置 NOT NULL 约束, TopicResponse 含 org_id
This commit is contained in:
Yuzhiran Dev
2026-05-17 06:56:53 +08:00
parent 301dc3e438
commit 9c37c9a574
45 changed files with 3707 additions and 1366 deletions
+86
View File
@@ -8,6 +8,7 @@ import os
import sys
import json
import datetime
import logging
from pathlib import Path
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
@@ -25,6 +26,13 @@ import random
# 确保项目根目录在路径中
PROJECT_ROOT = Path('/root/openclaw-workspace/projects/yu-zhi-ran')
sys.path.insert(0, str(PROJECT_ROOT))
sys.path.insert(0, str(PROJECT_ROOT / 'platform' / 'backend'))
from db_helper import get_topic_by_id
from app.models import Article
from app.database import SessionLocal
logger = logging.getLogger(__name__)
# 加载配置
CONFIG_DIR = PROJECT_ROOT / "config"
@@ -441,7 +449,85 @@ class ImageGenerator:
return files
def generate_for_topic(topic_id: str, platforms: List[str] = None) -> Dict[str, Dict[str, str]]:
"""为指定选题生成三平台配图,路径存入 articles 表"""
if platforms is None:
platforms = ["zhihu", "wechat", "xiaohongshu"]
topic = get_topic_by_id(topic_id)
if not topic:
raise ValueError(f"Topic {topic_id} not found")
title = topic.get("title", "无标题")
generator = ImageGenerator()
results = {}
for platform in platforms:
try:
files = generator.generate_all_placeholders(title, platform)
cover_path = str(files.get("cover", ""))
chart_path = str(files.get("data_chart", ""))
checklist_path = str(files.get("action_checklist", ""))
images = {
"cover": cover_path,
"chart": chart_path,
"checklist": checklist_path,
}
# 存入 DB
save_article_images(topic_id, platform, images)
results[platform] = images
logger.info(f" [{platform}] cover={Path(cover_path).name}" if cover_path else "")
except Exception as e:
logger.error(f" [{platform}] 生成失败: {e}")
results[platform] = {}
return results
def save_article_images(topic_id: str, platform: str, images: Dict[str, str]):
"""将图片路径写入 articles 表的 images 字段"""
db = SessionLocal()
try:
from app.models import Article
article_id = f"{platform}_{topic_id}"
article = db.query(Article).filter(Article.id == article_id).first()
if article:
existing = article.images or {}
existing.update(images)
article.images = existing
else:
article = Article(
id=article_id,
topic_id=topic_id,
platform=platform,
file_path=f"db:{article_id}",
status="draft",
images=images,
)
db.add(article)
db.commit()
except Exception:
db.rollback()
raise
finally:
db.close()
def main():
import argparse
parser = argparse.ArgumentParser(description='文章配图生成器')
parser.add_argument('--topic-id', help='选题ID,指定则为选题生成配图')
args = parser.parse_args()
if args.topic_id:
print(f"为选题 {args.topic_id} 生成配图...")
results = generate_for_topic(args.topic_id)
print(json.dumps({"topic_id": args.topic_id, "images": results}, ensure_ascii=False))
sys.exit(0)
"""测试主函数"""
generator = ImageGenerator()