个股论坛重做
This commit is contained in:
@@ -274,6 +274,17 @@ def api_error(message, code=400):
|
||||
}), code if code >= 400 else 400
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 在线成员 API
|
||||
# ============================================================
|
||||
|
||||
@community_bp.route('/members/online', methods=['GET'])
|
||||
def get_online_members_api():
|
||||
"""获取当前在线成员列表"""
|
||||
members = get_online_members()
|
||||
return api_response(members)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 用户管理员状态 API
|
||||
# ============================================================
|
||||
@@ -1371,6 +1382,28 @@ def es_search_proxy(index):
|
||||
# ============================================================
|
||||
# WebSocket 事件处理(需要在 app.py 中注册)
|
||||
# ============================================================
|
||||
# 在线用户管理
|
||||
# ============================================================
|
||||
|
||||
# 在线用户字典: {user_id: {sid: socket_id, username: str, avatar: str, connected_at: datetime}}
|
||||
online_users = {}
|
||||
# Socket ID 到用户 ID 的映射: {socket_id: user_id}
|
||||
sid_to_user = {}
|
||||
|
||||
|
||||
def get_online_members():
|
||||
"""获取当前在线用户列表"""
|
||||
return [
|
||||
{
|
||||
'userId': str(user_id),
|
||||
'username': info['username'],
|
||||
'avatar': info.get('avatar', ''),
|
||||
'isOnline': True,
|
||||
'connectedAt': info['connected_at'].isoformat() if info.get('connected_at') else None,
|
||||
}
|
||||
for user_id, info in online_users.items()
|
||||
]
|
||||
|
||||
|
||||
def register_community_socketio(socketio):
|
||||
"""
|
||||
@@ -1381,14 +1414,51 @@ def register_community_socketio(socketio):
|
||||
socketio_instance = socketio
|
||||
|
||||
from flask_socketio import join_room, leave_room, emit
|
||||
from flask import request
|
||||
|
||||
@socketio.on('connect', namespace='/community')
|
||||
def handle_connect():
|
||||
print('[Community Socket] Client connected')
|
||||
user_id = session.get('user_id')
|
||||
username = session.get('username', '匿名用户')
|
||||
avatar = session.get('avatar', '')
|
||||
sid = request.sid
|
||||
|
||||
if user_id:
|
||||
# 记录在线用户
|
||||
online_users[user_id] = {
|
||||
'sid': sid,
|
||||
'username': username,
|
||||
'avatar': avatar,
|
||||
'connected_at': datetime.utcnow()
|
||||
}
|
||||
sid_to_user[sid] = user_id
|
||||
|
||||
# 广播用户上线事件
|
||||
emit('MEMBER_ONLINE', {
|
||||
'userId': str(user_id),
|
||||
'username': username,
|
||||
'avatar': avatar,
|
||||
}, broadcast=True, include_self=False)
|
||||
|
||||
print(f'[Community Socket] User {username}({user_id}) connected, online: {len(online_users)}')
|
||||
else:
|
||||
print('[Community Socket] Anonymous client connected')
|
||||
|
||||
@socketio.on('disconnect', namespace='/community')
|
||||
def handle_disconnect():
|
||||
print('[Community Socket] Client disconnected')
|
||||
sid = request.sid
|
||||
user_id = sid_to_user.pop(sid, None)
|
||||
|
||||
if user_id and user_id in online_users:
|
||||
username = online_users[user_id].get('username', '匿名')
|
||||
del online_users[user_id]
|
||||
|
||||
# 广播用户下线事件
|
||||
emit('MEMBER_OFFLINE', {
|
||||
'userId': str(user_id),
|
||||
}, broadcast=True)
|
||||
|
||||
print(f'[Community Socket] User {username}({user_id}) disconnected, online: {len(online_users)}')
|
||||
|
||||
@socketio.on('SUBSCRIBE_CHANNEL', namespace='/community')
|
||||
def handle_subscribe(data):
|
||||
|
||||
Reference in New Issue
Block a user