TellmeStpToGlb/api/routes.py
root 7bd0624829 fix: 修复层级保留功能的导入错误并重新实现
- 移除有问题的OCC.Core导入,避免模块依赖问题
- 重新实现基于trimesh的层级保留功能,使用连通组件分离
- 添加智能回退机制,如果分离失败自动使用标准转换
- 扩展CLI和API接口支持层级保留参数
- 更新文档说明新的实现方式

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-02 16:55:22 +08:00

135 lines
4.2 KiB
Python

#!/usr/bin/env python3
"""
API路由定义
"""
import os
from fastapi import APIRouter, HTTPException, BackgroundTasks
from api.schemas import (
ConvertRequestSchema,
ConvertResponseSchema,
TaskStatusSchema,
HealthResponseSchema
)
from services.task_manager import task_manager
from core.models import ConvertOptions, TaskStatus
router = APIRouter()
@router.get("/health", response_model=HealthResponseSchema)
async def health_check():
"""健康检查接口"""
return HealthResponseSchema()
@router.post("/api/v1/convert", response_model=ConvertResponseSchema)
async def convert_file(request: ConvertRequestSchema):
"""转换文件接口"""
# 验证输入文件是否存在
if not os.path.isfile(request.input_path):
raise HTTPException(status_code=400, detail=f"输入文件不存在: {request.input_path}")
# 验证输入文件扩展名
if not request.input_path.lower().endswith(('.stp', '.step')):
raise HTTPException(status_code=400, detail="输入文件必须是STP或STEP格式")
# 验证输出文件扩展名
if not request.output_path.lower().endswith('.glb'):
raise HTTPException(status_code=400, detail="输出文件必须是GLB格式")
# 确保输出目录存在
output_dir = os.path.dirname(request.output_path)
if output_dir and not os.path.exists(output_dir):
try:
os.makedirs(output_dir, exist_ok=True)
except Exception as e:
raise HTTPException(status_code=400, detail=f"无法创建输出目录: {str(e)}")
# 创建转换选项
options = ConvertOptions(
auto_scale=request.options.auto_scale,
auto_center=request.options.auto_center,
preserve_hierarchy=request.options.preserve_hierarchy
)
# 创建任务
task = task_manager.create_task(
input_path=request.input_path,
output_path=request.output_path,
options=options
)
# 启动任务
success = await task_manager.start_task(task.task_id)
if not success:
raise HTTPException(status_code=500, detail="任务启动失败")
return ConvertResponseSchema(
task_id=task.task_id,
status=task.status.value,
message="任务已创建并开始处理"
)
@router.get("/api/v1/status/{task_id}", response_model=TaskStatusSchema)
async def get_task_status(task_id: str):
"""获取任务状态接口"""
task = task_manager.get_task(task_id)
if not task:
raise HTTPException(status_code=404, detail="任务不存在")
return TaskStatusSchema(
task_id=task.task_id,
status=task.status.value,
progress=task.progress,
message=task.message,
created_at=task.created_at,
started_at=task.started_at,
completed_at=task.completed_at,
error_message=task.error_message
)
@router.delete("/api/v1/task/{task_id}")
async def cancel_task(task_id: str):
"""取消任务接口"""
task = task_manager.get_task(task_id)
if not task:
raise HTTPException(status_code=404, detail="任务不存在")
if task.status in [TaskStatus.COMPLETED, TaskStatus.FAILED]:
raise HTTPException(status_code=400, detail="任务已完成,无法取消")
success = task_manager.cancel_task(task_id)
if success:
return {"message": "任务已取消"}
else:
return {"message": "任务未在运行中"}
@router.get("/api/v1/tasks")
async def list_tasks():
"""获取所有任务列表接口"""
tasks = task_manager.get_all_tasks()
task_list = []
for task_id, task in tasks.items():
task_list.append({
"task_id": task.task_id,
"status": task.status.value,
"progress": task.progress,
"input_path": task.input_path,
"output_path": task.output_path,
"created_at": task.created_at,
"message": task.message
})
# 按创建时间倒序排列
task_list.sort(key=lambda x: x["created_at"], reverse=True)
return {"tasks": task_list, "total": len(task_list)}