deving
This commit is contained in:
+18
-173
@@ -116,97 +116,14 @@ async def upload_stp(
|
|||||||
|
|
||||||
@router.get("/status/{task_id}")
|
@router.get("/status/{task_id}")
|
||||||
@router.post("/status/{task_id}")
|
@router.post("/status/{task_id}")
|
||||||
async def get_status(task_id: str, db_session: AsyncSession = Depends(get_db_session)):
|
async def get_status(task_id: str):
|
||||||
"""获取任务状态"""
|
"""获取任务状态"""
|
||||||
from sqlalchemy import select
|
if task_id not in tasks:
|
||||||
from models.database import ProcessingTask, STPFile, GeometryData, MoldCavityData, HTMLFile
|
|
||||||
|
|
||||||
# 从数据库查询任务详情及相关数据
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
|
|
||||||
task_record = result.first()
|
|
||||||
|
|
||||||
if not task_record:
|
|
||||||
raise HTTPException(404, "任务不存在")
|
raise HTTPException(404, "任务不存在")
|
||||||
|
|
||||||
task, stp_file, geometry_data, mold_cavity_data, html_file = task_record
|
task = tasks[task_id]
|
||||||
|
logger.info(f"返回任务状态: {task_id} - {task['status']}")
|
||||||
# 构建任务详情数据
|
return task
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 如果有HTML文件信息,添加到返回结果
|
|
||||||
if html_file:
|
|
||||||
task_data["html_info"] = {
|
|
||||||
"filename": html_file.filename,
|
|
||||||
"file_path": html_file.file_path,
|
|
||||||
"generated_time": html_file.generated_time.isoformat() if html_file.generated_time else ""
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(f"返回任务状态: {task_id} - {task.status}")
|
|
||||||
return task_data
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/debug/tasks")
|
@router.get("/debug/tasks")
|
||||||
@@ -230,7 +147,7 @@ async def get_file_history(db_session: AsyncSession = Depends(get_db_session)):
|
|||||||
result = await db_session.execute(
|
result = await db_session.execute(
|
||||||
select(ProcessingTask, STPFile)
|
select(ProcessingTask, STPFile)
|
||||||
.join(STPFile, ProcessingTask.stp_file_id == STPFile.id)
|
.join(STPFile, ProcessingTask.stp_file_id == STPFile.id)
|
||||||
.order_by(ProcessingTask.created_time.desc())
|
.order_by(ProcessingTask.created_at.desc())
|
||||||
)
|
)
|
||||||
|
|
||||||
tasks = result.all()
|
tasks = result.all()
|
||||||
@@ -245,7 +162,7 @@ async def get_file_history(db_session: AsyncSession = Depends(get_db_session)):
|
|||||||
file_groups[filename].append({
|
file_groups[filename].append({
|
||||||
"task_id": task.task_id,
|
"task_id": task.task_id,
|
||||||
"filename": filename,
|
"filename": filename,
|
||||||
"upload_time": task.created_time.isoformat() if task.created_time else "",
|
"upload_time": task.created_at.isoformat() if task.created_at else "",
|
||||||
"status": task.status,
|
"status": task.status,
|
||||||
"file_size": stp_file.file_size
|
"file_size": stp_file.file_size
|
||||||
})
|
})
|
||||||
@@ -274,7 +191,7 @@ async def get_file_history(db_session: AsyncSession = Depends(get_db_session)):
|
|||||||
|
|
||||||
@router.get("/api/history/{filename}")
|
@router.get("/api/history/{filename}")
|
||||||
@router.post("/api/history/{filename}")
|
@router.post("/api/history/{filename}")
|
||||||
async def get_file_records(filename: str, db_session: AsyncSession = Depends(get_db_session)):
|
async def get_file_records(filename: str):
|
||||||
"""获取指定文件名的所有记录"""
|
"""获取指定文件名的所有记录"""
|
||||||
# URL解码文件名
|
# URL解码文件名
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
@@ -288,7 +205,7 @@ async def get_file_records(filename: str, db_session: AsyncSession = Depends(get
|
|||||||
select(ProcessingTask, STPFile)
|
select(ProcessingTask, STPFile)
|
||||||
.join(STPFile, ProcessingTask.stp_file_id == STPFile.id)
|
.join(STPFile, ProcessingTask.stp_file_id == STPFile.id)
|
||||||
.where(STPFile.original_filename == decoded_filename)
|
.where(STPFile.original_filename == decoded_filename)
|
||||||
.order_by(ProcessingTask.created_time.desc())
|
.order_by(ProcessingTask.created_at.desc())
|
||||||
)
|
)
|
||||||
|
|
||||||
tasks = result.all()
|
tasks = result.all()
|
||||||
@@ -300,9 +217,11 @@ async def get_file_records(filename: str, db_session: AsyncSession = Depends(get
|
|||||||
"task_id": task.task_id,
|
"task_id": task.task_id,
|
||||||
"filename": stp_file.original_filename,
|
"filename": stp_file.original_filename,
|
||||||
"file_size": stp_file.file_size,
|
"file_size": stp_file.file_size,
|
||||||
"upload_time": task.created_time.isoformat() if task.created_time else "",
|
"upload_time": task.created_at.isoformat() if task.created_at else "",
|
||||||
"status": task.status,
|
"status": task.status,
|
||||||
"completed_at": task.completed_time.isoformat() if task.completed_time else ""
|
"completed_at": task.completed_at.isoformat() if task.completed_at else "",
|
||||||
|
"geometry_data": task.geometry_data,
|
||||||
|
"cavity_data": task.cavity_data
|
||||||
})
|
})
|
||||||
|
|
||||||
# 按上传时间排序(最新的在前)
|
# 按上传时间排序(最新的在前)
|
||||||
@@ -327,87 +246,14 @@ async def history_page(request: Request):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/html-info/{task_id}")
|
|
||||||
@router.post("/api/html-info/{task_id}")
|
|
||||||
async def get_html_info(task_id: str, db_session: AsyncSession = Depends(get_db_session)):
|
|
||||||
"""获取任务的HTML文件信息"""
|
|
||||||
from sqlalchemy import select
|
|
||||||
from models.database import ProcessingTask, STPFile, HTMLFile
|
|
||||||
|
|
||||||
# 从数据库查询HTML文件信息
|
|
||||||
result = await db_session.execute(
|
|
||||||
select(ProcessingTask, STPFile, HTMLFile)
|
|
||||||
.join(STPFile, ProcessingTask.stp_file_id == STPFile.id)
|
|
||||||
.outerjoin(HTMLFile, STPFile.id == HTMLFile.stp_file_id)
|
|
||||||
.where(ProcessingTask.task_id == task_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
task_record = result.first()
|
|
||||||
|
|
||||||
if not task_record:
|
|
||||||
raise HTTPException(404, "任务不存在")
|
|
||||||
|
|
||||||
task, stp_file, html_file = task_record
|
|
||||||
|
|
||||||
if not html_file:
|
|
||||||
return {"message": "该任务没有HTML可视化报告"}
|
|
||||||
|
|
||||||
# 返回HTML文件信息
|
|
||||||
html_info = {
|
|
||||||
"filename": html_file.filename,
|
|
||||||
"file_path": html_file.file_path,
|
|
||||||
"generated_time": html_file.generated_time.isoformat() if html_file.generated_time else "",
|
|
||||||
"visualization_type": html_file.visualization_type
|
|
||||||
}
|
|
||||||
|
|
||||||
return html_info
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/result/{task_id}")
|
@router.get("/result/{task_id}")
|
||||||
@router.post("/result/{task_id}")
|
@router.post("/result/{task_id}")
|
||||||
async def result_page(request: Request, task_id: str, db_session: AsyncSession = Depends(get_db_session)):
|
async def result_page(request: Request, task_id: str):
|
||||||
"""结果详情页面"""
|
"""结果详情页面"""
|
||||||
from sqlalchemy import select
|
if task_id not in tasks:
|
||||||
from models.database import ProcessingTask, STPFile, GeometryData, MoldCavityData, HTMLFile
|
|
||||||
|
|
||||||
# 从数据库查询任务详情及相关数据
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
|
|
||||||
task_record = result.first()
|
|
||||||
|
|
||||||
if not task_record:
|
|
||||||
raise HTTPException(404, "任务不存在")
|
raise HTTPException(404, "任务不存在")
|
||||||
|
|
||||||
task, stp_file, geometry_data, mold_cavity_data, html_file = task_record
|
task = tasks[task_id]
|
||||||
|
|
||||||
# 构建任务详情数据
|
|
||||||
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,
|
|
||||||
"created_at": 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 ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# 如果有HTML文件,添加HTML文件信息
|
|
||||||
html_info = None
|
|
||||||
if html_file:
|
|
||||||
html_info = {
|
|
||||||
"filename": html_file.filename,
|
|
||||||
"file_path": html_file.file_path,
|
|
||||||
"generated_time": html_file.generated_time.isoformat() if html_file.generated_time else ""
|
|
||||||
}
|
|
||||||
|
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
import os
|
import os
|
||||||
@@ -416,8 +262,7 @@ async def result_page(request: Request, task_id: str, db_session: AsyncSession =
|
|||||||
templates = Jinja2Templates(directory=templates_dir)
|
templates = Jinja2Templates(directory=templates_dir)
|
||||||
return templates.TemplateResponse("result.html", {
|
return templates.TemplateResponse("result.html", {
|
||||||
"request": request,
|
"request": request,
|
||||||
"task": task_data,
|
"task": task,
|
||||||
"html_info": html_info,
|
|
||||||
"pythonocc_available": True,
|
"pythonocc_available": True,
|
||||||
"version": "3.0.0"
|
"version": "3.0.0"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -96,10 +96,6 @@ import os
|
|||||||
static_dir = os.path.join(os.getcwd(), "static")
|
static_dir = os.path.join(os.getcwd(), "static")
|
||||||
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
||||||
|
|
||||||
# 挂载HTML输出目录
|
|
||||||
html_output_dir = os.path.join(os.getcwd(), "html_output")
|
|
||||||
app.mount("/html-output", StaticFiles(directory=html_output_dir), name="html_output")
|
|
||||||
|
|
||||||
# 注册路由
|
# 注册路由
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
|
|
||||||
|
|||||||
+2
-73
@@ -152,8 +152,8 @@
|
|||||||
<div class="result-container">
|
<div class="result-container">
|
||||||
<div class="header-nav">
|
<div class="header-nav">
|
||||||
<div>
|
<div>
|
||||||
<h1>📊 历史记录 - 分析结果详情</h1>
|
<h1>📊 分析结果详情</h1>
|
||||||
<p>查看历史记录中STP文件的详细分析结果</p>
|
<p>查看STP文件的详细分析结果</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-buttons">
|
<div class="nav-buttons">
|
||||||
<button class="upload-btn" onclick="location.href='/history'">
|
<button class="upload-btn" onclick="location.href='/history'">
|
||||||
@@ -178,14 +178,6 @@
|
|||||||
<div class="results-grid" id="resultsGrid">
|
<div class="results-grid" id="resultsGrid">
|
||||||
<!-- 结果内容将通过JavaScript动态加载 -->
|
<!-- 结果内容将通过JavaScript动态加载 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- HTML可视化展示区域 -->
|
|
||||||
<div id="htmlVisualization" class="result-section" style="grid-column: 1 / -1; margin-top: 20px; display: none;">
|
|
||||||
<div class="section-title">🖥️ 3D可视化报告</div>
|
|
||||||
<div id="htmlViewerContainer">
|
|
||||||
<!-- HTML内容将在这里加载 -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -209,9 +201,6 @@
|
|||||||
displayTaskInfo(task);
|
displayTaskInfo(task);
|
||||||
displayResults(task);
|
displayResults(task);
|
||||||
|
|
||||||
// 加载HTML可视化内容
|
|
||||||
await loadHtmlVisualization(taskId);
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
document.getElementById('taskInfo').innerHTML = `
|
document.getElementById('taskInfo').innerHTML = `
|
||||||
<div class="error-message">
|
<div class="error-message">
|
||||||
@@ -225,66 +214,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadHtmlVisualization(taskId) {
|
|
||||||
try {
|
|
||||||
// 从后端获取HTML文件信息
|
|
||||||
const response = await fetch(`/api/html-info/${taskId}`);
|
|
||||||
if (response.ok) {
|
|
||||||
const htmlInfo = await response.json();
|
|
||||||
if (htmlInfo && htmlInfo.file_path) {
|
|
||||||
displayHtmlVisualization(htmlInfo);
|
|
||||||
} else {
|
|
||||||
console.log('该任务没有HTML可视化报告');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('获取HTML信息失败');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载HTML可视化失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayHtmlVisualization(htmlInfo) {
|
|
||||||
const htmlContainer = document.getElementById('htmlVisualization');
|
|
||||||
const viewerContainer = document.getElementById('htmlViewerContainer');
|
|
||||||
|
|
||||||
// 显示HTML可视化区域
|
|
||||||
htmlContainer.style.display = 'block';
|
|
||||||
|
|
||||||
// 创建iframe来显示HTML内容
|
|
||||||
viewerContainer.innerHTML = `
|
|
||||||
<div style="margin-bottom: 15px;">
|
|
||||||
<div class="data-item">
|
|
||||||
<div class="data-label">报告文件</div>
|
|
||||||
<div class="data-value">${htmlInfo.filename || 'N/A'}</div>
|
|
||||||
</div>
|
|
||||||
<div class="data-item">
|
|
||||||
<div class="data-label">生成时间</div>
|
|
||||||
<div class="data-value">${htmlInfo.generated_time ? new Date(htmlInfo.generated_time).toLocaleString() : 'N/A'}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="border: 1px solid #e0e0e0; border-radius: 8px; overflow: hidden; height: 600px;">
|
|
||||||
<iframe
|
|
||||||
src="/html-output/${htmlInfo.filename}"
|
|
||||||
style="width: 100%; height: 100%; border: none;"
|
|
||||||
title="3D可视化报告"
|
|
||||||
></iframe>
|
|
||||||
</div>
|
|
||||||
<div class="action-buttons">
|
|
||||||
<button class="upload-btn" onclick="window.open('/html-output/${htmlInfo.filename}', '_blank')">
|
|
||||||
🔗 在新窗口中打开
|
|
||||||
</button>
|
|
||||||
<button class="upload-btn" onclick="downloadHtmlReport('${htmlInfo.filename}')">
|
|
||||||
📥 下载HTML报告
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadHtmlReport(filename) {
|
|
||||||
window.open(`/html-output/${filename}?download=true`, '_blank');
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayTaskInfo(task) {
|
function displayTaskInfo(task) {
|
||||||
const taskInfo = document.getElementById('taskInfo');
|
const taskInfo = document.getElementById('taskInfo');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user