This commit is contained in:
2026-05-14 16:56:18 +08:00
parent d38a4630dd
commit 224330598a
15 changed files with 1151 additions and 277 deletions
+75 -8
View File
@@ -2,6 +2,7 @@
"""STP 文件处理流程编排器 — 协调解析、网格生成、型腔生成、保存、验证"""
import asyncio
import time
import traceback
from datetime import datetime
from pathlib import Path
@@ -42,6 +43,7 @@ class ProcessingService:
self.html_generator = HTMLGenerator()
self.storage_service = StorageIntegrationService()
self.multi_scheme_planner = MultiSchemeMoldPlanner()
self._export_shapes_cache: Dict[str, Dict[str, Dict[str, Any]]] = {}
# ─── 对外入口 ───
@@ -50,7 +52,7 @@ class ProcessingService:
task_id: str,
file_path: str,
stp_file_id: int,
material: str = "ABS",
process_params: Optional[Dict[str, Any]] = None,
):
"""处理文件的后台任务 — 使用独立数据库会话"""
@@ -65,7 +67,7 @@ class ProcessingService:
try:
await asyncio.wait_for(
self.process_file_core(
task_id, file_path, stp_file_id, db_session, material
task_id, file_path, stp_file_id, db_session, process_params
),
timeout_seconds,
)
@@ -96,29 +98,35 @@ class ProcessingService:
file_path: str,
stp_file_id: int,
db_session: AsyncSession,
material: str = "ABS",
process_params: Optional[Dict[str, Any]] = None,
):
"""核心处理逻辑"""
try:
logger.info(f"开始处理文件并生成模具型腔: {file_path}")
process_params = self._normalize_process_params(process_params)
stage_timings: Dict[str, float] = {}
# 1. 解析STP文件
await self.storage_service.update_task_status(
db_session, task_id, "processing", 20, "解析STP文件"
)
stage_started = time.perf_counter()
shape = self.stp_parser.load_step_file(Path(file_path))
geometry_data = self.stp_parser.analyze_geometry(shape)
stage_timings["parse_stp"] = round(time.perf_counter() - stage_started, 3)
# 2. 生成网格数据并持久化
await self.storage_service.update_task_status(
db_session, task_id, "processing", 30, "生成网格数据"
)
stage_started = time.perf_counter()
mesh_result = await self._step_generate_mesh(
shape, geometry_data, file_path, db_session, stp_file_id, task_id
)
stage_timings["generate_mesh"] = round(time.perf_counter() - stage_started, 3)
# 3. 生成模具型腔
await self.storage_service.update_task_status(
@@ -126,25 +134,35 @@ class ProcessingService:
)
# 材料属性 — 通过 MaterialService 集中管理
requested_material = MaterialService.resolve_material(material)
selected_material = MaterialService.get_material(requested_material)
requested_material = MaterialService.resolve_material(process_params["material"])
selected_material = dict(MaterialService.get_material(requested_material))
selected_material["shrinkage"] = process_params["shrinkage_rate"] / 100.0
is_foam_material = MaterialService.is_foam_material(requested_material)
stage_started = time.perf_counter()
plan_result = await self._step_generate_cavity(
shape, selected_material, is_foam_material
shape, selected_material, is_foam_material, process_params
)
stage_timings["generate_cavity"] = round(time.perf_counter() - stage_started, 3)
export_shapes = {}
if plan_result:
export_shapes = plan_result.pop("_export_shapes", {}) or {}
if export_shapes:
self._cache_export_shapes(task_id, export_shapes)
# 4. 生成详细JSON数据 — 委托 CalculationService
await self.storage_service.update_task_status(
db_session, task_id, "processing", 60, "生成型腔详细数据"
)
stage_started = time.perf_counter()
detailed_cavity_json = CalculationService.build_plan_result(
geometry_data=geometry_data,
material=selected_material,
file_path=str(file_path),
plan_result=plan_result,
)
stage_timings["build_plan_result"] = round(time.perf_counter() - stage_started, 3)
best_scheme = CalculationService.get_best_scheme(detailed_cavity_json)
best_cavity_data = best_scheme.get("cavity_data", {}) if best_scheme else {}
@@ -164,6 +182,7 @@ class ProcessingService:
db_session, task_id, "processing", 70, "保存几何数据"
)
stage_started = time.perf_counter()
await self.storage_service.save_geometry_data(
db_session,
stp_file_id,
@@ -229,9 +248,15 @@ class ProcessingService:
Path(html_file_path).name,
html_file_path,
)
stage_timings["persist_artifacts"] = round(time.perf_counter() - stage_started, 3)
# 9. 分析模具设计
analysis_result = self.geometry_analyzer.analyze_mold_design(geometry_data)
stage_started = time.perf_counter()
analysis_result = self.geometry_analyzer.analyze_mold_design(
geometry_data,
product_material=requested_material,
shape=shape,
)
if analysis_result:
await self.storage_service.save_features_and_recommendations(
@@ -242,6 +267,7 @@ class ProcessingService:
)
await self._save_analysis_metrics(db_session, stp_file_id, analysis_result)
stage_timings["analyze_design"] = round(time.perf_counter() - stage_started, 3)
# 9.6 更新STP文件的分析摘要字段
await self.storage_service.update_stp_file_analysis_summary(
@@ -255,20 +281,35 @@ class ProcessingService:
)
# 9.7 FreeCAD 几何验证
stage_started = time.perf_counter()
verification_result = await self._step_verify(
file_path, db_session, task_id, stp_file_id, analysis_result
)
stage_timings["verify_geometry"] = round(time.perf_counter() - stage_started, 3)
# 9.8 LLM 增强分析
llm_report = None
stage_started = time.perf_counter()
if analysis_result:
llm_report = await llm_service.generate_design_report(analysis_result, detailed_cavity_json)
stage_timings["generate_llm_report"] = round(time.perf_counter() - stage_started, 3)
# 10. 完成处理
await self.storage_service.update_stp_file_status(db_session, stp_file_id, "completed")
await self.storage_service.update_task_status(
db_session, task_id, "completed", 100, "模具型腔生成完成"
)
await self.storage_service.update_task_parameters(
db_session,
task_id,
{
"stage_timings": stage_timings,
"material": requested_material,
"verification": verification_result,
"llm_report": llm_report,
**process_params,
},
)
# 更新任务缓存状态
await redis_task_manager.update_task(task_id, {
@@ -279,6 +320,9 @@ class ProcessingService:
"best_scheme_id": detailed_cavity_json.get("best_scheme_id"),
"cavity_data": best_cavity_data,
"key_info": best_key_info,
"material": requested_material,
"parameters": process_params,
"stage_timings": stage_timings,
"html_file": best_scheme.get("html_file", f"/html/{Path(html_file_path).name}") if best_scheme else f"/html/{Path(html_file_path).name}",
"verification": verification_result,
"llm_report": llm_report,
@@ -370,7 +414,7 @@ class ProcessingService:
return mesh_result
async def _step_generate_cavity(
self, shape, selected_material: dict, is_foam_material: bool,
self, shape, selected_material: dict, is_foam_material: bool, process_params: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
"""生成多方案分模结果"""
plan_result = None
@@ -380,6 +424,7 @@ class ProcessingService:
shape=shape,
material=selected_material,
is_foam_material=is_foam_material,
process_params=process_params,
)
logger.info(
f"多方案分模完成: 生成 {len(plan_result.get('candidate_schemes', []))} 套方案"
@@ -391,6 +436,28 @@ class ProcessingService:
return plan_result
def _cache_export_shapes(self, task_id: str, export_shapes: Dict[str, Dict[str, Any]]):
self._export_shapes_cache[task_id] = export_shapes
def get_export_shapes(self, task_id: str, scheme_id: Optional[str] = None) -> Optional[Dict[str, Any]]:
scheme_map = self._export_shapes_cache.get(task_id, {})
if not scheme_map:
return None
if scheme_id:
return scheme_map.get(scheme_id)
return next(iter(scheme_map.values()), None)
@staticmethod
def _normalize_process_params(process_params: Optional[Dict[str, Any]]) -> Dict[str, Any]:
payload = dict(process_params or {})
return {
"material": MaterialService.resolve_material(str(payload.get("material", "ABS"))),
"draft_angle": float(payload.get("draft_angle", 2.0)),
"shrinkage_rate": float(payload.get("shrinkage_rate", 0.5)),
"parting_precision": float(payload.get("parting_precision", 0.1)),
"cavity_match": int(payload.get("cavity_match", 95)),
}
async def _step_verify(
self, file_path: str, db_session: AsyncSession,
task_id: str, stp_file_id: int, analysis_result: Optional[dict],