Files
tw/core/websocket_quote_flow.py

129 lines
6.5 KiB
Python

import asyncio
import logging
logger = logging.getLogger("cs_agent")
async def handle_single_image_quote(client, data: dict, url: str):
try:
from image.image_analyzer import image_analyzer
result = await image_analyzer.analyze(url)
if isinstance(result, dict) and result.get("success", False):
if result.get("feasibility") == "no" or result.get("risk") == "high":
note = str(result.get("note", "") or "")
if "文字内容过于密集" in note or "密集文字" in note:
reply = "这类文字太密的图我们这边不接单,抱歉哈。你要是简化后再发我可以继续看。"
else:
reply = "这张处理风险比较高,我这边先不直接接,建议转人工评估更稳。"
await client.send_reply(data, reply)
return
from config.config import MIN_PRICE_FLOOR
price = result.get("price_suggest", 20)
floor_dyn = result.get("price_min", MIN_PRICE_FLOOR)
floor = max(MIN_PRICE_FLOOR, int(floor_dyn) if isinstance(floor_dyn, (int, float)) else MIN_PRICE_FLOOR)
price = max(floor, round(price / 5) * 5)
try:
from db.customer_db import db as _db
_db.update_last_min_price(data.get('from_id', ''), floor)
except Exception:
logger.debug("更新单图最低价失败", exc_info=True)
reply = f"这张按{price}元,满意再拍"
else:
# 识别失败时不做兜底报价,避免把未识别图片误判为可做
reply = "这张我这边暂时识别不稳定,先不乱报价。你可以换一张更清晰的,我再给你准报价。"
await client.send_reply(data, reply)
except Exception:
logger.exception("单图分析流程失败")
async def handle_multi_image_quote(client, data: dict, urls: list):
try:
from image.image_analyzer import image_analyzer
def _detect_composite_request() -> bool:
try:
from db.chat_log_db import get_recent_conversation
recent = get_recent_conversation(
customer_id=data.get('from_id', ''),
acc_id=data.get('acc_id', ''),
limit=8,
)
keywords = ("抓到", "放到", "合成", "融合", "嵌到", "换到", "替换", "P到", "抠出来放到")
for item in recent:
msg = (item.get("message") or "")
if any(k in msg for k in keywords):
return True
except Exception:
logger.debug("检测合成需求失败,按非合成处理", exc_info=True)
return False
tasks = [image_analyzer.analyze(u) for u in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
# 先做风险分流:多图中只要出现不可做/高风险,不进入报价
unsafe = []
dense_text_reject = []
for i, result in enumerate(results, 1):
if isinstance(result, dict) and result.get("success", False):
if result.get("feasibility") == "no" or result.get("risk") == "high":
unsafe.append(f"{i}")
note = str(result.get("note", "") or "")
if "文字内容过于密集" in note or "密集文字" in note:
dense_text_reject.append(f"{i}")
if unsafe:
if dense_text_reject and len(dense_text_reject) == len(unsafe):
reply = "这类文字太密的图我们这边不接单,抱歉哈。你要是简化后再发我可以继续看。"
else:
reply = f"这批里{''.join(unsafe)}处理风险较高,我这边先不直接接,建议转人工评估更稳。"
await client.send_reply(data, reply)
return
pairs = []
for u, result in zip(urls, results):
if isinstance(result, dict) and result.get("success", False):
from config.config import MIN_PRICE_FLOOR
floor_dyn = result.get("price_min", MIN_PRICE_FLOOR)
floor = max(MIN_PRICE_FLOOR, int(floor_dyn) if isinstance(floor_dyn, (int, float)) else MIN_PRICE_FLOOR)
price = max(floor, round(result.get("price_suggest", 20) / 5) * 5)
pairs.append((u, price, result.get("category", ""), result.get("megapixels", 0.0)))
try:
if pairs:
floors = []
for _u, result in zip(urls, results):
if isinstance(result, dict) and result.get("success", False):
from config.config import MIN_PRICE_FLOOR
floor_dyn = result.get("price_min", MIN_PRICE_FLOOR)
floor = max(MIN_PRICE_FLOOR, int(floor_dyn) if isinstance(floor_dyn, (int, float)) else MIN_PRICE_FLOOR)
floors.append(floor)
if floors:
from db.customer_db import db as _db
_db.update_last_min_price(data.get('from_id', ''), min(floors))
except Exception:
logger.debug("更新多图最低价失败", exc_info=True)
if not pairs:
await client.send_reply(data, "这组图我这边暂时识别不稳定,先不乱报价。你可以换清晰图再发我。")
return
composite = _detect_composite_request()
composite_fee = 5 if composite else 0
avg_raw = sum(p for _, p, _, _ in pairs) / len(pairs)
from config.config import MIN_PRICE_FLOOR
avg_price = max(MIN_PRICE_FLOOR, round((avg_raw + composite_fee) / 5) * 5)
top_price = max(MIN_PRICE_FLOOR, max(pairs, key=lambda x: x[1])[1] + composite_fee)
count = len(pairs)
if composite:
reply = f"这组{count}张我看了,按{avg_price}元一张;合成那张{top_price}元,满意再拍"
else:
reply = f"这组{count}张我看了,按{avg_price}元一张;复杂那张{top_price}元,满意再拍"
await client.send_reply(data, reply)
except Exception as e:
logger.error("多图分析失败: %s", e)
try:
await client.send_reply(data, "这组图我这边暂时识别异常,先不乱报价。你可以稍后再发我。")
except Exception:
logger.debug("多图分析失败后的兜底回复发送失败", exc_info=True)