从「选中一段」到「整章润色」:编辑器里的 AI 润色是怎么做出来的

📅 发布时间:2026/7/3 11:44:54 👁️ 浏览次数:
从「选中一段」到「整章润色」:编辑器里的 AI 润色是怎么做出来的
从「选中一段」到「整章润色」编辑器里的 AI 润色是怎么做出来的在51 码字里写作者可以选中任意一段文字或整章正文一键交给 AI 润色在弹框里对比原文与润色结果再决定是「替换」还是「复制走」。本文从产品意图到技术实现拆解这套「AI 润色」功能是如何在 Electron Vue TipTap 编辑器里落地的。51 码字为完全开源项目完整代码与可运行程序欢迎在GitHub查看与下载体验。 目录功能长什么样为什么这样设计技术架构谁负责什么前端选区 vs 整章、弹框与替换主进程与 DeepSeek润色接口与 IPC小结与可扩展点体验完整功能与 GitHub功能长什么样在章节编辑页编辑区右上角有一个半透明的「AI 润色」按钮鼠标悬停时变为不透明点击后出现下拉菜单菜单项含义润色选中文本先选中一段或多段文字再点此项只对选区内容调用 AI 润色。润色整章不依赖选区把当前章节的整篇正文发给 AI 润色。无论选哪一种都会把对应纯文本发到 DeepSeek 做润色弹出左右分栏的弹框左侧「原文」右侧「润色后」底部提供取消、一键复制复制润色结果、确认替换用润色结果替换选区或整章。未选中文字就点「润色选中文本」时会提示「请先选中要润色的文本」整章为空时点「润色整章」会提示「当前章节内容为空无法润色」。为什么这样设计润色选中文本适合「这一段写得不顺只想改这一块」的场景减少误改、提高可控性。润色整章适合「整章初稿写完想统一提升一遍语感」的场景一次请求、一次确认。弹框左右对比 一键复制方便先看再决定——要么在编辑器里直接「确认替换」要么「一键复制」到别处用不强制覆盖原文。这样既照顾「局部打磨」又照顾「整章优化」同时把「是否替换」的决策权留给用户。技术架构谁负责什么整体仍是「渲染进程只负责 UI 与编辑器状态主进程负责调用 DeepSeek、保管 API Key」的拆分方式。┌─────────────────────────────────────────────────────────────────┐ │ EditorPanel.vueVue 3 TipTap │ │ · 获取选区/整章纯文本 · 弹框展示 · 替换选区/整章 · 一键复制 │ └────────────────────────────┬────────────────────────────────────┘ │ window.electron.polishTextWithAI(text) ▼ ┌─────────────────────────────────────────────────────────────────┐ │ PreloadcontextBridge │ │ polishTextWithAI(text) → ipcRenderer.invoke(deepseek:polish-text, { text }) │ └────────────────────────────┬────────────────────────────────────┘ │ IPC ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 主进程Node │ │ ipcMain.handle(deepseek:polish-text, …) → deepseekService.polishChapter(text) │ └────────────────────────────┬────────────────────────────────────┘ │ HTTP ▼ ┌─────────────────────────────────────────────────────────────────┐ │ DeepSeek Chat API/chat/completions │ │ 系统提示专业写作编辑润色整章正文只输出正文、无解释 │ └─────────────────────────────────────────────────────────────────┘渲染进程不碰 API Key只通过window.electron.polishTextWithAI(text)传纯文本、收润色结果。主进程负责鉴权、限频、调用 DeepSeek并返回{ success, content }或错误信息。Preload只做 IPC 桥接把「润色」这一能力以「一个函数」的形式暴露给前端。前端选区 vs 整章、弹框与替换编辑器基于TipTapProseMirror因此「选区」和「整章」都来自同一套文档模型。润色选中文本从editor.state.selection取from、to。若from to说明是光标而非选区提示「请先选中要润色的文本」。否则用state.doc.textBetween(from, to, \n)得到选区纯文本发给polishTextWithAI(text)。弹框打开前把polishMode设为selection并保存polishReplaceFrom、polishReplaceTo。用户点「确认替换」时用TipTap 的insertContentAt({ from, to }, polishedText)只替换这一段其它内容不动。润色整章用editor.getText()取整章纯文本若为空提示「当前章节内容为空无法润色」。同样调用polishTextWithAI(fullText)弹框打开前把polishMode设为chapter。用户点「确认替换整章」时需要把纯文本转成编辑器可接受的HTML段落用p段内换行用br并做转义再用editor.chain().focus().setContent(html)整章替换。纯文本转 HTML 的规则可以简单归纳为按\n\n分段每段包成p…/p段内\n换成br并对、、等做转义避免注入和格式错乱。弹框与按钮弹框标题和底部主按钮根据polishMode切换「选中文本」时显示「AI 润色结果选中文本」和「确认替换」「整章」时显示「AI 润色结果整章」和「确认替换整章」。一键复制navigator.clipboard.writeText(polishResultText)成功后提示「已复制到剪贴板」不改变编辑器内容。弹框采用左右布局原文 | 润色后、宽度 80%内容区域可滚动便于长文对比。按钮位置与样式「AI 润色」按钮放在编辑区右上角在包裹编辑区的容器上使用position: absolute; top: 12px; right: 12px保证始终相对编辑区定位。默认半透明如opacity: 0.45悬停时变为不透明减少对写作时的视觉干扰。完整前端实现选区获取、弹框左右布局、一键复制与确认替换等逻辑均在 EditorPanel.vue 中欢迎在 GitHub 仓库查看带注释的源码。主进程与 DeepSeek润色接口与 IPC主进程里已有 DeepSeek 服务如src/main/services/deepseek.js润色只新增一个纯文本进、纯文本出的接口即可。完整实现可在 GitHub 仓库 中按文件名搜索查看。polishChapter(text)入参待润色的纯文本可以是选区的一段也可以是整章。系统提示强调角色是「专业中文写作编辑」、润色「整章正文」、优化表达与语病、保持原意与段落结构、只输出润色后的正文不要任何解释或前后缀。调用this.chat({ messages, temperature: 0.5, max_tokens: 8000, requestId })其中max_tokens留足空间给长章。返回从响应中取出contenttrim 后返回若为空则抛错「润色结果为空请重试」。这样「选中一段」和「润色整章」共用同一套 API 和提示词只是传入的文本长度不同。IPC 与 Preload主进程ipcMain.handle(deepseek:polish-text, async (_, { text }) { … })内部调用deepseekService.polishChapter(text)返回{ success, content }或{ success: false, message }。PreloadpolishTextWithAI: (text) ipcRenderer.invoke(deepseek:polish-text, { text })通过contextBridge挂到window.electron供渲染进程调用。API Key 的读取、限频、错误信息友好化等沿用项目里已有 DeepSeek 能力即可无需为润色单独开一套。小结与可扩展点产品支持「润色选中文本」和「润色整章」两种范围弹框左右对比 一键复制 确认替换满足局部打磨和整章优化两种场景。前端TipTap 选区selectiontextBetween与整章getText统一成「一段纯文本」替换时选区用insertContentAt整章用setContent(plainTextToEditorHtml(...))弹框与按钮根据polishMode切换文案。后端主进程提供polishChapter(text)IPC 暴露polish-textPreload 暴露polishTextWithAIAPI Key 与限频仍在主进程安全且易维护。后续若要增强可以考虑流式输出润色结果、支持「仅替换当前段落」的快捷方式、或对超长章做分段润色再合并等。当前实现已经为「选中即润、整章可替换」提供了一个清晰、可扩展的技术底座。 体验完整功能与 GitHub如果你想亲自体验 AI 润色或在自己的项目里做类似功能欢迎访问 51 码字开源仓库⭐Star 项目GitHub 仓库下载使用在 GitHub Release 中下载对应平台安装包配置 DeepSeek API Key 后即可使用 AI 润色查看源码编辑器润色 UI、主进程润色接口、IPC 与 Preload 暴露方式均有完整实现与注释反馈建议使用中若有问题或想法欢迎提 Issue 或 Discussion报告问题遇到 Bug 可直接在仓库提 Issue帮助项目改进51 码字— 开源小说写作软件让 AI 润色无缝融入写作流程。 相关链接项目地址GitHub - 51mazi给个 Star 哦~AI 润色编辑器侧EditorPanel.vue按钮、下拉、弹框、选区/整章逻辑、一键复制与替换DeepSeek 润色服务deepseek.js - polishChapter润色提示词与 Chat 调用主进程 IPCindex.js - deepseek:polish-text润色 IPC 注册Preload 暴露preload/index.jspolishTextWithAI暴露给渲染进程DeepSeek 官方文档DeepSeek API Documentation️ 标签#AI润色#DeepSeek#小说写作#51码字#Electron#Vue3#TipTap#编辑器#写作辅助#开源#创作效率如果这篇文章对你有帮助请到 GitHub 给个 ⭐️ Star就是对项目最好的支持想直接看实现细节欢迎在 GitHub 仓库 中打开上述代码文件每个模块都有注释说明。本文基于 51 码字51mazi开源项目中的 AI 润色功能整理技术栈Electron、Vue 3、TipTap、DeepSeek API。