update
This commit is contained in:
parent
c79cf5186c
commit
b2b7770de2
@ -137,11 +137,6 @@ async def read_clothes_by_category(
|
|||||||
db: AsyncSession = Depends(get_db)
|
db: AsyncSession = Depends(get_db)
|
||||||
):
|
):
|
||||||
"""根据分类获取衣服"""
|
"""根据分类获取衣服"""
|
||||||
# 检查分类是否存在
|
|
||||||
category = await clothing_service.get_category(db, category_id=category_id)
|
|
||||||
if category is None:
|
|
||||||
raise BusinessError("分类不存在", code=404)
|
|
||||||
|
|
||||||
clothes = await clothing_service.get_clothes_by_category(
|
clothes = await clothing_service.get_clothes_by_category(
|
||||||
db=db,
|
db=db,
|
||||||
category_id=category_id,
|
category_id=category_id,
|
||||||
@ -151,46 +146,6 @@ async def read_clothes_by_category(
|
|||||||
# 手动返回标准响应格式
|
# 手动返回标准响应格式
|
||||||
return StandardResponse(code=200, data=[Clothing.model_validate(clothing) for clothing in clothes])
|
return StandardResponse(code=200, data=[Clothing.model_validate(clothing) for clothing in clothes])
|
||||||
|
|
||||||
@router.get("/{clothing_id}", tags=["clothing"])
|
|
||||||
async def read_clothing(
|
|
||||||
clothing_id: int,
|
|
||||||
db: AsyncSession = Depends(get_db)
|
|
||||||
):
|
|
||||||
"""获取单个衣服"""
|
|
||||||
clothing = await clothing_service.get_clothing(db, clothing_id=clothing_id)
|
|
||||||
if clothing is None:
|
|
||||||
raise BusinessError("衣服不存在", code=404)
|
|
||||||
# 手动返回标准响应格式
|
|
||||||
return StandardResponse(code=200, data=Clothing.model_validate(clothing))
|
|
||||||
|
|
||||||
@router.put("/{clothing_id}", tags=["clothing"])
|
|
||||||
async def update_clothing(
|
|
||||||
clothing_id: int,
|
|
||||||
clothing: ClothingUpdate,
|
|
||||||
db: AsyncSession = Depends(get_db),
|
|
||||||
current_user: UserModel = Depends(get_current_user)
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
更新衣服
|
|
||||||
|
|
||||||
需要JWT令牌认证
|
|
||||||
"""
|
|
||||||
# 检查分类是否存在
|
|
||||||
if clothing.clothing_category_id is not None:
|
|
||||||
category = await clothing_service.get_category(db, category_id=clothing.clothing_category_id)
|
|
||||||
if category is None:
|
|
||||||
raise BusinessError("指定的分类不存在", code=404)
|
|
||||||
|
|
||||||
clothing = await clothing_service.update_clothing(
|
|
||||||
db=db,
|
|
||||||
clothing_id=clothing_id,
|
|
||||||
clothing_update=clothing
|
|
||||||
)
|
|
||||||
if clothing is None:
|
|
||||||
raise BusinessError("衣服不存在", code=404)
|
|
||||||
# 手动返回标准响应格式
|
|
||||||
return StandardResponse(code=200, data=Clothing.model_validate(clothing))
|
|
||||||
|
|
||||||
@router.delete("/{clothing_id}", tags=["clothing"])
|
@router.delete("/{clothing_id}", tags=["clothing"])
|
||||||
async def delete_clothing(
|
async def delete_clothing(
|
||||||
clothing_id: int,
|
clothing_id: int,
|
||||||
|
|||||||
70
app/api/v1/tryon.py
Normal file
70
app/api/v1/tryon.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
from fastapi import APIRouter, Depends, HTTPException, status, Response
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
import logging
|
||||||
|
from fastapi.security import OAuth2PasswordRequestForm
|
||||||
|
from app.api import deps
|
||||||
|
from app.core import security
|
||||||
|
from app.core.config import settings
|
||||||
|
from app.schemas.tryon import TryonRequest
|
||||||
|
from app.schemas.user import User
|
||||||
|
from app.services import person_image as person_image_service
|
||||||
|
from app.services import clothing as clothing_service
|
||||||
|
from app.api.deps import get_current_user
|
||||||
|
from app.services.dashscope_service import DashScopeService
|
||||||
|
from app.schemas.response import StandardResponse
|
||||||
|
from app.models.tryon import TryonHistory
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.post("/tryon", tags=["tryon"])
|
||||||
|
async def tryon(
|
||||||
|
tryon_request: TryonRequest,
|
||||||
|
db: AsyncSession = Depends(deps.get_db),
|
||||||
|
current_user: User = Depends(get_current_user)
|
||||||
|
):
|
||||||
|
# 获取当前用户的默认形象
|
||||||
|
person_image = await person_image_service.get_default_image(db, current_user.id)
|
||||||
|
if not person_image:
|
||||||
|
raise HTTPException(status_code=404, detail="默认形象不存在")
|
||||||
|
|
||||||
|
# 获取试穿请求中的衣物ID
|
||||||
|
top_clothing_id = tryon_request.top_clothing_id
|
||||||
|
bottom_clothing_id = tryon_request.bottom_clothing_id
|
||||||
|
|
||||||
|
# 获取衣物详情
|
||||||
|
top_clothing_url = tryon_request.top_clothing_url
|
||||||
|
bottom_clothing_url = tryon_request.bottom_clothing_url
|
||||||
|
|
||||||
|
if top_clothing_id:
|
||||||
|
top_clothing = await clothing_service.get_clothing(db, top_clothing_id)
|
||||||
|
top_clothing_url = top_clothing.image_url
|
||||||
|
|
||||||
|
if bottom_clothing_id:
|
||||||
|
bottom_clothing = await clothing_service.get_clothing(db, bottom_clothing_id)
|
||||||
|
bottom_clothing_url = bottom_clothing.image_url
|
||||||
|
|
||||||
|
|
||||||
|
# 调用试穿服务
|
||||||
|
dashscope_service = DashScopeService()
|
||||||
|
tryon_result = await dashscope_service.generate_tryon(person_image.image_url,
|
||||||
|
top_clothing_url,
|
||||||
|
bottom_clothing_url)
|
||||||
|
|
||||||
|
task_id = tryon_result.get("task_id")
|
||||||
|
if task_id:
|
||||||
|
tryon_history = TryonHistory(
|
||||||
|
user_id=current_user.id,
|
||||||
|
person_image_id=person_image.id,
|
||||||
|
top_clothing_id=top_clothing_id,
|
||||||
|
bottom_clothing_id=bottom_clothing_id,
|
||||||
|
top_clothing_url=top_clothing_url,
|
||||||
|
bottom_clothing_url=bottom_clothing_url,
|
||||||
|
task_id=task_id
|
||||||
|
)
|
||||||
|
db.add(tryon_history)
|
||||||
|
await db.commit()
|
||||||
|
return StandardResponse(code=200, message="试穿任务已提交", data=tryon_history.id)
|
||||||
|
else:
|
||||||
|
return StandardResponse(code=500, message="试穿任务提交失败")
|
||||||
@ -3,6 +3,7 @@ from app.db.database import Base, engine
|
|||||||
from app.models.users import User
|
from app.models.users import User
|
||||||
from app.models.person_images import PersonImage
|
from app.models.person_images import PersonImage
|
||||||
from app.models.clothing import ClothingCategory, Clothing
|
from app.models.clothing import ClothingCategory, Clothing
|
||||||
|
from app.models.tryon import TryonHistory
|
||||||
|
|
||||||
# 创建所有表格
|
# 创建所有表格
|
||||||
async def init_db():
|
async def init_db():
|
||||||
|
|||||||
37
app/models/tryon.py
Normal file
37
app/models/tryon.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Enum
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
from app.db.database import Base
|
||||||
|
import enum
|
||||||
|
|
||||||
|
class TryonStatus(enum.Enum):
|
||||||
|
"""试穿状态枚举"""
|
||||||
|
GENERATING = "生成中"
|
||||||
|
COMPLETED = "已生成"
|
||||||
|
FAILED = "失败"
|
||||||
|
|
||||||
|
class TryonHistory(Base):
|
||||||
|
"""试穿记录数据模型"""
|
||||||
|
__tablename__ = "tryon_history"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
|
||||||
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True, comment="用户ID")
|
||||||
|
person_image_id = Column(Integer, ForeignKey("person_images.id"), nullable=False, index=True, comment="人物形象ID")
|
||||||
|
top_clothing_id = Column(Integer, ForeignKey("clothing.id"), nullable=True, comment="上衣ID")
|
||||||
|
bottom_clothing_id = Column(Integer, ForeignKey("clothing.id"), nullable=True, comment="下装ID")
|
||||||
|
top_clothing_url = Column(String(500), nullable=True, comment="上衣图片URL")
|
||||||
|
bottom_clothing_url = Column(String(500), nullable=True, comment="下装图片URL")
|
||||||
|
task_id = Column(String(100), nullable=True, index=True, comment="任务ID")
|
||||||
|
completion_url = Column(String(500), nullable=True, comment="生成结果URL")
|
||||||
|
status = Column(Enum(TryonStatus), default=TryonStatus.GENERATING, comment="状态")
|
||||||
|
create_time = Column(DateTime, default=func.now(), comment="创建时间")
|
||||||
|
update_time = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间")
|
||||||
|
|
||||||
|
# 关系
|
||||||
|
user = relationship("User", backref="tryon_histories")
|
||||||
|
person_image = relationship("PersonImage", backref="tryon_histories")
|
||||||
|
top_clothing = relationship("Clothing", foreign_keys=[top_clothing_id], backref="top_tryon_histories")
|
||||||
|
bottom_clothing = relationship("Clothing", foreign_keys=[bottom_clothing_id], backref="bottom_tryon_histories")
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<TryonHistory(id={self.id}, status={self.status.name})>"
|
||||||
@ -18,6 +18,7 @@ class User(Base):
|
|||||||
# 关系
|
# 关系
|
||||||
person_images = relationship("PersonImage", back_populates="user", cascade="all, delete-orphan")
|
person_images = relationship("PersonImage", back_populates="user", cascade="all, delete-orphan")
|
||||||
clothings = relationship("Clothing", back_populates="user", cascade="all, delete-orphan")
|
clothings = relationship("Clothing", back_populates="user", cascade="all, delete-orphan")
|
||||||
|
# tryon_histories已通过backref在TryonHistory模型中定义
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<User(id={self.id}, nickname={self.nickname})>"
|
return f"<User(id={self.id}, nickname={self.nickname})>"
|
||||||
|
|||||||
9
app/schemas/tryon.py
Normal file
9
app/schemas/tryon.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
class TryonRequest(BaseModel):
|
||||||
|
top_clothing_id: Optional[int] = None
|
||||||
|
bottom_clothing_id: Optional[int] = None
|
||||||
|
top_clothing_url: Optional[str] = None
|
||||||
|
bottom_clothing_url: Optional[str] = None
|
||||||
Loading…
Reference in New Issue
Block a user