Files
geMoldInsight/src/moldinsight/api/cam_router.py
T

121 lines
4.4 KiB
Python
Raw Normal View History

import asyncio
from datetime import datetime
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
2026-05-02 00:39:04 +08:00
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
2026-05-29 18:10:08 +08:00
from shared.database.database import get_db_session
from shared.models.identity import User
from moldinsight.models import ProcessingTask
2026-05-29 18:10:08 +08:00
from shared.services.auth_service import get_current_active_user
from moldinsight.services.cam_bundle_service import cam_bundle_service
from moldinsight.services.task_query_service import TaskQueryService
from shared.utils.logger import get_logger
2026-05-02 00:39:04 +08:00
logger = get_logger(__name__)
router = APIRouter()
DEFAULT_CAM_PREFERENCES = {
"mold_steel": "P20",
"surface_quality": "standard",
"controller": "fanuc",
2026-06-16 11:15:03 +08:00
"include_gcode": True,
2026-05-02 00:39:04 +08:00
}
class CamPlanRequest(BaseModel):
"""未提供的偏好字段回落到任务持久化偏好,再回落到默认值。"""
task_id: str
scheme_id: Optional[str] = None
mold_steel: Optional[str] = None
surface_quality: Optional[str] = None
controller: Optional[str] = None
include_gcode: Optional[bool] = None
2026-05-02 00:39:04 +08:00
@router.post("/cam/plan")
async def generate_cam_plan(
body: CamPlanRequest,
2026-05-02 00:39:04 +08:00
db_session: AsyncSession = Depends(get_db_session),
current_user: User = Depends(get_current_active_user),
):
"""基于任务分模结果生成 CAM 准备包(MVP)。"""
_ = current_user
task_id = body.task_id
2026-05-02 00:39:04 +08:00
task_result = await db_session.execute(
select(ProcessingTask).where(ProcessingTask.task_id == task_id)
)
processing_task = task_result.scalar_one_or_none()
persisted_preferences = {}
if processing_task and isinstance(processing_task.parameters, dict):
persisted_preferences = (
processing_task.parameters.get("cam_preferences", {}) or {}
)
# 注意 include_gcode 显式判 None:False 是有效值,不能走 or 回落
mold_steel = (
body.mold_steel
if body.mold_steel is not None
else persisted_preferences.get("mold_steel", DEFAULT_CAM_PREFERENCES["mold_steel"])
2026-05-02 00:39:04 +08:00
)
surface_quality = (
body.surface_quality
if body.surface_quality is not None
else persisted_preferences.get("surface_quality", DEFAULT_CAM_PREFERENCES["surface_quality"])
2026-05-02 00:39:04 +08:00
)
controller = (
body.controller
if body.controller is not None
else persisted_preferences.get("controller", DEFAULT_CAM_PREFERENCES["controller"])
2026-05-02 00:39:04 +08:00
)
include_gcode = (
body.include_gcode
if body.include_gcode is not None
else persisted_preferences.get("include_gcode", DEFAULT_CAM_PREFERENCES["include_gcode"])
2026-05-02 00:39:04 +08:00
)
task_view = await TaskQueryService.get_task_view(db_session, task_id)
if not task_view:
raise HTTPException(status_code=404, detail="任务不存在")
if task_view.get("status") != "completed":
raise HTTPException(status_code=400, detail="任务尚未完成,无法生成CAM计划")
try:
# CAM 刀路计算为纯 Python 重计算,投放线程池避免阻塞事件循环
data = await asyncio.to_thread(
cam_bundle_service.build_bundle,
2026-05-02 00:39:04 +08:00
task_view=task_view,
scheme_id=body.scheme_id,
2026-05-02 00:39:04 +08:00
mold_steel=mold_steel,
surface_quality=surface_quality,
controller=controller,
include_gcode=include_gcode,
)
cam_preferences = {
"mold_steel": mold_steel,
"surface_quality": surface_quality,
"controller": controller,
"include_gcode": include_gcode,
}
if processing_task:
parameters = processing_task.parameters if isinstance(processing_task.parameters, dict) else {}
parameters["cam_preferences"] = cam_preferences
parameters["cam_last_plan"] = {
"scheme_id": data.get("scheme_id"),
"generated_at": datetime.now().isoformat(),
}
processing_task.parameters = parameters
await db_session.commit()
2026-08-31 18:01:34 +08:00
# parameters 已变更,任务视图缓存失效
TaskQueryService.invalidate_task_view(task_id)
2026-05-02 00:39:04 +08:00
return {"status": "success", "data": data, "cam_preferences": cam_preferences}
except Exception as exc:
logger.error(f"生成CAM准备包失败 task_id={task_id}: {exc}")
raise HTTPException(status_code=500, detail=f"生成CAM准备包失败: {exc}")