This commit is contained in:
cjw
2026-02-16 15:33:52 +08:00
parent 745c32ea26
commit 5a7a4e6a03
4 changed files with 203 additions and 2 deletions
+99
View File
@@ -15,6 +15,7 @@ from database.database import get_db_session
from utils.logger import get_logger
from sqlalchemy.ext.asyncio import AsyncSession
from core.mold_generator import MoldCavityGenerator
from datetime import datetime
logger = get_logger(__name__)
@@ -244,6 +245,71 @@ async def history_page(request: Request):
})
@router.get("/api/snapshots/{stp_file_id}")
@router.post("/api/snapshots/{stp_file_id}")
async def get_analysis_snapshots(stp_file_id: int, db_session: AsyncSession = Depends(get_db_session)):
"""获取指定STP文件的分析结果快照列表"""
storage_service = StorageIntegrationService()
try:
snapshots = await storage_service.get_analysis_result_snapshots(db_session, stp_file_id)
# 构建返回数据
snapshot_list = []
for snapshot in snapshots:
snapshot_list.append({
"id": snapshot.id,
"snapshot_name": snapshot.snapshot_name,
"created_time": snapshot.created_time.isoformat() if snapshot.created_time else "",
"analysis_time": snapshot.analysis_time.isoformat() if snapshot.analysis_time else "",
"task_data": snapshot.task_data
})
return {
"stp_file_id": stp_file_id,
"total_snapshots": len(snapshot_list),
"snapshots": snapshot_list
}
except Exception as e:
logger.error(f"获取分析结果快照失败: {e}")
raise HTTPException(500, f"获取快照失败: {str(e)}")
@router.get("/api/snapshot/{snapshot_id}")
@router.post("/api/snapshot/{snapshot_id}")
async def get_analysis_snapshot(snapshot_id: int, db_session: AsyncSession = Depends(get_db_session)):
"""获取指定分析结果快照的完整数据"""
from sqlalchemy import select
from models.database import AnalysisResultSnapshot
try:
result = await db_session.execute(
select(AnalysisResultSnapshot).where(AnalysisResultSnapshot.id == snapshot_id)
)
snapshot = result.scalar_one_or_none()
if not snapshot:
raise HTTPException(404, "快照不存在")
return {
"id": snapshot.id,
"snapshot_name": snapshot.snapshot_name,
"stp_file_id": snapshot.stp_file_id,
"created_time": snapshot.created_time.isoformat() if snapshot.created_time else "",
"analysis_time": snapshot.analysis_time.isoformat() if snapshot.analysis_time else "",
"task_data": snapshot.task_data,
"geometry_data": snapshot.geometry_data,
"mold_cavity_data": snapshot.mold_cavity_data,
"key_info": snapshot.key_info,
"html_info": snapshot.html_info
}
except Exception as e:
logger.error(f"获取分析结果快照详情失败: {e}")
raise HTTPException(500, f"获取快照详情失败: {str(e)}")
@router.get("/result/{task_id}")
@router.post("/result/{task_id}")
async def result_page(request: Request, task_id: str, db_session: AsyncSession = Depends(get_db_session)):
@@ -579,6 +645,39 @@ async def process_file_core(
db_session, task_id, "completed", 100, "模具型腔生成完成"
)
# 构建完整的分析结果数据
task_info = tasks[task_id]
# 构建任务基本信息
task_data = {
"task_id": task_info["task_id"],
"filename": task_info["filename"],
"file_size": task_info["file_size"],
"status": task_info["status"],
"upload_time": task_info["upload_time"],
"completed_at": str(datetime.now())
}
# 保存分析结果快照到数据库
try:
await storage_service.save_analysis_result_snapshot(
db_session,
stp_file_id,
task_data=task_data,
geometry_data=geometry_data,
mold_cavity_data=detailed_cavity_json,
key_info=detailed_cavity_json,
html_info={
"filename": Path(html_file_path).name,
"file_path": html_file_path,
"generated_time": str(datetime.now())
}
)
logger.info(f"分析结果快照保存成功: {task_id}")
except Exception as e:
logger.error(f"保存分析结果快照失败: {e}")
# 不影响主流程,继续执行
# 更新内存任务状态
tasks[task_id]["geometry_data"] = geometry_data
tasks[task_id]["analysis_result"] = analysis_result
+29
View File
@@ -326,3 +326,32 @@ class SystemLog(Base):
def __repr__(self):
return f"<SystemLog(id={self.id}, level='{self.level}', module='{self.module}')>"
class AnalysisResultSnapshot(Base):
"""分析结果快照表 - 存储每次分析结果的完整副本"""
__tablename__ = "analysis_result_snapshots"
id = Column(Integer, primary_key=True, index=True)
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
# 快照标识信息
snapshot_name = Column(String(255), nullable=False, index=True) # 文件名+日期时间格式
snapshot_type = Column(String(50), default="complete") # complete, geometry_only, key_info_only
# 完整分析结果数据
task_data = Column(JSON, nullable=False) # 任务基本信息
geometry_data = Column(JSON, nullable=True) # 几何数据
mold_cavity_data = Column(JSON, nullable=True) # 模具型腔数据
key_info = Column(JSON, nullable=True) # 关键信息
html_info = Column(JSON, nullable=True) # HTML文件信息
# 时间戳
created_time = Column(DateTime, default=func.now())
analysis_time = Column(DateTime, nullable=False) # 原始分析时间
# 关联关系
stp_file = relationship("STPFile")
def __repr__(self):
return f"<AnalysisResultSnapshot(id={self.id}, snapshot_name='{self.snapshot_name}', stp_file_id={self.stp_file_id})>"
+74 -1
View File
@@ -11,7 +11,7 @@ from models.database import (
STPFile, GeometryData, MoldCavityData,
HTMLFile, ProcessingTask, User,
FeatureDetection, DesignRecommendation,
UserActivity, SystemLog
UserActivity, SystemLog, AnalysisResultSnapshot
)
from storage.rustfs_storage import rustfs_manager
from utils.logger import get_logger
@@ -493,6 +493,79 @@ class StorageIntegrationService:
logger.info(f"STP文件及其关联数据已删除: {stp_file_id}")
async def save_analysis_result_snapshot(
self,
session: AsyncSession,
stp_file_id: int,
task_data: Dict[str, Any],
geometry_data: Optional[Dict[str, Any]] = None,
mold_cavity_data: Optional[Dict[str, Any]] = None,
key_info: Optional[Dict[str, Any]] = None,
html_info: Optional[Dict[str, Any]] = None
) -> AnalysisResultSnapshot:
"""保存分析结果快照 - 文件名+日期时间命名方式"""
# 获取STP文件信息
stp_file = await session.get(STPFile, stp_file_id)
if not stp_file:
raise ValueError(f"STP文件不存在: {stp_file_id}")
# 生成快照名称:文件名_YYYYMMDD_HHMMSS
filename = stp_file.original_filename
# 移除文件扩展名
base_name = Path(filename).stem
# 生成时间戳
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
snapshot_name = f"{base_name}_{timestamp}"
# 获取分析时间(从任务数据中获取或使用当前时间)
analysis_time_str = task_data.get('created_at') or task_data.get('upload_time')
if analysis_time_str:
analysis_time = datetime.fromisoformat(analysis_time_str.replace('Z', '+00:00'))
else:
analysis_time = datetime.now()
# 创建快照记录
snapshot = AnalysisResultSnapshot(
stp_file_id=stp_file_id,
snapshot_name=snapshot_name,
task_data=task_data,
geometry_data=geometry_data,
mold_cavity_data=mold_cavity_data,
key_info=key_info,
html_info=html_info,
analysis_time=analysis_time
)
session.add(snapshot)
await session.commit()
await session.refresh(snapshot)
logger.info(f"分析结果快照保存成功: {snapshot_name} (ID: {snapshot.id})")
return snapshot
async def get_analysis_result_snapshots(
self,
session: AsyncSession,
stp_file_id: int,
limit: int = 10
) -> List[AnalysisResultSnapshot]:
"""获取指定STP文件的分析结果快照列表"""
from sqlalchemy import select
from sqlalchemy.orm import selectinload
result = await session.execute(
select(AnalysisResultSnapshot)
.where(AnalysisResultSnapshot.stp_file_id == stp_file_id)
.order_by(AnalysisResultSnapshot.created_time.desc())
.limit(limit)
)
snapshots = result.scalars().all()
logger.info(f"获取到 {len(snapshots)} 个分析结果快照")
return snapshots
# 全局存储集成服务实例
storage_integration = StorageIntegrationService()
+1 -1
View File
@@ -159,7 +159,7 @@
<button class="upload-btn" onclick="location.href='/history'">
📋 返回历史记录
</button>
<button class="upload-btn" onclick="location.href='/upload'">
<button class="upload-btn" onclick="location.href='/'">
📁 上传新文件
</button>
<button class="upload-btn" onclick="location.href='/'">