""" 设计服务 处理设计相关的业务逻辑 """ import os from typing import List, Optional, Tuple from sqlalchemy.orm import Session from sqlalchemy import desc from ..models import Design, Category, SubType, Color from ..schemas import DesignCreate from ..config import settings from .mock_generator import generate_mock_design def create_design(db: Session, user_id: int, design_data: DesignCreate) -> Design: """ 创建设计记录 1. 创建设计记录(status=generating) 2. 调用 mock_generator 生成图片 3. 更新设计记录(status=completed, image_url) 4. 返回设计对象 """ # 获取关联信息 category = db.query(Category).filter(Category.id == design_data.category_id).first() if not category: raise ValueError(f"品类不存在: {design_data.category_id}") sub_type = None if design_data.sub_type_id: sub_type = db.query(SubType).filter(SubType.id == design_data.sub_type_id).first() color = None if design_data.color_id: color = db.query(Color).filter(Color.id == design_data.color_id).first() # 创建设计记录 design = Design( user_id=user_id, category_id=design_data.category_id, sub_type_id=design_data.sub_type_id, color_id=design_data.color_id, prompt=design_data.prompt, carving_technique=design_data.carving_technique, design_style=design_data.design_style, motif=design_data.motif, size_spec=design_data.size_spec, surface_finish=design_data.surface_finish, usage_scene=design_data.usage_scene, status="generating" ) db.add(design) db.flush() # 获取 ID # 生成图片 save_path = os.path.join(settings.UPLOAD_DIR, "designs", f"{design.id}.png") image_url = generate_mock_design( category_name=category.name, sub_type_name=sub_type.name if sub_type else None, color_name=color.name if color else None, prompt=design_data.prompt, save_path=save_path, carving_technique=design_data.carving_technique, design_style=design_data.design_style, motif=design_data.motif, size_spec=design_data.size_spec, surface_finish=design_data.surface_finish, usage_scene=design_data.usage_scene, ) # 更新设计记录 design.image_url = image_url design.status = "completed" db.commit() db.refresh(design) return design def get_user_designs( db: Session, user_id: int, page: int = 1, page_size: int = 20 ) -> Tuple[List[Design], int]: """ 分页查询用户设计历史 Returns: (设计列表, 总数) """ query = db.query(Design).filter(Design.user_id == user_id) # 获取总数 total = query.count() # 分页查询,按创建时间倒序 offset = (page - 1) * page_size designs = query.order_by(desc(Design.created_at)).offset(offset).limit(page_size).all() return designs, total def get_design_by_id(db: Session, design_id: int, user_id: int) -> Optional[Design]: """ 获取单个设计 只返回属于该用户的设计 """ return db.query(Design).filter( Design.id == design_id, Design.user_id == user_id ).first() def delete_design(db: Session, design_id: int, user_id: int) -> bool: """ 删除设计 1. 查找设计(必须属于该用户) 2. 删除图片文件 3. 删除数据库记录 Returns: 是否删除成功 """ design = db.query(Design).filter( Design.id == design_id, Design.user_id == user_id ).first() if not design: return False # 删除图片文件 if design.image_url: # image_url 格式: /uploads/designs/1001.png # 转换为实际文件路径 file_path = design.image_url.lstrip("/") if os.path.exists(file_path): try: os.remove(file_path) except Exception: pass # 忽略删除失败 # 删除数据库记录 db.delete(design) db.commit() return True