Files
note2any/ARCHITECTURE_QUICK_REFERENCE.md
2025-10-08 19:45:28 +08:00

462 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 新架构快速参考指南
## 📋 文件结构
```
src/
├── preview-view.ts # Obsidian 视图容器 (241 行)
├── preview-manager.ts # 中央调度器 (368 行) ★
├── platform-chooser.ts # 平台选择器 (172 行)
├── wechat/
│ └── wechat-preview.ts # 微信预览 (274 行)
└── xiaohongshu/
└── xhs-preview.ts # 小红书预览 (390 行)
```
## 🎯 各文件职责
### 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