DeepSeek对话分类管理

为DeepSeek网页版添加分类管理功能

安装此脚本?
作者推荐脚本

您可能也喜欢Deepseek Chat Assistant

安装此脚本
  1. // ==UserScript==
  2. // @name DeepSeek对话分类管理
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description 为DeepSeek网页版添加分类管理功能
  6. // @author shy
  7. // @match https://chat.deepseek.com/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_registerMenuCommand
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. /*developed with deepseek*/
  15. (function() {
  16. 'use strict';
  17.  
  18. // 初始化存储结构
  19. const initStorage = () => ({
  20. categories: {
  21. '默认分类': []
  22. },
  23. records: {}
  24. });
  25.  
  26. // 获取或初始化数据
  27. const getStorage = () => GM_getValue('classification', initStorage());
  28. const setStorage = (data) => GM_setValue('classification', data);
  29.  
  30. // 创建悬浮控件
  31. const createFloatingUI = () => {
  32. const container = document.createElement('div');
  33. container.style.cssText = `
  34. position: fixed;
  35. bottom: 20px;
  36. right: 20px;
  37. z-index: 9999;
  38. transition: all 0.3s ease;
  39. color: #007BFF; /* 新增全局颜色设置 */
  40. `;
  41.  
  42. // 悬浮按钮
  43. const toggleBtn = document.createElement('div');
  44. toggleBtn.innerHTML = '📁';
  45. toggleBtn.style.cssText = `
  46. cursor: pointer;
  47. background: white;
  48. border-radius: 50%;
  49. width: 40px;
  50. height: 40px;
  51. display: flex;
  52. align-items: center;
  53. justify-content: center;
  54. box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  55. `;
  56.  
  57. // 悬浮窗主体
  58. const panel = document.createElement('div');
  59. panel.style.cssText = `
  60. background: white;
  61. border-radius: 8px;
  62. box-shadow: 0 5px 15px rgba(0,0,0,0.2);
  63. width: 300px;
  64. max-height: 60vh;
  65. overflow: hidden;
  66. display: none;
  67. flex-direction: column;
  68. `;
  69.  
  70. // 头部
  71. const header = document.createElement('div');
  72. header.style.padding = '10px';
  73. header.style.borderBottom = '1px solid #eee';
  74. header.style.display = 'flex';
  75. header.style.justifyContent = 'space-between';
  76.  
  77. const title = document.createElement('h3');
  78. title.textContent = '对话分类';
  79. title.style.color = '#2196F3';
  80. title.style.margin = '0';
  81.  
  82. const addBtn = document.createElement('button');
  83. addBtn.textContent = '+';
  84. addBtn.onclick = addNewRecord;
  85.  
  86. header.append(title, addBtn);
  87.  
  88. // 内容区域
  89. const content = document.createElement('div');
  90. content.style.overflowY = 'auto';
  91. content.style.padding = '10px';
  92.  
  93. // 组装组件
  94. panel.append(header, content);
  95. container.append(toggleBtn, panel);
  96.  
  97. // 切换显示状态
  98. toggleBtn.onclick = () => {
  99. panel.style.display = panel.style.display === 'none'
  100. ? 'flex'
  101. : 'none';
  102. };
  103.  
  104. return { container, content };
  105. };
  106.  
  107. // 添加新记录
  108. const addNewRecord = async () => {
  109. const recordName = prompt('请输入记录名称:');
  110. if (!recordName) return;
  111.  
  112. const categoryPath = prompt('请输入分类路径(使用/分隔):\n示例: 工作/项目1') || '默认分类';
  113. const currentUrl = window.location.href;
  114.  
  115. const storage = getStorage();
  116.  
  117. // 创建分类结构
  118. const pathParts = categoryPath.split('/');
  119. let currentLevel = storage.categories;
  120.  
  121. pathParts.forEach((part, index) => {
  122. if (!currentLevel[part]) {
  123. currentLevel[part] = index === pathParts.length - 1 ? [] : {};
  124. }
  125. currentLevel = currentLevel[part];
  126. });
  127.  
  128. // 添加记录
  129. storage.records[Date.now()] = {
  130. name: recordName,
  131. url: currentUrl,
  132. path: categoryPath
  133. };
  134.  
  135. setStorage(storage);
  136. refreshContent();
  137. };
  138.  
  139. // 渲染分类树
  140. const renderTree = (container, categories, path = '') => {
  141. const ul = document.createElement('ul');
  142. ul.style.listStyle = 'none';
  143. ul.style.paddingLeft = '15px';
  144.  
  145. for (const [name, value] of Object.entries(categories)) {
  146. const li = document.createElement('li');
  147.  
  148. // 分类节点
  149. const categorySpan = document.createElement('span');
  150. categorySpan.style.color = '#007BFF'; // 深蓝色
  151. categorySpan.style.fontWeight = '500'; // 增加可读性
  152. categorySpan.textContent = name;
  153. categorySpan.style.cursor = 'pointer';
  154.  
  155. // 记录显示
  156. const recordsDiv = document.createElement('div');
  157. recordsDiv.style.display = 'none';
  158.  
  159. if (Array.isArray(value)) {
  160. // 显示记录
  161. const records = getStorage().records;
  162. Object.values(records)
  163. .filter(r => r.path === (path ? `${path}/${name}` : name))
  164. .forEach(record => {
  165. const recordDiv = document.createElement('div');
  166. recordDiv.style.color = '#FE5F5F'; // 与标题同色系
  167. recordDiv.textContent = record.name;
  168. recordDiv.style.cursor = 'pointer';
  169. recordDiv.style.padding = '5px';
  170. recordDiv.style.margin = '2px 0';
  171. recordDiv.style.borderRadius = '4px';
  172. recordDiv.style.backgroundColor = '#f5f5f5';
  173. recordDiv.onclick = () => window.open(record.url, '_blank');
  174.  
  175. // 右键菜单事件
  176. recordDiv.addEventListener('contextmenu', (e) => {
  177. e.preventDefault(); // 阻止默认右键菜单
  178. if (confirm(`是否删除记录: ${record.name}?`)) {
  179. deleteRecord(record); // 删除记录
  180. }
  181. });
  182.  
  183. recordsDiv.append(recordDiv);
  184. });
  185. } else {
  186. // 递归子分类
  187. renderTree(recordsDiv, value, path ? `${path}/${name}` : name);
  188. }
  189.  
  190. // 切换显示
  191. categorySpan.onclick = () => {
  192. recordsDiv.style.display = recordsDiv.style.display === 'none'
  193. ? 'block'
  194. : 'none';
  195. };
  196.  
  197. li.append(categorySpan, recordsDiv);
  198. ul.append(li);
  199. }
  200.  
  201. container.append(ul);
  202. };
  203.  
  204. // 删除记录
  205. const deleteRecord = (record) => {
  206. const storage = getStorage();
  207. const records = storage.records;
  208. // 找到记录的时间戳
  209. const timestamp = Object.keys(records).find(t => records[t].name === record.name && records[t].url === record.url);
  210. if (timestamp) {
  211. delete records[timestamp];
  212. setStorage(storage);
  213. refreshContent();
  214. }
  215. };
  216.  
  217. // 刷新内容
  218. const refreshContent = () => {
  219. contentContainer.innerHTML = '';
  220. const storage = getStorage();
  221. renderTree(contentContainer, storage.categories);
  222. };
  223.  
  224. // 初始化
  225. const { container, content: contentContainer } = createFloatingUI();
  226. document.body.append(container);
  227. refreshContent();
  228.  
  229. // 注册(不可用)菜单命令
  230. GM_registerMenuCommand('清除所有数据', () => {
  231. if (confirm('确定要清除所有分类数据吗?')) {
  232. setStorage(initStorage());
  233. refreshContent();
  234. }
  235. });
  236. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址