SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DeepSeek Chat</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/marked@4.2.12/marked.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/lib/highlight.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/styles/github-dark.min.css">
    <style>
        .typing-dots::after {
            content: '';
            animation: dots 1.5s infinite;
        }
        @keyframes dots {
            0%, 20% { content: '.'; }
            40% { content: '..'; }
            60%, 100% { content: '...'; }
        }
        .markdown-content pre {
            background-color: #1e1e1e;
            border-radius: 0.375rem;
            padding: 1rem;
            overflow-x: auto;
            margin: 1rem 0;
        }
        .markdown-content code {
            font-family: ui-monospace, monospace;
            font-size: 0.875rem;
        }
        .markdown-content p {
            margin-bottom: 0.75rem;
        }
        .markdown-content ul, .markdown-content ol {
            margin-left: 1.5rem;
            margin-bottom: 0.75rem;
        }
        .markdown-content ul {
            list-style-type: disc;
        }
        .markdown-content ol {
            list-style-type: decimal;
        }
    </style>
</head>
<body class="bg-gray-800 text-gray-100 flex flex-col h-screen">
    <header class="bg-gray-900 p-4 border-b border-gray-700">
        <h1 class="text-xl font-semibold text-center">DeepSeek Chat</h1>
    </header>

    <main class="flex-1 overflow-y-auto p-4 space-y-6" id="chat-container">
        <div class="bg-gray-700 p-4 rounded-lg max-w-3xl mx-auto">
            <p>�� 你好!我是基于 DeepSeek 的 AI 助手。有什么我可以帮助你的吗?</p>
        </div>
    </main>

    <footer class="bg-gray-900 p-4 border-t border-gray-700">
        <form id="chat-form" class="max-w-3xl mx-auto">
            <div class="flex gap-2">
                <textarea 
                    id="user-input" 
                    class="flex-1 bg-gray-700 text-gray-100 rounded-lg p-3 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
                    placeholder="输入消息..." 
                    rows="1"
                ></textarea>
                <button 
                    type="submit" 
                    class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg"
                    id="send-button"
                >
                    发送
                </button>
            </div>
            <p class="text-gray-400 text-xs mt-2 text-center">DeepSeek 可能会产生不准确的信息</p>
        </form>
    </footer>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const chatForm = document.getElementById('chat-form');
            const userInput = document.getElementById('user-input');
            const chatContainer = document.getElementById('chat-container');
            const sendButton = document.getElementById('send-button');

            const API_URL = 'https://test.590702.xyz';
            const API_KEY = 'sk-123456';
            const MODEL = 'deepseek-ai/DeepSeek-V3-0324';

            let isGenerating = false;
            let conversation = [];

            chatForm.addEventListener('submit', async (e) => {
                e.preventDefault();
                
                const message = userInput.value.trim();
                if (!message || isGenerating) return;
                
                addMessage(message, 'user');
                userInput.value = '';
                adjustTextareaHeight();
                
                conversation.push({ role: 'user', content: message });
                await getAIResponse();
            });

            userInput.addEventListener('input', adjustTextareaHeight);
            
            userInput.addEventListener('keydown', (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    if (userInput.value.trim()) {
                        chatForm.dispatchEvent(new Event('submit'));
                    }
                }
            });

            async function getAIResponse() {
                try {
                    isGenerating = true;
                    sendButton.disabled = true;
                    
                    const loadingDiv = document.createElement('div');
                    loadingDiv.className = 'bg-gray-700 p-4 rounded-lg max-w-3xl mx-auto';
                    loadingDiv.innerHTML = '<span class="typing-dots">思考中</span>';
                    chatContainer.appendChild(loadingDiv);
                    chatContainer.scrollTop = chatContainer.scrollHeight;
                    
                    const responseDiv = document.createElement('div');
                    responseDiv.className = 'bg-gray-700 p-4 rounded-lg max-w-3xl mx-auto';
                    responseDiv.innerHTML = '<div class="markdown-content"></div>';
                    
                    const response = await fetch(`${API_URL}/v1/chat/completions`, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'Authorization': `Bearer ${API_KEY}`
                        },
                        body: JSON.stringify({
                            model: MODEL,
                            messages: conversation,
                            stream: true
                        })
                    });
                    
                    if (!response.ok) {
                        throw new Error(`API请求失败: ${response.status}`);
                    }
                    
                    chatContainer.removeChild(loadingDiv);
                    chatContainer.appendChild(responseDiv);
                    
                    const reader = response.body.getReader();
                    const decoder = new TextDecoder('utf-8');
                    let responseText = '';
                    
                    while (true) {
                        const { done, value } = await reader.read();
                        if (done) break;
                        
                        const chunk = decoder.decode(value, { stream: true });
                        const lines = chunk.split('\n');
                        
                        for (const line of lines) {
                            if (line.startsWith('data: ') && line !== 'data: [DONE]') {
                                try {
                                    const data = JSON.parse(line.substring(6));
                                    if (data.choices && data.choices[0].delta && data.choices[0].delta.content) {
                                        const content = data.choices[0].delta.content;
                                        responseText += content;
                                        updateResponseContent(responseDiv, responseText);
                                        chatContainer.scrollTop = chatContainer.scrollHeight;
                                    }
                                } catch (e) {
                                    console.error('解析流数据失败:', e);
                                }
                            }
                        }
                    }
                    
                    conversation.push({ role: 'assistant', content: responseText });
                    
                } catch (error) {
                    console.error('获取AI响应失败:', error);
                    showErrorMessage(error.message);
                } finally {
                    isGenerating = false;
                    sendButton.disabled = false;
                }
            }

            function addMessage(message, role) {
                const div = document.createElement('div');
                div.className = role === 'user' 
                    ? 'bg-gray-600 p-4 rounded-lg max-w-3xl mx-auto ml-auto' 
                    : 'bg-gray-700 p-4 rounded-lg max-w-3xl mx-auto';
                div.textContent = message;
                chatContainer.appendChild(div);
                chatContainer.scrollTop = chatContainer.scrollHeight;
            }

            function updateResponseContent(element, markdown) {
                const contentElement = element.querySelector('.markdown-content');
                contentElement.innerHTML = marked.parse(markdown);
                element.querySelectorAll('pre code').forEach((block) => {
                    hljs.highlightElement(block);
                });
            }

            function showErrorMessage(message) {
                const errorDiv = document.createElement('div');
                errorDiv.className = 'bg-red-700 p-4 rounded-lg max-w-3xl mx-auto';
                errorDiv.textContent = `错误: ${message}`;
                chatContainer.appendChild(errorDiv);
                chatContainer.scrollTop = chatContainer.scrollHeight;
            }

            function adjustTextareaHeight() {
                userInput.style.height = 'auto';
                userInput.style.height = Math.min(userInput.scrollHeight, 200) + 'px';
            }
        });
    </script>
</body>
</html>