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>