yx_only_office_flutter/docs/ADVANCED_DEVELOPMENT_SUMMAR...

8.3 KiB
Raw Blame History

高级功能开发总结

概述

基于对 ONLYOFFICE 官方 Android 和 iOS 项目的深入研究,我创建了一个高级功能分支,提供了完整的编辑器控制能力。

官方项目研究成果

从官方 Android 项目学到的关键实现

  1. WebView 桥接模式

    • 使用 addJavascriptInterface 在原生代码和 JavaScript 之间通信
    • 实现双向通信Flutter ↔ JavaScript ↔ DocsAPI
  2. 图片插入流程

    用户点击插入图片 
    → 编辑器触发 onRequestInsertImage 事件
    → Flutter 打开图片选择器
    → 上传图片到服务器
    → 调用 docEditor.insertImage() 方法
    
  3. 文件下载处理

    • 拦截下载 URL
    • 使用原生下载管理器
    • 保存到本地存储

从官方 iOS 项目学到的关键实现

  1. WKWebView 消息处理

    • 使用 WKScriptMessageHandler 接收消息
    • 实现 evaluateJavaScript 调用编辑器方法
  2. 生命周期管理

    • onAppReady: 编辑器应用加载完成
    • onDocumentReady: 文档加载完成,可以调用方法
    • onDocumentStateChange: 跟踪文档修改状态
  3. 权限和安全

    • 相机/相册权限请求
    • 文件访问权限
    • JWT 签名验证

实现的高级功能

1. YxOnlyOfficeAdvancedViewer

完整的高级查看器,提供:

class YxOnlyOfficeAdvancedViewer extends StatefulWidget {
  // WebViewController 访问
  final Function(WebViewController controller)? onControllerReady;
  
  // 生命周期事件
  final Function()? onDocumentReady;
  final Function()? onAppReady;
  
  // 图片插入
  final Future<String?> Function()? onRequestImageFromGallery;
  final Future<String?> Function()? onRequestImageFromCamera;
  
  // 文件下载
  final Future<void> Function(String url, String filename)? onDownloadFile;
  
  // 其他配置...
}

2. 编辑器方法调用

直接调用 DocsAPI 方法:

// 插入图片
await viewerState.insertImage('https://example.com/image.jpg');

// 下载文档
await viewerState.downloadAs('pdf');

// 设置审阅模式
await viewerState.setReviewerMode(true);

// 显示修订
await viewerState.showReviewChanges(true);

// 销毁编辑器
await viewerState.destroyEditor();

// 执行自定义 JavaScript
await viewerState.executeJavaScript('window.docEditor.getDocumentName()');

3. EditorMethodResult

统一的方法调用结果:

class EditorMethodResult {
  final bool success;
  final dynamic data;
  final String? error;
}

4. 图片插入完整流程

// 1. 用户触发插入
onRequestInsertImage: (data) async {
  // 2. 选择图片来源
  final source = await showDialog(...);
  
  // 3. 打开图片选择器
  final image = await ImagePicker().pickImage(source: source);
  
  // 4. 上传到服务器
  final imageUrl = await uploadImage(image);
  
  // 5. 插入到文档
  await viewerState.insertImage(imageUrl);
}

5. 文件下载处理

onDownloadFile: (url, filename) async {
  // 1. 下载文件
  final response = await http.get(Uri.parse(url));
  
  // 2. 保存到本地
  final directory = await getApplicationDocumentsDirectory();
  final file = File('${directory.path}/$filename');
  await file.writeAsBytes(response.bodyBytes);
  
  // 3. 通知用户
  print('文件已保存: ${file.path}');
}

完整示例应用

创建了 example/lib/main_advanced.dart,展示:

  • 图片插入(相机/相册)
  • 文件下载(多种格式)
  • 审阅模式切换
  • 显示修订
  • 自定义 JavaScript 执行
  • 完整的错误处理
  • 用户友好的 UI
  • 编辑器信息面板

文件结构

lib/src/
├── onlyoffice_config.dart           # 配置类(已有)
├── onlyoffice_html_builder.dart     # HTML 构建器(已有)
├── onlyoffice_viewer.dart           # 基础查看器(已有)
└── onlyoffice_advanced_viewer.dart  # 🆕 高级查看器

example/lib/
├── main.dart                        # 基础示例(已有)
└── main_advanced.dart               # 🆕 高级功能示例

