# Note2Any v1.4.0 架构快速参考指南 > **重大更新**: v1.4.0引入了全新的模块化核心系统,本文档为新架构的快速参考。 > > **相关文档**: [详细架构文档](./architecture-v1.4.0.md) | [升级对比](./ARCHITECTURE_COMPARISON.md) ## 📋 新文件结构 ``` src/ ├── main.ts # 插件入口 (集成核心模块) ├── preview-view.ts # Obsidian 视图容器 (增强版) ├── preview-manager.ts # 中央调度器 ★ ├── platform-chooser.ts # 平台选择器 ├── article-render.ts # 内容渲染 (重构中) ├── core/ # 🆕 核心模块系统 │ ├── error-handler.ts # 统一错误处理 │ ├── progress-indicator.ts # 进度反馈系统 │ ├── config-manager.ts # 配置管理中心 │ ├── publisher-interface.ts # 发布平台抽象 │ ├── publisher-manager.ts # 发布管理器 │ ├── content-processor.ts # 内容处理流水线 │ ├── gallery-processor.ts # 图库处理器 │ ├── image-processor.ts # 图像处理引擎 │ └── html-processor.ts # HTML生成器 ├── wechat/ │ └── wechat-preview.ts # 微信预览 └── xiaohongshu/ └── xhs-preview.ts # 小红书预览 ``` ## 🎯 核心模块职责 (v1.4.0 新增) ### 核心支撑层 #### ErrorHandler - 统一错误处理 **职责**: - 全局错误捕获和分类 - 用户友好的错误提示 - 错误日志记录和分析 - 错误恢复策略 **关键方法**: ```typescript ErrorHandler.handle(error: Error, context: string): void ErrorHandler.log(level: LogLevel, message: string): void ErrorHandler.getUserFriendlyMessage(error: Error): string ``` **使用示例**: ```typescript try { await risky_operation(); } catch (error) { ErrorHandler.handle(error, 'MyModule.doSomething'); // 用户将看到友好的错误提示 } ``` --- #### ProgressIndicator - 进度反馈系统 **职责**: - 长时间操作的进度反馈 - 统一的用户状态提示 - 可视化进度显示 **关键方法**: ```typescript progress.start(message: string): void progress.update(message: string, progress?: number): void progress.finish(message: string): void progress.error(message: string): void ``` **使用示例**: ```typescript const progress = new ProgressIndicator(); progress.start('处理图片'); progress.update('上传第1张图片', 25); progress.update('上传第2张图片', 50); progress.finish('图片处理完成'); ``` --- #### ConfigManager - 配置管理中心 **职责**: - 中心化配置管理 - 运行时配置验证 - 配置变更通知 - 类型安全的配置访问 **关键方法**: ```typescript ConfigManager.initialize(settings: NMPSettings): void ConfigManager.getInstance(): ConfigManager config.get(key: string): T config.set(key: string, value: T): void ``` **使用示例**: ```typescript const config = ConfigManager.getInstance(); const theme = config.get('defaultStyle'); config.set('enableDebug', true); ``` --- ### 发布平台层 #### PublisherInterface & PublisherManager **职责**: - 统一的平台发布接口 - 平台无关的业务逻辑 - 可扩展的平台架构 **平台接口**: ```typescript interface IPlatformPublisher { id: string; name: string; initialize(config: PlatformConfig): Promise; publish(content: PublishContent): Promise; uploadImage(image: ImageData): Promise; validateConfig(): ValidationResult; } ``` **使用示例**: ```typescript const publisherManager = PublisherManager.getInstance(); const result = await publisherManager.publishTo('wechat', content); ``` --- ### 内容处理层 #### ContentProcessor - 内容处理流水线 **职责**: - 模块化内容处理 - 可配置的处理管道 - 支持自定义扩展 **处理器接口**: ```typescript interface IContentProcessor { id: string; priority: number; process(content: string, context: ProcessContext): Promise; } ``` **使用示例**: ```typescript const processor = new ContentProcessor(); processor.addProcessor(new GalleryProcessor()); processor.addProcessor(new ImageProcessor()); const result = await processor.process(markdown); ``` --- #### ImageProcessor - 图像处理引擎 **职责**: - WebP转JPG转换 - 批量图片处理 - 微信图片上传 - HTML转PNG功能 **关键方法**: ```typescript async convertWebpToJpg(data: ArrayBuffer): Promise async uploadToWechat(data: ArrayBuffer, filename: string, token: string): Promise async htmlToPng(element: HTMLElement): Promise ``` --- #### GalleryProcessor - 图库处理器 **职责**: - 图库短代码解析 - 本地图片目录扫描 - Wikilink格式转换 **关键方法**: ```typescript async processGalleryShortcodes(content: string): Promise ``` --- #### HtmlProcessor - HTML生成器 **职责**: - HTML文档生成 - CSS样式内联 - 响应式设计优化 - 移动端适配 **关键方法**: ```typescript generateFullHtml(content: string, options: HtmlProcessOptions): string optimizeForMobile(html: string): string ``` --- ## 🔄 新架构调用关系图 ``` PreviewView (Obsidian容器) │ ├─ 集成 ─> ProgressIndicator (进度反馈) ├─ 集成 ─> ErrorHandler (错误处理) │ └─ holds ─> PreviewManager (协调者) │ ├─ 使用 ─> ConfigManager (配置管理) ├─ 使用 ─> PublisherManager (发布管理) ├─ 使用 ─> ContentProcessor (内容处理) │ │ │ ├─ GalleryProcessor │ ├─ ImageProcessor │ └─ HtmlProcessor │ ├─ creates ─> PlatformChooser ├─ creates ─> WechatPreview └─ creates ─> XhsPreview ``` --- ## 📝 常见任务示例 (v1.4.0) ### 1. 添加新的内容处理器 **步骤一**:实现处理器接口 ```typescript // src/processors/my-processor.ts import { IContentProcessor, ProcessContext } from '../core/content-processor'; export class MyContentProcessor implements IContentProcessor { id = 'my-processor'; priority = 100; // 优先级,数字越小越先执行 async process(content: string, context: ProcessContext): Promise { // 实现自定义处理逻辑 const processed = content.replace(/\{\{custom\}\}/g, 'Custom Content'); return processed; } } ``` **步骤二**:注册处理器 ```typescript // src/main.ts 或相关初始化文件 import { MyContentProcessor } from './processors/my-processor'; const contentProcessor = ContentProcessor.getInstance(); contentProcessor.addProcessor(new MyContentProcessor()); ``` --- ### 2. 添加新平台支持 **步骤一**:实现平台发布接口 ```typescript // src/platforms/my-platform-publisher.ts import { IPlatformPublisher, PlatformConfig, PublishContent, PublishResult } from '../core/publisher-interface'; export class MyPlatformPublisher implements IPlatformPublisher { id = 'my-platform'; name = 'My Platform'; async initialize(config: PlatformConfig): Promise { // 平台初始化逻辑 const progress = new ProgressIndicator(); progress.start('初始化平台连接'); try { // 验证配置、建立连接等 progress.finish('平台初始化完成'); } catch (error) { progress.error('平台初始化失败'); ErrorHandler.handle(error, 'MyPlatformPublisher.initialize'); throw error; } } async publish(content: PublishContent): Promise { const progress = new ProgressIndicator(); progress.start('发布内容'); try { // 发布逻辑实现 progress.finish('发布成功'); return { success: true, id: 'published-id' }; } catch (error) { progress.error('发布失败'); ErrorHandler.handle(error, 'MyPlatformPublisher.publish'); throw error; } } async uploadImage(image: ImageData): Promise { // 图片上传逻辑 return 'uploaded-image-url'; } validateConfig(): ValidationResult { // 配置验证逻辑 return { valid: true }; } } ``` **步骤二**:注册平台 ```typescript // src/main.ts import { MyPlatformPublisher } from './platforms/my-platform-publisher'; const publisherManager = PublisherManager.getInstance(); publisherManager.registerPublisher(new MyPlatformPublisher()); ``` --- ### 3. 使用统一错误处理 **在模块中使用**: ```typescript export class MyModule { async doSomething() { const progress = new ProgressIndicator(); progress.start('执行操作'); try { // 可能出错的操作 await riskyOperation(); progress.finish('操作完成'); } catch (error) { progress.error('操作失败'); ErrorHandler.handle(error as Error, 'MyModule.doSomething'); // 错误已被处理,用户已看到友好提示 throw error; // 可选:继续抛出供上层处理 } } } ``` --- ### 4. 配置管理最佳实践 **读取配置**: ```typescript const config = ConfigManager.getInstance(); // 类型安全的配置访问 const theme = config.get('defaultStyle'); const enableDebug = config.get('enableDebug'); const timeout = config.get('requestTimeout'); ``` **监听配置变更**: ```typescript config.onUpdate((updatedConfig) => { console.log('配置已更新:', updatedConfig); // 响应配置变更 }); ``` --- ## 🐛 调试技巧 (v1.4.0) ### 1. 查看模块状态 在浏览器控制台中: ```javascript // 查看错误处理器状态 console.log('错误统计:', ErrorHandler.getErrorStats()); // 查看配置管理器状态 const config = ConfigManager.getInstance(); console.log('当前配置:', config.getAll()); // 查看发布管理器状态 const publisherManager = PublisherManager.getInstance(); console.log('可用平台:', publisherManager.listAvailablePublishers()); // 查看内容处理器状态 const contentProcessor = ContentProcessor.getInstance(); console.log('已注册处理器:', contentProcessor.getProcessors()); ``` ### 2. 启用调试模式 ```typescript // 在开发环境中启用详细日志 const config = ConfigManager.getInstance(); config.set('enableDebug', true); config.set('logLevel', 'debug'); ``` ### 3. 错误追踪 ```typescript // 注册错误监听器 ErrorHandler.onError((error, context) => { console.log(`错误发生在: ${context}`, error); // 可以发送到错误监控服务 }); ``` --- ## ⚠️ 注意事项 (v1.4.0) ### 1. 模块初始化顺序 ```typescript // ✅ 正确的初始化顺序 await ErrorHandler.initialize(); await ConfigManager.initialize(settings); await PublisherManager.initialize(); await ContentProcessor.initialize(); // ❌ 错误(ConfigManager 未初始化就使用) const config = ConfigManager.getInstance(); // 可能抛出错误 ``` ### 2. 错误处理最佳实践 ```typescript // ✅ 正确(使用统一错误处理) try { await operation(); } catch (error) { ErrorHandler.handle(error, 'Module.method'); } // ❌ 错误(绕过错误处理系统) try { await operation(); } catch (error) { console.error(error); // 用户不会收到友好提示 } ``` ### 3. 进度反馈规范 ```typescript // ✅ 正确(完整的进度生命周期) const progress = new ProgressIndicator(); progress.start('开始操作'); try { progress.update('步骤1', 25); await step1(); progress.update('步骤2', 50); await step2(); progress.finish('操作完成'); } catch (error) { progress.error('操作失败'); throw error; } // ❌ 错误(没有结束进度指示器) const progress = new ProgressIndicator(); progress.start('开始操作'); await operation(); // 如果出错,进度指示器会一直显示 ``` --- ## 🚀 性能优化建议 ### 1. 模块懒加载 ```typescript // 按需加载重型模块 const imageProcessor = await import('./core/image-processor'); const processor = new imageProcessor.ImageProcessor(); ``` ### 2. 缓存优化 ```typescript // 利用配置管理器的缓存 const config = ConfigManager.getInstance(); const cachedTheme = config.get('currentTheme'); // 自动缓存 ``` ### 3. 批量操作 ```typescript // 使用批量处理API const imageProcessor = new ImageProcessor(); const results = await imageProcessor.processImages(imageList, options); ``` --- ## 📚 相关文档 - [详细架构文档](./architecture-v1.4.0.md) - 完整的架构说明 - [模块开发指南](./module-development-guide.md) - 如何开发新模块 - [发布平台开发](./publisher-development.md) - 如何添加新平台 - [错误处理指南](./error-handling-guide.md) - 错误处理最佳实践 - [性能优化指南](./performance-optimization.md) - 性能优化建议 --- **架构版本**:v1.4.0 (模块化核心系统) **最后更新**:2025年10月16日 ## 🎯 各文件职责 ### preview-view.ts **角色**:Obsidian 视图容器 **职责**: - 实现 `ItemView` 接口 - 管理视图生命周期 - 监听 Obsidian 事件 - 委托业务逻辑给 `PreviewManager` **关键方法**: ```typescript async onOpen() // 视图打开 async onClose() // 视图关闭 async setFile(file) // 设置文件 async refresh() // 刷新预览 ``` --- ### preview-manager.ts ★ **角色**:中央调度器(核心) **职责**: - 创建和管理所有子组件 - 协调平台切换 - 管理文件渲染 - 统一对外接口 **关键方法**: ```typescript async build() // 构建界面 private switchPlatform(platform) // 平台切换(唯一入口) async setFile(file) // 设置文件 async refresh() // 刷新预览 private renderForWechat(file) // 渲染微信 private renderForXiaohongshu(file) // 渲染小红书 destroy() // 清理资源 ``` **创建流程**: ```typescript constructor(container, app, render) ↓ async build() ├─ createPlatformChooser() ├─ createWechatPreview() └─ createXiaohongshuPreview() ``` --- ### platform-chooser.ts **角色**:平台选择 UI 组件 **职责**: - 渲染平台选择下拉框 - 处理用户选择事件 - 触发平台切换回调 **关键方法**: ```typescript render() // 渲染 UI setOnChange(callback) // 设置回调 switchPlatform(platform) // 程序化切换 getCurrentPlatform() // 获取当前平台 ``` **使用示例**: ```typescript const chooser = new PlatformChooser(container); chooser.setOnChange((platform) => { console.log('切换到:', platform); }); chooser.render(); ``` --- ### wechat/wechat-preview.ts **角色**:微信公众号预览实现 **职责**: - 渲染微信专属工具栏 - 处理微信相关操作 - 管理微信公众号配置 **关键方法**: ```typescript build() // 构建 UI show() // 显示 hide() // 隐藏 updateStyleAndHighlight() // 更新样式 destroy() // 清理 // 待实现 uploadImages() // 上传图片 postArticle() // 发布草稿 exportHTML() // 导出 HTML ``` --- ### xiaohongshu/xhs-preview.ts **角色**:小红书预览实现 **职责**: - 渲染小红书专属界面 - 处理分页和切图 - 管理小红书样式 **关键方法**: ```typescript build() // 构建 UI show() // 显示 hide() // 隐藏 async renderArticle(html, file) // 渲染文章 destroy() // 清理 ``` --- ## 🔄 调用关系图 ``` PreviewView (视图容器) │ ├─ holds ─> PreviewManager (协调者) │ │ │ ├─ creates ─> PlatformChooser │ │ │ │ │ └─ onChange callback ─┐ │ │ │ │ ├─ creates ─> WechatPreview │ │ │ │ │ │ │ ├─ onRefreshCallback ─┤ │ │ └─ onAppIdChange ─────┤ │ │ │ │ └─ creates ─> XhsPreview │ │ │ │ │ ├─ onRefreshCallback ─────┤ │ ├─ onPublishCallback ─────┤ │ └─ onPlatformChange ──────┤ │ │ └──────────────────────────── all callbacks handled ─────┘ ``` --- ## 📝 常见任务示例 ### 1. 添加新平台(如抖音) **步骤一**:创建预览组件 ```typescript // src/douyin/douyin-preview.ts export class DouyinPreview { container: HTMLElement; app: any; constructor(container: HTMLElement, app: any) { this.container = container; this.app = app; } build(): void { // 构建抖音专属 UI } show(): void { this.container.style.display = 'flex'; } hide(): void { this.container.style.display = 'none'; } destroy(): void { // 清理资源 } } ``` **步骤二**:添加到支持列表 ```typescript // platform-chooser.ts const SUPPORTED_PLATFORMS: PlatformInfo[] = [ { value: 'wechat', label: '微信公众号', icon: '📱' }, { value: 'xiaohongshu', label: '小红书', icon: '📔' }, { value: 'douyin', label: '抖音', icon: '🎵' } // ← 新增 ]; // 更新类型定义 export type PlatformType = 'wechat' | 'xiaohongshu' | 'douyin'; ``` **步骤三**:集成到 PreviewManager ```typescript // preview-manager.ts import { DouyinPreview } from './douyin/douyin-preview'; export class PreviewManager { private douyinPreview: DouyinPreview | null = null; private createDouyinPreview(): void { const container = this.mainDiv!.createDiv({ cls: 'douyin-preview-container' }); this.douyinPreview = new DouyinPreview(container, this.app); this.douyinPreview.build(); } private async switchPlatform(platform: PlatformType): Promise { // ... 现有代码 if (platform === 'douyin') { this.showDouyin(); this.hideWechat(); this.hideXiaohongshu(); if (this.currentFile) { await this.renderForDouyin(this.currentFile); } } } private async renderForDouyin(file: TFile): Promise { // 实现抖音渲染逻辑 } } ``` --- ### 2. 修改平台切换逻辑 **位置**:`preview-manager.ts` **方法**:`switchPlatform()` ```typescript private async switchPlatform(platform: PlatformType): Promise { console.log(`切换平台: ${this.currentPlatform} → ${platform}`); const previousPlatform = this.currentPlatform; this.currentPlatform = platform; // 更新 UI this.platformChooser?.switchPlatform(platform); // 根据平台显示/隐藏 if (platform === 'wechat') { this.showWechat(); this.hideXiaohongshu(); // 如果需要,重新渲染 if (this.currentFile && previousPlatform !== 'wechat') { await this.renderForWechat(this.currentFile); } } else if (platform === 'xiaohongshu') { this.showXiaohongshu(); this.hideWechat(); if (this.currentFile && previousPlatform !== 'xiaohongshu') { await this.renderForXiaohongshu(this.currentFile); } } } ``` --- ### 3. 添加新的回调函数 **场景**:在微信预览中添加新的操作按钮 **步骤一**:在 WechatPreview 中定义回调 ```typescript // wechat-preview.ts export class WechatPreview { onCustomActionCallback?: () => Promise; private buildToolbar() { // ... 现有代码 const customBtn = lineDiv.createEl('button', { text: '自定义操作', cls: 'toolbar-button' }); customBtn.onclick = async () => { if (this.onCustomActionCallback) { await this.onCustomActionCallback(); } }; } } ``` **步骤二**:在 PreviewManager 中设置回调 ```typescript // preview-manager.ts private createWechatPreview(): void { // ... 现有代码 this.wechatPreview.onCustomActionCallback = async () => { await this.handleCustomAction(); }; } private async handleCustomAction(): Promise { // 实现自定义操作逻辑 console.log('执行自定义操作'); } ``` --- ### 4. 监听文件变化 **位置**:`preview-view.ts` **方法**:`registerEventListeners()` ```typescript private registerEventListeners(): void { // 监听文件切换 this.listeners.push( this.app.workspace.on('file-open', async (file: TFile | null) => { if (this.manager) { await this.manager.setFile(file); } }) ); // 监听文件修改 this.listeners.push( this.app.vault.on('modify', async (file) => { if (file instanceof TFile) { const currentFile = this.manager?.getCurrentFile(); if (currentFile && currentFile.path === file.path) { await this.manager?.refresh(); } } }) ); // 添加新的事件监听 this.listeners.push( this.app.workspace.on('your-custom-event', async (data) => { // 处理自定义事件 }) ); } ``` --- ## 🐛 调试技巧 ### 1. 查看平台切换流程 在 `preview-manager.ts` 中添加日志: ```typescript private async switchPlatform(platform: PlatformType): Promise { console.log(`[PreviewManager] 切换平台: ${this.currentPlatform} → ${platform}`); console.log('[PreviewManager] 当前文件:', this.currentFile?.path); // ... 现有代码 console.log('[PreviewManager] 平台切换完成'); } ``` ### 2. 检查组件状态 在浏览器控制台中: ```javascript // 查看所有预览视图 app.workspace.getLeavesOfType('note-preview') // 获取 PreviewView 实例 const leaf = app.workspace.getLeavesOfType('note-preview')[0] const previewView = leaf.view // 查看 PreviewManager 状态(通过 private 访问需要技巧) console.log(previewView.manager) ``` ### 3. 断点调试 在关键方法中设置断点: - `PreviewManager.switchPlatform()` - `PreviewManager.setFile()` - `PreviewManager.renderForWechat()` - `PreviewManager.renderForXiaohongshu()` --- ## ⚠️ 注意事项 ### 1. 回调函数必须在构建前设置 ```typescript // ✅ 正确 this.wechatPreview = new WechatPreview(...); this.wechatPreview.onRefreshCallback = async () => { ... }; this.wechatPreview.build(); // ❌ 错误(回调可能不会生效) this.wechatPreview = new WechatPreview(...); this.wechatPreview.build(); this.wechatPreview.onRefreshCallback = async () => { ... }; ``` ### 2. 平台切换不要直接修改 currentPlatform ```typescript // ❌ 错误(绕过了协调逻辑) previewManager.currentPlatform = 'xiaohongshu'; // ✅ 正确(通过 switchPlatform) await previewManager.switchPlatform('xiaohongshu'); ``` ### 3. 清理资源 在组件销毁时必须清理资源: ```typescript destroy(): void { // 清理 DOM 引用 this.container = null as any; // 清理子组件 this.wechatPreview?.destroy(); this.xhsPreview?.destroy(); // 清理回调 this.onRefreshCallback = undefined; } ``` --- ## 📚 相关文档 - [完整重构总结](./ARCHITECTURE_REFACTORING_COMPLETE.md) - [架构对比](./ARCHITECTURE_COMPARISON.md) - [平台重构总结](./PLATFORM_REFACTORING_SUMMARY.md) --- **最后更新**:2025年1月 **架构版本**:v2.0(引入 PreviewManager)