Files
param-auto-manager/routes/tasks.py
T
hz4th_coder 6534c3315b feat: 新增后台任务系统,支持抓取任务在后台持续运行
- 新增后台任务API (/api/tasks)
- 抓取任务在后台独立运行,不受页面刷新影响
- 支持任务状态查询和手动停止
- 新增后台任务管理界面
- 数据库新增 background_tasks 表
- 前端使用轮询方式更新任务进度
2026-07-14 10:59:18 +08:00

178 lines
4.3 KiB
Python

"""
后台任务 API 路由
"""
from flask import Blueprint, jsonify, request
from services.task_service import task_service
from models.database import db
import logging
logger = logging.getLogger('tasks_api')
bp = Blueprint('tasks', __name__, url_prefix='/api/tasks')
@bp.route('/start', methods=['POST'])
def start_task():
"""
启动后台抓取任务
请求体:
{
"results": [{"title": "...", "url": "..."}, ...],
"auto_save": true,
"category": "AI模型",
"keywords": ["关键词1", "关键词2"]
}
"""
try:
data = request.get_json()
if not data or 'results' not in data:
return jsonify({
'success': False,
'error': '缺少 results 参数'
}), 400
results = data.get('results', [])
auto_save = data.get('auto_save', False)
category = data.get('category', '')
keywords = data.get('keywords', [])
if not results:
return jsonify({
'success': False,
'error': '结果列表为空'
}), 400
# 启动后台任务
task_id = task_service.start_fetch_task(
results=results,
auto_save=auto_save,
category=category,
keywords=keywords
)
return jsonify({
'success': True,
'task_id': task_id,
'message': f'任务已启动,共 {len(results)} 个URL'
})
except Exception as e:
logger.error(f"启动任务失败: {e}")
return jsonify({
'success': False,
'error': str(e)
}), 500
@bp.route('/<task_id>/status', methods=['GET'])
def get_task_status(task_id):
"""获取任务状态"""
task = task_service.get_task_status(task_id)
if not task:
return jsonify({
'success': False,
'error': '任务不存在'
}), 404
return jsonify({
'success': True,
'task': task
})
@bp.route('/<task_id>/stop', methods=['POST'])
def stop_task(task_id):
"""停止任务"""
task = db.get_task(task_id)
if not task:
return jsonify({
'success': False,
'error': '任务不存在'
}), 404
if task['status'] not in ('pending', 'running'):
return jsonify({
'success': False,
'error': '任务已完成或已停止'
}), 400
# 设置停止标志
if task_service.stop_task(task_id):
return jsonify({
'success': True,
'message': '已请求停止任务'
})
else:
return jsonify({
'success': False,
'error': '停止任务失败'
}), 500
@bp.route('/active', methods=['GET'])
def get_active_tasks():
"""获取活动任务列表"""
tasks = task_service.get_active_tasks()
return jsonify({
'success': True,
'tasks': tasks,
'count': len(tasks)
})
@bp.route('/recent', methods=['GET'])
def get_recent_tasks():
"""获取最近的任务"""
limit = request.args.get('limit', 20, type=int)
tasks = db.get_recent_tasks(limit)
return jsonify({
'success': True,
'tasks': tasks,
'count': len(tasks)
})
@bp.route('/<task_id>', methods=['DELETE'])
def delete_task(task_id):
"""删除任务记录"""
task = db.get_task(task_id)
if not task:
return jsonify({
'success': False,
'error': '任务不存在'
}), 404
if task['status'] in ('pending', 'running'):
return jsonify({
'success': False,
'error': '任务仍在运行,请先停止'
}), 400
if db.delete_task(task_id):
return jsonify({
'success': True,
'message': '任务已删除'
})
else:
return jsonify({
'success': False,
'error': '删除失败'
}), 500
@bp.route('/clear', methods=['POST'])
def clear_completed_tasks():
"""清理已完成的任务"""
count = db.clear_completed_tasks()
return jsonify({
'success': True,
'message': f'已清理 {count} 个任务'
})