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:
116
core/websocket_client.py
Normal file → Executable file
116
core/websocket_client.py
Normal file → Executable file
@@ -95,6 +95,15 @@ class QingjianAPIClient:
|
||||
self._pending_images: dict = {}
|
||||
self._pending_image_tasks: dict = {}
|
||||
|
||||
# 延迟加载任务模块(避免循环导入)
|
||||
self.task_scheduler = None
|
||||
self.task_manager = None
|
||||
self.trigger_engine = None
|
||||
|
||||
# 多进程分片支持
|
||||
self.shard_keys: set = set() # 本进程负责的客户 key 集合
|
||||
self.worker_id = int(os.getenv('AI_CS_WORKER_ID', '0'))
|
||||
|
||||
# 初始化 Agent
|
||||
if self.enable_agent:
|
||||
try:
|
||||
@@ -108,6 +117,7 @@ class QingjianAPIClient:
|
||||
if workflow:
|
||||
workflow.register_send_callback(self._workflow_send)
|
||||
workflow.register_agent_notify_callback(self._workflow_agent_notify)
|
||||
|
||||
|
||||
async def connect(self):
|
||||
"""连接WebSocket服务器"""
|
||||
@@ -190,11 +200,18 @@ class QingjianAPIClient:
|
||||
|
||||
async def handle_message(self, message):
|
||||
"""处理接收到的消息"""
|
||||
timestamp = self.get_time()
|
||||
|
||||
try:
|
||||
data = json.loads(message)
|
||||
|
||||
# 多进程分片检查:只处理分配给本进程的客户
|
||||
if self.shard_keys:
|
||||
customer_key = self._customer_key(data)
|
||||
if customer_key not in self.shard_keys:
|
||||
# 不属于本进程的客户,跳过
|
||||
return
|
||||
|
||||
timestamp = self.get_time()
|
||||
|
||||
# 保存最后一条消息用于回复
|
||||
self.last_msg = data
|
||||
|
||||
@@ -517,7 +534,7 @@ class QingjianAPIClient:
|
||||
urls = self._extract_image_urls(msg_text)
|
||||
key = self._customer_key(data)
|
||||
self._add_pending_images(key, urls)
|
||||
await self.send_reply(data, "图片收到了,说下要求(尺寸/要做什么)")
|
||||
await self.send_reply(data, "收到,我看看哈")
|
||||
old = self._pending_image_tasks.get(key)
|
||||
if old and not old.done():
|
||||
old.cancel()
|
||||
@@ -546,7 +563,7 @@ class QingjianAPIClient:
|
||||
if len(urls) == 1:
|
||||
key = self._customer_key(data)
|
||||
self._add_pending_images(key, urls)
|
||||
await self.send_reply(data, "图片收到了,说下要求(尺寸/要做什么)")
|
||||
await self.send_reply(data, "收到,我看看哈")
|
||||
else:
|
||||
if self._msg_requests_external_contact(msg_text):
|
||||
reply = "这里沟通就可以哦,其他联系方式不方便"
|
||||
@@ -1303,3 +1320,94 @@ if __name__ == "__main__":
|
||||
asyncio.run(client.run())
|
||||
except KeyboardInterrupt:
|
||||
print("\n已停止")
|
||||
|
||||
|
||||
async def _load_task_modules(self):
|
||||
"""延迟加载任务模块,避免循环导入"""
|
||||
from core.task_scheduler import get_task_scheduler
|
||||
from core.task_trigger import get_trigger_engine
|
||||
from db.task_db.task_model import get_task_manager
|
||||
self.trigger_engine = get_trigger_engine()
|
||||
|
||||
async def check_and_trigger_tasks(self, data: dict):
|
||||
"""检查并触发匹配的任务"""
|
||||
try:
|
||||
customer_key = self._customer_key(data)
|
||||
customer_id = data.get('from_id')
|
||||
message = data.get('content', '')
|
||||
|
||||
# 获取该客户的待触发任务
|
||||
pending_tasks = self.task_manager.get_pending_tasks(customer_id)
|
||||
|
||||
for task in pending_tasks:
|
||||
trigger = {
|
||||
'type': task['trigger_type'],
|
||||
'keyword': task['trigger_keyword'],
|
||||
'keywords': task['trigger_keywords']
|
||||
}
|
||||
|
||||
# 检查是否匹配触发条件
|
||||
if self.task_scheduler.check_trigger_match(message, trigger):
|
||||
logger.info(f"任务触发条件匹配:{task['task_id']}")
|
||||
|
||||
# 异步执行任务
|
||||
asyncio.create_task(self.task_scheduler.execute_task(task))
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"检查任务触发失败:{e}")
|
||||
|
||||
|
||||
async def _load_task_modules(self):
|
||||
"""延迟加载任务模块,避免循环导入"""
|
||||
from core.task_scheduler import get_task_scheduler
|
||||
from core.task_trigger import get_trigger_engine
|
||||
from db.task_db.task_model import get_task_manager
|
||||
self.trigger_engine = get_trigger_engine()
|
||||
|
||||
async def _load_task_modules(self):
|
||||
"""延迟加载任务模块"""
|
||||
if self.task_scheduler is None:
|
||||
from core.task_scheduler import get_task_scheduler
|
||||
from core.task_trigger import get_trigger_engine
|
||||
from db.task_db.task_model import get_task_manager
|
||||
self.trigger_engine = get_trigger_engine()
|
||||
|
||||
async def check_and_trigger_tasks_v2(self, data: dict):
|
||||
"""增强版:检查并触发匹配的任务(支持指定客户)"""
|
||||
# 确保任务模块已加载
|
||||
await self._load_task_modules()
|
||||
try:
|
||||
customer_key = self._customer_key(data)
|
||||
customer_id = data.get('from_id')
|
||||
customer_name = data.get('from_name')
|
||||
message = data.get('content', '')
|
||||
|
||||
# 准备上下文
|
||||
context = {
|
||||
'customer_id': customer_id,
|
||||
'customer_name': customer_name,
|
||||
'acc_id': data.get('acc_id')
|
||||
}
|
||||
|
||||
# 获取该客户的待触发任务
|
||||
pending_tasks = self.task_manager.get_pending_tasks(customer_id)
|
||||
|
||||
for task in pending_tasks:
|
||||
trigger = {
|
||||
'type': task['trigger_type'],
|
||||
'keyword': task['trigger_keyword'],
|
||||
'keywords': task['trigger_keywords'],
|
||||
# 指定客户相关字段
|
||||
'customer_id': task.get('specified_customer_id'),
|
||||
'customer_name': task.get('specified_customer_name')
|
||||
}
|
||||
|
||||
# 使用触发引擎检查是否匹配
|
||||
if self.trigger_engine.check_trigger(message, trigger, context):
|
||||
logger.info(f"任务触发条件匹配:{task['task_id']} (客户:{customer_name}/{customer_id})")
|
||||
|
||||
# 异步执行任务
|
||||
asyncio.create_task(self.task_scheduler.execute_task(task))
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"检查任务触发失败:{e}")
|
||||
|
||||
Reference in New Issue
Block a user