From 49d6e0376a3fcd5eb22cd786e615c8b814fbd01e Mon Sep 17 00:00:00 2001 From: cjw <792430652@qq.com> Date: Mon, 16 Feb 2026 16:25:32 +0800 Subject: [PATCH] deving --- src/api/routes.py | 235 +++++++++++++++++++++++----------------- static/history.js | 26 +---- static/style.css | 11 +- templates/result.html | 45 ++------ templates/snapshot.html | 14 +-- 5 files changed, 157 insertions(+), 174 deletions(-) diff --git a/src/api/routes.py b/src/api/routes.py index a6cb10b..d24c725 100644 --- a/src/api/routes.py +++ b/src/api/routes.py @@ -117,14 +117,56 @@ async def upload_stp( @router.get("/status/{task_id}") @router.post("/status/{task_id}") -async def get_status(task_id: str): +async def get_status(task_id: str, db_session: AsyncSession = Depends(get_db_session)): """获取任务状态""" - if task_id not in tasks: + # 先从内存查找 + if task_id in tasks: + task = tasks[task_id] + logger.info(f"返回任务状态(内存): {task_id} - {task['status']}") + return task + + # 内存中没有,从数据库查找 + from sqlalchemy import select + from models.database import ProcessingTask, STPFile + + result = await db_session.execute( + select(ProcessingTask, STPFile) + .join(STPFile, ProcessingTask.stp_file_id == STPFile.id) + .where(ProcessingTask.task_id == task_id) + ) + + task_record = result.first() + if not task_record: raise HTTPException(404, "任务不存在") - task = tasks[task_id] - logger.info(f"返回任务状态: {task_id} - {task['status']}") - return task + task, stp_file = task_record + task_data = { + "task_id": task.task_id, + "filename": stp_file.original_filename if stp_file else "", + "file_size": stp_file.file_size if stp_file else 0, + "status": task.status, + "progress": task.progress, + "current_step": task.current_step, + "upload_time": task.created_time.isoformat() if task.created_time else "", + "completed_at": task.completed_time.isoformat() if task.completed_time else "", + "error": task.error_message if task.error_message else "" + } + + # 尝试获取快照中的 key_info + from models.database import AnalysisResultSnapshot + snapshot_result = await db_session.execute( + select(AnalysisResultSnapshot) + .where(AnalysisResultSnapshot.stp_file_id == stp_file.id) + .order_by(AnalysisResultSnapshot.created_time.desc()) + .limit(1) + ) + snapshot = snapshot_result.scalar_one_or_none() + + if snapshot and snapshot.key_info: + task_data["key_info"] = snapshot.key_info + + logger.info(f"返回任务状态(数据库): {task_id} - {task['status']}") + return task_data @router.get("/debug/tasks") @@ -316,121 +358,110 @@ async def result_page(request: Request, task_id: str, db_session: AsyncSession = """结果详情页面""" from sqlalchemy import select from models.database import ProcessingTask, STPFile, GeometryData, MoldCavityData, HTMLFile, AnalysisResultSnapshot - - # 先尝试从分析结果快照获取数据(包含完整的 key_info) - result = await db_session.execute( - select(AnalysisResultSnapshot, ProcessingTask, STPFile) - .join(ProcessingTask, AnalysisResultSnapshot.stp_file_id == ProcessingTask.stp_file_id) + + # 先查询任务记录 + task_result = await db_session.execute( + select(ProcessingTask, STPFile) .join(STPFile, ProcessingTask.stp_file_id == STPFile.id) .where(ProcessingTask.task_id == task_id) + ) + task_record = task_result.first() + + if not task_record: + raise HTTPException(404, "任务不存在") + + task, stp_file = task_record + + # 构建任务详情数据 + task_data = { + "task_id": task.task_id, + "filename": stp_file.original_filename if stp_file else "", + "file_size": stp_file.file_size if stp_file else 0, + "status": task.status, + "progress": task.progress, + "current_step": task.current_step, + "upload_time": task.created_time.isoformat() if task.created_time else "", + "completed_at": task.completed_time.isoformat() if task.completed_time else "", + "error": task.error_message if task.error_message else "" + } + + # 尝试从分析结果快照获取数据 + snapshot_result = await db_session.execute( + select(AnalysisResultSnapshot) + .where(AnalysisResultSnapshot.stp_file_id == stp_file.id) .order_by(AnalysisResultSnapshot.created_time.desc()) .limit(1) ) - - snapshot_record = result.first() - - # 构建任务详情数据 - task_data = {} - - if snapshot_record: - # 从快照获取完整数据 - snapshot, task, stp_file = snapshot_record - task_data = { - "task_id": task.task_id, - "filename": stp_file.original_filename if stp_file else "", - "file_size": stp_file.file_size if stp_file else 0, - "status": task.status, - "progress": task.progress, - "current_step": task.current_step, - "upload_time": task.created_time.isoformat() if task.created_time else "", - "completed_at": task.completed_time.isoformat() if task.completed_time else "", - "error": task.error_message if task.error_message else "" - } - + snapshot = snapshot_result.scalar_one_or_none() + + if snapshot: # 从快照获取完整的数据 task_data["geometry_data"] = snapshot.geometry_data if snapshot.geometry_data else None task_data["key_info"] = snapshot.key_info if snapshot.key_info else None task_data["mold_cavity_data"] = snapshot.mold_cavity_data if snapshot.mold_cavity_data else None - logger.info(f"从快照加载任务数据: {task_id}") else: # 如果没有快照,从各个表分别获取 result = await db_session.execute( - select(ProcessingTask, STPFile, GeometryData, MoldCavityData, HTMLFile) - .join(STPFile, ProcessingTask.stp_file_id == STPFile.id) - .outerjoin(GeometryData, STPFile.id == GeometryData.stp_file_id) - .outerjoin(MoldCavityData, STPFile.id == MoldCavityData.stp_file_id) - .outerjoin(HTMLFile, STPFile.id == HTMLFile.stp_file_id) - .where(ProcessingTask.task_id == task_id) + select(GeometryData, MoldCavityData, HTMLFile) + .outerjoin(MoldCavityData, GeometryData.stp_file_id == MoldCavityData.stp_file_id) + .outerjoin(HTMLFile, GeometryData.stp_file_id == HTMLFile.stp_file_id) + .where(GeometryData.stp_file_id == stp_file.id) ) - - task_record = result.first() - - if not task_record: - raise HTTPException(404, "任务不存在") - - task, stp_file, geometry_data, mold_cavity_data, html_file = task_record - - task_data = { - "task_id": task.task_id, - "filename": stp_file.original_filename if stp_file else "", - "file_size": stp_file.file_size if stp_file else 0, - "status": task.status, - "progress": task.progress, - "current_step": task.current_step, - "upload_time": task.created_time.isoformat() if task.created_time else "", - "completed_at": task.completed_time.isoformat() if task.completed_time else "", - "error": task.error_message if task.error_message else "" - } - - # 如果有几何数据,添加到返回结果 - if geometry_data: - task_data["geometry_data"] = { - "volume": geometry_data.volume, - "surface_area": geometry_data.surface_area, - "bounding_box": { - "min": geometry_data.bounding_box_min, - "max": geometry_data.bounding_box_max, - "dimensions": [ - geometry_data.bounding_box_max[0] - geometry_data.bounding_box_min[0] if geometry_data.bounding_box_max and geometry_data.bounding_box_min else 0, - geometry_data.bounding_box_max[1] - geometry_data.bounding_box_min[1] if geometry_data.bounding_box_max and geometry_data.bounding_box_min else 0, - geometry_data.bounding_box_max[2] - geometry_data.bounding_box_min[2] if geometry_data.bounding_box_max and geometry_data.bounding_box_min else 0 - ] - }, - "topology": { - "faces": geometry_data.topology_faces, - "edges": geometry_data.topology_edges, - "vertices": geometry_data.topology_vertices - }, - "center_of_mass": geometry_data.center_of_mass - } - - # 如果有模具型腔数据,添加到返回结果 - if mold_cavity_data: - task_data["key_info"] = { - "metadata": { - "shrinkage_rate": mold_cavity_data.shrinkage_rate, - "draft_angle": mold_cavity_data.draft_angle - }, - "manufacturing_info": { - "mold_material": mold_cavity_data.mold_material, - "estimated_clamping_force": mold_cavity_data.estimated_clamping_force, - "parting_line_length": mold_cavity_data.parting_line_length - }, - "mold_cavities": { - "cavity_key_info": { - "geometric_characteristics": { - "product_weight": mold_cavity_data.product_weight, - "product_volume": mold_cavity_data.product_volume, - "wall_thickness_range": mold_cavity_data.wall_thickness_range, - "complexity_score": mold_cavity_data.complexity_score + + other_data = result.first() + + if other_data: + geometry_data, mold_cavity_data, html_file = other_data + + # 如果有几何数据,添加到返回结果 + if geometry_data: + task_data["geometry_data"] = { + "volume": geometry_data.volume, + "surface_area": geometry_data.surface_area, + "bounding_box": { + "min": geometry_data.bounding_box_min, + "max": geometry_data.bounding_box_max, + "dimensions": [ + geometry_data.bounding_box_max[0] - geometry_data.bounding_box_min[0] if geometry_data.bounding_box_max and geometry_data.bounding_box_min else 0, + geometry_data.bounding_box_max[1] - geometry_data.bounding_box_min[1] if geometry_data.bounding_box_max and geometry_data.bounding_box_min else 0, + geometry_data.bounding_box_max[2] - geometry_data.bounding_box_min[2] if geometry_data.bounding_box_max and geometry_data.bounding_box_min else 0 + ] + }, + "topology": { + "faces": geometry_data.topology_faces, + "edges": geometry_data.topology_edges, + "vertices": geometry_data.topology_vertices + }, + "center_of_mass": geometry_data.center_of_mass + } + + # 如果有模具型腔数据,添加到返回结果 + if mold_cavity_data: + task_data["key_info"] = { + "metadata": { + "shrinkage_rate": mold_cavity_data.shrinkage_rate, + "draft_angle": mold_cavity_data.draft_angle + }, + "manufacturing_info": { + "mold_material": mold_cavity_data.mold_material, + "estimated_clamping_force": mold_cavity_data.estimated_clamping_force, + "parting_line_length": mold_cavity_data.parting_line_length + }, + "mold_cavities": { + "cavity_key_info": { + "geometric_characteristics": { + "product_weight": mold_cavity_data.product_weight, + "product_volume": mold_cavity_data.product_volume, + "wall_thickness_range": mold_cavity_data.wall_thickness_range, + "complexity_score": mold_cavity_data.complexity_score + } } } } - } - + logger.info(f"从各个表加载任务数据: {task_id}") - + from fastapi.templating import Jinja2Templates import os # 简化路径配置,直接使用当前工作目录下的templates文件夹 diff --git a/static/history.js b/static/history.js index 013e0a1..dee08a0 100644 --- a/static/history.js +++ b/static/history.js @@ -147,30 +147,8 @@ async function toggleFileRecords(filename) { } async function viewRecordDetails(taskId) { - // 先检查任务状态,如果数据不完整,提示用户重新分析 - try { - const response = await fetch(`/status/${taskId}`); - if (response.ok) { - const task = await response.json(); - if (task.status === 'completed' && task.key_info) { - // 数据完整,跳转到结果页面 - window.location.href = `/result/${taskId}`; - } else { - // 数据不完整,提示用户重新分析 - if (confirm('该历史记录的分析数据不完整,是否重新分析?')) { - // 重新分析逻辑 - await reanalyzeTask(taskId); - } - } - } else { - // 任务不存在或无法访问,跳转到结果页面尝试显示 - window.location.href = `/result/${taskId}`; - } - } catch (error) { - console.error('检查任务状态失败:', error); - // 出错时直接跳转 - window.location.href = `/result/${taskId}`; - } + // 直接跳转到结果页面,由后端从数据库加载完整数据 + window.location.href = `/result/${taskId}`; } async function reanalyzeTask(taskId) { diff --git a/static/style.css b/static/style.css index 9a81952..c8073e3 100644 --- a/static/style.css +++ b/static/style.css @@ -174,12 +174,18 @@ body { } .key-info-categories { - display: grid; - grid-template-columns: repeat(3, 1fr); + display: grid !important; + grid-template-columns: repeat(3, 1fr) !important; gap: 20px; margin-bottom: 20px; } +.data-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 10px; +} + .category-section { background: #f8f9fa; border-radius: 10px; @@ -508,5 +514,4 @@ body { .analysis-info { grid-template-columns: 1fr; } -} } \ No newline at end of file diff --git a/templates/result.html b/templates/result.html index 1d84d0b..b357c81 100644 --- a/templates/result.html +++ b/templates/result.html @@ -5,7 +5,7 @@