deving
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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})>"
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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='/'">
|
||||
|
||||
Reference in New Issue
Block a user