From df0a9e7ea634a4162b118a00e2db9073a9560705 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Mon, 14 Apr 2025 14:16:45 +0800 Subject: [PATCH] update --- app/api/v1/tryon.py | 33 ++++++++++++ app/models/tryon.py | 2 + app/schemas/tryon.py | 2 + app/services/dashscope_service.py | 84 ++++++++++++++++++++++++++++++- 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/app/api/v1/tryon.py b/app/api/v1/tryon.py index 696dfb6..50a4565 100644 --- a/app/api/v1/tryon.py +++ b/app/api/v1/tryon.py @@ -178,3 +178,36 @@ async def check_tryon_status( return StandardResponse(code=200, message="", data=TryonHistoryModel.model_validate(tryon_history)) + + +@router.get("/comment", tags=["tryon"]) +async def comment_tryon( + history_id: int, + db: AsyncSession = Depends(deps.get_db) +): + """ + 穿搭点评 + """ + history = await db.execute(select(TryonHistory).where(TryonHistory.id == history_id)) + tryon_history = history.scalar_one_or_none() + if not tryon_history: + raise BusinessError(code=404, message="试穿历史不存在") + + if tryon_history.status != TryonStatus.COMPLETED: + raise BusinessError(code=400, message="试穿未完成") + + if tryon_history.comment and tryon_history.score: + return StandardResponse(code=200, message="穿搭点评获取成功", data=TryonHistoryModel.model_validate(tryon_history)) + + dashscope_service = DashScopeService() + comment = await dashscope_service.generate_dressing_comment(tryon_history.completion_url) + + if comment.get("comment") and comment.get("score"): + logger.info(f"穿搭点评: {comment}") + tryon_history.comment = comment.get("comment") + tryon_history.score = comment.get("score") + await db.commit() + await db.refresh(tryon_history) + + return StandardResponse(code=200, message="穿搭点评获取成功", data=TryonHistoryModel.model_validate(tryon_history)) + diff --git a/app/models/tryon.py b/app/models/tryon.py index 1aa11cd..e78a5d3 100644 --- a/app/models/tryon.py +++ b/app/models/tryon.py @@ -24,6 +24,8 @@ class TryonHistory(Base): 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="状态") + comment = Column(String(500), nullable=True, comment="穿搭评价") + score = Column(Integer, nullable=True, comment="穿搭评分(满分100)") create_time = Column(DateTime, default=func.now(), comment="创建时间") update_time = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间") diff --git a/app/schemas/tryon.py b/app/schemas/tryon.py index f6040b3..02e77d4 100644 --- a/app/schemas/tryon.py +++ b/app/schemas/tryon.py @@ -21,5 +21,7 @@ class TryonHistoryModel(BaseModel): status: TryonStatus task_id: Optional[str] = None completion_url: Optional[str] = None + comment: Optional[str] = None + score: Optional[int] = None class Config: from_attributes = True diff --git a/app/services/dashscope_service.py b/app/services/dashscope_service.py index 6f5ae20..8130b16 100644 --- a/app/services/dashscope_service.py +++ b/app/services/dashscope_service.py @@ -6,7 +6,16 @@ from dashscope import Generation from typing import List, Dict, Any, Optional import asyncio import httpx +import json +import re from app.core.config import settings +# 导入 DashScope SDK +try: + from dashscope import MultiModalConversation + from dashscope.api_entities.dashscope_response import DashScopeAPIResponse +except ImportError: + logging.error("请安装 DashScope SDK: pip install dashscope") + raise logger = logging.getLogger(__name__) @@ -20,6 +29,8 @@ class DashScopeService: # 配置API URL self.image_synthesis_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/image-synthesis" + self.comment_url = "https://dashscope.aliyuncs.com/compatible-mode/v1" + async def chat_completion( self, messages: List[Dict[str, str]], @@ -268,4 +279,75 @@ class DashScopeService: raise Exception(error_msg) except Exception as e: logger.error(f"查询试穿任务状态出错: {str(e)}") - raise e \ No newline at end of file + raise e + + # 传入图片url,通过 DashScope 的 qwen-vl-plus 模型,生成穿搭点评 + async def generate_dressing_comment(self, image_url: str): + """ + 调用DashScope的qwen-vl-plus模型生成穿搭点评 + + Args: + image_url: 穿搭图片URL + + Returns: + Dict: 包含任务ID和请求ID的响应 + """ + try: + # 构建请求头 + headers = { + "Authorization": f"Bearer {self.api_key}", + "Content-Type": "application/json" + } + + # 构建请求数据 + messages = [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "你是一个穿搭点评师,请根据图片中的穿搭,给出穿搭点评,点评内容包括穿搭风格、穿搭亮点等。不超过 80字,并给出一个打分,满分100分。返回格式以json格式返回,返回内容包括:'comment': '穿搭点评', 'score': '打分'" + }, + { + "type": "image", + "image": image_url + } + ] + } + ] + + #使用Dashscope sdk 进行请求 + loop = asyncio.get_event_loop() + response = await loop.run_in_executor( + None, + lambda: dashscope.MultiModalConversation.call( + api_key=self.api_key, + model="qwen-vl-plus", + messages=messages, + result_format='json' + ) + ) + logger.info(f"穿搭点评API响应: {response.output.choices[0].message.content}") + + content = response.output.choices[0].message.content + + # 将内容转换为json + if isinstance(content, list) and len(content) > 0: + text_content = "" + for item in content: + if isinstance(item, dict) and 'text' in item: + text_content = item.get('text', '') + print(f"提取的文本内容: {text_content}") + # 只获取 ```json 和 ``` 之间的内容 + text_content = re.search(r'```json(.*)```', text_content, re.DOTALL).group(1) + + return json.loads(text_content) + else: + return None + else: + return None + + + except Exception as e: + logger.error(f"DashScope穿搭点评API调用出错: {str(e)}") + raise e