<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DeepSeek Chat</title>
<link href="./layui/css/layui.css" rel="stylesheet">
<style>
body { background-color: #f5f5f5; }
.container { margin: 20px auto; max-width: 1200px; }
.chat-box { background: #fff; border-radius: 10px; box-shadow: 0 2px 12px rgba(0,0,0,.1); }
.chat-history { height: 70vh; overflow-y: auto; padding: 20px; }
.message { margin-bottom: 20px; }
.user-message { text-align: right; }
.bot-message { text-align: left; }
.message-content {
display: inline-block;
max-width: 80%;
padding: 12px 20px;
border-radius: 20px;
word-break: break-word;
}
.user-message .message-content { background: #1890ff; color: #fff; }
.bot-message .message-content { background: #f0f2f5; }
.input-box { border-top: 1px solid #eee; padding: 20px; position: relative; }
.layui-textarea { border: none; resize: none; }
.send-btn { position: absolute; right: 30px; bottom: 30px; }
</style>
</head>
<body>
<div class="container layui-row">
<!-- 左侧导航 -->
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">历史会话</div>
<div class="layui-card-body" id="history-list"></div>
</div>
</div>
<!-- 右侧聊天区 -->
<div class="layui-col-md9">
<div class="chat-box">
<div class="chat-history" id="chat-container"></div>
<div class="input-box">
<form class="layui-form" >
<div class="layui-form-item">
<textarea id="input-area" class="layui-textarea" rows="3" placeholder="输入你的问题..."></textarea>
<button class="layui-btn send-btn" >发送</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="./layui/layui.js"></script>
<script>
let isGenerating = false;
let controller = null;
// 初始化
layui.use(['form', 'util'], function(){
const form = layui.form;
const util = layui.util;
// 绑定Enter键
util.event('keydown', '#input-area', function(e){
if(e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
});
async function sendMessage() {
if (isGenerating) return;
const input = document.getElementById('input-area');
const question = input.value.trim();
if (!question) return;
isGenerating = true;
input.value = '';
controller = new AbortController();
// 添加用户消息
appendMessage(question, 'user');
const API_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
const API_KEY = 'sk-888888888888888888888888888';
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify({
model: "deepseek-r1",
messages: [{ role: "user", content: question }],
stream: true
}),
signal: controller.signal
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
let partialLine = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
let lines = buffer.split('\n');
// 保留最后不完整的行
buffer = lines.pop() || '';
for (const line of lines) {
try {
// 处理可能存在的data:前缀
const cleanLine = line.replace(/^data: /, '').trim();
if (!cleanLine) continue;
if (cleanLine === '[DONE]') break;
const data = JSON.parse(cleanLine);
const content = data.choices[0]?.delta?.content || '';
if (content) {
appendMessage(content, 'bot', true);
}
} catch (e) {
console.error('解析错误:', e, '原始数据:', line);
}
}
}
} catch (error) {
if (error.name !== 'AbortError') {
appendMessage('请求出错,请重试', 'bot');
}
} finally {
isGenerating = false;
controller = null;
}
}
function appendMessage(content, role, isAppend = false) {
const container = document.getElementById('chat-container');
let messageElement;
if (isAppend && container.lastElementChild?.classList.contains('bot-message')) {
messageElement = container.lastElementChild.querySelector('.message-content');
messageElement.innerHTML += content;
} else {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${role}-message`;
messageDiv.innerHTML = `
<div class="message-content">
${content.replace(/\n/g, '<br>')}
</div>
`;
container.appendChild(messageDiv);
messageElement = messageDiv.querySelector('.message-content');
}
// 自动滚动
container.scrollTop = container.scrollHeight;
}
// 停止生成
function stopGenerate() {
if (controller) {
controller.abort();
isGenerating = false;
}
}
</script>
</body>
</html>