个股论坛重做
This commit is contained in:
250
community_api.py
250
community_api.py
@@ -136,6 +136,120 @@ def admin_required(permission=None):
|
||||
return decorator
|
||||
|
||||
|
||||
def get_channel_admin_info(channel_id, user_id):
|
||||
"""获取用户在指定频道的管理员信息"""
|
||||
# 先检查是否是超级管理员
|
||||
super_admin = get_user_admin_info(user_id)
|
||||
if super_admin and super_admin['isAdmin']:
|
||||
return {
|
||||
'role': 'super_admin',
|
||||
'isSuperAdmin': True,
|
||||
'isOwner': True,
|
||||
'isAdmin': True,
|
||||
'isModerator': True,
|
||||
'permissions': {
|
||||
'delete_channel': True,
|
||||
'edit_channel': True,
|
||||
'manage_admins': True,
|
||||
'pin_messages': True,
|
||||
'delete_messages': True,
|
||||
'slow_mode': True,
|
||||
'lock_channel': True
|
||||
}
|
||||
}
|
||||
|
||||
# 检查频道管理员
|
||||
try:
|
||||
with get_db_engine().connect() as conn:
|
||||
sql = text("""
|
||||
SELECT role, permissions
|
||||
FROM community_channel_admins
|
||||
WHERE channel_id = :channel_id AND user_id = :user_id
|
||||
""")
|
||||
result = conn.execute(sql, {
|
||||
'channel_id': channel_id,
|
||||
'user_id': int(user_id)
|
||||
}).fetchone()
|
||||
|
||||
if result:
|
||||
import json
|
||||
permissions = result.permissions
|
||||
if isinstance(permissions, str):
|
||||
permissions = json.loads(permissions)
|
||||
|
||||
role = result.role
|
||||
return {
|
||||
'role': role,
|
||||
'isSuperAdmin': False,
|
||||
'isOwner': role == 'owner',
|
||||
'isAdmin': role in ['owner', 'admin'],
|
||||
'isModerator': role in ['owner', 'admin', 'moderator'],
|
||||
'permissions': permissions or {}
|
||||
}
|
||||
except Exception as e:
|
||||
print(f"[Community API] 获取频道管理员信息失败: {e}")
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def check_channel_permission(channel_id, user_id, permission):
|
||||
"""检查用户是否有指定频道的权限"""
|
||||
admin_info = get_channel_admin_info(channel_id, user_id)
|
||||
if not admin_info:
|
||||
return False
|
||||
if admin_info['isSuperAdmin'] or admin_info['isOwner']:
|
||||
return True
|
||||
return admin_info['permissions'].get(permission, False)
|
||||
|
||||
|
||||
def add_channel_admin(channel_id, user_id, role='owner'):
|
||||
"""添加频道管理员"""
|
||||
try:
|
||||
with get_db_engine().connect() as conn:
|
||||
# 根据角色设置默认权限
|
||||
permissions = {}
|
||||
if role == 'owner':
|
||||
permissions = {
|
||||
'delete_channel': True,
|
||||
'edit_channel': True,
|
||||
'manage_admins': True,
|
||||
'pin_messages': True,
|
||||
'delete_messages': True,
|
||||
'slow_mode': True,
|
||||
'lock_channel': True
|
||||
}
|
||||
elif role == 'admin':
|
||||
permissions = {
|
||||
'edit_channel': True,
|
||||
'pin_messages': True,
|
||||
'delete_messages': True,
|
||||
'slow_mode': True
|
||||
}
|
||||
elif role == 'moderator':
|
||||
permissions = {
|
||||
'pin_messages': True,
|
||||
'delete_messages': True
|
||||
}
|
||||
|
||||
import json
|
||||
sql = text("""
|
||||
INSERT INTO community_channel_admins (channel_id, user_id, role, permissions)
|
||||
VALUES (:channel_id, :user_id, :role, :permissions)
|
||||
ON DUPLICATE KEY UPDATE role = :role, permissions = :permissions
|
||||
""")
|
||||
conn.execute(sql, {
|
||||
'channel_id': channel_id,
|
||||
'user_id': int(user_id),
|
||||
'role': role,
|
||||
'permissions': json.dumps(permissions)
|
||||
})
|
||||
conn.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"[Community API] 添加频道管理员失败: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def api_response(data=None, message='success', code=200):
|
||||
"""统一 API 响应格式"""
|
||||
return jsonify({
|
||||
@@ -180,6 +294,136 @@ def get_my_admin_status():
|
||||
})
|
||||
|
||||
|
||||
@community_bp.route('/channels/<channel_id>/admin-status', methods=['GET'])
|
||||
@login_required
|
||||
def get_channel_admin_status(channel_id):
|
||||
"""获取当前用户在指定频道的管理员状态"""
|
||||
user = g.current_user
|
||||
admin_info = get_channel_admin_info(channel_id, user['id'])
|
||||
|
||||
if admin_info:
|
||||
return api_response({
|
||||
'role': admin_info['role'],
|
||||
'isSuperAdmin': admin_info['isSuperAdmin'],
|
||||
'isOwner': admin_info['isOwner'],
|
||||
'isAdmin': admin_info['isAdmin'],
|
||||
'isModerator': admin_info['isModerator'],
|
||||
'permissions': admin_info['permissions']
|
||||
})
|
||||
else:
|
||||
return api_response({
|
||||
'role': None,
|
||||
'isSuperAdmin': False,
|
||||
'isOwner': False,
|
||||
'isAdmin': False,
|
||||
'isModerator': False,
|
||||
'permissions': {}
|
||||
})
|
||||
|
||||
|
||||
@community_bp.route('/channels/<channel_id>/admins', methods=['GET'])
|
||||
@login_required
|
||||
def get_channel_admins(channel_id):
|
||||
"""获取频道管理员列表"""
|
||||
try:
|
||||
with get_db_engine().connect() as conn:
|
||||
sql = text("""
|
||||
SELECT cca.user_id, cca.role, cca.permissions, cca.created_at,
|
||||
u.username, u.avatar
|
||||
FROM community_channel_admins cca
|
||||
LEFT JOIN users u ON cca.user_id = u.id
|
||||
WHERE cca.channel_id = :channel_id
|
||||
ORDER BY
|
||||
CASE cca.role
|
||||
WHEN 'owner' THEN 1
|
||||
WHEN 'admin' THEN 2
|
||||
WHEN 'moderator' THEN 3
|
||||
END
|
||||
""")
|
||||
result = conn.execute(sql, {'channel_id': channel_id}).fetchall()
|
||||
|
||||
admins = []
|
||||
for row in result:
|
||||
import json
|
||||
permissions = row.permissions
|
||||
if isinstance(permissions, str):
|
||||
permissions = json.loads(permissions)
|
||||
|
||||
admins.append({
|
||||
'userId': str(row.user_id),
|
||||
'username': row.username,
|
||||
'avatar': row.avatar,
|
||||
'role': row.role,
|
||||
'permissions': permissions or {},
|
||||
'createdAt': row.created_at.isoformat() if row.created_at else None
|
||||
})
|
||||
|
||||
return api_response(admins)
|
||||
|
||||
except Exception as e:
|
||||
print(f"[Community API] 获取频道管理员列表失败: {e}")
|
||||
return api_error(f'获取管理员列表失败: {str(e)}', 500)
|
||||
|
||||
|
||||
@community_bp.route('/channels/<channel_id>/admins', methods=['POST'])
|
||||
@login_required
|
||||
def add_channel_admin_api(channel_id):
|
||||
"""添加频道管理员(需要 owner 或超级管理员权限)"""
|
||||
user = g.current_user
|
||||
|
||||
# 检查权限
|
||||
if not check_channel_permission(channel_id, user['id'], 'manage_admins'):
|
||||
return api_error('无权限管理频道管理员', 403)
|
||||
|
||||
data = request.get_json()
|
||||
target_user_id = data.get('userId')
|
||||
role = data.get('role', 'moderator')
|
||||
|
||||
if not target_user_id:
|
||||
return api_error('请指定用户ID')
|
||||
|
||||
if role not in ['admin', 'moderator']:
|
||||
return api_error('无效的角色,只能设置 admin 或 moderator')
|
||||
|
||||
# 不能设置为 owner(owner 只能是创建者)
|
||||
if add_channel_admin(channel_id, target_user_id, role):
|
||||
return api_response({'success': True, 'message': f'已添加 {role}'})
|
||||
else:
|
||||
return api_error('添加管理员失败', 500)
|
||||
|
||||
|
||||
@community_bp.route('/channels/<channel_id>/admins/<user_id>', methods=['DELETE'])
|
||||
@login_required
|
||||
def remove_channel_admin_api(channel_id, user_id):
|
||||
"""移除频道管理员(需要 owner 或超级管理员权限)"""
|
||||
current_user = g.current_user
|
||||
|
||||
# 检查权限
|
||||
if not check_channel_permission(channel_id, current_user['id'], 'manage_admins'):
|
||||
return api_error('无权限管理频道管理员', 403)
|
||||
|
||||
# 不能移除 owner
|
||||
target_admin = get_channel_admin_info(channel_id, user_id)
|
||||
if target_admin and target_admin['isOwner'] and not target_admin['isSuperAdmin']:
|
||||
return api_error('不能移除频道创建者', 400)
|
||||
|
||||
try:
|
||||
with get_db_engine().connect() as conn:
|
||||
sql = text("""
|
||||
DELETE FROM community_channel_admins
|
||||
WHERE channel_id = :channel_id AND user_id = :user_id
|
||||
""")
|
||||
conn.execute(sql, {
|
||||
'channel_id': channel_id,
|
||||
'user_id': int(user_id)
|
||||
})
|
||||
conn.commit()
|
||||
return api_response({'success': True, 'message': '已移除管理员'})
|
||||
except Exception as e:
|
||||
print(f"[Community API] 移除频道管理员失败: {e}")
|
||||
return api_error(f'移除管理员失败: {str(e)}', 500)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 频道相关 API
|
||||
# ============================================================
|
||||
@@ -373,6 +617,9 @@ def create_channel():
|
||||
})
|
||||
conn.commit()
|
||||
|
||||
# 将创建者设为频道管理员(owner)
|
||||
add_channel_admin(channel_id, user['id'], role='owner')
|
||||
|
||||
# 返回创建的频道信息
|
||||
response_data = {
|
||||
'id': channel_id,
|
||||
@@ -387,9 +634,10 @@ def create_channel():
|
||||
'subscriberCount': 0,
|
||||
'messageCount': 0,
|
||||
'createdAt': now.isoformat(),
|
||||
'isOwner': True, # 创建者自动是 owner
|
||||
}
|
||||
|
||||
print(f"[Community API] 创建频道成功: {channel_id} - {name}")
|
||||
print(f"[Community API] 创建频道成功: {channel_id} - {name}, 创建者: {user['id']}")
|
||||
return api_response(response_data)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
49
community_channel_admins.sql
Normal file
49
community_channel_admins.sql
Normal file
@@ -0,0 +1,49 @@
|
||||
-- 频道管理员表
|
||||
-- 在 MySQL 中执行
|
||||
|
||||
-- 1. 创建频道管理员表
|
||||
CREATE TABLE IF NOT EXISTS community_channel_admins (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
channel_id VARCHAR(50) NOT NULL,
|
||||
user_id INT NOT NULL,
|
||||
role ENUM('owner', 'admin', 'moderator') NOT NULL DEFAULT 'moderator',
|
||||
-- owner: 频道创建者,拥有最高权限
|
||||
-- admin: 频道管理员,可以管理消息和成员
|
||||
-- moderator: 版主,可以删除消息
|
||||
permissions JSON,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_channel_user (channel_id, user_id),
|
||||
INDEX idx_channel_id (channel_id),
|
||||
INDEX idx_user_id (user_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- 2. 权限说明
|
||||
-- owner 权限(频道创建者):
|
||||
-- - delete_channel: 删除频道
|
||||
-- - edit_channel: 编辑频道信息
|
||||
-- - manage_admins: 管理频道管理员
|
||||
-- - pin_messages: 置顶消息
|
||||
-- - delete_messages: 删除任何消息
|
||||
-- - slow_mode: 设置慢速模式
|
||||
-- - lock_channel: 锁定频道
|
||||
|
||||
-- admin 权限:
|
||||
-- - edit_channel: 编辑频道信息(部分)
|
||||
-- - pin_messages: 置顶消息
|
||||
-- - delete_messages: 删除消息
|
||||
-- - slow_mode: 设置慢速模式
|
||||
|
||||
-- moderator 权限:
|
||||
-- - pin_messages: 置顶消息
|
||||
-- - delete_messages: 删除消息
|
||||
|
||||
-- 3. 超级管理员说明
|
||||
-- community_admins 表中 role='admin' 的用户(如 user_id=65)
|
||||
-- 自动拥有所有频道的最高权限,不需要在此表中添加记录
|
||||
|
||||
-- 查看频道管理员
|
||||
-- SELECT cca.*, u.username, c.name as channel_name
|
||||
-- FROM community_channel_admins cca
|
||||
-- LEFT JOIN users u ON cca.user_id = u.id
|
||||
-- LEFT JOIN community_channels c ON cca.channel_id = c.id;
|
||||
Reference in New Issue
Block a user