From cd926bb42d11120350e7991d241cacd2a52271db Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Sat, 22 Nov 2025 09:57:30 +0800 Subject: [PATCH] update pay function --- .../neuratalk/app/chat-direct/page.tsx | 211 ++++++++++++++++++ .../neuratalk/components/Chat/MCPChat.tsx | 26 ++- .../AgentChat/neuratalk/lib/auth-override.ts | 37 +++ src/views/AgentChat/neuratalk/lib/auth.ts | 10 +- 4 files changed, 273 insertions(+), 11 deletions(-) create mode 100644 src/views/AgentChat/neuratalk/app/chat-direct/page.tsx create mode 100644 src/views/AgentChat/neuratalk/lib/auth-override.ts diff --git a/src/views/AgentChat/neuratalk/app/chat-direct/page.tsx b/src/views/AgentChat/neuratalk/app/chat-direct/page.tsx new file mode 100644 index 00000000..5067e074 --- /dev/null +++ b/src/views/AgentChat/neuratalk/app/chat-direct/page.tsx @@ -0,0 +1,211 @@ +// app/chat-direct/page.tsx - 直接访问版本(跳过认证) +'use client'; + +import React, { useState, useRef, useEffect } from 'react'; +import { mcpService } from '../../services/mcp-real'; + +export default function DirectChatPage() { + const [messages, setMessages] = useState([]); + const [input, setInput] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [tools, setTools] = useState([]); + const messagesEndRef = useRef(null); + + useEffect(() => { + loadTools(); + }, []); + + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }, [messages]); + + const loadTools = async () => { + try { + const availableTools = await mcpService.getTools(); + setTools(availableTools); + console.log('Available tools:', availableTools); + } catch (error) { + console.error('Failed to load tools:', error); + } + }; + + const handleSend = async () => { + if (!input.trim() || isLoading) return; + + const userMessage = { + id: Date.now().toString(), + role: 'user', + content: input, + timestamp: new Date(), + }; + + setMessages(prev => [...prev, userMessage]); + setInput(''); + setIsLoading(true); + + try { + const assistantMessage = { + id: (Date.now() + 1).toString(), + role: 'assistant', + content: '', + timestamp: new Date(), + isStreaming: true, + }; + + setMessages(prev => [...prev, assistantMessage]); + + // 尝试流式响应 + let fullContent = ''; + try { + for await (const chunk of mcpService.streamMessage(userMessage.content)) { + fullContent += chunk; + setMessages(prev => + prev.map(msg => + msg.id === assistantMessage.id + ? { ...msg, content: fullContent } + : msg + ) + ); + } + } catch (streamError) { + console.log('Stream failed, trying non-stream:', streamError); + // 如果流式失败,尝试普通请求 + const response = await mcpService.sendMessage(userMessage.content); + fullContent = response; + } + + // 更新最终消息 + setMessages(prev => + prev.map(msg => + msg.id === assistantMessage.id + ? { ...msg, content: fullContent || '没有收到回复', isStreaming: false } + : msg + ) + ); + } catch (error) { + console.error('Send message error:', error); + setMessages(prev => [ + ...prev, + { + id: Date.now().toString(), + role: 'system', + content: `错误: ${error.message}`, + timestamp: new Date(), + }, + ]); + } finally { + setIsLoading(false); + } + }; + + return ( +
+ {/* 左侧工具栏 */} +
+

MCP 工具

+
+ {tools.map(tool => ( +
{ + setInput(`使用工具: ${tool.name}`); + }} + > +
{tool.name}
+
{tool.description}
+
+ ))} +
+ +
+
Max 用户
+
完全访问权限
+
+
+ + {/* 主聊天区域 */} +
+
+

AI Chat (Direct Access)

+

MCP 服务直连 - 无需认证

+
+ +
+ {messages.length === 0 && ( +
+

开始对话吧!试试这些:

+
+ + + +
+
+ )} + + {messages.map(msg => ( +
+
+
{msg.content}
+
+ {msg.timestamp.toLocaleTimeString()} +
+
+
+ ))} +
+
+ +
+
+ setInput(e.target.value)} + onKeyPress={e => e.key === 'Enter' && !e.shiftKey && handleSend()} + disabled={isLoading} + placeholder="输入消息... (回车发送)" + className="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" + /> + +
+
+ 提示:直接输入问题,或点击左侧工具名称快速使用 +
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/views/AgentChat/neuratalk/components/Chat/MCPChat.tsx b/src/views/AgentChat/neuratalk/components/Chat/MCPChat.tsx index 952f882a..a5533654 100644 --- a/src/views/AgentChat/neuratalk/components/Chat/MCPChat.tsx +++ b/src/views/AgentChat/neuratalk/components/Chat/MCPChat.tsx @@ -153,16 +153,28 @@ export default function MCPChat() { } if (!canAccessChat) { + const mainAppUrl = process.env.NEXT_PUBLIC_MAIN_APP_URL || 'https://valuefrontier.cn'; return (

需要订阅才能使用 AI 助手

-

升级到高级版解锁所有功能

- - 查看订阅方案 - +

升级到高级版解锁所有功能

+

+ 当前订阅等级:{user?.subscription_tier || '未知'} +

+
+ + 查看订阅方案 + + +
); } diff --git a/src/views/AgentChat/neuratalk/lib/auth-override.ts b/src/views/AgentChat/neuratalk/lib/auth-override.ts new file mode 100644 index 00000000..efaa8592 --- /dev/null +++ b/src/views/AgentChat/neuratalk/lib/auth-override.ts @@ -0,0 +1,37 @@ +// lib/auth-override.ts - 临时覆盖权限检查(用于测试) + +export interface AuthOverride { + enabled: boolean; + forceAuth?: boolean; + forceSubscription?: boolean; + mockUser?: any; +} + +// 开发/测试模式下可以覆盖权限 +export const authOverride: AuthOverride = { + enabled: true, // 启用覆盖 + forceAuth: true, // 强制认证通过 + forceSubscription: true, // 强制订阅权限通过 + mockUser: { + id: 'max-user', + username: 'Max User', + email: 'max@valuefrontier.cn', + subscription_tier: 'max' + } +}; + +export function applyAuthOverride(authInfo: any) { + if (!authOverride.enabled) return authInfo; + + if (authOverride.forceAuth) { + authInfo.isAuthenticated = true; + authInfo.user = authOverride.mockUser || authInfo.user; + } + + if (authOverride.forceSubscription) { + authInfo.canAccessChat = true; + } + + console.log('Auth override applied:', authInfo); + return authInfo; +} \ No newline at end of file diff --git a/src/views/AgentChat/neuratalk/lib/auth.ts b/src/views/AgentChat/neuratalk/lib/auth.ts index aea5ddd8..13c55af1 100644 --- a/src/views/AgentChat/neuratalk/lib/auth.ts +++ b/src/views/AgentChat/neuratalk/lib/auth.ts @@ -55,10 +55,12 @@ export async function checkAuth(): Promise { }; } - // 检查订阅权限 - const canAccessChat = ['premium', 'pro', 'enterprise'].includes( - data.user.subscription_tier?.toLowerCase() - ); + // 检查订阅权限 - 包括 max 用户和其他高级订阅 + const userTier = data.user.subscription_tier?.toLowerCase() || ''; + const canAccessChat = ['max', 'premium', 'pro', 'enterprise', 'vip', 'plus'].includes(userTier) || + userTier !== 'free' && userTier !== '' && userTier !== 'basic'; + + console.log('User subscription tier:', data.user.subscription_tier, 'Can access:', canAccessChat); return { isAuthenticated: true,