后端模块拆分

This commit is contained in:
2026-05-29 18:10:08 +08:00
parent 5bb9bc84ea
commit 823a387118
93 changed files with 198 additions and 833 deletions
-1
View File
@@ -1 +0,0 @@
# API 模块
-601
View File
@@ -1,601 +0,0 @@
# api/routes.py
from fastapi import APIRouter, UploadFile, File, HTTPException, Request, Depends
from typing import Optional, Dict, Any, List
import uuid
from datetime import datetime
import os
from pathlib import Path
from models.schemas import ProcessingStatus, create_task_info
from utils.file_handler import FileHandler
from services.storage_integration_rustfs import StorageIntegrationService
from services.redis_task_manager import redis_task_manager
from services.task_query_service import TaskQueryService
from database.database import get_db_session
try:
from celery_tasks import process_stp_task
_use_celery = True
except ImportError:
process_stp_task = None
_use_celery = False
from utils.logger import get_logger
from sqlalchemy.ext.asyncio import AsyncSession
from core.cavity_layout_optimizer import CavityLayoutOptimizer
from core.mold_system_designer import MoldSystemDesigner
from core.side_action_designer import SideActionDesigner
from core.mold_cam import MoldCAMDesigner
from core.mold_machining import CollisionDetector, ToolpathOptimizer, EDMElectrodeDesigner, MachiningSimulator
from core.cad_exporter import CADExporter
from services.auth_service import get_current_active_user
from models.database import User
logger = get_logger(__name__)
router = APIRouter()
file_handler = FileHandler()
cavity_layout_optimizer = CavityLayoutOptimizer()
mold_system_designer = MoldSystemDesigner()
side_action_designer = SideActionDesigner()
mold_cam_designer = MoldCAMDesigner()
collision_detector = CollisionDetector()
toolpath_optimizer = ToolpathOptimizer()
edm_designer = EDMElectrodeDesigner()
machining_simulator = MachiningSimulator()
cad_exporter = CADExporter()
@router.get("/health")
@router.post("/health")
async def health():
task_count = await redis_task_manager.get_task_count()
return {
"status": "healthy",
"pythonocc": True,
"total_tasks": task_count,
"redis_connected": redis_task_manager.is_connected,
}
@router.post("/upload")
async def upload_stp(
file: UploadFile = File(...),
material: Optional[str] = "ABS",
db_session: AsyncSession = Depends(get_db_session),
current_user: User = Depends(get_current_active_user)
):
"""上传STP文件并存储到数据库"""
logger.info(
f"[UPLOAD] 用户={current_user.username}(id={current_user.id}) "
f"文件={file.filename} 材料={material}"
)
if not file.filename.lower().endswith(('.stp', '.step')):
logger.warning(f"[UPLOAD] 拒绝: 不支持的文件类型 - {file.filename}")
raise HTTPException(400, "只支持STP/STEP文件")
task_id = str(uuid.uuid4())
# 保存文件
file_path, file_size = await file_handler.save_uploaded_file(file)
logger.info(f"[UPLOAD] 文件已保存: {file_path} ({file_size} bytes), task_id={task_id}")
# 创建存储集成服务实例
storage_service = StorageIntegrationService()
# 保存STP文件到RustFS + PostgreSQL
stp_file = await storage_service.save_stp_file(
session=db_session,
file_path=file_path,
original_filename=file.filename,
user_id=current_user.id
)
logger.info(f"[UPLOAD] STP文件已存入RustFS+PG: stp_file.id={stp_file.id}")
# 创建处理任务记录
await storage_service.create_processing_task(db_session, task_id, stp_file.id)
# 创建任务记录(Redis 为主,内存作为兼容回退)
task_info = create_task_info(
task_id=task_id,
status=ProcessingStatus.PROCESSING,
filename=file.filename,
file_path=str(file_path),
file_size=file_size,
upload_time=str(datetime.now())
)
await redis_task_manager.set_task(task_id, task_info)
# 后台处理走统一编排服务,避免请求会话在后台失效
process_params = {"material": material}
if _use_celery:
process_stp_task.delay(task_id, str(file_path), stp_file.id, process_params)
logger.info(f"[UPLOAD] Celery 任务已调度: task_id={task_id}")
else:
import asyncio
from services.processing_service import processing_service
asyncio.create_task(processing_service.process_file_with_storage(
task_id, str(file_path), stp_file.id, process_params
))
logger.info(f"[UPLOAD] 直接后台处理: task_id={task_id} (celery 未安装)")
return {
"task_id": task_id,
"status": "processing",
"message": "文件上传成功,开始处理并存储到数据库",
"file_info": {
"filename": file.filename,
"size": file_size,
"pythonocc_available": True,
"database_file_id": stp_file.id
}
}
@router.get("/status/{task_id}")
@router.post("/status/{task_id}")
async def get_status(task_id: str, db_session: AsyncSession = Depends(get_db_session)):
"""
获取任务状态
优先返回内存中的任务信息;
如果内存中不存在,则从 PostgreSQL + RustFS 组装一个持久化的任务视图,
结构与内存任务保持尽量一致,便于前端集中展示总结性信息。
"""
try:
task_view = await TaskQueryService.get_task_view(db_session, task_id)
if task_view is None:
raise HTTPException(404, "任务不存在")
return task_view
except HTTPException:
raise
except Exception as e:
logger.error(f"获取任务状态失败: {e}")
raise HTTPException(500, f"获取任务状态失败: {str(e)}")
@router.get("/debug/tasks")
@router.post("/debug/tasks")
async def debug_tasks():
"""调试接口:查看所有任务"""
all_tasks = await redis_task_manager.get_all_tasks()
return {
"total_tasks": len(all_tasks),
"tasks": all_tasks,
"redis_connected": redis_task_manager.is_connected,
}
@router.get("/history")
@router.post("/history")
async def get_file_history(db_session: AsyncSession = Depends(get_db_session)):
"""获取按文件名分组的文件历史记录(支持多上传)"""
storage_service = StorageIntegrationService()
file_groups = await storage_service.get_all_file_groups(db_session)
return {
"total_files": len(file_groups),
"files": file_groups
}
@router.get("/history/{filename}")
@router.post("/history/{filename}")
async def get_file_records(filename: str, db_session: AsyncSession = Depends(get_db_session)):
"""获取指定文件名的所有上传记录(支持多上传历史)"""
import urllib.parse
decoded_filename = urllib.parse.unquote(filename)
storage_service = StorageIntegrationService()
file_records = await storage_service.get_file_history_by_filename(
db_session,
decoded_filename
)
return file_records
@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)):
"""结果详情页面"""
from sqlalchemy import select
from models.database import ProcessingTask, STPFile, GeometryData, MoldCavityData, HTMLFile
# 从数据库查询任务详情
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, 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,
"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 ""
}
from fastapi.templating import Jinja2Templates
import os
# 简化路径配置,直接使用当前工作目录下的templates文件夹
templates_dir = os.path.join(os.getcwd(), "templates")
templates = Jinja2Templates(directory=templates_dir)
return templates.TemplateResponse("result.html", {
"request": request,
"task": task_data,
"pythonocc_available": True,
"version": "3.0.0"
})
# ==================== P3 新增 API ====================
@router.post("/optimize-layout")
async def optimize_cavity_layout(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""多型腔布局优化"""
body = await request.json()
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
cavity_count = body.get("cavity_count", 1)
mold_base_size = body.get("mold_base_size")
layout_type = body.get("layout_type", "auto")
if cavity_count < 1 or cavity_count > 64:
raise HTTPException(400, "型腔数量必须在 1-64 之间")
result = cavity_layout_optimizer.optimize_layout(
product_bbox=product_bbox,
cavity_count=cavity_count,
mold_base_size=mold_base_size,
layout_type=layout_type,
)
return {"status": "success", "data": result}
@router.post("/design-cooling")
async def design_cooling_system(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""冷却系统设计"""
body = await request.json()
mold_size = body.get("mold_size", {"length": 300, "width": 300, "height": 200})
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
material = body.get("material", "ABS")
cavity_count = body.get("cavity_count", 1)
cycle_time_target = body.get("cycle_time_target")
from core.mold_system_designer import CoolingSystemDesigner
designer = CoolingSystemDesigner()
result = designer.design_cooling_system(
mold_size=mold_size,
product_bbox=product_bbox,
material=material,
cavity_count=cavity_count,
cycle_time_target=cycle_time_target,
)
return {"status": "success", "data": result}
@router.post("/design-gating")
async def design_gating_system(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""浇注系统设计"""
body = await request.json()
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
material = body.get("material", "ABS")
cavity_count = body.get("cavity_count", 1)
gate_type = body.get("gate_type", "auto")
layout_positions = body.get("layout_positions")
from core.mold_system_designer import GatingSystemDesigner
designer = GatingSystemDesigner()
result = designer.design_gating_system(
product_bbox=product_bbox,
material=material,
cavity_count=cavity_count,
gate_type=gate_type,
layout_positions=layout_positions,
)
return {"status": "success", "data": result}
@router.post("/design-mold-system")
async def design_complete_mold_system(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""综合模具系统设计(冷却+浇注)"""
body = await request.json()
mold_size = body.get("mold_size", {"length": 300, "width": 300, "height": 200})
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
material = body.get("material", "ABS")
cavity_count = body.get("cavity_count", 1)
gate_type = body.get("gate_type", "auto")
cycle_time_target = body.get("cycle_time_target")
layout_positions = body.get("layout_positions")
result = mold_system_designer.design_complete_system(
mold_size=mold_size,
product_bbox=product_bbox,
material=material,
cavity_count=cavity_count,
gate_type=gate_type,
cycle_time_target=cycle_time_target,
layout_positions=layout_positions,
)
return {"status": "success", "data": result}
@router.post("/ai-parting-detect")
async def ai_parting_surface_detect(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""AI 分型面检测"""
body = await request.json()
task_id = body.get("task_id")
if not task_id:
raise HTTPException(404, "缺少 task_id")
task_data = await redis_task_manager.get_task(task_id)
if not task_data:
raise HTTPException(404, "任务不存在")
geometry_data = task_data.get("geometry_data")
if not geometry_data:
raise HTTPException(400, "该任务尚未完成几何分析")
from core.ai_parting_detector import AIPartingSurfaceDetectorV2
detector = AIPartingSurfaceDetectorV2(use_gnn=True)
result = detector._detect_with_geometry(None, geometry_data)
return {"status": "success", "data": result}
@router.post("/detect-undercuts")
async def detect_undercuts(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""倒扣区域检测与滑块/斜顶机构设计"""
body = await request.json()
task_id = body.get("task_id")
parting_direction = body.get("parting_direction", [0, 0, 1])
mold_size = body.get("mold_size", {"length": 300, "width": 300, "height": 200})
if not task_id:
raise HTTPException(404, "缺少 task_id")
task_data = await redis_task_manager.get_task(task_id)
if not task_data:
raise HTTPException(404, "任务不存在")
geometry_data = task_data.get("geometry_data")
if not geometry_data:
raise HTTPException(400, "该任务尚未完成几何分析")
result = side_action_designer.analyze_and_design(
shape=None, parting_direction=parting_direction, mold_size=mold_size
)
return {"status": "success", "data": result}
@router.post("/design-cam")
async def design_mold_cam(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""模具CAM刀路设计"""
body = await request.json()
cavity_bbox = body.get("cavity_bbox", {"dimensions": [100, 100, 50], "min": [-50, -50, -25], "max": [50, 50, 25]})
stock_bbox = body.get("stock_bbox", {"dimensions": [150, 150, 100], "min": [-75, -75, -50], "max": [75, 75, 50]})
mold_steel = body.get("mold_steel", "P20")
surface_quality = body.get("surface_quality", "standard")
controller = body.get("controller", "fanuc")
result = mold_cam_designer.design_mold_cam(
cavity_bbox=cavity_bbox,
stock_bbox=stock_bbox,
mold_steel=mold_steel,
surface_quality=surface_quality,
controller=controller,
)
return {"status": "success", "data": result}
@router.post("/check-collision")
async def check_toolpath_collision(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""刀路碰撞检测"""
body = await request.json()
toolpath_points = body.get("toolpath_points", [[0, 0, 50], [10, 10, -5], [20, 20, -10]])
tool = body.get("tool", {"diameter": 10, "flute_length": 30, "shank_diameter": 10})
stock_bbox = body.get("stock_bbox", {"min": [-50, -50, -25], "max": [50, 50, 25]})
clamp_positions = body.get("clamp_positions")
result = collision_detector.check_toolpath_safety(
toolpath_points, tool, stock_bbox, clamp_positions
)
return {"status": "success", "data": result}
@router.post("/optimize-toolpath")
async def optimize_toolpath(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""刀路优化"""
body = await request.json()
toolpath_points = body.get("toolpath_points", [[0, 0, 50], [10, 10, -5], [20, 20, -10]])
cutting_params = body.get("cutting_params", {"feed_rate_mm_min": 500})
stock_bbox = body.get("stock_bbox")
result = toolpath_optimizer.optimize_toolpath(
toolpath_points, cutting_params, stock_bbox
)
return {"status": "success", "data": result}
@router.post("/design-electrodes")
async def design_edm_electrodes(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""EDM电极设计"""
body = await request.json()
undercut_regions = body.get("undercut_regions", [{"center": [0, 0, 0], "area": 100, "type": "undercut"}])
cavity_bbox = body.get("cavity_bbox", {"dimensions": [100, 100, 50]})
material = body.get("material", "copper")
spark_gap = body.get("spark_gap", 0.05)
overburn = body.get("overburn", 0.1)
result = edm_designer.design_electrodes(
undercut_regions, cavity_bbox, material, spark_gap, overburn
)
return {"status": "success", "data": result}
@router.post("/simulate-machining")
async def simulate_machining(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""加工仿真"""
body = await request.json()
operations = body.get("operations", [{"strategy": "z_level_roughing", "levels": [{"z": -5}]}])
stock_bbox = body.get("stock_bbox", {"dimensions": [100, 100, 50], "min": [-50, -50, -25], "max": [50, 50, 25]})
resolution = body.get("resolution", 2.0)
result = machining_simulator.simulate_machining(
operations, stock_bbox, resolution
)
return {"status": "success", "data": result}
# ==================== CAD 导出 API ====================
@router.post("/export-mold")
async def export_mold_results(
request: Request,
current_user: User = Depends(get_current_active_user),
):
"""导出模具设计结果(STEP/IGES/STL/BRep)"""
body = await request.json()
task_id = body.get("task_id")
formats = body.get("formats", ["step", "stl"])
components = body.get("components", ["cavity", "core"])
scheme_id = body.get("scheme_id")
if not task_id:
raise HTTPException(404, "缺少 task_id")
cavity_shapes = processing_service.get_export_shapes(task_id, scheme_id=scheme_id)
if not cavity_shapes:
task_data = await redis_task_manager.get_task(task_id)
if not task_data:
raise HTTPException(404, "任务不存在")
filename = task_data.get("filename", f"mold_{task_id}")
raise HTTPException(
400,
f"该任务的 OCC 形状数据已过期(仅保留 STEP 导出文件),"
f"请通过历史页面的下载链接获取已导出的 STEP 文件",
)
task_data = await redis_task_manager.get_task(task_id)
base_filename = (
Path(task_data.get("filename", f"mold_{task_id}")).stem
if task_data
else f"mold_{task_id}"
)
result = cad_exporter.export_mold_results(
cavity_data=cavity_shapes,
base_filename=base_filename,
formats=formats,
components=components,
)
return {"status": "success", "data": result}
@router.get("/export-download/{filepath:path}")
async def download_export_file(
filepath: str,
current_user: User = Depends(get_current_active_user),
):
"""下载导出的CAD文件"""
from fastapi.responses import FileResponse
full_path = os.path.join(cad_exporter.output_dir, filepath)
if not os.path.exists(full_path):
raise HTTPException(404, "文件不存在")
if not os.path.abspath(full_path).startswith(os.path.abspath(cad_exporter.output_dir)):
raise HTTPException(403, "禁止访问")
media_types = {
".step": "application/step",
".stp": "application/step",
".iges": "application/iges",
".igs": "application/iges",
".stl": "model/stl",
".brep": "application/octet-stream",
}
ext = Path(full_path).suffix.lower()
media_type = media_types.get(ext, "application/octet-stream")
return FileResponse(
full_path,
media_type=media_type,
filename=os.path.basename(full_path),
)
@router.get("/export-recommendations")
async def get_export_recommendations(
target: str = "ug",
current_user: User = Depends(get_current_active_user),
):
"""获取导出格式建议(UG/FreeCAD/SolidWorks)"""
result = cad_exporter.get_export_recommendations(target)
return {"status": "success", "data": result}
+2 -2
View File
@@ -1,6 +1,6 @@
from celery_app import app from celery_app import app
from services.processing_service import processing_service from moldinsight.services.processing_service import processing_service
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -15,9 +15,9 @@ from sqlalchemy import select
from typing import Optional, List from typing import Optional, List
from datetime import datetime from datetime import datetime
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user, get_current_admin_user from shared.services.auth_service import get_current_active_user, get_current_admin_user
from models.database import User, Customer from shared.models.database import User, Customer
from .schemas import CustomerCreate, CustomerResponse from .schemas import CustomerCreate, CustomerResponse
router = APIRouter(prefix="/customers", tags=["客户管理"]) router = APIRouter(prefix="/customers", tags=["客户管理"])
@@ -13,9 +13,9 @@ from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func from sqlalchemy import select, func
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import ( from shared.models.database import (
User, Product, Supplier, Customer, Warehouse, User, Product, Supplier, Customer, Warehouse,
Inventory, PurchaseOrder, SalesOrder Inventory, PurchaseOrder, SalesOrder
) )
@@ -6,9 +6,9 @@ from typing import Optional, List, Dict, Tuple
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import ( from shared.models.database import (
User, User,
Customer, Customer,
Supplier, Supplier,
@@ -34,7 +34,7 @@ from .schemas import (
PaginatedResponse, PaginatedResponse,
) )
from .utils import generate_order_no from .utils import generate_order_no
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -12,9 +12,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update, func from sqlalchemy import select, update, func
from typing import Optional, List from typing import Optional, List
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import User, Product, Warehouse, Inventory from shared.models.database import User, Product, Warehouse, Inventory
from .schemas import InventoryResponse, InventoryCreate, InventoryUpdate, PaginatedResponse from .schemas import InventoryResponse, InventoryCreate, InventoryUpdate, PaginatedResponse
router = APIRouter(prefix="/inventory", tags=["库存管理"]) router = APIRouter(prefix="/inventory", tags=["库存管理"])
@@ -13,9 +13,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, desc from sqlalchemy import select, func, desc
from typing import Optional, List from typing import Optional, List
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import User, Product, MaterialPriceHistory, MaterialSupplier, Supplier from shared.models.database import User, Product, MaterialPriceHistory, MaterialSupplier, Supplier
from .schemas import ( from .schemas import (
MaterialPriceHistoryCreate, MaterialPriceHistoryCreate,
MaterialPriceHistoryResponse, MaterialPriceHistoryResponse,
@@ -15,9 +15,9 @@ from sqlalchemy import select, or_, func, delete
from typing import Optional, List, Dict from typing import Optional, List, Dict
from decimal import Decimal from decimal import Decimal
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user, get_current_admin_user from shared.services.auth_service import get_current_active_user, get_current_admin_user
from models.database import User, Product, ProductMaterial from shared.models.database import User, Product, ProductMaterial
from .schemas import ( from .schemas import (
ProductCreate, ProductCreate,
ProductResponse, ProductResponse,
@@ -14,9 +14,9 @@ from sqlalchemy import select, func, update
from typing import Optional, List from typing import Optional, List
from decimal import Decimal from decimal import Decimal
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import ( from shared.models.database import (
User, User,
Supplier, Supplier,
Product, Product,
@@ -16,9 +16,9 @@ from math import ceil
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from decimal import Decimal from decimal import Decimal
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import ( from shared.models.database import (
User, User,
Customer, Customer,
Product, Product,
@@ -14,9 +14,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update, func from sqlalchemy import select, update, func
from typing import Optional, List from typing import Optional, List
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import User, Product, Warehouse, Inventory, StockMovement from shared.models.database import User, Product, Warehouse, Inventory, StockMovement
from .schemas import StockMovementCreate, StockMovementResponse, PaginatedResponse from .schemas import StockMovementCreate, StockMovementResponse, PaginatedResponse
from .utils import generate_order_no from .utils import generate_order_no
@@ -15,9 +15,9 @@ from sqlalchemy import select
from typing import Optional, List from typing import Optional, List
from datetime import datetime from datetime import datetime
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user, get_current_admin_user from shared.services.auth_service import get_current_active_user, get_current_admin_user
from models.database import User, Supplier from shared.models.database import User, Supplier
from .schemas import SupplierCreate, SupplierResponse from .schemas import SupplierCreate, SupplierResponse
router = APIRouter(prefix="/suppliers", tags=["供应商管理"]) router = APIRouter(prefix="/suppliers", tags=["供应商管理"])
@@ -13,9 +13,9 @@ from sqlalchemy import select
from typing import List from typing import List
from datetime import datetime from datetime import datetime
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import User, Warehouse from shared.models.database import User, Warehouse
from .schemas import WarehouseCreate, WarehouseResponse from .schemas import WarehouseCreate, WarehouseResponse
router = APIRouter(prefix="/warehouses", tags=["仓库管理"]) router = APIRouter(prefix="/warehouses", tags=["仓库管理"])
+15 -26
View File
@@ -19,7 +19,7 @@ print(f"当前工作目录: {os.getcwd()}")
# 测试导入配置模块 # 测试导入配置模块
try: try:
from config.settings import settings from shared.config.settings import settings
print("[OK] 配置模块导入成功") print("[OK] 配置模块导入成功")
except ImportError as e: except ImportError as e:
print(f"[FAIL] 配置模块导入失败: {e}") print(f"[FAIL] 配置模块导入失败: {e}")
@@ -42,11 +42,11 @@ from fastapi.responses import JSONResponse
import asyncio import asyncio
import time import time
from api.auth_routes import router as auth_router from shared.services.auth_routes import router as auth_router
from api.inventory import inventory_router from inventory.api import inventory_router
from api.aluminum_price_routes import router as aluminum_price_router from moldinsight.api.aluminum_price_routes import router as aluminum_price_router
from utils.logger import setup_logging, get_logger from shared.utils.logger import setup_logging, get_logger
from database.init_db import init_database from shared.database.init_db import init_database
setup_logging() setup_logging()
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -94,8 +94,8 @@ async def startup_event():
# 初始化RustFS连接 # 初始化RustFS连接
try: try:
from storage.rustfs_storage import rustfs_manager from moldinsight.storage.rustfs_storage import rustfs_manager
from config.settings import settings from shared.config.settings import settings
await rustfs_manager.connect( await rustfs_manager.connect(
endpoint=settings.RUSTFS_ENDPOINT, endpoint=settings.RUSTFS_ENDPOINT,
@@ -110,7 +110,7 @@ async def startup_event():
# 初始化Redis连接 # 初始化Redis连接
try: try:
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
await redis_task_manager.connect() await redis_task_manager.connect()
if redis_task_manager.is_connected: if redis_task_manager.is_connected:
print("[OK] Redis连接成功") print("[OK] Redis连接成功")
@@ -124,7 +124,7 @@ async def startup_event():
async def shutdown_event(): async def shutdown_event():
"""应用关闭时清理资源""" """应用关闭时清理资源"""
try: try:
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
await redis_task_manager.disconnect() await redis_task_manager.disconnect()
print("[OK] Redis连接已断开") print("[OK] Redis连接已断开")
except Exception as e: except Exception as e:
@@ -154,27 +154,16 @@ app.include_router(auth_router)
app.include_router(inventory_router) app.include_router(inventory_router)
app.include_router(aluminum_price_router, prefix="/api") app.include_router(aluminum_price_router, prefix="/api")
try: try:
from api.v1 import router as moldinsight_router from moldinsight.api import router as moldinsight_router
except Exception as e:
moldinsight_router = None
print(f"[WARN] MoldInsight v1路由未加载: {e}")
if moldinsight_router is None:
try:
from api.routes import router as moldinsight_router
print("[WARN] 已回退到旧版 MoldInsight 路由")
except Exception as fallback_error:
moldinsight_router = None
print(f"[WARN] MoldInsight旧版路由也未加载: {fallback_error}")
if moldinsight_router is not None:
app.include_router(moldinsight_router, prefix="/api") app.include_router(moldinsight_router, prefix="/api")
except Exception as e:
print(f"[WARN] MoldInsight 路由未加载: {e}")
@app.get("/health") @app.get("/health")
@app.post("/health") @app.post("/health")
async def health(): async def health():
from database.database import db_manager from shared.database.database import db_manager
from sqlalchemy import text from sqlalchemy import text
db_ok = False db_ok = False
db_error = None db_error = None
@@ -246,7 +235,7 @@ async def release():
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn import uvicorn
from config.settings import settings from shared.config.settings import settings
reload_enabled = os.getenv("UVICORN_RELOAD", "0").lower() in {"1", "true", "yes", "on"} reload_enabled = os.getenv("UVICORN_RELOAD", "0").lower() in {"1", "true", "yes", "on"}
print("启动 Gemold 模具制造管理系统 v4.0...") print("启动 Gemold 模具制造管理系统 v4.0...")
View File
@@ -1,7 +1,7 @@
from fastapi import APIRouter from fastapi import APIRouter
import importlib import importlib
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -19,10 +19,10 @@ def _safe_include(module_path: str, label: str):
logger.warning(f"{label} 路由加载失败,已跳过: {exc}") logger.warning(f"{label} 路由加载失败,已跳过: {exc}")
_safe_include("api.v1.health_router", "健康检查") _safe_include("moldinsight.api.health_router", "健康检查")
_safe_include("api.v1.upload_router", "上传") _safe_include("moldinsight.api.upload_router", "上传")
_safe_include("api.v1.task_router", "任务") _safe_include("moldinsight.api.task_router", "任务")
_safe_include("api.v1.history_router", "历史") _safe_include("moldinsight.api.history_router", "历史")
_safe_include("api.v1.debug_router", "调试") _safe_include("moldinsight.api.debug_router", "调试")
_safe_include("api.v1.cam_router", "CAM") _safe_include("moldinsight.api.cam_router", "CAM")
_safe_include("api.v1.advanced_router", "高级") _safe_include("moldinsight.api.advanced_router", "高级")
@@ -7,16 +7,16 @@ from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
from services.processing_service import processing_service from moldinsight.services.processing_service import processing_service
from services.storage_integration_rustfs import StorageIntegrationService from moldinsight.services.storage_integration_rustfs import StorageIntegrationService
from services.task_query_service import TaskQueryService from moldinsight.services.task_query_service import TaskQueryService
from database.database import get_db_session from shared.database.database import get_db_session
from models.database import User from shared.models.database import User
from models.database import ProcessingTask, STPFile from shared.models.database import ProcessingTask, STPFile
from core.cad_exporter import CADExporter from moldinsight.core.cad_exporter import CADExporter
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -216,7 +216,7 @@ async def design_cooling_system(
material = body.get("material", "ABS") material = body.get("material", "ABS")
cavity_count = body.get("cavity_count", 1) cavity_count = body.get("cavity_count", 1)
cycle_time_target = body.get("cycle_time_target") cycle_time_target = body.get("cycle_time_target")
from core.mold_system_designer import CoolingSystemDesigner from moldinsight.core.mold_system_designer import CoolingSystemDesigner
designer = CoolingSystemDesigner() designer = CoolingSystemDesigner()
result = designer.design_cooling_system( result = designer.design_cooling_system(
mold_size=mold_size, product_bbox=product_bbox, mold_size=mold_size, product_bbox=product_bbox,
@@ -237,7 +237,7 @@ async def design_gating_system(
cavity_count = body.get("cavity_count", 1) cavity_count = body.get("cavity_count", 1)
gate_type = body.get("gate_type", "auto") gate_type = body.get("gate_type", "auto")
layout_positions = body.get("layout_positions") layout_positions = body.get("layout_positions")
from core.mold_system_designer import GatingSystemDesigner from moldinsight.core.mold_system_designer import GatingSystemDesigner
designer = GatingSystemDesigner() designer = GatingSystemDesigner()
result = designer.design_gating_system( result = designer.design_gating_system(
product_bbox=product_bbox, material=material, product_bbox=product_bbox, material=material,
@@ -287,7 +287,7 @@ async def ai_parting_surface_detect(
geometry_data = task_data.get("geometry_data") geometry_data = task_data.get("geometry_data")
if not geometry_data: if not geometry_data:
raise HTTPException(400, "该任务尚未完成几何分析") raise HTTPException(400, "该任务尚未完成几何分析")
from core.ai_parting_detector import AIPartingSurfaceDetectorV2 from moldinsight.core.ai_parting_detector import AIPartingSurfaceDetectorV2
detector = AIPartingSurfaceDetectorV2(use_gnn=True) detector = AIPartingSurfaceDetectorV2(use_gnn=True)
result = detector._detect_with_geometry(None, geometry_data) result = detector._detect_with_geometry(None, geometry_data)
return {"status": "success", "data": result} return {"status": "success", "data": result}
@@ -6,7 +6,7 @@
不需要认证,公开访问。 不需要认证,公开访问。
""" """
from fastapi import APIRouter, Query from fastapi import APIRouter, Query
from services.aluminum_price_service import get_aluminum_current_price, get_aluminum_price_history from moldinsight.services.aluminum_price_service import get_aluminum_current_price, get_aluminum_price_history
router = APIRouter(prefix="/aluminum-price", tags=["铝金属价格"]) router = APIRouter(prefix="/aluminum-price", tags=["铝金属价格"])
@@ -3,12 +3,12 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from datetime import datetime from datetime import datetime
from database.database import get_db_session from shared.database.database import get_db_session
from models.database import User, ProcessingTask from shared.models.database import User, ProcessingTask
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from services.cam_bundle_service import cam_bundle_service from moldinsight.services.cam_bundle_service import cam_bundle_service
from services.task_query_service import TaskQueryService from moldinsight.services.task_query_service import TaskQueryService
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -1,7 +1,7 @@
# api/v1/debug_router.py # api/v1/debug_router.py
from fastapi import APIRouter from fastapi import APIRouter
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
router = APIRouter() router = APIRouter()
@@ -1,7 +1,7 @@
# api/v1/health_router.py # api/v1/health_router.py
from fastapi import APIRouter from fastapi import APIRouter
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
router = APIRouter() router = APIRouter()
@@ -2,8 +2,8 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
import urllib.parse import urllib.parse
from services.storage_integration_rustfs import StorageIntegrationService from moldinsight.services.storage_integration_rustfs import StorageIntegrationService
from database.database import get_db_session from shared.database.database import get_db_session
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
router = APIRouter() router = APIRouter()
@@ -4,10 +4,10 @@ from fastapi import APIRouter, HTTPException, Request, Depends
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from services.task_query_service import TaskQueryService from moldinsight.services.task_query_service import TaskQueryService
from database.database import get_db_session from shared.database.database import get_db_session
from utils.logger import get_logger from shared.utils.logger import get_logger
from models.database import ProcessingTask, STPFile from shared.models.database import ProcessingTask, STPFile
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -4,15 +4,15 @@ import uuid
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from models.schemas import ProcessingStatus, create_task_info from shared.models.schemas import ProcessingStatus, create_task_info
from utils.file_handler import FileHandler from shared.utils.file_handler import FileHandler
from services.storage_integration_rustfs import StorageIntegrationService from moldinsight.services.storage_integration_rustfs import StorageIntegrationService
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
from database.database import get_db_session from shared.database.database import get_db_session
from utils.logger import get_logger from shared.utils.logger import get_logger
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from services.auth_service import get_current_active_user from shared.services.auth_service import get_current_active_user
from models.database import User from shared.models.database import User
try: try:
from celery_tasks import process_stp_task from celery_tasks import process_stp_task
@@ -101,7 +101,7 @@ async def upload_stp(
logger.info(f"[UPLOAD] Celery 任务已调度: task_id={task_id}") logger.info(f"[UPLOAD] Celery 任务已调度: task_id={task_id}")
else: else:
import asyncio import asyncio
from services.processing_service import processing_service from moldinsight.services.processing_service import processing_service
asyncio.create_task(processing_service.process_file_with_storage( asyncio.create_task(processing_service.process_file_with_storage(
task_id, str(file_path), stp_file.id, process_params task_id, str(file_path), stp_file.id, process_params
)) ))
@@ -195,7 +195,7 @@ if __name__ == "__main__":
draft_analyzer = AIDraftAnalyzer(model_path="models/draft_analysis.pth") draft_analyzer = AIDraftAnalyzer(model_path="models/draft_analysis.pth")
# 2. 设置到 MoldCavityGenerator # 2. 设置到 MoldCavityGenerator
from core.mold_generator import MoldCavityGenerator from moldinsight.core.mold_generator import MoldCavityGenerator
generator = MoldCavityGenerator() generator = MoldCavityGenerator()
generator.set_ai_model( generator.set_ai_model(
@@ -23,7 +23,7 @@ GNN 模型:
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape from OCC.Core.TopoDS import TopoDS_Shape
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -25,10 +25,10 @@ from OCC.Core.BRepBndLib import brepbndlib
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
from OCC.Core.BRepGProp import brepgprop from OCC.Core.BRepGProp import brepgprop
from models.schemas import create_mold_cavity_data, create_mold_key_info from shared.models.schemas import create_mold_cavity_data, create_mold_key_info
from utils.logger import get_logger from shared.utils.logger import get_logger
from core.base_mold_generator import BaseMoldGenerator from moldinsight.core.base_mold_generator import BaseMoldGenerator
from core.side_action_designer import SideActionDesigner from moldinsight.core.side_action_designer import SideActionDesigner
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -18,8 +18,8 @@ from OCC.Core.Bnd import Bnd_Box
from OCC.Core.BRepBndLib import brepbndlib from OCC.Core.BRepBndLib import brepbndlib
from OCC.Core.TopLoc import TopLoc_Location from OCC.Core.TopLoc import TopLoc_Location
from models.schemas import create_mold_cavity_data, create_mold_key_info from shared.models.schemas import create_mold_cavity_data, create_mold_key_info
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -30,7 +30,7 @@ import re
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
from pathlib import Path from pathlib import Path
from OCC.Core.TopoDS import TopoDS_Shape from OCC.Core.TopoDS import TopoDS_Shape
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -20,7 +20,7 @@
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
import math import math
import numpy as np import numpy as np
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -3,12 +3,12 @@ import math
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape from OCC.Core.TopoDS import TopoDS_Shape
from models.schemas import ( from shared.models.schemas import (
create_mold_feature, create_mold_feature,
create_design_recommendation, create_design_recommendation,
create_analysis_result create_analysis_result
) )
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -19,7 +19,7 @@
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
import math import math
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -9,10 +9,10 @@ from OCC.Core.TopAbs import TopAbs_FACE
from OCC.Core.Bnd import Bnd_Box from OCC.Core.Bnd import Bnd_Box
from OCC.Core.BRepBndLib import brepbndlib from OCC.Core.BRepBndLib import brepbndlib
from models.schemas import create_mold_cavity_data, create_mold_key_info from shared.models.schemas import create_mold_cavity_data, create_mold_key_info
from utils.logger import get_logger from shared.utils.logger import get_logger
from core.base_mold_generator import BaseMoldGenerator from moldinsight.core.base_mold_generator import BaseMoldGenerator
from core.side_action_designer import SideActionDesigner from moldinsight.core.side_action_designer import SideActionDesigner
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -29,7 +29,7 @@
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
import math import math
import numpy as np import numpy as np
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -7,7 +7,7 @@
from typing import Dict, List, Any from typing import Dict, List, Any
import numpy as np import numpy as np
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -16,7 +16,7 @@
from typing import Dict, List, Any, Optional from typing import Dict, List, Any, Optional
import math import math
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -8,11 +8,11 @@ from OCC.Core.TopAbs import TopAbs_FACE
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Shape, topods from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Shape, topods
from core.mold_generator import MoldCavityGenerator from moldinsight.core.mold_generator import MoldCavityGenerator
from core.aluminum_foam_mold import AluminumFoamMoldGenerator from moldinsight.core.aluminum_foam_mold import AluminumFoamMoldGenerator
from core.parting_candidate_generator import PartingCandidateGenerator from moldinsight.core.parting_candidate_generator import PartingCandidateGenerator
from core.parting_scheme_scorer import PartingSchemeScorer from moldinsight.core.parting_scheme_scorer import PartingSchemeScorer
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -22,7 +22,7 @@ from typing import Dict, List, Any, Optional, Tuple
import math import math
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Face from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Face
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -3,7 +3,7 @@ from pathlib import Path
from typing import Dict, Any, Optional, List from typing import Dict, Any, Optional, List
import numpy as np import numpy as np
import json import json
from utils.logger import get_logger from shared.utils.logger import get_logger
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
from OCC.Core.BRepGProp import brepgprop from OCC.Core.BRepGProp import brepgprop
from OCC.Core.TopoDS import TopoDS_Shape from OCC.Core.TopoDS import TopoDS_Shape
@@ -371,7 +371,7 @@ class CalculationService:
material_name: str, material_name: str,
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""为每个候选方案补充注塑模冷却/浇注摘要。""" """为每个候选方案补充注塑模冷却/浇注摘要。"""
from core.mold_system_designer import MoldSystemDesigner from moldinsight.core.mold_system_designer import MoldSystemDesigner
designer = MoldSystemDesigner() designer = MoldSystemDesigner()
for scheme in plan_result.get("candidate_schemes", []): for scheme in plan_result.get("candidate_schemes", []):
@@ -1,6 +1,6 @@
from typing import Dict, Any, List, Optional from typing import Dict, Any, List, Optional
from core.mold_cam import MoldCAMDesigner from moldinsight.core.mold_cam import MoldCAMDesigner
class CAMBundleService: class CAMBundleService:
@@ -15,8 +15,8 @@ from typing import Optional, Dict, Any, List
import httpx import httpx
from config.settings import settings from shared.config.settings import settings
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -11,23 +11,23 @@ from typing import Optional, Dict, Any
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from core.stp_parser import STPParser from moldinsight.core.stp_parser import STPParser
from core.geometry_analyzer import GeometryAnalyzer from moldinsight.core.geometry_analyzer import GeometryAnalyzer
from core.mold_generator import MoldCavityGenerator from moldinsight.core.mold_generator import MoldCavityGenerator
from core.aluminum_foam_mold import AluminumFoamMoldGenerator from moldinsight.core.aluminum_foam_mold import AluminumFoamMoldGenerator
from core.mold_quality_inspector import AluminumFoamMoldQualityInspector from moldinsight.core.mold_quality_inspector import AluminumFoamMoldQualityInspector
from core.mesh_generator import MeshGenerator from moldinsight.core.mesh_generator import MeshGenerator
from core.multi_scheme_planner import MultiSchemeMoldPlanner from moldinsight.core.multi_scheme_planner import MultiSchemeMoldPlanner
from core.cad_exporter import CADExporter from moldinsight.core.cad_exporter import CADExporter
from services.storage_integration_rustfs import StorageIntegrationService from moldinsight.services.storage_integration_rustfs import StorageIntegrationService
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
from services.material_service import MaterialService from moldinsight.services.material_service import MaterialService
from services.calculation_service import CalculationService from moldinsight.services.calculation_service import CalculationService
from services.llm_service import llm_service from moldinsight.services.llm_service import llm_service
from models.schemas import ProcessingStatus from shared.models.schemas import ProcessingStatus
from database.database import db_manager from shared.database.database import db_manager
from utils.html_generator import HTMLGenerator from shared.utils.html_generator import HTMLGenerator
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -65,7 +65,7 @@ class ProcessingService:
try: try:
logger.info(f"开始处理文件并生成模具型腔: {file_path}") logger.info(f"开始处理文件并生成模具型腔: {file_path}")
from config.settings import settings from shared.config.settings import settings
file_size_bytes = Path(file_path).stat().st_size if Path(file_path).exists() else 0 file_size_bytes = Path(file_path).stat().st_size if Path(file_path).exists() else 0
file_size_mb = max(file_size_bytes / (1024 * 1024), 1) file_size_mb = max(file_size_bytes / (1024 * 1024), 1)
@@ -550,7 +550,7 @@ class ProcessingService:
task_id: str, stp_file_id: int, analysis_result: Optional[dict], task_id: str, stp_file_id: int, analysis_result: Optional[dict],
) -> Optional[Dict[str, Any]]: ) -> Optional[Dict[str, Any]]:
"""FreeCAD 几何验证(可通过配置禁用)""" """FreeCAD 几何验证(可通过配置禁用)"""
from config.settings import settings from shared.config.settings import settings
if not settings.ENABLE_FREECAD_VERIFICATION: if not settings.ENABLE_FREECAD_VERIFICATION:
logger.info("FreeCAD验证已禁用(设置 ENABLE_FREECAD_VERIFICATION=true 启用)") logger.info("FreeCAD验证已禁用(设置 ENABLE_FREECAD_VERIFICATION=true 启用)")
@@ -561,7 +561,7 @@ class ProcessingService:
) )
try: try:
from services.verification_service import GeometryVerificationService from moldinsight.services.verification_service import GeometryVerificationService
verification_svc = GeometryVerificationService(timeout=settings.FREECAD_VERIFICATION_TIMEOUT) verification_svc = GeometryVerificationService(timeout=settings.FREECAD_VERIFICATION_TIMEOUT)
verification_result = await verification_svc.verify_stp_file(file_path) verification_result = await verification_svc.verify_stp_file(file_path)
@@ -611,7 +611,7 @@ class ProcessingService:
async def _save_analysis_metrics(self, session: AsyncSession, stp_file_id: int, analysis_result: dict): async def _save_analysis_metrics(self, session: AsyncSession, stp_file_id: int, analysis_result: dict):
"""保存分析指标到数据库""" """保存分析指标到数据库"""
from models.database import AnalysisMetrics from shared.models.database import AnalysisMetrics
quality_metrics = analysis_result.get("quality_metrics", {}) quality_metrics = analysis_result.get("quality_metrics", {})
analysis_summary = analysis_result.get("analysis_summary", "") analysis_summary = analysis_result.get("analysis_summary", "")
@@ -630,7 +630,7 @@ class ProcessingService:
async def _save_verification_metrics(self, session: AsyncSession, stp_file_id: int, verification_result: dict): async def _save_verification_metrics(self, session: AsyncSession, stp_file_id: int, verification_result: dict):
"""保存验证指标到数据库""" """保存验证指标到数据库"""
from models.database import AnalysisMetrics from shared.models.database import AnalysisMetrics
from sqlalchemy import select from sqlalchemy import select
result = await session.execute( result = await session.execute(
@@ -6,14 +6,14 @@ from pathlib import Path
from typing import Optional, Dict, Any from typing import Optional, Dict, Any
import json import json
from models.database import ( from shared.models.database import (
STPFile, GeometryData, MoldCavityData, STPFile, GeometryData, MoldCavityData,
HTMLFile, ProcessingTask, User, HTMLFile, ProcessingTask, User,
FeatureDetection, DesignRecommendation, FeatureDetection, DesignRecommendation,
UserActivity, SystemLog UserActivity, SystemLog
) )
from storage.object_storage import storage_manager from moldinsight.storage.object_storage import storage_manager
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -8,14 +8,14 @@ import json
from datetime import datetime from datetime import datetime
import uuid import uuid
from models.database import ( from shared.models.database import (
STPFile, GeometryData, MeshData, MoldCavityData, STPFile, GeometryData, MeshData, MoldCavityData,
HTMLFile, ProcessingTask, User, HTMLFile, ProcessingTask, User,
FeatureDetection, DesignRecommendation, FeatureDetection, DesignRecommendation,
UserActivity, SystemLog UserActivity, SystemLog
) )
from storage.rustfs_storage import rustfs_manager from moldinsight.storage.rustfs_storage import rustfs_manager
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -662,7 +662,7 @@ class StorageIntegrationService:
limit: int = 50 limit: int = 50
) -> list: ) -> list:
"""获取同一文件名的所有上传历史记录""" """获取同一文件名的所有上传历史记录"""
from models.database import ProcessingTask from shared.models.database import ProcessingTask
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
query = select(STPFile).options( query = select(STPFile).options(
@@ -705,7 +705,7 @@ class StorageIntegrationService:
from sqlalchemy import func, desc from sqlalchemy import func, desc
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from models.database import ProcessingTask from shared.models.database import ProcessingTask
# 子查询:获取每个文件名的最新上传 # 子查询:获取每个文件名的最新上传
subquery = ( subquery = (
@@ -7,10 +7,10 @@ import json
from pathlib import Path from pathlib import Path
from typing import Optional, Dict, Any from typing import Optional, Dict, Any
from models.database import STPFile, GeometryData, HTMLFile, ProcessingTask from shared.models.database import STPFile, GeometryData, HTMLFile, ProcessingTask
from utils.logger import get_logger from shared.utils.logger import get_logger
from models.database import MoldCavityData from shared.models.database import MoldCavityData
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -7,10 +7,10 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from services.storage_integration_rustfs import StorageIntegrationService from moldinsight.services.storage_integration_rustfs import StorageIntegrationService
from services.redis_task_manager import redis_task_manager from shared.services.redis_task_manager import redis_task_manager
from models.database import ProcessingTask, STPFile, MeshData, HTMLFile from shared.models.database import ProcessingTask, STPFile, MeshData, HTMLFile
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -11,7 +11,7 @@ from pathlib import Path
from typing import Dict, Any, Optional from typing import Dict, Any, Optional
from datetime import datetime from datetime import datetime
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -10,9 +10,9 @@ src_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root)) sys.path.insert(0, str(project_root))
sys.path.insert(0, str(src_root)) sys.path.insert(0, str(src_root))
from storage.rustfs_storage import rustfs_manager from moldinsight.storage.rustfs_storage import rustfs_manager
from config.settings import settings from shared.config.settings import settings
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -5,7 +5,7 @@ from minio.error import S3Error
from pathlib import Path from pathlib import Path
from typing import Optional, BinaryIO from typing import Optional, BinaryIO
from io import BytesIO from io import BytesIO
from utils.logger import get_logger from shared.utils.logger import get_logger
import hashlib import hashlib
import uuid import uuid
@@ -5,7 +5,7 @@ from minio.error import S3Error
from pathlib import Path from pathlib import Path
from typing import Optional, Dict, Any from typing import Optional, Dict, Any
from io import BytesIO from io import BytesIO
from utils.logger import get_logger from shared.utils.logger import get_logger
from datetime import timedelta from datetime import timedelta
import hashlib import hashlib
import uuid import uuid
+5 -5
View File
@@ -8,11 +8,11 @@ sys.path.insert(0, str(project_root))
sys.path.insert(0, str(src_root)) sys.path.insert(0, str(src_root))
from sqlalchemy import select from sqlalchemy import select
from database.database import db_manager from shared.database.database import db_manager
from models.database import User, Role, UserRole from shared.models.database import User, Role, UserRole
from services.auth_service import get_password_hash from shared.services.auth_service import get_password_hash
from config.settings import settings from shared.config.settings import settings
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
View File
View File
@@ -1,18 +1,15 @@
# database/database.py # shared/database/database.py
import sys import sys
import os import os
from pathlib import Path from pathlib import Path
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy import text from sqlalchemy import text
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from config.settings import settings from shared.config.settings import settings
import asyncio import asyncio
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -1,19 +1,12 @@
import asyncio import asyncio
import sys import sys
from pathlib import Path from pathlib import Path
from sqlalchemy import text from sqlalchemy import text, select
from shared.database.database import db_manager
project_root = Path(__file__).parent.parent.parent from shared.models.database import User, Role, Permission, UserRole, RolePermission
src_root = Path(__file__).parent.parent from shared.services.auth_service import get_password_hash
sys.path.insert(0, str(project_root)) from shared.config.settings import settings
sys.path.insert(0, str(src_root)) from shared.utils.logger import get_logger
from sqlalchemy import select
from database.database import db_manager
from models.database import User, Role, Permission, UserRole, RolePermission
from services.auth_service import get_password_hash
from config.settings import settings
from utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -1,20 +1,8 @@
"""数据库迁移脚本 - 删除旧表并重新创建""" """数据库迁移脚本 - 删除旧表并重新创建"""
import asyncio import asyncio
import sys from shared.database.database import db_manager
import os from shared.models.database import Base
from pathlib import Path from shared.utils.logger import get_logger
# 添加项目根目录到路径
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
sys.path.insert(0, str(Path(__file__).parent.parent))
# 设置环境变量确保正确导入
os.environ['PYTHONPATH'] = str(project_root) + os.pathsep + str(Path(__file__).parent.parent)
from src.database.database import db_manager
from src.models.database import Base
from src.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
View File
@@ -7,16 +7,16 @@ from datetime import timedelta
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from database.database import get_db_session from shared.database.database import get_db_session
from services.auth_service import ( from shared.services.auth_service import (
authenticate_user, authenticate_user,
create_access_token, create_access_token,
get_current_active_user, get_current_active_user,
get_password_hash get_password_hash
) )
from models.database import User, Role, Permission, UserRole, RolePermission from shared.models.database import User, Role, Permission, UserRole, RolePermission
from config.settings import settings from shared.config.settings import settings
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
router = APIRouter(prefix="/api/auth", tags=["认证"]) router = APIRouter(prefix="/api/auth", tags=["认证"])
@@ -8,10 +8,10 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from config.settings import settings from shared.config.settings import settings
from database.database import get_db_session from shared.database.database import get_db_session
from models.database import User, UserRole from shared.models.database import User, UserRole
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -8,7 +8,7 @@ from datetime import datetime
import redis.asyncio as aioredis import redis.asyncio as aioredis
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -2,7 +2,7 @@
from pathlib import Path from pathlib import Path
from typing import Dict, Any, Optional from typing import Dict, Any, Optional
from datetime import datetime from datetime import datetime
from utils.logger import get_logger from shared.utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)