171 lines
5.6 KiB
Python
171 lines
5.6 KiB
Python
import json
|
|
|
|
from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ..database import get_db
|
|
from ..models.block_config import BlockConfig
|
|
from ..models.template import Template
|
|
from ..models.template_block import TemplateBlock
|
|
from ..schemas.template import BlockConfigPayload
|
|
from ..services.doc_parser import build_tree
|
|
from ..services.doc_parser import parse_document
|
|
from ..services.html_generator import generate_preview_html
|
|
from ..services.template_service import create_template_record, save_template_blocks, store_template_file
|
|
|
|
|
|
router = APIRouter(prefix="/api/templates", tags=["templates"])
|
|
|
|
|
|
@router.get("")
|
|
def list_templates(db: Session = Depends(get_db)):
|
|
templates = db.query(Template).order_by(Template.updated_at.desc(), Template.id.desc()).all()
|
|
return {"data": [serialize_template(template) for template in templates], "message": "ok"}
|
|
|
|
|
|
@router.post("/upload")
|
|
def upload_template(
|
|
file: UploadFile = File(...),
|
|
name: str = Form(...),
|
|
type: str = Form("report"),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""上传 Word 模板并创建模板记录。"""
|
|
try:
|
|
stored_path, content = store_template_file(file)
|
|
blocks = parse_document(content)
|
|
template = create_template_record(db, name=name, file_path=stored_path, type=type)
|
|
save_template_blocks(db, template.id, blocks)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
except Exception as exc:
|
|
db.rollback()
|
|
raise HTTPException(status_code=500, detail="模板上传失败") from exc
|
|
|
|
return {
|
|
"data": {
|
|
"template_id": template.id,
|
|
"name": template.name,
|
|
"block_count": len(blocks),
|
|
"status": "uploaded",
|
|
},
|
|
"message": "ok",
|
|
}
|
|
|
|
|
|
@router.get("/{template_id}")
|
|
def get_template_detail(template_id: int, db: Session = Depends(get_db)):
|
|
template = db.get(Template, template_id)
|
|
if not template:
|
|
raise HTTPException(status_code=404, detail="模板不存在")
|
|
|
|
block_records = (
|
|
db.query(TemplateBlock)
|
|
.filter(TemplateBlock.template_id == template_id)
|
|
.order_by(TemplateBlock.sort_order.asc(), TemplateBlock.id.asc())
|
|
.all()
|
|
)
|
|
blocks = [serialize_block(block) for block in block_records]
|
|
tree = build_tree([block.copy() for block in blocks])
|
|
configs = {
|
|
config.block_id: serialize_config(config)
|
|
for config in db.query(BlockConfig).filter(BlockConfig.template_id == template_id).all()
|
|
}
|
|
|
|
return {
|
|
"data": {
|
|
"template": serialize_template(template),
|
|
"preview_html": generate_preview_html(blocks),
|
|
"blocks": blocks,
|
|
"tree": tree,
|
|
"configs": configs,
|
|
},
|
|
"message": "ok",
|
|
}
|
|
|
|
|
|
@router.post("/{template_id}/blocks/{block_id}/config")
|
|
def save_block_config(
|
|
template_id: int,
|
|
block_id: str,
|
|
payload: BlockConfigPayload,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
block = (
|
|
db.query(TemplateBlock)
|
|
.filter(TemplateBlock.template_id == template_id, TemplateBlock.block_id == block_id)
|
|
.first()
|
|
)
|
|
if not block:
|
|
raise HTTPException(status_code=404, detail="模板区域不存在")
|
|
|
|
config = (
|
|
db.query(BlockConfig)
|
|
.filter(BlockConfig.template_id == template_id, BlockConfig.block_id == block_id)
|
|
.first()
|
|
)
|
|
if not config:
|
|
config = BlockConfig(template_id=template_id, block_id=block_id)
|
|
db.add(config)
|
|
|
|
config.region_name = payload.region_name
|
|
config.region_type = payload.region_type
|
|
config.data_sources = json.dumps(payload.data_sources, ensure_ascii=False)
|
|
config.prompt = payload.prompt
|
|
config.output_format = payload.output_format
|
|
config.need_review = payload.need_review
|
|
config.remark = payload.remark
|
|
config.enabled = payload.enabled
|
|
|
|
db.commit()
|
|
db.refresh(config)
|
|
return {"data": serialize_config(config), "message": "ok"}
|
|
|
|
|
|
def serialize_template(template: Template) -> dict:
|
|
return {
|
|
"id": template.id,
|
|
"name": template.name,
|
|
"type": template.type,
|
|
"version": template.version,
|
|
"original_file_path": template.original_file_path,
|
|
"status": template.status,
|
|
"created_by": template.created_by,
|
|
"created_at": template.created_at.isoformat() if template.created_at else None,
|
|
"updated_at": template.updated_at.isoformat() if template.updated_at else None,
|
|
}
|
|
|
|
|
|
def serialize_block(block: TemplateBlock) -> dict:
|
|
return {
|
|
"id": block.id,
|
|
"template_id": block.template_id,
|
|
"block_id": block.block_id,
|
|
"parent_block_id": block.parent_block_id,
|
|
"type": block.block_type,
|
|
"block_type": block.block_type,
|
|
"block_name": block.block_name,
|
|
"text": block.text_preview or "",
|
|
"text_preview": block.text_preview,
|
|
"level": block.level,
|
|
"sort_order": block.sort_order,
|
|
"table_rows": block.table_rows,
|
|
"table_cols": block.table_cols,
|
|
}
|
|
|
|
|
|
def serialize_config(config: BlockConfig) -> dict:
|
|
return {
|
|
"id": config.id,
|
|
"template_id": config.template_id,
|
|
"block_id": config.block_id,
|
|
"region_name": config.region_name,
|
|
"region_type": config.region_type,
|
|
"data_sources": json.loads(config.data_sources or "[]"),
|
|
"prompt": config.prompt,
|
|
"output_format": config.output_format,
|
|
"need_review": config.need_review,
|
|
"remark": config.remark,
|
|
"enabled": config.enabled,
|
|
}
|