数据人与超自然意识 发表于 2025-3-30 05:38:09

调用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, input {
            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.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密钥
[*]通过以下方式访问:# 使用Python启动简易服务器
python3 -m http.server 8000
访问 http://localhost: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密钥需通事后端服务保护(正式环境)
[*]欣赏器内存限制:建议添加文件数量限制
项目下载地址:
调用DeepSeek API 增强版纯前端实现方案,支持文件上传和内容解析功能

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 调用DeepSeek API 增强版纯前端实现方案,支持文件上传和内容解析功能