blob: 038f8f490e2e77d56ae0c4426948221d85eca635 [file] [log] [blame]
Raverb48556a2025-06-18 22:55:03 +08001"""
2定时任务管理API蓝图
3提供定时任务的启动、停止、状态查询等接口
4"""
5from flask import Blueprint, jsonify, request, current_app
6from functools import wraps
7
8scheduler_bp = Blueprint('scheduler', __name__, url_prefix='/api/scheduler')
9
10def admin_required(f):
11 """装饰器:需要管理员权限"""
12 @wraps(f)
13 def decorated(*args, **kwargs):
14 # 这里可以添加管理员权限验证逻辑
15 # 暂时允许所有请求通过
16 return f(*args, **kwargs)
17 return decorated
18
19@scheduler_bp.route('/status', methods=['GET'])
20def get_scheduler_status():
21 """获取定时任务状态"""
22 try:
23 scheduler_manager = current_app.scheduler_manager
24 status = scheduler_manager.get_task_status()
25
26 return jsonify({
27 'success': True,
28 'data': status,
29 'message': '获取定时任务状态成功'
30 })
31 except Exception as e:
32 return jsonify({
33 'success': False,
34 'message': f'获取定时任务状态失败: {str(e)}'
35 }), 500
36
37@scheduler_bp.route('/start', methods=['POST'])
38@admin_required
39def start_scheduler():
40 """启动定时任务"""
41 try:
42 data = request.get_json() or {}
43 interval_minutes = data.get('interval_minutes', 1)
44
45 # 验证间隔时间
46 if not isinstance(interval_minutes, (int, float)) or interval_minutes <= 0:
47 return jsonify({
48 'success': False,
49 'message': '无效的间隔时间,必须是大于0的数字'
50 }), 400
51
52 scheduler_manager = current_app.scheduler_manager
53 scheduler_manager.start_graph_rebuild_task(interval_minutes)
54
55 return jsonify({
56 'success': True,
57 'message': f'定时任务已启动,间隔: {interval_minutes}分钟'
58 })
59 except Exception as e:
60 return jsonify({
61 'success': False,
62 'message': f'启动定时任务失败: {str(e)}'
63 }), 500
64
65@scheduler_bp.route('/stop', methods=['POST'])
66@admin_required
67def stop_scheduler():
68 """停止定时任务"""
69 try:
70 scheduler_manager = current_app.scheduler_manager
71 scheduler_manager.stop_graph_rebuild_task()
72
73 return jsonify({
74 'success': True,
75 'message': '定时任务已停止'
76 })
77 except Exception as e:
78 return jsonify({
79 'success': False,
80 'message': f'停止定时任务失败: {str(e)}'
81 }), 500
82
83@scheduler_bp.route('/update-interval', methods=['POST'])
84@admin_required
85def update_interval():
86 """更新任务间隔"""
87 try:
88 data = request.get_json()
89 if not data or 'interval_minutes' not in data:
90 return jsonify({
91 'success': False,
92 'message': '缺少interval_minutes参数'
93 }), 400
94
95 interval_minutes = data['interval_minutes']
96
97 # 验证间隔时间
98 if not isinstance(interval_minutes, (int, float)) or interval_minutes <= 0:
99 return jsonify({
100 'success': False,
101 'message': '无效的间隔时间,必须是大于0的数字'
102 }), 400
103
104 scheduler_manager = current_app.scheduler_manager
105 scheduler_manager.update_task_interval(interval_minutes)
106
107 return jsonify({
108 'success': True,
109 'message': f'任务间隔已更新为 {interval_minutes}分钟'
110 })
111 except Exception as e:
112 return jsonify({
113 'success': False,
114 'message': f'更新任务间隔失败: {str(e)}'
115 }), 500
116
117@scheduler_bp.route('/rebuild-now', methods=['POST'])
118@admin_required
119def rebuild_graph_now():
120 """立即执行一次图重建"""
121 try:
122 scheduler_manager = current_app.scheduler_manager
123
124 # 在新线程中执行,避免阻塞请求
125 import threading
126 thread = threading.Thread(target=scheduler_manager.rebuild_graph_job)
127 thread.start()
128
129 return jsonify({
130 'success': True,
131 'message': '图重建任务已开始执行'
132 })
133 except Exception as e:
134 return jsonify({
135 'success': False,
136 'message': f'执行图重建失败: {str(e)}'
137 }), 500
138
139@scheduler_bp.route('/logs', methods=['GET'])
140def get_rebuild_logs():
141 """获取重建日志统计"""
142 try:
143 scheduler_manager = current_app.scheduler_manager
144 status = scheduler_manager.get_task_status()
145
146 log_info = {
147 'rebuild_count': status['rebuild_count'],
148 'error_count': status['error_count'],
149 'last_rebuild_time': status['last_rebuild_time'],
150 'success_rate': (
151 ((status['rebuild_count'] - status['error_count']) / status['rebuild_count'] * 100)
152 if status['rebuild_count'] > 0 else 0
153 )
154 }
155
156 return jsonify({
157 'success': True,
158 'data': log_info,
159 'message': '获取重建日志成功'
160 })
161 except Exception as e:
162 return jsonify({
163 'success': False,
164 'message': f'获取重建日志失败: {str(e)}'
165 }), 500