update /api/events/<int:event_id>/stocks resp format

This commit is contained in:
2025-10-23 08:18:13 +08:00
parent 0a28f235d3
commit 0b1591c3dd
22 changed files with 144 additions and 2317 deletions

81
app.py
View File

@@ -7475,12 +7475,18 @@ def add_event_comment(event_id):
@socketio.on('connect')
def handle_connect():
"""客户端连接事件"""
print(f'\n[WebSocket DEBUG] ========== 客户端连接 ==========')
print(f'[WebSocket DEBUG] Socket ID: {request.sid}')
print(f'[WebSocket DEBUG] Remote Address: {request.remote_addr if hasattr(request, "remote_addr") else "N/A"}')
print(f'[WebSocket] 客户端已连接: {request.sid}')
emit('connection_response', {
'status': 'connected',
'sid': request.sid,
'message': '已连接到事件推送服务'
})
print(f'[WebSocket DEBUG] ✓ 已发送 connection_response')
print(f'[WebSocket DEBUG] ========== 连接完成 ==========\n')
@socketio.on('subscribe_events')
@@ -7494,25 +7500,40 @@ def handle_subscribe(data):
}
"""
try:
print(f'\n[WebSocket DEBUG] ========== 收到订阅请求 ==========')
print(f'[WebSocket DEBUG] Socket ID: {request.sid}')
print(f'[WebSocket DEBUG] 订阅数据: {data}')
event_type = data.get('event_type', 'all')
importance = data.get('importance', 'all')
print(f'[WebSocket DEBUG] 事件类型: {event_type}')
print(f'[WebSocket DEBUG] 重要性: {importance}')
# 加入对应的房间
room_name = f"events_{event_type}"
print(f'[WebSocket DEBUG] 准备加入房间: {room_name}')
join_room(room_name)
print(f'[WebSocket DEBUG] ✓ 已加入房间: {room_name}')
print(f'[WebSocket] 客户端 {request.sid} 订阅了房间: {room_name}')
emit('subscription_confirmed', {
response_data = {
'success': True,
'room': room_name,
'event_type': event_type,
'importance': importance,
'message': f'已订阅 {event_type} 类型的事件推送'
})
}
print(f'[WebSocket DEBUG] 准备发送 subscription_confirmed: {response_data}')
emit('subscription_confirmed', response_data)
print(f'[WebSocket DEBUG] ✓ 已发送 subscription_confirmed')
print(f'[WebSocket DEBUG] ========== 订阅完成 ==========\n')
except Exception as e:
print(f'[WebSocket] 订阅失败: {e}')
print(f'[WebSocket ERROR] 订阅失败: {e}')
import traceback
traceback.print_exc()
emit('subscription_error', {
'success': False,
'error': str(e)
@@ -7523,9 +7544,16 @@ def handle_subscribe(data):
def handle_unsubscribe(data):
"""取消订阅事件推送"""
try:
print(f'\n[WebSocket DEBUG] ========== 收到取消订阅请求 ==========')
print(f'[WebSocket DEBUG] Socket ID: {request.sid}')
print(f'[WebSocket DEBUG] 数据: {data}')
event_type = data.get('event_type', 'all')
room_name = f"events_{event_type}"
print(f'[WebSocket DEBUG] 准备离开房间: {room_name}')
leave_room(room_name)
print(f'[WebSocket DEBUG] ✓ 已离开房间: {room_name}')
print(f'[WebSocket] 客户端 {request.sid} 取消订阅房间: {room_name}')
@@ -7534,9 +7562,12 @@ def handle_unsubscribe(data):
'room': room_name,
'message': f'已取消订阅 {event_type} 类型的事件推送'
})
print(f'[WebSocket DEBUG] ========== 取消订阅完成 ==========\n')
except Exception as e:
print(f'[WebSocket] 取消订阅失败: {e}')
print(f'[WebSocket ERROR] 取消订阅失败: {e}')
import traceback
traceback.print_exc()
emit('unsubscription_error', {
'success': False,
'error': str(e)
@@ -7546,7 +7577,10 @@ def handle_unsubscribe(data):
@socketio.on('disconnect')
def handle_disconnect():
"""客户端断开连接事件"""
print(f'\n[WebSocket DEBUG] ========== 客户端断开 ==========')
print(f'[WebSocket DEBUG] Socket ID: {request.sid}')
print(f'[WebSocket] 客户端已断开: {request.sid}')
print(f'[WebSocket DEBUG] ========== 断开完成 ==========\n')
# ==================== WebSocket 辅助函数 ====================
@@ -7560,6 +7594,12 @@ def broadcast_new_event(event):
event: Event 模型实例
"""
try:
print(f'\n[WebSocket DEBUG] ========== 广播新事件 ==========')
print(f'[WebSocket DEBUG] 事件ID: {event.id}')
print(f'[WebSocket DEBUG] 事件标题: {event.title}')
print(f'[WebSocket DEBUG] 事件类型: {event.event_type}')
print(f'[WebSocket DEBUG] 重要性: {event.importance}')
event_data = {
'id': event.id,
'title': event.title,
@@ -7575,19 +7615,29 @@ def broadcast_new_event(event):
'keywords': event.keywords_list if hasattr(event, 'keywords_list') else event.keywords,
}
print(f'[WebSocket DEBUG] 准备发送的数据: {event_data}')
# 发送到所有订阅者all 房间)
print(f'[WebSocket DEBUG] 正在发送到房间: events_all')
socketio.emit('new_event', event_data, room='events_all', namespace='/')
print(f'[WebSocket DEBUG] ✓ 已发送到 events_all')
# 发送到特定类型订阅者
if event.event_type:
room_name = f"events_{event.event_type}"
print(f'[WebSocket DEBUG] 正在发送到房间: {room_name}')
socketio.emit('new_event', event_data, room=room_name, namespace='/')
print(f'[WebSocket DEBUG] ✓ 已发送到 {room_name}')
print(f'[WebSocket] 已推送新事件到房间: events_all, {room_name}')
else:
print(f'[WebSocket] 已推送新事件到房间: events_all')
print(f'[WebSocket DEBUG] ========== 广播完成 ==========\n')
except Exception as e:
print(f'[WebSocket] 推送新事件失败: {e}')
print(f'[WebSocket ERROR] 推送新事件失败: {e}')
import traceback
traceback.print_exc()
# ==================== WebSocket 轮询机制(检测新事件) ====================
@@ -7615,6 +7665,10 @@ def poll_new_events():
from datetime import datetime, timedelta
current_time = datetime.now()
print(f'\n[轮询 DEBUG] ========== 开始轮询 ==========')
print(f'[轮询 DEBUG] 当前时间: {current_time.strftime("%Y-%m-%d %H:%M:%S")}')
print(f'[轮询 DEBUG] 上次检查时间: {last_checked_time.strftime("%Y-%m-%d %H:%M:%S") if last_checked_time else "None"}')
print(f'[轮询 DEBUG] 已推送事件数量: {len(pushed_event_ids)}')
# 如果是第一次运行,只查询最近 30 秒的事件
if last_checked_time is None:
@@ -7623,6 +7677,8 @@ def poll_new_events():
# 向前多查 60 秒(重叠窗口),防止漏掉延迟写入的事件
query_start_time = last_checked_time - timedelta(seconds=60)
print(f'[轮询 DEBUG] 查询时间范围: {query_start_time.strftime("%Y-%m-%d %H:%M:%S")} ~ {current_time.strftime("%Y-%m-%d %H:%M:%S")}')
# 查询时间范围内的新事件
new_events = Event.query.filter(
Event.created_at >= query_start_time,
@@ -7630,16 +7686,24 @@ def poll_new_events():
Event.status == 'active'
).order_by(Event.created_at.asc()).all()
print(f'[轮询 DEBUG] 数据库查询结果: 找到 {len(new_events)} 个事件')
if new_events:
for evt in new_events:
print(f'[轮询 DEBUG] - ID={evt.id}, 标题={evt.title}, 创建时间={evt.created_at}, 已推送={evt.id in pushed_event_ids}')
# 过滤掉已经推送过的事件
unpushed_events = [
event for event in new_events
if event.id not in pushed_event_ids
]
print(f'[轮询 DEBUG] 过滤后未推送事件: {len(unpushed_events)}')
if unpushed_events:
print(f'[轮询] 发现 {len(unpushed_events)} 个新事件(查询到 {len(new_events)} 个,已过滤 {len(new_events) - len(unpushed_events)} 个重复)')
for event in unpushed_events:
print(f'[轮询 DEBUG] 准备推送事件: ID={event.id}, 标题={event.title}')
# 推送新事件
broadcast_new_event(event)
# 记录已推送
@@ -7657,11 +7721,16 @@ def poll_new_events():
print(f'[轮询] 已清理推送记录,当前保留 {len(pushed_event_ids)}')
else:
print(f'[轮询 DEBUG] 没有新事件需要推送')
# 没有新事件,也要更新检查时间
last_checked_time = current_time
print(f'[轮询 DEBUG] ========== 轮询结束 ==========\n')
except Exception as e:
print(f'[轮询] 检查新事件时出错: {e}')
print(f'[轮询 ERROR] 检查新事件时出错: {e}')
import traceback
traceback.print_exc()
def initialize_event_polling():