From 15d521dd596dbfb899c080b022e7740309f23d4d Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Sat, 22 Nov 2025 10:37:15 +0800 Subject: [PATCH] update pay function --- .../app/ai-chat/generate-code-simple/page.tsx | 6 + .../app/ai-chat/generate-code/test-auth.tsx | 81 +++++ .../neuratalk/app/ai-chat/test-auth/page.tsx | 6 + .../AgentChat/neuratalk/app/demo/page.tsx | 9 +- .../neuratalk/components/Layout/MCPLayout.tsx | 7 + .../AgentChat/neuratalk/hooks/useAuth.tsx | 9 +- .../templates/GenerateCodePage/SimpleMCP.tsx | 336 ++++++++++++++++++ 7 files changed, 450 insertions(+), 4 deletions(-) create mode 100644 src/views/AgentChat/neuratalk/app/ai-chat/generate-code-simple/page.tsx create mode 100644 src/views/AgentChat/neuratalk/app/ai-chat/generate-code/test-auth.tsx create mode 100644 src/views/AgentChat/neuratalk/app/ai-chat/test-auth/page.tsx create mode 100644 src/views/AgentChat/neuratalk/templates/GenerateCodePage/SimpleMCP.tsx diff --git a/src/views/AgentChat/neuratalk/app/ai-chat/generate-code-simple/page.tsx b/src/views/AgentChat/neuratalk/app/ai-chat/generate-code-simple/page.tsx new file mode 100644 index 00000000..c36a0a52 --- /dev/null +++ b/src/views/AgentChat/neuratalk/app/ai-chat/generate-code-simple/page.tsx @@ -0,0 +1,6 @@ +// app/ai-chat/generate-code-simple/page.tsx - 简化版 MCP 集成 +import SimpleMCPGenerateCodePage from "@/templates/GenerateCodePage/SimpleMCP"; + +export default function Page() { + return ; +} \ No newline at end of file diff --git a/src/views/AgentChat/neuratalk/app/ai-chat/generate-code/test-auth.tsx b/src/views/AgentChat/neuratalk/app/ai-chat/generate-code/test-auth.tsx new file mode 100644 index 00000000..f0fd98d7 --- /dev/null +++ b/src/views/AgentChat/neuratalk/app/ai-chat/generate-code/test-auth.tsx @@ -0,0 +1,81 @@ +// 测试页面 - 检查认证是否工作 +'use client'; + +import { useEffect, useState } from 'react'; + +export default function TestAuth() { + const [authData, setAuthData] = useState(null); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + fetch('https://valuefrontier.cn/api/auth/session', { + method: 'GET', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + }) + .then(res => { + console.log('Response status:', res.status); + console.log('Response headers:', res.headers); + return res.json(); + }) + .then(data => { + console.log('Auth data received:', data); + setAuthData(data); + setLoading(false); + }) + .catch(err => { + console.error('Auth check error:', err); + setError(err.message); + setLoading(false); + }); + }, []); + + return ( +
+

认证测试页面

+ + {loading &&

加载中...

} + + {error && ( +
+

错误

+

{error}

+
+ )} + + {authData && ( +
+

认证信息

+
{JSON.stringify(authData, null, 2)}
+ + {authData.user?.avatar_url && ( +
+

头像测试

+ 用户头像 +
+ )} +
+ )} + +
+

图片路径测试

+

1. 相对路径:

+ test1 + +

2. 带 basePath 的路径:

+ test2 + +

3. 完整 URL:

