init
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
# models/database.py
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, JSON, LargeBinary, Boolean, Float, ForeignKey
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.sql import func
|
||||
from sqlalchemy.orm import relationship
|
||||
from datetime import datetime
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class User(Base):
|
||||
"""用户表"""
|
||||
__tablename__ = "users"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
username = Column(String(50), unique=True, index=True, nullable=False)
|
||||
email = Column(String(255), unique=True, index=True, nullable=False)
|
||||
hashed_password = Column(String(255), nullable=False)
|
||||
full_name = Column(String(100))
|
||||
is_active = Column(Boolean, default=True)
|
||||
is_superuser = Column(Boolean, default=False)
|
||||
created_at = Column(DateTime, default=func.now())
|
||||
last_login = Column(DateTime, nullable=True)
|
||||
|
||||
# 关联关系
|
||||
stp_files = relationship("STPFile", back_populates="user")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User(id={self.id}, username='{self.username}', email='{self.email}')>"
|
||||
|
||||
class STPFile(Base):
|
||||
"""STP源文件元数据表"""
|
||||
__tablename__ = "stp_files"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
|
||||
|
||||
# 对象存储信息
|
||||
object_key = Column(String(500), nullable=False, index=True) # MinIO对象键
|
||||
storage_bucket = Column(String(100), nullable=False) # 存储桶名称
|
||||
object_url = Column(String(1000), nullable=True) # 预签名URL(可选)
|
||||
|
||||
# 文件信息
|
||||
original_filename = Column(String(255), nullable=False)
|
||||
file_size = Column(Integer, nullable=False)
|
||||
file_hash = Column(String(64), unique=True, index=True) # SHA256 hash
|
||||
mime_type = Column(String(50), default="application/octet-stream")
|
||||
|
||||
# 时间戳
|
||||
upload_time = Column(DateTime, default=func.now())
|
||||
processed_time = Column(DateTime, nullable=True)
|
||||
|
||||
# 状态
|
||||
status = Column(String(20), default="pending") # pending, processing, completed, failed
|
||||
error_message = Column(Text, nullable=True)
|
||||
|
||||
# 保留旧字段以兼容
|
||||
file_path = Column(String(500), nullable=True) # 本地路径(已弃用)
|
||||
file_content = Column(LargeBinary, nullable=True) # 本地存储(已弃用)
|
||||
filename = Column(String(255), nullable=True) # 已弃用
|
||||
|
||||
# 关联关系
|
||||
user = relationship("User", back_populates="stp_files")
|
||||
geometry_data = relationship("GeometryData", back_populates="stp_file", uselist=False)
|
||||
mold_cavity_data = relationship("MoldCavityData", back_populates="stp_file", uselist=False)
|
||||
html_file = relationship("HTMLFile", back_populates="stp_file", uselist=False)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<STPFile(id={self.id}, object_key='{self.object_key}', status='{self.status}')>"
|
||||
|
||||
class GeometryData(Base):
|
||||
"""几何数据JSON元数据表"""
|
||||
__tablename__ = "geometry_data"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
|
||||
|
||||
# 对象存储信息
|
||||
object_key = Column(String(500), nullable=False)
|
||||
storage_bucket = Column(String(100), nullable=False)
|
||||
object_url = Column(String(1000), nullable=True)
|
||||
|
||||
# 分析方法
|
||||
analysis_method = Column(String(50), default="pythonocc") # pythonocc, simulated
|
||||
|
||||
# 时间戳
|
||||
created_time = Column(DateTime, default=func.now())
|
||||
|
||||
# 几何属性摘要(便于快速查询)
|
||||
volume = Column(Float, nullable=True)
|
||||
surface_area = Column(Float, nullable=True)
|
||||
bounding_box_min = Column(JSON, nullable=True)
|
||||
bounding_box_max = Column(JSON, nullable=True)
|
||||
center_of_mass = Column(JSON, nullable=True)
|
||||
|
||||
# 拓扑信息
|
||||
topology_faces = Column(Integer, nullable=True)
|
||||
topology_edges = Column(Integer, nullable=True)
|
||||
topology_vertices = Column(Integer, nullable=True)
|
||||
|
||||
# 关联关系
|
||||
stp_file = relationship("STPFile", back_populates="geometry_data")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<GeometryData(id={self.id}, stp_file_id={self.stp_file_id})>"
|
||||
|
||||
class HTMLFile(Base):
|
||||
"""网页文件元数据表"""
|
||||
__tablename__ = "html_files"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
|
||||
|
||||
# 对象存储信息
|
||||
object_key = Column(String(500), nullable=False)
|
||||
storage_bucket = Column(String(100), nullable=False)
|
||||
object_url = Column(String(1000), nullable=True)
|
||||
|
||||
# 文件信息
|
||||
filename = Column(String(255), nullable=False)
|
||||
generated_time = Column(DateTime, default=func.now())
|
||||
|
||||
# 可视化相关元数据
|
||||
visualization_type = Column(String(50), default="3d_viewer")
|
||||
has_interactive_elements = Column(Boolean, default=True)
|
||||
|
||||
# 保留旧字段以兼容
|
||||
file_path = Column(String(500), nullable=True)
|
||||
html_content = Column(Text, nullable=True)
|
||||
|
||||
# 关联关系
|
||||
stp_file = relationship("STPFile", back_populates="html_file")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<HTMLFile(id={self.id}, stp_file_id={self.stp_file_id}, object_key='{self.object_key}')>"
|
||||
|
||||
class ProcessingTask(Base):
|
||||
"""处理任务记录表"""
|
||||
__tablename__ = "processing_tasks"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
task_id = Column(String(36), unique=True, index=True, nullable=False)
|
||||
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
|
||||
|
||||
# 任务类型和状态
|
||||
task_type = Column(String(50), default="stp_parsing") # stp_parsing, geometry_analysis, mold_generation
|
||||
status = Column(String(20), default="pending") # pending, processing, completed, failed
|
||||
|
||||
# 时间戳
|
||||
created_time = Column(DateTime, default=func.now())
|
||||
started_time = Column(DateTime, nullable=True)
|
||||
completed_time = Column(DateTime, nullable=True)
|
||||
|
||||
# 处理进度
|
||||
progress = Column(Integer, default=0) # 0-100
|
||||
current_step = Column(String(100), nullable=True)
|
||||
|
||||
# 错误信息
|
||||
error_message = Column(Text, nullable=True)
|
||||
error_stack = Column(Text, nullable=True)
|
||||
|
||||
# 处理参数
|
||||
parameters = Column(JSON, nullable=True) # 任务参数
|
||||
|
||||
def __repr__(self):
|
||||
return f"<ProcessingTask(id={self.id}, task_id='{self.task_id}', status='{self.status}')>"
|
||||
|
||||
class MoldCavityData(Base):
|
||||
"""模具型腔数据元数据表"""
|
||||
__tablename__ = "mold_cavity_data"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
|
||||
|
||||
# 对象存储信息
|
||||
detailed_object_key = Column(String(500), nullable=False) # 完整三维数据
|
||||
storage_bucket = Column(String(100), nullable=False)
|
||||
|
||||
# 模具类型和材料
|
||||
mold_material = Column(String(100), default="Aluminum Alloy 7075")
|
||||
mold_type = Column(String(50), default="single_cavity") # single_cavity, multi_cavity
|
||||
|
||||
# 工艺参数
|
||||
shrinkage_rate = Column(Float, nullable=False)
|
||||
draft_angle = Column(Float, nullable=False)
|
||||
parting_line_length = Column(Float, nullable=True)
|
||||
|
||||
# 生成时间
|
||||
generated_time = Column(DateTime, default=func.now())
|
||||
|
||||
# 关键信息摘要(快速查询字段)
|
||||
cavity_key_info = Column(JSON, nullable=True) # 完整关键信息
|
||||
|
||||
# 提取的字段(便于查询和排序)
|
||||
mold_size_length = Column(Float, nullable=True)
|
||||
mold_size_width = Column(Float, nullable=True)
|
||||
mold_size_height = Column(Float, nullable=True)
|
||||
estimated_clamping_force = Column(String(50), nullable=True)
|
||||
product_weight = Column(String(50), nullable=True)
|
||||
product_volume = Column(Float, nullable=True)
|
||||
wall_thickness_range = Column(String(50), nullable=True)
|
||||
complexity_score = Column(Float, nullable=True)
|
||||
|
||||
# 质量评估
|
||||
weld_line_risk = Column(String(50), nullable=True) # 熔接痕风险
|
||||
sink_mark_risk = Column(String(50), nullable=True) # 缩痕风险
|
||||
warpage_risk = Column(String(50), nullable=True) # 翘曲风险
|
||||
|
||||
# 关联关系
|
||||
stp_file = relationship("STPFile", back_populates="mold_cavity_data")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<MoldCavityData(stp_file_id={self.stp_file_id}, mold_material='{self.mold_material}')>"
|
||||
|
||||
|
||||
class FeatureDetection(Base):
|
||||
"""特征检测结果表"""
|
||||
__tablename__ = "feature_detections"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
|
||||
|
||||
# 特征信息
|
||||
feature_type = Column(String(50), nullable=False, index=True) # thin_wall, thick_wall, rib, boss, draft_angle
|
||||
confidence = Column(Float, nullable=False) # 0.0 - 1.0
|
||||
|
||||
# 位置和尺寸
|
||||
location = Column(JSON, nullable=True) # [x, y, z]
|
||||
dimensions = Column(JSON, nullable=True) # [length, width, height]
|
||||
|
||||
# 特征参数
|
||||
parameters = Column(JSON, nullable=True) # 自定义参数
|
||||
|
||||
# 检测时间
|
||||
detected_at = Column(DateTime, default=func.now())
|
||||
|
||||
# 关联的几何数据
|
||||
geometry_data_id = Column(Integer, ForeignKey("geometry_data.id"), nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<FeatureDetection(id={self.id}, feature_type='{self.feature_type}', confidence={self.confidence})>"
|
||||
|
||||
|
||||
class DesignRecommendation(Base):
|
||||
"""设计建议表"""
|
||||
__tablename__ = "design_recommendations"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
stp_file_id = Column(Integer, ForeignKey("stp_files.id"), nullable=False, index=True)
|
||||
|
||||
# 建议信息
|
||||
rec_type = Column(String(50), nullable=False) # wall_thickness, draft_angle, etc.
|
||||
priority = Column(String(20), nullable=False) # high, medium, low
|
||||
description = Column(String(500), nullable=False)
|
||||
reason = Column(Text, nullable=True)
|
||||
|
||||
# 建议参数
|
||||
parameters = Column(JSON, nullable=True)
|
||||
|
||||
# 状态
|
||||
status = Column(String(20), default="pending") # pending, accepted, rejected
|
||||
user_notes = Column(Text, nullable=True)
|
||||
|
||||
# 时间戳
|
||||
created_at = Column(DateTime, default=func.now())
|
||||
updated_at = Column(DateTime, nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<DesignRecommendation(id={self.id}, rec_type='{self.rec_type}', priority='{self.priority}')>"
|
||||
|
||||
|
||||
class UserActivity(Base):
|
||||
"""用户活动日志表"""
|
||||
__tablename__ = "user_activities"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
|
||||
|
||||
# 活动信息
|
||||
activity_type = Column(String(50), nullable=False, index=True) # upload, view, download, delete, export
|
||||
resource_type = Column(String(50), nullable=True) # stp_file, geometry_data, mold_cavity
|
||||
resource_id = Column(Integer, nullable=True)
|
||||
|
||||
# 活动详情
|
||||
description = Column(Text, nullable=True)
|
||||
meta_data = Column(JSON, nullable=True)
|
||||
|
||||
# 时间戳
|
||||
created_at = Column(DateTime, default=func.now(), index=True)
|
||||
|
||||
# IP和设备信息
|
||||
ip_address = Column(String(45), nullable=True)
|
||||
user_agent = Column(String(500), nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<UserActivity(id={self.id}, user_id={self.user_id}, activity_type='{self.activity_type}')>"
|
||||
|
||||
|
||||
class SystemLog(Base):
|
||||
"""系统日志表(重要操作和错误)"""
|
||||
__tablename__ = "system_logs"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
|
||||
# 日志级别
|
||||
level = Column(String(20), nullable=False, index=True) # INFO, WARNING, ERROR, CRITICAL
|
||||
|
||||
# 日志信息
|
||||
message = Column(Text, nullable=False)
|
||||
module = Column(String(100), nullable=True) # 模块名
|
||||
function_name = Column(String(100), nullable=True)
|
||||
|
||||
# 时间戳
|
||||
created_at = Column(DateTime, default=func.now(), index=True)
|
||||
|
||||
# 用户信息(如果有关联用户)
|
||||
user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
||||
|
||||
# 额外信息
|
||||
request_id = Column(String(100), nullable=True) # 关联的请求ID
|
||||
execution_time_ms = Column(Integer, nullable=True) # 执行时间
|
||||
|
||||
# 关联数据
|
||||
resource_type = Column(String(50), nullable=True)
|
||||
resource_id = Column(Integer, nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<SystemLog(id={self.id}, level='{self.level}', module='{self.module}')>"
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
# models/schemas.py
|
||||
from typing import Dict, List, Optional, Any
|
||||
from enum import Enum
|
||||
|
||||
class ProcessingStatus(str, Enum):
|
||||
PENDING = "pending"
|
||||
PROCESSING = "processing"
|
||||
COMPLETED = "completed"
|
||||
FAILED = "failed"
|
||||
|
||||
# 简化的数据模型,避免复杂的Pydantic验证
|
||||
def create_geometry_data(
|
||||
bounding_box: Dict[str, List[float]],
|
||||
volume: float,
|
||||
surface_area: float,
|
||||
topology: Dict[str, int],
|
||||
analysis_method: str,
|
||||
center_of_mass: Optional[List[float]] = None,
|
||||
inertia_properties: Optional[Dict[str, Any]] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""创建几何数据"""
|
||||
return {
|
||||
"bounding_box": bounding_box,
|
||||
"volume": volume,
|
||||
"surface_area": surface_area,
|
||||
"topology": topology,
|
||||
"center_of_mass": center_of_mass or [0.0, 0.0, 0.0],
|
||||
"inertia_properties": inertia_properties or {},
|
||||
"analysis_method": analysis_method
|
||||
}
|
||||
|
||||
def create_mold_feature(
|
||||
feature_type: str,
|
||||
confidence: float,
|
||||
location: List[float],
|
||||
dimensions: List[float],
|
||||
parameters: Dict[str, Any],
|
||||
recommendations: List[str]
|
||||
) -> Dict[str, Any]:
|
||||
"""创建模具特征"""
|
||||
return {
|
||||
"feature_type": feature_type,
|
||||
"confidence": confidence,
|
||||
"location": location,
|
||||
"dimensions": dimensions,
|
||||
"parameters": parameters,
|
||||
"recommendations": recommendations
|
||||
}
|
||||
|
||||
def create_design_recommendation(
|
||||
rec_type: str,
|
||||
priority: str,
|
||||
description: str,
|
||||
parameters: Dict[str, Any],
|
||||
reason: str
|
||||
) -> Dict[str, Any]:
|
||||
"""创建设计建议"""
|
||||
return {
|
||||
"type": rec_type,
|
||||
"priority": priority,
|
||||
"description": description,
|
||||
"parameters": parameters,
|
||||
"reason": reason
|
||||
}
|
||||
|
||||
def create_analysis_result(
|
||||
geometry_data: Dict[str, Any],
|
||||
detected_features: List[Dict[str, Any]],
|
||||
design_recommendations: List[Dict[str, Any]],
|
||||
quality_metrics: Dict[str, float],
|
||||
analysis_summary: str
|
||||
) -> Dict[str, Any]:
|
||||
"""创建分析结果"""
|
||||
return {
|
||||
"geometry_data": geometry_data,
|
||||
"detected_features": detected_features,
|
||||
"design_recommendations": design_recommendations,
|
||||
"quality_metrics": quality_metrics,
|
||||
"analysis_summary": analysis_summary
|
||||
}
|
||||
|
||||
def create_task_info(
|
||||
task_id: str,
|
||||
status: ProcessingStatus,
|
||||
filename: str,
|
||||
file_path: str,
|
||||
file_size: int,
|
||||
upload_time: str,
|
||||
completed_at: Optional[str] = None,
|
||||
geometry_data: Optional[Dict[str, Any]] = None,
|
||||
analysis_result: Optional[Dict[str, Any]] = None,
|
||||
error: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""创建任务信息"""
|
||||
return {
|
||||
"task_id": task_id,
|
||||
"status": status,
|
||||
"filename": filename,
|
||||
"file_path": file_path,
|
||||
"file_size": file_size,
|
||||
"upload_time": upload_time,
|
||||
"completed_at": completed_at,
|
||||
"geometry_data": geometry_data,
|
||||
"analysis_result": analysis_result,
|
||||
"error": error
|
||||
}
|
||||
# 添加到 schemas.py
|
||||
|
||||
def create_mold_cavity_data(
|
||||
cavity_geometry: Dict[str, Any],
|
||||
core_geometry: Dict[str, Any],
|
||||
parting_surface: Dict[str, Any],
|
||||
manufacturing_info: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""创建模具型腔详细数据"""
|
||||
return {
|
||||
"cavity_geometry": cavity_geometry,
|
||||
"core_geometry": core_geometry,
|
||||
"parting_surface": parting_surface,
|
||||
"manufacturing_info": manufacturing_info
|
||||
}
|
||||
|
||||
def create_mold_key_info(
|
||||
mold_parameters: Dict[str, Any],
|
||||
geometric_characteristics: Dict[str, Any],
|
||||
manufacturing_requirements: Dict[str, Any],
|
||||
quality_considerations: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""创建模具型腔关键信息"""
|
||||
return {
|
||||
"mold_parameters": mold_parameters,
|
||||
"geometric_characteristics": geometric_characteristics,
|
||||
"manufacturing_requirements": manufacturing_requirements,
|
||||
"quality_considerations": quality_considerations
|
||||
}
|
||||
Reference in New Issue
Block a user