From d8dc79d32c8b18731fe83f3a74566573b655ff1a Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Fri, 7 Nov 2025 22:45:46 +0800 Subject: [PATCH] =?UTF-8?q?agent=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0MCP=E5=90=8E=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mcp_server.py | 69 ++++++++++++++++++++++++++++++------ src/views/AgentChat/index.js | 7 ++-- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/mcp_server.py b/mcp_server.py index e9b0f8b8..371e2825 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -140,6 +140,7 @@ class AgentChatRequest(BaseModel): user_id: Optional[str] = None # 用户ID user_nickname: Optional[str] = None # 用户昵称 user_avatar: Optional[str] = None # 用户头像URL + subscription_type: Optional[str] = None # 用户订阅类型(free/pro/max) session_id: Optional[str] = None # 会话ID(如果为空则创建新会话) # ==================== MCP工具定义 ==================== @@ -1549,22 +1550,36 @@ async def agent_chat(request: AgentChatRequest): logger.info(f"Agent chat: {request.message} (user: {request.user_id})") # ==================== 权限检查 ==================== - # 仅允许 max 用户使用(支持多种格式:字符串 "max"、数字 1、或 nickname 为 "max") - is_max_user = ( - request.user_id == "max" or - request.user_id == "1" or - request.user_id == 1 or - request.user_nickname == "max" - ) + # 订阅等级判断函数(与 app.py 保持一致) + def subscription_level(sub_type: str) -> int: + """将订阅类型映射到等级数值,free=0, pro=1, max=2""" + mapping = {'free': 0, 'pro': 1, 'max': 2} + return mapping.get((sub_type or 'free').lower(), 0) - if not is_max_user: - logger.warning(f"权限检查失败 - user_id: {request.user_id}, nickname: {request.user_nickname}") + # 获取用户订阅类型(默认为 free) + user_subscription = (request.subscription_type or 'free').lower() + required_level = 'max' + + # 权限检查:仅允许 max 用户访问(与传导链分析权限保持一致) + has_access = subscription_level(user_subscription) >= subscription_level(required_level) + + if not has_access: + logger.warning( + f"权限检查失败 - user_id: {request.user_id}, " + f"nickname: {request.user_nickname}, " + f"subscription_type: {user_subscription}, " + f"required: {required_level}" + ) raise HTTPException( status_code=403, - detail="很抱歉,「价小前投研」功能目前仅对特定用户开放。如需使用,请联系管理员。" + detail="很抱歉,「价小前投研」功能仅对 Max 订阅用户开放。请升级您的订阅以使用此功能。" ) - logger.info(f"权限检查通过 - user_id: {request.user_id}, nickname: {request.user_nickname}") + logger.info( + f"权限检查通过 - user_id: {request.user_id}, " + f"nickname: {request.user_nickname}, " + f"subscription_type: {user_subscription}" + ) # ==================== 会话管理 ==================== # 如果没有提供 session_id,创建新会话 @@ -1644,6 +1659,38 @@ async def agent_chat_stream(request: AgentChatRequest): """智能代理对话端点(流式 SSE)""" logger.info(f"Agent chat stream: {request.message}") + # ==================== 权限检查 ==================== + # 订阅等级判断函数(与 app.py 保持一致) + def subscription_level(sub_type: str) -> int: + """将订阅类型映射到等级数值,free=0, pro=1, max=2""" + mapping = {'free': 0, 'pro': 1, 'max': 2} + return mapping.get((sub_type or 'free').lower(), 0) + + # 获取用户订阅类型(默认为 free) + user_subscription = (request.subscription_type or 'free').lower() + required_level = 'max' + + # 权限检查:仅允许 max 用户访问(与传导链分析权限保持一致) + has_access = subscription_level(user_subscription) >= subscription_level(required_level) + + if not has_access: + logger.warning( + f"[Stream] 权限检查失败 - user_id: {request.user_id}, " + f"nickname: {request.user_nickname}, " + f"subscription_type: {user_subscription}, " + f"required: {required_level}" + ) + raise HTTPException( + status_code=403, + detail="很抱歉,「价小前投研」功能仅对 Max 订阅用户开放。请升级您的订阅以使用此功能。" + ) + + logger.info( + f"[Stream] 权限检查通过 - user_id: {request.user_id}, " + f"nickname: {request.user_nickname}, " + f"subscription_type: {user_subscription}" + ) + # 获取工具列表 tools = [tool.dict() for tool in TOOLS] diff --git a/src/views/AgentChat/index.js b/src/views/AgentChat/index.js index b221de98..56cd16d1 100644 --- a/src/views/AgentChat/index.js +++ b/src/views/AgentChat/index.js @@ -220,8 +220,8 @@ const AgentChatV3 = () => { const handleSendMessage = async () => { if (!inputValue.trim() || isProcessing) return; - // 权限检查 - 检查订阅类型(与Community等页面保持一致) - const hasAccess = user?.subscription_type === 'max' || user?.subscription_type === 'pro'; + // 权限检查 - 只允许 max 用户访问(与传导链分析权限保持一致) + const hasAccess = user?.subscription_type === 'max'; if (!hasAccess) { logger.warn('AgentChat', '权限检查失败', { @@ -233,7 +233,7 @@ const AgentChatV3 = () => { toast({ title: '订阅升级', - description: '「价小前投研」功能需要 Pro 或 Max 订阅。请前往设置页面升级您的订阅。', + description: '「价小前投研」功能需要 Max 订阅。请前往设置页面升级您的订阅。', status: 'warning', duration: 5000, isClosable: true, @@ -284,6 +284,7 @@ const AgentChatV3 = () => { user_id: user?.id ? String(user.id) : 'anonymous', user_nickname: user?.nickname || user?.username || '匿名用户', user_avatar: user?.avatar || '', + subscription_type: user?.subscription_type || 'free', // 传递订阅类型 session_id: currentSessionId, });