// ==UserScript== // @name DeepSeek Chat Exporter (Markdown & PDF) // @namespace http://tampermonkey.net/ // @version 1.1 // @description 导出 DeepSeek 聊天记录为 Markdown 和 PDF 格式 // @author HSyuf/Blueberrycongee // @match https://chat.deepseek.com/* // @grant GM_addStyle // @grant GM_download // @license MIT // @downloadURL none // ==/UserScript== (function () { "use strict"; class AiAnswer { constructor(aiChain, aiAnswer) { this.aiChain = { type: "ai_chain", content: aiChain ? aiChain.textContent.trim() : "[无内容]", }; this.aiAnswer = { type: "ai_formal_reply", content: aiAnswer ? aiAnswer.textContent.trim() : "[无内容]", }; } } // ===================== // 获取用户消息 // ===================== function getUserMessages() { const chatContainer = Array.from(document.querySelectorAll(".fa81")); return chatContainer.map((el) => ({ type: "user", content: el.textContent.trim() || "[无内容]", })); } // ===================== // 获取 AI 消息 // ===================== function getAiMessages() { const aiAnswers = Array.from( document.querySelectorAll(".f9bf7997.c05b5566") ); return aiAnswers.map((el) => { const aiStatus = el.querySelector(".a6d716f5.db5991dd"); const aiChain = el.querySelector(".e1675d8b"); const aiAnswers = el.querySelector(".ds-markdown.ds-markdown--block"); return aiStatus.textContent === "思考已停止" ? new AiAnswer() : new AiAnswer(aiChain, aiAnswers); }); } // ===================== // 生成 Markdown 内容 // ===================== function generateMdContent() { const userMessages = getUserMessages(); const aiMessages = getAiMessages(); if (userMessages.length === 0 && aiMessages.length === 0) { alert("未找到聊天记录!"); return null; } const allMessages = []; for (let i = 0; i < userMessages.length; i++) { allMessages.push(userMessages[i], aiMessages[i].aiChain, aiMessages[i].aiAnswer); } return allMessages .map((msg) => { if (msg.type === "user") return `**用户:**\n${msg.content}`; if (msg.type === "ai_formal_reply") return `**AI 回答:**\n${msg.content}`; if (msg.type === "ai_chain") return `**AI 思维链:**\n${msg.content}`; return ""; }) .join("\n\n---\n\n"); } // ===================== // 导出为 Markdown // ===================== function exportMarkdown() { const mdContent = generateMdContent(); if (!mdContent) return; const blob = new Blob([mdContent], { type: "text/markdown" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `DeepSeek_Chat_${Date.now()}.md`; a.click(); setTimeout(() => URL.revokeObjectURL(url), 5000); } // ===================== // 导出为 PDF // ===================== function exportPDF() { const mdContent = generateMdContent(); if (!mdContent) return; // 创建打印内容 const printContent = ` DeepSeek Chat Export ${mdContent .replace(/\*\*用户:\*\*\n/g, '

用户提问

') .replace(/\*\*AI 回答:\*\*\n/g, '

AI 回答

') .replace(/\*\*AI 思维链:\*\*\n/g, '

思维链

') .replace(/\n/g, '
') .replace(/---/g, '

')} `; // 创建打印窗口 const printWindow = window.open("", "_blank"); printWindow.document.write(printContent); printWindow.document.close(); // 添加延迟确保内容加载完成 setTimeout(() => { printWindow.print(); printWindow.close(); }, 500); } // ===================== // 添加导出菜单 // ===================== function createExportMenu() { const menu = document.createElement("div"); menu.className = "ds-exporter-menu"; menu.innerHTML = ` `; menu.querySelector("#md-btn").addEventListener("click", exportMarkdown); menu.querySelector("#pdf-btn").addEventListener("click", exportPDF); document.body.appendChild(menu); } // ===================== // 样式注入 // ===================== GM_addStyle(` .ds-exporter-menu { position: fixed; top: 20px; right: 20px; z-index: 9999; background: rgba(255, 255, 255, 0.95); padding: 12px; border-radius: 8px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15); display: flex; flex-direction: column; gap: 8px; backdrop-filter: blur(4px); } .export-btn { background: #2196F3; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px; transition: all 0.2s; } .export-btn:hover { background: #1976D2; transform: translateY(-1px); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); } `); // ===================== // 初始化脚本 // ===================== function init() { const checkInterval = setInterval(() => { if (document.querySelector(".fa81")) { clearInterval(checkInterval); createExportMenu(); } }, 500); } init(); })();