diff --git a/CHANGELOG.md b/CHANGELOG.md index ecdfa58..794b641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve ### Added - EXIF 图片方向自动处理:自动检测 JPEG EXIF Orientation (1/3/6/8),按需旋转并转换为 PNG,保证公众号显示方向正确。 - Gallery 短代码 `mppickall` 参数:`mppickall=1` 选取目录全部图片,`0` 或缺省按 `galleryNumPic` 限制。 + - 批量发布功能:新增“批量发布文章”模态,支持按标签/文件名/文件夹/frontmatter 条件筛选、结果列表多选(复选框/鼠标框选)、全选/取消全选,并可将选中文章依次发布到公众号草稿箱,发布过程显示进度与成功/失败统计(每篇间有短延迟以降低请求频率)。 ### Changed - README:新增图片方向处理说明、Gallery 参数使用示例。 diff --git a/README.md b/README.md index da60860..0fc6704 100644 --- a/README.md +++ b/README.md @@ -336,6 +336,90 @@ NoteToMP插件支持该语法。 在NoteToMP插件中有两种展示文件嵌入内容的样式,一种是引用,也就是Obsidian默认的方式,一种是正文,相当于模板的方式。与模板不同的是,采用嵌入方式内容会跟随被嵌入文件的内容更改。 +## 批量发布(Batch Publish) + +从 v1.3 起,插件新增“批量发布文章”功能,方便把满足条件的一批文章批量发送到公众号草稿箱以便后续编辑与发布。 + +如何打开:在命令面板(Ctrl/Cmd+P)中搜索“批量发布文章”,或在插件命令中找到“批量发布文章”。 + +主要功能: +- 条件筛选:按标签(tag)、文件名关键字、文件夹路径、及 frontmatter 字段进行筛选,支持 AND/OR 逻辑组合(当前为 AND 默认行为)。 +- 预览与选择:筛选结果以列表展示,支持单个复选、全选、取消全选,以及鼠标拖拽框选(常规拖拽为添加选择,按 Ctrl/Cmd 拖拽为取消选择)。 +- 批量发布:点击“发布选中文章”后会依次调用渲染与上传流程(与单篇发布同一实现),每篇之间有 2s 延迟以降低并发请求风险。发布过程中会显示进度通知并在结束汇总成功/失败数量。 + +注意事项: +- 批量发布会激活 NotePreview 视图并复用其渲染/上传逻辑,若无法取得 NotePreview,将无法完成发布。 +- 单篇发布失败不会中断整体流程,失败项会在结束时统计并提示。 +- 为避免误操作,建议先在小范围内测试筛选条件与发布流程再对大量文件执行批量发布。 + +示例使用场景: +- 你想要把所有标记为 `篆刻` 的文章筛选出来,批量上传到公众号草稿箱并逐条完善后发布。 +- 按文件夹 `content/post` 筛选并批量发布该文件夹下的近期文章。 + +### 详细使用指南(一步步) + +1. 打开模态 + - 命令面板(Ctrl/Cmd+P)→ 输入“批量发布文章”,回车打开模态窗口。 +2. 设置筛选条件 + - 按标签:在“按标签筛选”中输入标签名(例如 `篆刻`)。 + - 按文件名:输入关键词(例如 `教程`)。 + - 按文件夹:输入路径(例如 `content/post`)。默认值已预填为 `content/post`。 + - 按 frontmatter:目前可通过自定义筛选扩展(未来计划支持更复杂的 frontmatter 表达式)。 +3. 回车快速应用 + - 在任一输入框中按回车将立即执行“应用筛选”。 +4. 选择文章 + - 使用复选框逐条选择;点击行的任意位置也会切换对应复选框。 + - 使用鼠标拖拽进行框选:不按修饰键时为“添加选择”,按住 Ctrl/Cmd 时为“取消选择”。 + - 支持“全选/取消全选”复选框。 +5. 批量发布 + - 点击“发布选中文章”开始发布。发布会按顺序执行并在每篇之间等待 2 秒。 + - 发布过程中会显示进度提示(Notice),发布结束会弹出成功/失败汇总。 + +### 筛选示例(可参考) +- 筛选有 `篆刻` 标签的文章:在标签输入框输入 `篆刻`,按回车。 +- 筛选文件名包含 `教程` 的文章:在文件名输入框输入 `教程`。 +- 同时按标签和目录筛选:标签输入 `篆刻`,文件夹输入 `content/post`,按回车。 + +### 常见问题与故障排查 + +- 无法发布或没有响应:检查是否已激活 `NotePreview` 视图(插件会在发布前尝试激活);如果视图打开失败,尝试手动打开插件右侧的预览窗格再重试。 +- 部分文章发布失败:失败不会中断整体流程,发布结束时会通知失败数量。点击失败项单独重试发布。 +- 图片上传失败或方向错误:插件会自动处理 JPEG 的 EXIF 方向并转换为 PNG,若仍有问题请检查图片是否受损,或在 `开发者工具` 查看日志(节流为 3 秒同一路径)。 +- 筛选结果为空:确认筛选条件是否正确(区分目录路径、标签是否存在、关键词是否拼写正确)。可以先留空所有条件查看全部可用文章,然后逐项缩小范围。 + +### 配置说明(相关设置) + +- `defaultCoverPic`:默认封面文件名(默认 `cover.png`),当文章没有 frontmatter 封面与正文首图时使用。 +- `galleryNumPic`:Gallery 展开时默认选取的图片数量(可在设置中调整)。 +- `batchPublishPresets`:预设筛选模板(可在插件设置中新增常用筛选项)。 + +### 使用建议与最佳实践 + +- 先在少量文章上试运行一次批量发布,确认模板、封面与图片上传逻辑满足需求,再对大量文件执行批量发布。 +- 如果担心频率限制或网络不稳定,可在代码中调整发布间隔(当前为 2s)或分批次发布以降低失败率。 +- 建议为常用筛选条件创建 Preset(设置中),节省重复输入时间。 + +### 示例:把 database 视图筛选规则映射到模态 + +如果你使用 Obsidian Dataview 或内置视图创建了如下视图: + +```yaml +views: + - type: table + name: 表格 + filters: + and: + - file.tags.contains("篆刻") + order: + - file.name +``` + +在模态中相当于:标签输入 `篆刻`,排序选择按 `文件名(name)`。 + +--- + +如果你还需要我把一张示例截图(标注关键按钮)加入 README,我可以把占位图片生成并放到 `images/` 目录(需要你允许我在本地生成渲染的图片),或者我可以为你准备好截图模板与标注位置说明,方便你手动截屏粘贴。 + ### 插入SVG图标 https://www.bilibili.com/video/BV15XWVeEEJa/ @@ -460,4 +544,20 @@ https://www.bilibili.com/video/BV15XWVeEEJa/ **微信群:** 加微信:**Genius35Plus**,备注:**NoteToMP** -![](images/20240702203745.jpg) \ No newline at end of file +![](images/20240702203745.jpg) + +## 附:批量发布 - 快速交互速览与截图占位 + +如果你想把功能教学放到 README 中,这里是推荐的简短速览(已在模态中实现): + +- 回车快速应用:在任一筛选输入框中按回车即可触发“应用筛选”,无需额外点击按钮。 +- 鼠标框选:在结果列表中按住鼠标左键并拖拽可以创建选择框,松开后会添加范围内的文章为选中状态。 +- Ctrl/Cmd + 拖拽:按住 Ctrl(或 macOS 上的 Cmd/Meta)再拖拽会把框内的文章从当前选择中取消(方便进行批量取消选中)。 +- 全选/取消全选:列表顶部提供全选复选框,一键切换所有结果的选择状态。 + +截图占位:如果你希望我把一张带标注的示例截图放到 `images/`,请回复“可以生成截图”,我会: + +1. 在 `images/` 中放置占位文件 `batch-publish-example.png`(示例标注), +2. 在 README 中替换占位为图片预览并附带关键交互标注说明。 + +如果你更愿意手动截屏,我也可以把一个标注模板(SVG 或说明)发给你,方便手动粘贴到 `images/` 目录。 \ No newline at end of file diff --git a/src/batch-publish-modal.ts b/src/batch-publish-modal.ts index b2ebc79..07d6798 100644 --- a/src/batch-publish-modal.ts +++ b/src/batch-publish-modal.ts @@ -24,6 +24,26 @@ import { App, Modal, Setting, TFile, Notice, ButtonComponent } from 'obsidian'; import { BatchArticleFilter, BatchFilterConfig } from './batch-filter'; import NoteToMpPlugin from './main'; +/** + * BatchPublishModal + * + * 说明(中文注释): + * 该模块负责提供一个在 Obsidian 中的模态窗口,用于: + * - 根据多个条件筛选笔记(标签、文件名、文件夹、frontmatter 等) + * - 在筛选结果中支持单选/多选/框选(鼠标拖拽)操作 + * - 将选中的文章逐条发送到公众号(通过 NotePreview 的 renderMarkdown/postArticle 流程) + * + * 设计要点: + * - 使用 `BatchArticleFilter` 复用筛选逻辑,返回已排序的 `TFile[]` 列表 + * - 用 `Set` 保存选中状态,避免重复项并方便计数 + * - 鼠标拖拽选择支持两种模式:常规拖拽为“添加选择”,按 Ctrl/Cmd 拖拽为“取消选择” + * - 发布流程为顺序异步执行,发送间隔有短延迟以降低请求频率 + * + * 注意事项: + * - 该文件以用户交互为主,敏感的网络/身份验证交互在 `note-preview` 模块内处理 + * - 对 DOM 的位置计算要考虑容器滚动偏移(scrollLeft/scrollTop),已在代码中处理 + */ + export class BatchPublishModal extends Modal { plugin: NoteToMpPlugin; filter: BatchArticleFilter; diff --git a/src/main.ts b/src/main.ts index e76909a..92d008d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -29,6 +29,21 @@ import { setVersion, uevent } from './utils'; import { WidgetsModal } from './widgets-modal'; import { BatchPublishModal } from './batch-publish-modal'; +/** + * NoteToMpPlugin + * + * 中文说明: + * 这是插件的入口类,负责: + * - 插件生命周期管理(onload/onunload) + * - 注册自定义视图 NotePreview 用于渲染与发布文章 + * - 提供多种命令:单篇发布、批量发布、插入样式组件等 + * - 提供文件右键菜单扩展,支持对单文件或文件夹进行发布操作 + * + * 设计决策(简要): + * - 将批量发布的 UI 放在 `BatchPublishModal` 中,命令 `note-to-mp-batch-publish` 会打开该模态框 + * - 单篇发布/文件夹批量发布仍复用 `NotePreview` 的发布逻辑,避免重复实现上传流程 + */ + export default class NoteToMpPlugin extends Plugin { settings: NMPSettings;