964 lines
25 KiB
Markdown
964 lines
25 KiB
Markdown
# 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<T>(key: string): T
|
||
config.set<T>(key: string, value: T): void
|
||
```
|
||
|
||
**使用示例**:
|
||
```typescript
|
||
const config = ConfigManager.getInstance();
|
||
const theme = config.get<string>('defaultStyle');
|
||
config.set('enableDebug', true);
|
||
```
|
||
|
||
---
|
||
|
||
### 发布平台层
|
||
|
||
#### PublisherInterface & PublisherManager
|
||
**职责**:
|
||
- 统一的平台发布接口
|
||
- 平台无关的业务逻辑
|
||
- 可扩展的平台架构
|
||
|
||
**平台接口**:
|
||
```typescript
|
||
interface IPlatformPublisher {
|
||
id: string;
|
||
name: string;
|
||
initialize(config: PlatformConfig): Promise<void>;
|
||
publish(content: PublishContent): Promise<PublishResult>;
|
||
uploadImage(image: ImageData): Promise<string>;
|
||
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<string>;
|
||
}
|
||
```
|
||
|
||
**使用示例**:
|
||
```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<ArrayBuffer>
|
||
async uploadToWechat(data: ArrayBuffer, filename: string, token: string): Promise<string>
|
||
async htmlToPng(element: HTMLElement): Promise<Blob>
|
||
```
|
||
|
||
---
|
||
|
||
#### GalleryProcessor - 图库处理器
|
||
**职责**:
|
||
- 图库短代码解析
|
||
- 本地图片目录扫描
|
||
- Wikilink格式转换
|
||
|
||
**关键方法**:
|
||
```typescript
|
||
async processGalleryShortcodes(content: string): Promise<string>
|
||
```
|
||
|
||
---
|
||
|
||
#### 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<string> {
|
||
// 实现自定义处理逻辑
|
||
const processed = content.replace(/\{\{custom\}\}/g, '<span class="custom">Custom Content</span>');
|
||
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<void> {
|
||
// 平台初始化逻辑
|
||
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<PublishResult> {
|
||
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<string> {
|
||
// 图片上传逻辑
|
||
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<string>('defaultStyle');
|
||
const enableDebug = config.get<boolean>('enableDebug');
|
||
const timeout = config.get<number>('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<void> {
|
||
// ... 现有代码
|
||
|
||
if (platform === 'douyin') {
|
||
this.showDouyin();
|
||
this.hideWechat();
|
||
this.hideXiaohongshu();
|
||
|
||
if (this.currentFile) {
|
||
await this.renderForDouyin(this.currentFile);
|
||
}
|
||
}
|
||
}
|
||
|
||
private async renderForDouyin(file: TFile): Promise<void> {
|
||
// 实现抖音渲染逻辑
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 修改平台切换逻辑
|
||
|
||
**位置**:`preview-manager.ts`
|
||
**方法**:`switchPlatform()`
|
||
|
||
```typescript
|
||
private async switchPlatform(platform: PlatformType): Promise<void> {
|
||
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<void>;
|
||
|
||
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<void> {
|
||
// 实现自定义操作逻辑
|
||
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<void> {
|
||
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)
|