添加令牌验证和推荐系统接口
Change-Id: I2d318c167683a5106ced96047ab9f39b33b75bd1
diff --git a/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc b/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc
index 29c786d..75ccdab 100644
--- a/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc
+++ b/Merge/back_rhj/app/blueprints/__pycache__/recommend.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc b/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc
new file mode 100644
index 0000000..ae84b70
--- /dev/null
+++ b/Merge/back_rhj/app/blueprints/__pycache__/scheduler.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_rhj/app/blueprints/scheduler.py b/Merge/back_rhj/app/blueprints/scheduler.py
new file mode 100644
index 0000000..038f8f4
--- /dev/null
+++ b/Merge/back_rhj/app/blueprints/scheduler.py
@@ -0,0 +1,165 @@
+"""
+定时任务管理API蓝图
+提供定时任务的启动、停止、状态查询等接口
+"""
+from flask import Blueprint, jsonify, request, current_app
+from functools import wraps
+
+scheduler_bp = Blueprint('scheduler', __name__, url_prefix='/api/scheduler')
+
+def admin_required(f):
+ """装饰器:需要管理员权限"""
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ # 这里可以添加管理员权限验证逻辑
+ # 暂时允许所有请求通过
+ return f(*args, **kwargs)
+ return decorated
+
+@scheduler_bp.route('/status', methods=['GET'])
+def get_scheduler_status():
+ """获取定时任务状态"""
+ try:
+ scheduler_manager = current_app.scheduler_manager
+ status = scheduler_manager.get_task_status()
+
+ return jsonify({
+ 'success': True,
+ 'data': status,
+ 'message': '获取定时任务状态成功'
+ })
+ except Exception as e:
+ return jsonify({
+ 'success': False,
+ 'message': f'获取定时任务状态失败: {str(e)}'
+ }), 500
+
+@scheduler_bp.route('/start', methods=['POST'])
+@admin_required
+def start_scheduler():
+ """启动定时任务"""
+ try:
+ data = request.get_json() or {}
+ interval_minutes = data.get('interval_minutes', 1)
+
+ # 验证间隔时间
+ if not isinstance(interval_minutes, (int, float)) or interval_minutes <= 0:
+ return jsonify({
+ 'success': False,
+ 'message': '无效的间隔时间,必须是大于0的数字'
+ }), 400
+
+ scheduler_manager = current_app.scheduler_manager
+ scheduler_manager.start_graph_rebuild_task(interval_minutes)
+
+ return jsonify({
+ 'success': True,
+ 'message': f'定时任务已启动,间隔: {interval_minutes}分钟'
+ })
+ except Exception as e:
+ return jsonify({
+ 'success': False,
+ 'message': f'启动定时任务失败: {str(e)}'
+ }), 500
+
+@scheduler_bp.route('/stop', methods=['POST'])
+@admin_required
+def stop_scheduler():
+ """停止定时任务"""
+ try:
+ scheduler_manager = current_app.scheduler_manager
+ scheduler_manager.stop_graph_rebuild_task()
+
+ return jsonify({
+ 'success': True,
+ 'message': '定时任务已停止'
+ })
+ except Exception as e:
+ return jsonify({
+ 'success': False,
+ 'message': f'停止定时任务失败: {str(e)}'
+ }), 500
+
+@scheduler_bp.route('/update-interval', methods=['POST'])
+@admin_required
+def update_interval():
+ """更新任务间隔"""
+ try:
+ data = request.get_json()
+ if not data or 'interval_minutes' not in data:
+ return jsonify({
+ 'success': False,
+ 'message': '缺少interval_minutes参数'
+ }), 400
+
+ interval_minutes = data['interval_minutes']
+
+ # 验证间隔时间
+ if not isinstance(interval_minutes, (int, float)) or interval_minutes <= 0:
+ return jsonify({
+ 'success': False,
+ 'message': '无效的间隔时间,必须是大于0的数字'
+ }), 400
+
+ scheduler_manager = current_app.scheduler_manager
+ scheduler_manager.update_task_interval(interval_minutes)
+
+ return jsonify({
+ 'success': True,
+ 'message': f'任务间隔已更新为 {interval_minutes}分钟'
+ })
+ except Exception as e:
+ return jsonify({
+ 'success': False,
+ 'message': f'更新任务间隔失败: {str(e)}'
+ }), 500
+
+@scheduler_bp.route('/rebuild-now', methods=['POST'])
+@admin_required
+def rebuild_graph_now():
+ """立即执行一次图重建"""
+ try:
+ scheduler_manager = current_app.scheduler_manager
+
+ # 在新线程中执行,避免阻塞请求
+ import threading
+ thread = threading.Thread(target=scheduler_manager.rebuild_graph_job)
+ thread.start()
+
+ return jsonify({
+ 'success': True,
+ 'message': '图重建任务已开始执行'
+ })
+ except Exception as e:
+ return jsonify({
+ 'success': False,
+ 'message': f'执行图重建失败: {str(e)}'
+ }), 500
+
+@scheduler_bp.route('/logs', methods=['GET'])
+def get_rebuild_logs():
+ """获取重建日志统计"""
+ try:
+ scheduler_manager = current_app.scheduler_manager
+ status = scheduler_manager.get_task_status()
+
+ log_info = {
+ 'rebuild_count': status['rebuild_count'],
+ 'error_count': status['error_count'],
+ 'last_rebuild_time': status['last_rebuild_time'],
+ 'success_rate': (
+ ((status['rebuild_count'] - status['error_count']) / status['rebuild_count'] * 100)
+ if status['rebuild_count'] > 0 else 0
+ )
+ }
+
+ return jsonify({
+ 'success': True,
+ 'data': log_info,
+ 'message': '获取重建日志成功'
+ })
+ except Exception as e:
+ return jsonify({
+ 'success': False,
+ 'message': f'获取重建日志失败: {str(e)}'
+ }), 500