docs/
├── API_REFERENCE.md                 # API 参考(已有)
├── QUICK_START.md                   # 快速开始(已有)
├── REFACTORING_SUMMARY.md           # 重构总结(已有)
└── ADVANCED_FEATURES.md             # 🆕 高级功能指南

与官方实现的对比

功能 官方 Android/iOS 我们的实现 状态
文档查看/编辑 完成
WebView 桥接 完成
图片插入 完成
文件下载 完成
编辑器方法调用 完成
生命周期管理 完成
JWT 签名 完成
离线编辑 🔄 未来版本
协作编辑 由 DocsAPI 提供
插件系统 ⚠️ 🔄 可通过 JS 实现

技术亮点

1. 状态暴露设计

_YxOnlyOfficeAdvancedViewerState 改为公开的 YxOnlyOfficeAdvancedViewerState,允许外部访问:

final GlobalKey<YxOnlyOfficeAdvancedViewerState> viewerKey = GlobalKey();

// 可以调用状态方法
await viewerKey.currentState!.insertImage(url);

2. 结果封装

使用 EditorMethodResult 统一封装方法调用结果:

final result = await viewerState.insertImage(url);
if (result.success) {
  print('成功: ${result.data}');
} else {
  print('失败: ${result.error}');
}

3. 回调链设计

支持多层回调处理:

// 方式 1: 使用内置处理器
onRequestImageFromGallery: () async {
  return await pickAndUploadImage();
}

// 方式 2: 手动调用
await viewerState.insertImage(imageUrl);

4. 文件下载拦截

自动拦截下载 URL

bool _isDownloadUrl(String url) {
  return url.contains('/download') || 
         url.contains('download=') ||
         url.contains('outputtype=');
}

使用方式对比

基础版本YxOnlyOfficeViewer

YxOnlyOfficeViewer.create(
  serverUrl: serverUrl,
  fileUrl: fileUrl,
  mode: 'edit',
  onError: (error) => print(error),
)

适用于

  • 简单的文档查看/编辑
  • 不需要高级控制
  • 快速集成

高级版本YxOnlyOfficeAdvancedViewer

YxOnlyOfficeAdvancedViewer(
  serverUrl: serverUrl,
  config: config,
  onControllerReady: (controller) {
    // 完全控制 WebView
  },
  onDocumentReady: () {
    // 文档准备好,可以调用方法
  },
  onRequestImageFromGallery: () async {
    // 自定义图片选择
  },
)

// 调用编辑器方法
await viewerState.insertImage(url);
await viewerState.downloadAs('pdf');

适用于

  • 需要完整控制编辑器
  • 图片插入功能
  • 文件下载处理
  • 自定义 JavaScript 执行
  • 高级编辑功能

运行示例

基础示例

flutter run \
  --dart-define ONLYOFFICE_SERVER_URL=https://... \
  --dart-define ONLYOFFICE_FILE_URL=https://...

高级示例

flutter run -t lib/main_advanced.dart \
  --dart-define ONLYOFFICE_SERVER_URL=https://... \
  --dart-define ONLYOFFICE_FILE_URL=https://... \
  --dart-define ONLYOFFICE_JWT_SECRET=secret \
  --dart-define UPLOAD_URL=https://...

未来改进方向

基于官方项目,以下功能可以在未来版本中添加:

  1. 离线编辑支持

    • 本地文档缓存
    • 离线修改同步
  2. 更多编辑器方法

    • 插入表格
    • 插入图表
    • 插入书签
    • 查找/替换
  3. 插件系统

    • 支持 ONLYOFFICE 插件
    • 自定义工具栏
  4. 性能优化

    • 文档预加载
    • 图片压缩
    • 增量更新
  5. 协作功能增强

    • 用户在线状态
    • 实时光标显示
    • 聊天功能

总结

通过深入研究官方 Android 和 iOS 项目,我们成功实现了:

完整的 WebView 桥接 - 实现 Flutter 与 DocsAPI 的双向通信 编辑器方法调用 - 直接控制编辑器行为 图片插入功能 - 完整的图片选择和插入流程 文件下载处理 - 自动拦截和处理下载 生命周期管理 - 完整的编辑器生命周期事件 高质量示例 - 展示所有高级功能的使用

这个高级功能分支为 Flutter 开发者提供了与官方移动应用相当的功能和控制能力!🎉