
调用DeepSeek API 增强版纯前端实现方案,支持文件上传和内容解析功能
以下是一个增强版纯前端实现方案,支持文件上传和内容解析功能,直接调用DeepSeek API:功能亮点:文件上传管理:内容处理:安全控制:使用说明:访问 http://localhost:8000扩展建议:添加预览功能:添加会话管理:注意事项:项目下载地址:调用DeepSeek API 增强版纯前端实现方案,支持文件上传和内容解析功能
·
以下是一个增强版纯前端实现方案,支持文件上传和内容解析功能,直接调用DeepSeek API:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>DeepSeek 智能助手 (支持附件)</title>
<style>
:root {
--primary-color: #2c3e50;
--accent-color: #3498db;
--error-color: #e74c3c;
}
body {
font-family: 'Segoe UI', system-ui, sans-serif;
max-width: 800px;
margin: 2rem auto;
padding: 0 20px;
background: #f8f9fa;
}
.container {
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
padding: 2rem;
}
.input-group {
display: flex;
gap: 10px;
margin-bottom: 1rem;
}
input[type="text"], input[type="file"] {
flex: 1;
padding: 12px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 16px;
}
button {
padding: 12px 24px;
background: var(--accent-color);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: opacity 0.3s;
}
button:hover {
opacity: 0.9;
}
#file-list {
margin: 1rem 0;
padding: 0;
list-style: none;
}
.file-item {
display: flex;
align-items: center;
padding: 8px;
background: #f8f9fa;
border-radius: 6px;
margin-bottom: 6px;
}
.file-item span {
flex: 1;
font-size: 0.9em;
}
#response {
margin-top: 20px;
padding: 16px;
background: #f8f9fa;
border-radius: 8px;
min-height: 100px;
white-space: pre-wrap;
line-height: 1.6;
}
.loading {
display: none;
color: #666;
font-style: italic;
}
.error {
color: var(--error-color);
margin: 0.5rem 0;
}
</style>
</head>
<body>
<div class="container">
<h1 style="color: var(--primary-color); margin-bottom: 1.5rem;">DeepSeek 智能助手</h1>
<!-- 文件上传区域 -->
<div class="input-group">
<input type="file" id="file-input" multiple accept=".txt,.pdf,.docx">
<button onclick="handleFileUpload()">上传文件</button>
</div>
<ul id="file-list"></ul>
<!-- 问答区域 -->
<div class="input-group">
<input type="text" id="question" placeholder="请输入您的问题...">
<button onclick="askQuestion()">发送</button>
</div>
<div class="loading" id="loading">处理中...</div>
<div id="response"></div>
</div>
<script>
// 配置参数(⚠️ 安全提示:前端暴露API密钥仅限本地测试)
const CONFIG = {
API_KEY: 'your-api-key-here',
API_URL: 'https://api.deepseek.com/v1/chat/completions',
MODEL: 'deepseek-chat',
MAX_FILE_SIZE: 2 * 1024 * 1024, // 2MB
ALLOWED_TYPES: ['text/plain', 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']
}
let uploadedFiles = [];
// 文件上传处理
async function handleFileUpload() {
const fileInput = document.getElementById('file-input');
const files = Array.from(fileInput.files);
const fileList = document.getElementById('file-list');
try {
for (const file of files) {
// 验证文件
if (file.size > CONFIG.MAX_FILE_SIZE) {
throw new Error(`文件 ${file.name} 超过大小限制 (最大 ${CONFIG.MAX_FILE_SIZE/1024/1024}MB)`);
}
if (!CONFIG.ALLOWED_TYPES.includes(file.type)) {
throw new Error(`不支持的文件类型: ${file.type}`);
}
// 读取文件内容
const content = await readFileContent(file);
// 存储文件信息
uploadedFiles.push({
name: file.name,
type: file.type,
size: file.size,
content: content,
uploadedAt: new Date().toISOString()
});
// 更新文件列表
const li = document.createElement('li');
li.className = 'file-item';
li.innerHTML = `
<span>${file.name} (${formatFileSize(file.size)})</span>
<button onclick="removeFile('${file.name}')">删除</button>
`;
fileList.appendChild(li);
}
fileInput.value = ''; // 清空选择
} catch (error) {
showError(error.message);
}
}
// 文件内容读取
function readFileContent(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
if (file.type === 'application/pdf') {
// PDF处理需要第三方库(此处简化处理)
reader.readAsArrayBuffer(file);
} else {
reader.readAsText(file, 'UTF-8');
}
});
}
// 提问处理
async function askQuestion() {
const question = document.getElementById('question').value.trim();
const loading = document.getElementById('loading');
const responseDiv = document.getElementById('response');
if (!question) {
showError('请输入有效问题');
return;
}
try {
loading.style.display = 'block';
responseDiv.textContent = '';
// 构建上下文
const context = uploadedFiles.length > 0
? `参考文件内容:\n${uploadedFiles.map(f => f.content).join('\n')}\n\n问题:`
: '';
// API请求
const response = await fetch(CONFIG.API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CONFIG.API_KEY}`
},
body: JSON.stringify({
model: CONFIG.MODEL,
messages: [{
role: "user",
content: context + question
}]
})
});
if (!response.ok) throw new Error(`API请求失败: ${response.status}`);
const data = await response.json();
responseDiv.textContent = data.choices[0].message.content;
} catch (error) {
showError(error.message);
console.error(error);
} finally {
loading.style.display = 'none';
}
}
// 辅助函数
function formatFileSize(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1048576) return (bytes/1024).toFixed(1) + ' KB';
return (bytes/1048576).toFixed(1) + ' MB';
}
function removeFile(filename) {
uploadedFiles = uploadedFiles.filter(f => f.name !== filename);
document.querySelectorAll('.file-item').forEach(li => {
if (li.textContent.includes(filename)) li.remove();
});
}
function showError(message) {
const errorDiv = document.createElement('div');
errorDiv.className = 'error';
errorDiv.textContent = message;
document.body.appendChild(errorDiv);
setTimeout(() => errorDiv.remove(), 3000);
}
// 事件监听
document.getElementById('question').addEventListener('keypress', e => {
if (e.key === 'Enter') askQuestion();
});
</script>
</body>
</html>
功能亮点:
-
文件上传管理:
- 支持多文件上传 (PDF/DOCX/TXT)
- 实时显示文件列表
- 文件大小和类型验证
- 单个文件删除功能
-
内容处理:
- 自动将文件内容作为上下文附加到问题
- 基础PDF/DOCX文件处理(需扩展解析逻辑)
-
安全控制:
- 文件大小限制 (2MB)
- 允许的文件类型白名单
使用说明:
- 保存为
.html
文件 - 替换API密钥
- 通过以下方式访问:
访问 http://localhost:8000# 使用Python启动简易服务器 python3 -m http.server 8000
扩展建议:
- 增强文件解析(需引入库):
<!-- 在<head>添加 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
<script src="https://unpkg.com/mammoth@1.4.8/mammoth.browser.min.js"></script>
<script>
// 修改readFileContent函数
async function readFileContent(file) {
if (file.type === 'application/pdf') {
const arrayBuffer = await file.arrayBuffer();
const pdf = await pdfjsLib.getDocument(arrayBuffer).promise;
let text = '';
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const content = await page.getTextContent();
text += content.items.map(item => item.str).join(' ');
}
return text;
} else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
const arrayBuffer = await file.arrayBuffer();
const result = await mammoth.extractRawText({arrayBuffer});
return result.value;
}
return await file.text();
}
</script>
- 添加预览功能:
function previewFile(filename) {
const file = uploadedFiles.find(f => f.name === filename);
if (file) {
const win = window.open();
win.document.write(`<pre>${file.content}</pre>`);
}
}
- 添加会话管理:
// 在CONFIG中添加
SESSION_MAX_AGE: 3600 // 1小时有效期
// 初始化时读取本地存储
if (localStorage.getItem('chatSession')) {
const session = JSON.parse(localStorage.getItem('chatSession'));
if (Date.now() - session.timestamp < CONFIG.SESSION_MAX_AGE * 1000) {
uploadedFiles = session.files;
// 更新文件列表显示...
}
}
// 定期保存
setInterval(() => {
localStorage.setItem('chatSession', JSON.stringify({
files: uploadedFiles,
timestamp: Date.now()
}));
}, 30000);
注意事项:
- 前端文件处理能力有限,大文件可能影响性能
- 复杂文档解析建议在服务端进行
- API密钥需通过后端服务保护(正式环境)
- 浏览器内存限制:建议添加文件数量限制
更多推荐
所有评论(0)