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:
2026-02-28 11:20:40 +08:00
parent 5aedf1665d
commit a6c42d505a
171 changed files with 7979 additions and 328 deletions

307
api/http_server.py Normal file
View File

@@ -0,0 +1,307 @@
# -*- coding: utf-8 -*-
"""
HTTP API 服务器
提供天网任务接收接口
"""
from flask import Flask, request, jsonify
import logging
from datetime import datetime
from db.task_db.task_model import get_task_manager, TaskStatus
from core.task_scheduler import get_task_scheduler
import asyncio
import threading
logger = logging.getLogger(__name__)
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False # 支持中文
task_manager = None
task_scheduler = None
def get_async_loop():
"""获取异步事件循环"""
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
return loop
def run_async(coro):
"""运行异步协程"""
loop = get_async_loop()
return loop.run_until_complete(coro)
@app.route('/api/task/receive', methods=['POST'])
def receive_task():
"""
接收天网下发的任务
Request Body:
{
"task_id": "TASK_20260226_001",
"type": "send_file_after_reply",
"customer": {
"name": "小明",
"id": "customer_123"
},
"trigger": {
"type": "customer_reply",
"keyword": "好的"
},
"action": {
"type": "send_file",
"file_url": "https://xxx.com/file.zip",
"message": "这是您要的文件"
},
"priority": "normal",
"timeout_hours": 24,
"created_by": "设计师 lz"
}
Response:
{
"code": 200,
"message": "任务接收成功",
"data": {
"task_id": "TASK_20260226_001",
"status": "pending"
}
}
"""
try:
data = request.get_json()
if not data:
return jsonify({
'code': 400,
'message': '请求体不能为空'
}), 400
# 验证必填字段
required_fields = ['task_id', 'type', 'customer', 'trigger', 'action']
for field in required_fields:
if field not in data:
return jsonify({
'code': 400,
'message': f'缺少必填字段:{field}'
}), 400
# 添加时间戳
data['created_at'] = datetime.now().isoformat()
data['status'] = 'pending'
# 保存到数据库
success = task_manager.add_task(data)
if success:
logger.info(f"任务接收成功:{data['task_id']}")
return jsonify({
'code': 200,
'message': '任务接收成功',
'data': {
'task_id': data['task_id'],
'status': 'pending'
}
})
else:
logger.error(f"任务保存失败:{data['task_id']}")
return jsonify({
'code': 500,
'message': '任务保存失败'
}), 500
except Exception as e:
logger.error(f"接收任务异常:{e}")
return jsonify({
'code': 500,
'message': f'服务器错误:{str(e)}'
}), 500
@app.route('/api/task/cancel', methods=['POST'])
def cancel_task():
"""
取消任务
Request Body:
{
"task_id": "TASK_20260226_001",
"reason": "客户已退款"
}
"""
try:
data = request.get_json()
task_id = data.get('task_id')
reason = data.get('reason')
if not task_id:
return jsonify({
'code': 400,
'message': '缺少 task_id'
}), 400
task_manager.cancel_task(task_id, reason)
logger.info(f"任务已取消:{task_id}")
return jsonify({
'code': 200,
'message': '任务已取消',
'data': {
'task_id': task_id,
'status': 'cancelled'
}
})
except Exception as e:
logger.error(f"取消任务异常:{e}")
return jsonify({
'code': 500,
'message': f'服务器错误:{str(e)}'
}), 500
@app.route('/api/task/status/<task_id>', methods=['GET'])
def get_task_status(task_id):
"""
查询任务状态
Response:
{
"code": 200,
"data": {
"task_id": "TASK_20260226_001",
"status": "pending",
"created_at": "2026-02-26 16:30:00",
"triggered_at": null,
"completed_at": null
}
}
"""
try:
task = task_manager.get_task(task_id)
if not task:
return jsonify({
'code': 404,
'message': '任务不存在'
}), 404
return jsonify({
'code': 200,
'data': {
'task_id': task['task_id'],
'type': task['type'],
'status': task['status'],
'priority': task['priority'],
'retry_count': task['retry_count'],
'created_at': task['created_at'],
'created_by': task['created_by'],
'triggered_at': task.get('triggered_at'),
'completed_at': task.get('completed_at'),
'error_message': task.get('error_message')
}
})
except Exception as e:
logger.error(f"查询任务状态异常:{e}")
return jsonify({
'code': 500,
'message': f'服务器错误:{str(e)}'
}), 500
@app.route('/api/task/list', methods=['GET'])
def list_tasks():
"""
查询任务列表
Query Params:
- customer_id: 客户 ID可选
- status: 任务状态(可选)
- page: 页码(默认 1
- page_size: 每页数量(默认 20
"""
try:
customer_id = request.args.get('customer_id')
status = request.args.get('status')
page = int(request.args.get('page', 1))
page_size = int(request.args.get('page_size', 20))
if status:
if status == 'pending':
tasks = task_manager.get_pending_tasks(customer_id)
else:
# TODO: 实现其他状态查询
tasks = []
else:
tasks = task_manager.get_pending_tasks(customer_id)
# 分页
total = len(tasks)
start = (page - 1) * page_size
end = start + page_size
tasks_page = tasks[start:end]
return jsonify({
'code': 200,
'data': {
'total': total,
'page': page,
'page_size': page_size,
'tasks': tasks_page
}
})
except Exception as e:
logger.error(f"查询任务列表异常:{e}")
return jsonify({
'code': 500,
'message': f'服务器错误:{str(e)}'
}), 500
@app.route('/api/health', methods=['GET'])
def health_check():
"""健康检查"""
return jsonify({
'code': 200,
'message': 'OK',
'data': {
'timestamp': datetime.now().isoformat(),
'service': 'ai-cs-tianwang-bridge'
}
})
def start_http_server(host='0.0.0.0', port=6060, debug=False):
"""启动 HTTP 服务器"""
global task_manager, task_scheduler
task_manager = get_task_manager()
logger.info(f"HTTP API 服务器启动http://{host}:{port}")
# 在新线程中运行 Flask
thread = threading.Thread(
target=app.run,
kwargs={
'host': host,
'port': port,
'debug': debug,
'use_reloader': False
},
daemon=True
)
thread.start()
return thread
if __name__ == '__main__':
logging.basicConfig(
level=logging.INFO,
format='[%(asctime)s] %(levelname)s: %(message)s'
)
start_http_server(port=6060, debug=True)