TellmeStpToGlb/api/routes.py
sladro b5e18c5c7a feat: 重构转换系统,默认启用层级转换和组件名称保留
## 主要变更
- 创建新的STP文件文本解析器,直接读取文件内容提取组件名称
- 简化CLI和API接口,移除层级和名称保留参数
- 所有转换默认使用层级模式并保留原始组件名称
- 重构转换器类,清理冗余代码

## 技术改进
- 新增 core/stp_parser.py:直接解析PRODUCT和PRODUCT_DEFINITION实体
- 优化 converter.py:统一转换流程,默认层级转换
- 更新 main.py:简化命令行参数,移除 --hierarchy 和 --preserve-names
- 修复 API 错误处理:全局异常处理器返回正确的JSON响应
- 完善 API 精度参数传递:支持自定义精度选项

## 接口变更
- CLI:`python main.py input.stp output.glb` 即可获得层级转换结果
- API:移除 preserve_hierarchy 和 preserve_original_names 参数
- 保持向后兼容:原有的基本用法不变

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-15 10:25:14 +08:00

142 lines
4.5 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, PrecisionOptions
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)}")
# 创建精度选项
precision = PrecisionOptions(
linear_deflection=request.options.precision.linear_deflection,
angular_deflection=request.options.precision.angular_deflection,
mesh_quality=request.options.precision.mesh_quality
)
# 创建转换选项
options = ConvertOptions(
auto_scale=request.options.auto_scale,
auto_center=request.options.auto_center,
precision=precision
)
# 创建任务
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)}