UI优化完善初版
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from fastapi import APIRouter, HTTPException, Query, Depends
|
||||
from pathlib import Path
|
||||
import os
|
||||
from datetime import datetime, date
|
||||
|
||||
from ..database import get_db
|
||||
from ..models import User
|
||||
from .auth import get_current_user
|
||||
|
||||
router = APIRouter(prefix="/api/articles", tags=["articles"])
|
||||
|
||||
PROJECT_ROOT = Path('/root/openclaw-workspace/projects/yu-zhi-ran')
|
||||
|
||||
@router.get("/drafts")
|
||||
def list_drafts(publish_date: str = None):
|
||||
def list_drafts(publish_date: str = None, current_user: User = Depends(get_current_user)):
|
||||
"""列出指定日期的草稿文件(三平台)"""
|
||||
if not publish_date:
|
||||
publish_date = date.today().isoformat()
|
||||
@@ -28,21 +32,19 @@ def list_drafts(publish_date: str = None):
|
||||
return {"date": publish_date, "files": result}
|
||||
|
||||
@router.get("/{topic_id}/preview")
|
||||
def preview_article(topic_id: str, platform: str = "zhihu", publish_date: str = None):
|
||||
def preview_article(topic_id: str, platform: str = "zhihu", publish_date: str = None, current_user: User = Depends(get_current_user)):
|
||||
"""预览某选题的HTML内容"""
|
||||
if not publish_date:
|
||||
publish_date = date.today().isoformat()
|
||||
filename = f"{platform}_{topic_id}_{platform}.html"
|
||||
file_path = PROJECT_ROOT / "automation" / "data" / "releases" / publish_date / platform / filename
|
||||
# DEBUG
|
||||
print(f"[DEBUG] file_path={file_path}, exists={file_path.exists()}")
|
||||
if not file_path.exists():
|
||||
raise HTTPException(status_code=404, detail=f"Article not found: {file_path}")
|
||||
content = file_path.read_text(encoding='utf-8')
|
||||
return {"topic_id": topic_id, "platform": platform, "html": content}
|
||||
|
||||
@router.get("/optimization-report")
|
||||
def get_optimization_report(publish_date: str = None):
|
||||
def get_optimization_report(publish_date: str = None, current_user: User = Depends(get_current_user)):
|
||||
"""获取合规优化报告"""
|
||||
if not publish_date:
|
||||
publish_date = date.today().isoformat()
|
||||
|
||||
@@ -146,6 +146,12 @@ def get_current_user(request: Request, db: Session = Depends(get_db)) -> User:
|
||||
token = auth_header.split(" ")[1]
|
||||
user = verify_token(token, db)
|
||||
return user
|
||||
|
||||
def get_current_admin(current_user: User = Depends(get_current_user)) -> User:
|
||||
"""依赖项:验证管理员权限"""
|
||||
if current_user.role != "admin":
|
||||
raise HTTPException(status_code=403, detail="需要管理员权限")
|
||||
return current_user
|
||||
@router.get("/me")
|
||||
def get_me(
|
||||
request: Request,
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
from sqlalchemy.orm import Session
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from ..database import get_db
|
||||
from ..models import User
|
||||
from .auth import get_current_admin
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["optimizer_logs"])
|
||||
|
||||
PROJECT_ROOT = Path(__file__).parent.parent.parent.parent.parent
|
||||
|
||||
@router.post("/optimizer/run")
|
||||
def run_optimizer(
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_admin)
|
||||
):
|
||||
"""
|
||||
触发合规优化器运行(管理员)
|
||||
"""
|
||||
try:
|
||||
body = request.json()
|
||||
except Exception:
|
||||
raise HTTPException(status_code=400, detail="Invalid JSON")
|
||||
topic_id = body.get("topic_id")
|
||||
if not topic_id:
|
||||
raise HTTPException(status_code=400, detail="topic_id is required")
|
||||
|
||||
script_path = PROJECT_ROOT / "automation" / "scripts" / "compliance_optimizer.py"
|
||||
if not script_path.exists():
|
||||
raise HTTPException(status_code=500, detail="Optimizer script not found")
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["python", str(script_path), "--topic-id", topic_id],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=600,
|
||||
cwd=PROJECT_ROOT
|
||||
)
|
||||
if result.returncode != 0:
|
||||
raise HTTPException(status_code=500, detail=f"Optimizer failed: {result.stderr}")
|
||||
return {"ok": True, "message": "Optimization completed", "output": result.stdout}
|
||||
except subprocess.TimeoutExpired:
|
||||
raise HTTPException(status_code=500, detail="Optimizer timed out")
|
||||
|
||||
@router.get("/logs")
|
||||
def get_logs(
|
||||
request: Request,
|
||||
type: str = None, # creator, optimizer, collector
|
||||
date: str = None, # YYYY-MM-DD
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_admin)
|
||||
):
|
||||
"""
|
||||
读取系统日志文件内容(管理员)
|
||||
"""
|
||||
if not type or not date:
|
||||
raise HTTPException(status_code=400, detail="type and date parameters are required")
|
||||
logs_dir = PROJECT_ROOT / "automation" / "logs"
|
||||
filename = f"{type}_{date}.log"
|
||||
log_path = logs_dir / filename
|
||||
if not log_path.exists():
|
||||
# 日志文件不存在返回空内容
|
||||
return {"type": type, "date": date, "content": ""}
|
||||
try:
|
||||
content = log_path.read_text(encoding="utf-8")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to read log: {str(e)}")
|
||||
return {"type": type, "date": date, "content": content}
|
||||
@@ -5,13 +5,13 @@ from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from app.database import get_db
|
||||
from app.models import Topic, PublishRecord, User
|
||||
from ..database import get_db
|
||||
from ..models import Topic, PublishRecord, User
|
||||
from sqlalchemy.orm import Session
|
||||
from .auth import verify_token
|
||||
from .auth import get_current_admin
|
||||
from ..core.audit_logger import audit_log
|
||||
|
||||
router = APIRouter()
|
||||
router = APIRouter(prefix="/api/publishing", tags=["publishing"])
|
||||
|
||||
class PublishRequest(BaseModel):
|
||||
topic_id: str
|
||||
@@ -21,26 +21,14 @@ class PublishResponse(BaseModel):
|
||||
topic_id: str
|
||||
message: str
|
||||
|
||||
def get_current_user(request: Request, db: Session = Depends(get_db)) -> User:
|
||||
"""获取当前登录用户(可选,未登录也允许,但记录为 anonymous)"""
|
||||
auth_header = request.headers.get("Authorization")
|
||||
if not auth_header or not auth_header.startswith("Bearer "):
|
||||
return None
|
||||
token = auth_header.split(" ")[1]
|
||||
try:
|
||||
from .auth import verify_token
|
||||
return verify_token(token, db)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@router.post("/api/publishing/create", response_model=PublishResponse)
|
||||
@router.post("/create", response_model=PublishResponse)
|
||||
async def create_publish_record(
|
||||
req: PublishRequest,
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user)
|
||||
current_user: User = Depends(get_current_admin)
|
||||
):
|
||||
"""标记选题为已发布,并创建发布记录"""
|
||||
"""标记选题为已发布,并创建发布记录(管理员)"""
|
||||
try:
|
||||
# 查找选题
|
||||
topic = db.query(Topic).filter(Topic.id == req.topic_id).first()
|
||||
@@ -56,7 +44,7 @@ async def create_publish_record(
|
||||
topic.published_at = datetime.now().date() # 设置发布时间为今天
|
||||
|
||||
# 创建发布记录
|
||||
operator = current_user.username if current_user else 'anonymous'
|
||||
operator = current_user.username
|
||||
record = PublishRecord(
|
||||
topic_id=req.topic_id,
|
||||
platform='all',
|
||||
|
||||
@@ -29,12 +29,12 @@ def get_status(db: Session = Depends(get_db)):
|
||||
by_status_result = db.query(Topic.status, func.count()).group_by(Topic.status).all()
|
||||
by_status = {status: count for status, count in by_status_result}
|
||||
|
||||
# 确保返回所有状态
|
||||
# 确保返回所有状态(数据库存中文,返回前端需要英文)
|
||||
status_map = {
|
||||
'pending': by_status.get('pending', 0),
|
||||
'review': by_status.get('review', 0),
|
||||
'ready': by_status.get('ready', 0),
|
||||
'published': by_status.get('published', 0)
|
||||
'pending': by_status.get('待处理', 0),
|
||||
'review': by_status.get('待审查', 0),
|
||||
'ready': by_status.get('待发布', 0),
|
||||
'published': by_status.get('已发布', 0)
|
||||
}
|
||||
|
||||
# 计算今日新增
|
||||
@@ -46,10 +46,10 @@ def get_status(db: Session = Depends(get_db)):
|
||||
return {
|
||||
"stats": {
|
||||
"total": total,
|
||||
"pending": status_map['待处理'],
|
||||
"review": status_map['待审查'],
|
||||
"ready": status_map['待发布'],
|
||||
"published": status_map['已发布'],
|
||||
"pending": status_map['pending'],
|
||||
"review": status_map['review'],
|
||||
"ready": status_map['ready'],
|
||||
"published": status_map['published'],
|
||||
"today": today_count
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user