+ test3 +
+
+ ); +} \ No newline at end of file diff --git a/src/views/AgentChat/neuratalk/app/ai-chat/test-auth/page.tsx b/src/views/AgentChat/neuratalk/app/ai-chat/test-auth/page.tsx new file mode 100644 index 00000000..2d1c1314 --- /dev/null +++ b/src/views/AgentChat/neuratalk/app/ai-chat/test-auth/page.tsx @@ -0,0 +1,6 @@ +// app/ai-chat/test-auth/page.tsx +import TestAuth from '../generate-code/test-auth'; + +export default function TestAuthPage() { + return ; +} \ No newline at end of file diff --git a/src/views/AgentChat/neuratalk/app/demo/page.tsx b/src/views/AgentChat/neuratalk/app/demo/page.tsx index 69bf2443..62cbbdab 100644 --- a/src/views/AgentChat/neuratalk/app/demo/page.tsx +++ b/src/views/AgentChat/neuratalk/app/demo/page.tsx @@ -48,8 +48,13 @@ export default function DemoPage() {
  • 🔥 最新集成: - AI 代码助手 - - 漂亮界面 + MCP 功能 + AI 代码助手(简化版) + - 直接集成,无复杂组件 +
  • +
  • + 🧪 测试页面: + 认证测试 + - 检查认证和图片路径
  • 最全功能: diff --git a/src/views/AgentChat/neuratalk/components/Layout/MCPLayout.tsx b/src/views/AgentChat/neuratalk/components/Layout/MCPLayout.tsx index 25e33ec0..039d7a44 100644 --- a/src/views/AgentChat/neuratalk/components/Layout/MCPLayout.tsx +++ b/src/views/AgentChat/neuratalk/components/Layout/MCPLayout.tsx @@ -22,6 +22,13 @@ const MCPLayout = ({ children }: Props) => { const [visibleSidebar, setVisibleSidebar] = useState(false); const { user, isAuthenticated, canAccessChat, loading: authLoading } = useAuth(); + console.log('[MCPLayout] Auth state:', { + user, + isAuthenticated, + canAccessChat, + authLoading + }); + // 权限检查 if (authLoading) { return ( diff --git a/src/views/AgentChat/neuratalk/hooks/useAuth.tsx b/src/views/AgentChat/neuratalk/hooks/useAuth.tsx index ef27e3fb..7dda88de 100644 --- a/src/views/AgentChat/neuratalk/hooks/useAuth.tsx +++ b/src/views/AgentChat/neuratalk/hooks/useAuth.tsx @@ -13,11 +13,13 @@ export function useAuth() { useEffect(() => { // 组件挂载时检查认证状态 const verifyAuth = async () => { + console.log('[useAuth] Starting auth verification...'); try { const info = await checkAuth(); + console.log('[useAuth] Auth info received:', info); setAuthInfo(info); } catch (error) { - console.error('Auth verification failed:', error); + console.error('[useAuth] Auth verification failed:', error); setAuthInfo({ isAuthenticated: false, message: '认证检查失败', @@ -36,7 +38,10 @@ export function useAuth() { }, []); return { - ...authInfo, + user: authInfo.user, + isAuthenticated: authInfo.isAuthenticated || false, + canAccessChat: authInfo.canAccessChat || false, + message: authInfo.message, loading, refresh: async () => { setLoading(true); diff --git a/src/views/AgentChat/neuratalk/templates/GenerateCodePage/SimpleMCP.tsx b/src/views/AgentChat/neuratalk/templates/GenerateCodePage/SimpleMCP.tsx new file mode 100644 index 00000000..9a8bf59c --- /dev/null +++ b/src/views/AgentChat/neuratalk/templates/GenerateCodePage/SimpleMCP.tsx @@ -0,0 +1,336 @@ +"use client"; + +import { useState, useEffect } from "react"; +import Layout from "@/components/Layout"; +import Chat from "@/components/Chat"; +import Question from "@/components/Question"; +import Answer from "@/components/Answer"; +import CodeEditor from "@/components/CodeEditor"; +import { mcpService } from '@/services/mcp-real'; + +interface Message { + id: string; + role: 'user' | 'assistant' | 'system'; + content: string; + timestamp: Date; + code?: { + language: string; + content: string; + title?: string; + }; + isStreaming?: boolean; +} + +interface User { + id: number; + username?: string; + nickname?: string; + email?: string; + avatar_url?: string; + subscription_type?: string; + subscription_days_left?: number; + is_subscription_active?: boolean; +} + +const SimpleMCPGenerateCodePage = () => { + const [messages, setMessages] = useState([]); + const [input, setInput] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [currentStreamingContent, setCurrentStreamingContent] = useState(''); + const [currentStreamingId, setCurrentStreamingId] = useState(null); + + // 认证状态 + const [user, setUser] = useState(null); + const [isAuthenticated, setIsAuthenticated] = useState(false); + const [canAccessChat, setCanAccessChat] = useState(false); + const [authLoading, setAuthLoading] = useState(true); + + // 检查认证状态 + useEffect(() => { + console.log('[SimpleMCP] Checking authentication...'); + + fetch('https://valuefrontier.cn/api/auth/session', { + method: 'GET', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + }) + .then(res => { + console.log('[SimpleMCP] Auth response status:', res.status); + if (!res.ok) throw new Error('Auth check failed'); + return res.json(); + }) + .then(data => { + console.log('[SimpleMCP] Auth data:', data); + + if (data.isAuthenticated && data.user) { + setUser(data.user); + setIsAuthenticated(true); + + // 检查订阅状态 + const subscriptionType = (data.user.subscription_type || '').toLowerCase(); + const isActive = data.user.is_subscription_active === true; + const canAccess = ['max', 'premium', 'pro'].includes(subscriptionType) || isActive; + + setCanAccessChat(canAccess); + console.log('[SimpleMCP] User can access chat:', canAccess); + } + }) + .catch(err => { + console.error('[SimpleMCP] Auth check error:', err); + }) + .finally(() => { + setAuthLoading(false); + }); + }, []); + + const extractCodeFromResponse = (content: string) => { + const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g; + const matches = [...content.matchAll(codeBlockRegex)]; + + if (matches.length > 0) { + const [, language = 'javascript', code] = matches[0]; + return { + hasCode: true, + language, + code: code.trim(), + textBefore: content.substring(0, matches[0].index), + textAfter: content.substring((matches[0].index || 0) + matches[0][0].length) + }; + } + + return { hasCode: false, content }; + }; + + const handleSend = async () => { + if (!input.trim() || isLoading) return; + + const userMessage: Message = { + id: Date.now().toString(), + role: 'user', + content: input, + timestamp: new Date(), + }; + + setMessages(prev => [...prev, userMessage]); + setInput(''); + setIsLoading(true); + setCurrentStreamingContent(''); + + try { + const assistantMessageId = (Date.now() + 1).toString(); + setCurrentStreamingId(assistantMessageId); + + const assistantMessage: Message = { + id: assistantMessageId, + role: 'assistant', + content: '', + timestamp: new Date(), + isStreaming: true, + }; + + setMessages(prev => [...prev, assistantMessage]); + + let fullContent = ''; + for await (const chunk of mcpService.streamMessage(input)) { + fullContent += chunk; + setCurrentStreamingContent(fullContent); + } + + const codeInfo = extractCodeFromResponse(fullContent); + + setMessages(prev => + prev.map(msg => + msg.id === assistantMessageId + ? { + ...msg, + content: codeInfo.hasCode + ? (codeInfo.textBefore || '这是生成的代码:') + : fullContent, + code: codeInfo.hasCode + ? { + language: codeInfo.language!, + content: codeInfo.code!, + title: '生成的代码' + } + : undefined, + isStreaming: false + } + : msg + ) + ); + + setCurrentStreamingContent(''); + setCurrentStreamingId(null); + } catch (error) { + console.error('Send message error:', error); + setMessages(prev => [ + ...prev, + { + id: Date.now().toString(), + role: 'system', + content: '抱歉,发送消息时出错了。请稍后重试。', + timestamp: new Date(), + }, + ]); + } finally { + setIsLoading(false); + } + }; + + // 加载中 + if (authLoading) { + return ( + +
    +
    +
    +

    验证身份中...

    +
    +
    +
    + ); + } + + // 未登录 + if (!isAuthenticated) { + return ( + +
    +

    请先登录

    +

    您需要登录才能使用 AI 助手

    + + 前往登录 + +
    +
    + ); + } + + // 未订阅 + if (!canAccessChat) { + return ( + +
    +

    需要订阅才能使用 AI 助手

    +

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

    +

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

    + + 查看订阅方案 + +
    +
    + ); + } + + return ( + + {/* 用户信息显示 */} + {user && ( +
    + {user.avatar_url ? ( + {user.username + ) : ( +
    + {(user.username || user.nickname || 'U')[0].toUpperCase()} +
    + )} +
    +

    {user.username || user.nickname}

    +

    + {user.subscription_type === 'max' ? '🌟 MAX会员' : '高级会员'} + {user.subscription_days_left ? ` · ${user.subscription_days_left}天` : ''} +

    +
    +
    + )} + + + {/* 输入框 */} +
    +
    + setInput(e.target.value)} + onKeyPress={(e) => e.key === 'Enter' && handleSend()} + placeholder="输入您的问题..." + className="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" + disabled={isLoading} + /> + +
    +
    + + {/* 消息列表 */} +
    + {messages.length === 0 ? ( +
    +

    👋 欢迎使用 AI 代码生成助手

    +

    输入您的需求,我会帮您生成代码

    +
    + ) : ( + messages.map((msg) => ( +
    + {msg.role === 'user' ? ( + {msg.content} + ) : msg.role === 'assistant' ? ( + + {msg.isStreaming ? ( +
    + {msg.id === currentStreamingId ? currentStreamingContent : msg.content} + {msg.id === currentStreamingId && !currentStreamingContent && ( + 思考中... + )} +
    + ) : ( + <> + {msg.content &&
    {msg.content}
    } + {msg.code && ( + {}} + isGenerating={false} + readOnly={false} + /> + )} + + )} +
    + ) : ( +
    + {msg.content} +
    + )} +
    + )) + )} +
    +
    +
    + ); +}; + +export default SimpleMCPGenerateCodePage; \ No newline at end of file