## 主要变更 - 创建新的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>
142 lines
4.5 KiB
Python
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)} |