feat: 完整功能部署 v1.0
新增功能: - 天网协作系统 (HTTP API 端口 6060) - 三种工作流 (查找图片/处理图片/转人工派单) - 图片任务数据库 (支持客户后续增加需求) - 图绘派单系统集成 (API: 8005) - 文字检测与加价 (60-80 元高价值订单) - 风险评估与接单判断 - 作图失败自动转人工 新增文档: - 项目功能汇总.md - 三种工作流功能说明.md - 文字加价功能说明.md - 风险评估功能说明.md - 图片任务数据库功能说明.md - 图绘派单系统集成说明.md - 作图失败转接人工说明.md - DEPLOYMENT.md - TIANWANG_INTEGRATION.md 核心修改: - core/pydantic_ai_agent.py - core/workflow.py - core/websocket_client.py - image/image_analyzer.py - services/service_tuhui_dispatch.py - db/image_tasks_db.py 版本:v1.0 日期:2026-02-28
This commit is contained in:
371
core/workflow.py
Normal file → Executable file
371
core/workflow.py
Normal file → Executable file
@@ -418,13 +418,13 @@ class CustomerServiceWorkflow:
|
||||
f"原因:{err_msg[:200]}\n"
|
||||
f"请人工跟进"
|
||||
)
|
||||
# 通知客户稍等,人工跟进
|
||||
# 通知客户稍等,并告知转人工
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=task.customer_id,
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type,
|
||||
content="您好,图片正在处理中,稍后发您,请稍等",
|
||||
content="您好,图片处理遇到点问题,已帮您转接人工客服处理,请稍候",
|
||||
msg_type=0,
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -614,3 +614,370 @@ class CustomerServiceWorkflow:
|
||||
|
||||
# ========== 全局实例 ==========
|
||||
workflow = CustomerServiceWorkflow()
|
||||
|
||||
# ========== 客户需求变更 ==========
|
||||
|
||||
async def add_customer_requirement(self, task_id: str, customer_id: str,
|
||||
requirement: str, changed_by: str = 'customer') -> bool:
|
||||
"""
|
||||
客户添加/修改需求细节
|
||||
|
||||
Args:
|
||||
task_id: 任务 ID
|
||||
customer_id: 客户 ID
|
||||
requirement: 需求内容(如:"需要去掉背景"、"要分层文件")
|
||||
changed_by: 修改者(customer/staff)
|
||||
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
# 检查任务是否存在
|
||||
task = self.get_task(task_id)
|
||||
if not task:
|
||||
# 尝试从数据库加载
|
||||
db_task = self.db.get_task(task_id)
|
||||
if db_task:
|
||||
print(f"[Workflow] 从数据库加载任务:{task_id[:8]}...")
|
||||
# 可以在这里重建内存任务
|
||||
else:
|
||||
print(f"[Workflow] 任务不存在:{task_id}")
|
||||
return False
|
||||
|
||||
# 添加到数据库
|
||||
success = self.db.add_customer_note(task_id, requirement, changed_by)
|
||||
|
||||
if success:
|
||||
print(f"[Workflow] 客户添加需求:{task_id[:8]}... | {requirement}")
|
||||
|
||||
# 如果任务还在待处理状态,通知 AI 客服
|
||||
if task and task.status.value == 'pending':
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=task.acc_id,
|
||||
acc_type=task.acc_type,
|
||||
content=f"好的,已记录您的需求:{requirement},处理时会注意的",
|
||||
msg_type=0,
|
||||
)
|
||||
|
||||
return success
|
||||
|
||||
async def modify_operation(self, task_id: str, customer_id: str,
|
||||
new_operation: str, changed_by: str = 'customer') -> bool:
|
||||
"""
|
||||
客户修改操作类型
|
||||
|
||||
Args:
|
||||
task_id: 任务 ID
|
||||
customer_id: 客户 ID
|
||||
new_operation: 新操作(enhance/remove_bg/vectorize 等)
|
||||
changed_by: 修改者
|
||||
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
task = self.get_task(task_id)
|
||||
if not task:
|
||||
db_task = self.db.get_task(task_id)
|
||||
if not db_task:
|
||||
print(f"[Workflow] 任务不存在:{task_id}")
|
||||
return False
|
||||
|
||||
# 检查状态,已处理完成的不允许修改
|
||||
if task and task.status.value in ['completed', 'processing']:
|
||||
print(f"[Workflow] 任务已开始处理,不允许修改操作:{task_id}")
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=task.acc_id,
|
||||
acc_type=task.acc_type,
|
||||
content="抱歉,图片已经开始处理了,无法修改操作类型",
|
||||
msg_type=0,
|
||||
)
|
||||
return False
|
||||
|
||||
# 修改数据库
|
||||
success = self.db.modify_operation(task_id, new_operation, changed_by)
|
||||
|
||||
if success and task:
|
||||
task.operation = new_operation
|
||||
print(f"[Workflow] 修改操作类型:{task_id[:8]}... -> {new_operation}")
|
||||
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=task.acc_id,
|
||||
acc_type=task.acc_type,
|
||||
content=f"好的,已为您修改为{new_operation}操作",
|
||||
msg_type=0,
|
||||
)
|
||||
|
||||
return success
|
||||
|
||||
def get_task_requirement_history(self, task_id: str) -> List[dict]:
|
||||
"""获取任务需求变更历史"""
|
||||
return self.db.get_requirement_history(task_id)
|
||||
|
||||
# ========== 三种工作流 ==========
|
||||
|
||||
async def find_image_workflow(self, customer_id: str, image_url: str,
|
||||
acc_id: str = "", acc_type: str = "AliWorkbench") -> bool:
|
||||
"""
|
||||
工作流 1:查找图片
|
||||
客户说"找一下这个图" → 自己处理 → 上传到图绘 → 返回 URL
|
||||
|
||||
Args:
|
||||
customer_id: 客户 ID
|
||||
image_url: 图片 URL
|
||||
acc_id: 店铺 ID
|
||||
acc_type: 平台类型
|
||||
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
try:
|
||||
print(f"[Workflow] 启动查找图片工作流 | 客户:{customer_id}")
|
||||
|
||||
# 1. 创建任务
|
||||
task_id = self.create_image_task(
|
||||
customer_id=customer_id,
|
||||
customer_name=customer_id,
|
||||
original_image=image_url,
|
||||
operation="find", # 查找操作
|
||||
requirements="type:find",
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type
|
||||
)
|
||||
|
||||
# 2. 这里调用图绘 API 上传图片
|
||||
# TODO: 调用图绘上传 API
|
||||
# tuhui_url = await self._upload_to_tuhui(image_url)
|
||||
|
||||
# 临时模拟
|
||||
tuhui_url = f"http://tuhui.cloud/works/123"
|
||||
|
||||
# 3. 更新任务结果
|
||||
self.db.update_result(task_id, tuhui_url)
|
||||
self.db.update_status(task_id, DBTaskStatus.COMPLETED)
|
||||
|
||||
# 4. 回复客户
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type,
|
||||
content=f"找到了!图片在这里:{tuhui_url}",
|
||||
msg_type=0,
|
||||
)
|
||||
|
||||
print(f"[Workflow] 查找图片完成 | 客户:{customer_id} | URL: {tuhui_url}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"查找图片工作流失败:{e}")
|
||||
return False
|
||||
|
||||
async def process_image_workflow(self, customer_id: str, image_url: str,
|
||||
acc_id: str = "", acc_type: str = "AliWorkbench") -> bool:
|
||||
"""
|
||||
工作流 2:处理图片
|
||||
客户说"做一下" → 评估图片 → 稍等做
|
||||
|
||||
Args:
|
||||
customer_id: 客户 ID
|
||||
image_url: 图片 URL
|
||||
acc_id: 店铺 ID
|
||||
acc_type: 平台类型
|
||||
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
try:
|
||||
print(f"[Workflow] 启动处理图片工作流 | 客户:{customer_id}")
|
||||
|
||||
# 1. 创建任务
|
||||
task_id = self.create_image_task(
|
||||
customer_id=customer_id,
|
||||
customer_name=customer_id,
|
||||
original_image=image_url,
|
||||
operation="enhance",
|
||||
requirements="type:process",
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type
|
||||
)
|
||||
|
||||
# 2. 回复客户稍等
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type,
|
||||
content="稍等,我看看...好的,可以做,马上处理",
|
||||
msg_type=0,
|
||||
)
|
||||
|
||||
# 3. 启动处理
|
||||
await self.trigger_processing_on_payment(customer_id, acc_id, acc_type)
|
||||
|
||||
print(f"[Workflow] 处理图片已启动 | 客户:{customer_id}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理图片工作流失败:{e}")
|
||||
return False
|
||||
|
||||
async def transfer_to_designer_workflow(self, customer_id: str, image_url: str,
|
||||
acc_id: str = "", acc_type: str = "AliWorkbench",
|
||||
reason: str = "做不了") -> bool:
|
||||
"""
|
||||
工作流 3:转人工派单
|
||||
做不了 → 查询企业微信在线设计师 → 派单
|
||||
|
||||
Args:
|
||||
customer_id: 客户 ID
|
||||
image_url: 图片 URL
|
||||
acc_id: 店铺 ID
|
||||
acc_type: 平台类型
|
||||
reason: 转接原因
|
||||
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
try:
|
||||
print(f"[Workflow] 启动转人工派单工作流 | 客户:{customer_id} | 原因:{reason}")
|
||||
|
||||
# 1. 创建任务
|
||||
task_id = self.create_image_task(
|
||||
customer_id=customer_id,
|
||||
customer_name=customer_id,
|
||||
original_image=image_url,
|
||||
operation="manual",
|
||||
requirements=f"type:transfer|reason:{reason}",
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type
|
||||
)
|
||||
|
||||
# 2. 查询企业微信在线设计师
|
||||
online_designers = await self._get_online_designers()
|
||||
|
||||
if not online_designers:
|
||||
# 无人在线,通知客户
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type,
|
||||
content="抱歉,现在设计师都不在线,稍后会有人联系您",
|
||||
msg_type=0,
|
||||
)
|
||||
|
||||
# 企业微信预警
|
||||
await _wechat_notify(
|
||||
f"⚠️ **人工派单但无人在线**\n"
|
||||
f"客户:{customer_id}\n"
|
||||
f"店铺:{acc_id}\n"
|
||||
f"原因:{reason}\n"
|
||||
f"请安排设计师上线"
|
||||
)
|
||||
|
||||
print(f"[Workflow] 无人在线 | 客户:{customer_id}")
|
||||
return False
|
||||
|
||||
# 3. 派单给在线设计师
|
||||
designer_name = online_designers[0] # 取第一个在线的
|
||||
success = await self._dispatch_to_designer(task_id, designer_name, customer_id, image_url, reason)
|
||||
|
||||
if not success:
|
||||
logger.error("派单失败")
|
||||
return False
|
||||
|
||||
# 4. 回复客户
|
||||
if self._send_message:
|
||||
await self._send_message(
|
||||
customer_id=customer_id,
|
||||
acc_id=acc_id,
|
||||
acc_type=acc_type,
|
||||
content="好的,已帮您安排设计师处理,请稍候",
|
||||
msg_type=0,
|
||||
)
|
||||
|
||||
print(f"[Workflow] 已派单给设计师:{designer} | 客户:{customer_id}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"转人工派单工作流失败:{e}")
|
||||
return False
|
||||
|
||||
async def _get_online_designers(self) -> list:
|
||||
"""
|
||||
查询在线设计师(使用图绘派单 API)
|
||||
|
||||
Returns:
|
||||
list: 在线设计师名单 ["橘子", "婷婷", ...]
|
||||
"""
|
||||
try:
|
||||
designers = await self.dispatch_client.get_online_designers()
|
||||
print(f"[Workflow] 查询在线设计师:{len(designers)}人在线 | {designers}")
|
||||
return designers
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"查询在线设计师失败:{e}")
|
||||
return []
|
||||
|
||||
async def _dispatch_to_designer(self, task_id: str, designer_name: str,
|
||||
customer_id: str, image_url: str, reason: str) -> bool:
|
||||
"""
|
||||
派单给设计师(使用图绘派单 API)
|
||||
|
||||
Args:
|
||||
task_id: 任务 ID
|
||||
designer_name: 设计师姓名
|
||||
customer_id: 客户 ID
|
||||
image_url: 图片 URL
|
||||
reason: 转接原因
|
||||
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
try:
|
||||
# 1. 在派单系统创建任务
|
||||
dispatch_task_id = await self.dispatch_client.create_task(
|
||||
task_name=f"图片处理-{customer_id[-4:]}",
|
||||
description=f"{reason}\n客户:{customer_id}\n图片:{image_url}",
|
||||
task_type="image_process",
|
||||
priority=2,
|
||||
deadline=None
|
||||
)
|
||||
|
||||
if not dispatch_task_id:
|
||||
logger.error("创建派单任务失败")
|
||||
return False
|
||||
|
||||
# 2. 分配给设计师
|
||||
success = await self.dispatch_client.assign_task(
|
||||
task_id=dispatch_task_id,
|
||||
designer_name=designer_name,
|
||||
notes=f"AI 客服自动派单\n原因:{reason}\n客户:{customer_id}"
|
||||
)
|
||||
|
||||
if success:
|
||||
print(f"[Workflow] 派单成功:{dispatch_task_id} → {designer_name} | 客户:{customer_id}")
|
||||
|
||||
# 企业微信通知
|
||||
await _wechat_notify(
|
||||
f"📋 **新任务派单**\n"
|
||||
f"设计师:{designer_name}\n"
|
||||
f"任务 ID: {dispatch_task_id}\n"
|
||||
f"客户:{customer_id}\n"
|
||||
f"原因:{reason}\n"
|
||||
f"请及时处理"
|
||||
)
|
||||
|
||||
return True
|
||||
else:
|
||||
logger.error("分配任务失败")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"派单失败:{e}")
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user