@mxmweb/fviewer 1.4.5 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,343 +1,591 @@
1
- # FViewer - 文件查看器组件库
1
+ # @mxmweb/fviewer
2
2
 
3
- ## 项目概述
3
+ 一个功能强大的文件查看器库,支持多种文件格式的解析和显示,包括PDF、图片、文本、Markdown等格式。
4
4
 
5
- FViewer 是一个基于 React 的文件查看器组件库,支持多种文件格式的预览和交互。项目采用分层架构设计,遵循 adopter_develop 规范,使用 HOC 模式封装核心组件。
5
+ ## 安装与依赖
6
6
 
7
- ### 支持的文件格式
8
- - **PDF**: 支持分页查看、缩放、旋转
9
- - **Markdown**: 支持格式化渲染、无限滚动
10
- - **图片**: 支持常见图片格式(JPG、PNG、GIF等)
11
- - **文本**: 支持纯文本文件
12
- - **HTML**: 支持网页内容预览
7
+ 本库为“易安装应用库”,仅外置最小运行时依赖。请在宿主项目中安装以下对等依赖(peerDependencies):
13
8
 
14
- ## 项目架构
15
-
16
- ### 目录结构
17
- ```
18
- apps/FViewer/
19
- ├── src/
20
- │ ├── core/ # 核心组件层
21
- │ │ ├── Fviewer.tsx # 主查看器组件
22
- │ │ ├── PdfRender/ # PDF渲染组件
23
- │ │ ├── types.ts # 类型定义
24
- │ │ └── utils/ # 工具函数
25
- │ ├── adopters/ # 业务适配层
26
- │ │ ├── GientechStreamReader.tsx # Stream业务流适配器
27
- │ │ ├── StaticFileReader.tsx # 静态文件适配器
28
- │ │ └── components/ # 适配器组件
29
- │ ├── StreamPreview.tsx # Stream业务流测试组件
30
- │ └── main.tsx # 应用入口
31
- ├── package.json
32
- └── README.md
9
+ ```bash
10
+ # 使用 pnpm(推荐)
11
+ pnpm add @mxmweb/fviewer \
12
+ react react-dom \
13
+ styled-components @mxmweb/zui @mxmweb/rtext \
14
+ pdfjs-dist
15
+
16
+ # 或 yarn
17
+ yarn add @mxmweb/fviewer \
18
+ react react-dom \
19
+ styled-components @mxmweb/zui @mxmweb/rtext \
20
+ pdfjs-dist
21
+
22
+ # 或 npm
23
+ npm i @mxmweb/fviewer \
24
+ react react-dom \
25
+ styled-components @mxmweb/zui @mxmweb/rtext \
26
+ pdfjs-dist
33
27
  ```
34
28
 
35
- ### 架构设计原则
29
+ PDF.js 的 worker 需由宿主自行注册一次(任意应用初始化位置):
36
30
 
37
- 1. **分层架构**:
38
- - `/core/`: 核心UI组件,只负责渲染和基础交互
39
- - `/adopters/`: 业务适配层,处理数据获取、缓存、业务逻辑
31
+ ```ts
32
+ import * as pdfjsLib from 'pdfjs-dist';
40
33
 
41
- 2. **HOC模式**: 业务层通过高阶组件模式扩展核心组件功能
34
+ // 方式一:指向你静态资源中的 worker 文件
35
+ pdfjsLib.GlobalWorkerOptions.workerSrc = '/worker/pdf.worker.min.js';
42
36
 
43
- 3. **事件驱动**: 使用统一的 `eventsEmit` 机制进行组件间通信
44
-
45
- 4. **主题化**: 支持动态主题配置,使用 styled-components 实现
46
-
47
- ## 核心组件
48
-
49
- ### Fviewer (核心查看器)
50
-
51
- **位置**: `src/core/Fviewer.tsx`
52
-
53
- **功能**: 文件类型检测、内容渲染、状态管理
54
-
55
- **接口**:
56
- ```typescript
57
- interface FviewerProps {
58
- data: FviewerData; // 文件数据
59
- annotationData?: Annotation[]; // 标注数据
60
- totalPage?: number; // 总页数
61
- currentPage?: number; // 当前页
62
- scale?: number; // 缩放比例
63
- rotation?: number; // 旋转角度
64
- eventsEmit?: (name: string, data?: any) => void; // 事件回调
65
- styles?: { theme?: AppTheme; mode?: 'light' | 'dark' }; // 样式配置
66
- tools?: ToolsConfig; // 工具配置
67
- customComponents?: CustomizeComponents; // 自定义组件
68
- }
37
+ // 方式二:直接引入(需确保构建可访问该路径)
38
+ // import 'pdfjs-dist/build/pdf.worker.min.js';
69
39
  ```
70
40
 
71
- **事件**:
72
- - `markdown_scroll`: Markdown滚动事件
73
- - `pageChange`: 页面变化事件
74
- - `zoomChange`: 缩放变化事件
75
- - `annotationChange`: 标注变化事件
76
-
77
- ### PdfRender (PDF渲染器)
41
+ > 说明:为降低包体积,`@mxmweb/rtext` 与 `pdfjs-dist` 均已外置;`react/react-dom/@mxmweb/zui/styled-components` 作为运行时依赖亦需由宿主提供。
78
42
 
79
- **位置**: `src/core/PdfRender/index.tsx`
43
+ ## 核心组件
80
44
 
81
- **功能**: PDF文档渲染、页面导航、缩放控制
45
+ ### StaticFileReader
82
46
 
83
- **特性**:
84
- - 支持分页PDF的页码映射
85
- - 基于PDF.js实现
86
- - 支持标注功能
47
+ 静态文件阅读器组件,用于加载和显示本地或远程静态文件。
87
48
 
88
- ## 业务适配器
49
+ #### Props接口
89
50
 
90
- ### GientechStreamReader (Stream业务流适配器)
51
+ - **fileUrl**: `string` - 文件URL地址(必需)
52
+ - **fileType**: `string` - 文件类型(可选)
53
+ - **fileName**: `string` - 文件名(可选)
54
+ - **token**: `string` - 认证令牌(可选)
55
+ - **initialPage**: `number` - 初始页码(可选)
56
+ - **annotations**: `(Annotation | MDAnnotation | TableAnnotation)[]` - 标注数据数组(可选)
57
+ - **data**: `any` - 直接数据传递(可选)
58
+ - **eventsEmit**: `(name: string, data?: any, innerFn?: any) => void` - 事件回调函数(可选)
59
+ - **styles**: `{ theme?: AppTheme; mode?: 'light' | 'dark' }` - 样式配置(可选)
60
+ - **tools**: `ToolsConfig` - 工具配置(可选)
61
+ - **customComponents**: `{ LoadingComponent?, ErrorComponent? }` - 自定义组件(可选)
62
+ - **className**: `string` - 自定义类名(可选)
63
+ - **headerClass**: `string` - 头部类名(可选)
64
+ - **contentClass**: `string` - 内容类名(可选)
91
65
 
92
- **位置**: `src/adopters/GientechStreamReader.tsx`
66
+ #### 调用实例
93
67
 
94
- **功能**: 基于Stream API的文件读取器,支持分页获取和缓存
68
+ ```tsx
69
+ import { StaticFileReader } from '@mxmweb/fviewer';
95
70
 
96
- **特性**:
97
- - **PDF支持**: 分页加载、智能缓存、页码映射
98
- - **Markdown支持**: 无限滚动、块级缓存、双向加载
99
- - **缓存机制**: 页面级和块级缓存,5分钟过期
100
- - **加载状态**: 初始加载、页面加载、无限滚动加载
71
+ function App() {
72
+ const handleEvents = (name: string, data?: any) => {
73
+ switch (name) {
74
+ case 'file_loaded':
75
+ console.log('文件加载完成:', data);
76
+ break;
77
+ case 'page_changed':
78
+ console.log('页面切换:', data);
79
+ break;
80
+ case 'annotation_added':
81
+ console.log('添加标注:', data);
82
+ break;
83
+ }
84
+ };
101
85
 
102
- **接口**:
103
- ```typescript
104
- interface GientechStreamReaderProps {
105
- convertedFilePath: string; // 文件路径
106
- fileName?: string; // 文件名
107
- fileType: string; // 文件类型
108
- initialPage?: number; // 初始页/块
109
- totalPages?: number; // 总页数/块数
110
- pageSize?: number; // 页面/块大小
111
- streamApiUrl?: string; // Stream API地址
112
- authorization?: string; // 认证信息
113
- eventsEmit?: (name: string, data?: any) => void;
114
- styles?: { theme?: AppTheme; mode?: 'light' | 'dark' };
115
- tools?: ToolsConfig;
116
- customComponents?: CustomizeComponents;
86
+ return (
87
+ <StaticFileReader
88
+ fileUrl="https://example.com/document.pdf"
89
+ fileName="示例文档.pdf"
90
+ fileType="pdf"
91
+ initialPage={1}
92
+ eventsEmit={handleEvents}
93
+ styles={{
94
+ mode: 'light',
95
+ theme: {
96
+ colors: {
97
+ primary: '#1890ff',
98
+ background: '#ffffff',
99
+ text: '#000000'
100
+ }
101
+ }
102
+ }}
103
+ tools={{
104
+ annotation: true,
105
+ download: true,
106
+ zoom: true,
107
+ navigation: true
108
+ }}
109
+ />
110
+ );
117
111
  }
118
112
  ```
119
113
 
120
- **缓存策略**:
121
- - **PDF**: 缓存解析后的PDF文档对象,避免重复解析
122
- - **Markdown**: 缓存块级内容,支持向前/向后拼接
123
-
124
- **无限滚动**:
125
- - 向下滚动到底部80%时加载下一块
126
- - 向上滚动到顶部20%时加载上一块
127
- - 智能内容拼接,保持阅读连续性
128
-
129
- ### StaticFileReader (静态文件适配器)
130
-
131
- **位置**: `src/adopters/StaticFileReader.tsx`
132
-
133
- **功能**: 静态文件读取器,支持本地文件预览
134
-
135
- ## 使用示例
136
-
137
- ### Stream业务流使用
114
+ #### eventsEmit详细说明
115
+
116
+ | 事件名 | 说明 | 数据格式 |
117
+ | --- | ---- | --- |
118
+ | `file_loaded` | 文件加载完成 | `{ fileName: string, fileType: string, totalPages?: number }` |
119
+ | `page_changed` | 页面切换 | `{ currentPage: number, totalPages: number }` |
120
+ | `annotation_added` | 添加标注 | `{ id: string, pageNumber: number, x: number, y: number, content: string }` |
121
+ | `annotation_removed` | 删除标注 | `{ id: string }` |
122
+ | `zoom_changed` | 缩放变化 | `{ scale: number }` |
123
+ | `download_clicked` | 下载按钮点击 | `{ fileName: string }` |
124
+ | `error_occurred` | 错误发生 | `{ error: string, details?: any }` |
125
+
126
+ #### 技术栈
127
+
128
+ - React 18 + TypeScript
129
+ - Styled-components v6 主题样式
130
+ - PDF.js 用于PDF文件解析
131
+ - 响应式设计,支持移动端
132
+
133
+ #### 其他
134
+
135
+ - 支持多种文件格式:PDF、图片、文本、Markdown、HTML
136
+ - 内置文件类型自动检测
137
+ - 支持自定义主题和样式
138
+ - 提供完整的标注功能
139
+ - 支持文件下载和打印
140
+
141
+ ### GientechStreamReader
142
+
143
+ 流式文件阅读器组件,专门用于处理大文件的流式加载和分页显示。
144
+
145
+ #### Props接口
146
+
147
+ - **convertedFilePath**: `string` - 转换后的文件路径(必需)
148
+ - **csrfToken**: `string` - CSRF令牌(可选)
149
+ - **fileName**: `string` - 文件名(可选)
150
+ - **fileType**: `string` - 文件类型(必需)
151
+ - **initialPage**: `number` - 初始页码(可选)
152
+ - **totalPages**: `number` - 总页数(可选)
153
+ - **annotations**: `(Annotation | MDAnnotation | TableAnnotation)[]` - 标注数据数组(可选)
154
+ - **userName**: `string` - 用户名(可选)
155
+ - **userId**: `string` - 用户ID(可选)
156
+ - **pageSize**: `number` - 页面大小(可选)
157
+ - **streamApiUrl**: `string` - 流式API地址(可选)
158
+ - **authorization**: `string` - 授权头(可选)
159
+ - **eventsEmit**: `(name: string, data?: any, innerFn?: any) => void` - 事件回调函数(可选)
160
+ - **tools**: `Partial<ToolsConfig>` - 工具配置(可选)
161
+ - **styles**: `Styles` - 样式配置(可选)
162
+ - **customComponents**: `{ LoadingComponent?, ErrorComponent? }` - 自定义组件(可选)
163
+ - **className**: `string` - 自定义类名(可选)
164
+ - **headerClass**: `string` - 头部类名(可选)
165
+ - **contentClass**: `string` - 内容类名(可选)
166
+
167
+ #### 调用实例
138
168
 
139
169
  ```tsx
140
- import GientechStreamReader from './adopters/GientechStreamReader';
170
+ import { GientechStreamReader } from '@mxmweb/fviewer';
141
171
 
142
172
  function App() {
143
- const handleEvents = (name: string, data: any) => {
173
+ const handleStreamEvents = (name: string, data?: any) => {
144
174
  switch (name) {
145
- case 'pageChange':
146
- console.log('页面变化:', data);
175
+ case 'page_loaded':
176
+ console.log('页面加载完成:', data);
147
177
  break;
148
- case 'markdown_scroll':
149
- console.log('Markdown滚动:', data);
178
+ case 'stream_error':
179
+ console.log('流式加载错误:', data);
180
+ break;
181
+ case 'cache_updated':
182
+ console.log('缓存更新:', data);
150
183
  break;
151
184
  }
152
185
  };
153
186
 
154
187
  return (
155
188
  <GientechStreamReader
156
- convertedFilePath="/path/to/file"
157
- fileName="document.pdf"
189
+ convertedFilePath="/api/files/12345"
158
190
  fileType="pdf"
159
- initialPage={1}
160
- totalPages={100}
161
- pageSize={5}
162
- streamApiUrl="http://api.example.com/stream"
163
- authorization="Bearer token"
164
- eventsEmit={handleEvents}
191
+ fileName="大型文档.pdf"
192
+ totalPages={1000}
193
+ pageSize={10}
194
+ userName="张三"
195
+ userId="user123"
196
+ eventsEmit={handleStreamEvents}
197
+ tools={{
198
+ annotation: true,
199
+ navigation: true,
200
+ zoom: true
201
+ }}
165
202
  styles={{
166
203
  theme: {
167
204
  colors: {
168
- primary: '#007bff',
169
- background: '#f8f9fa',
170
- text: '#343a40'
205
+ primary: '#52c41a',
206
+ background: '#fafafa'
171
207
  }
172
208
  }
173
209
  }}
174
- tools={{
175
- zoom: true,
176
- navigation: true,
177
- close: true
178
- }}
179
210
  />
180
211
  );
181
212
  }
182
213
  ```
183
214
 
184
- ### 自定义组件
215
+ #### eventsEmit详细说明
216
+
217
+ | 事件名 | 说明 | 数据格式 |
218
+ | --- | ---- | --- |
219
+ | `page_loaded` | 页面加载完成 | `{ pageNo: number, data: ArrayBuffer, timestamp: number }` |
220
+ | `stream_error` | 流式加载错误 | `{ error: string, pageNo?: number, retryCount: number }` |
221
+ | `cache_updated` | 缓存更新 | `{ cacheKey: string, pages: number[], timestamp: number }` |
222
+ | `page_requested` | 页面请求开始 | `{ pageNo: number, requestId: string }` |
223
+ | `navigation_changed` | 导航变化 | `{ currentPage: number, totalPages: number, direction: 'next' \| 'prev' }` |
224
+ | `user_action` | 用户操作 | `{ action: string, pageNo: number, timestamp: number }` |
225
+
226
+ #### 技术栈
227
+
228
+ - React 18 + TypeScript
229
+ - Axios 用于HTTP请求
230
+ - 智能分页缓存系统
231
+ - 流式数据加载
232
+ - 内存优化管理
233
+
234
+ #### 其他
235
+
236
+ - 支持超大文件的分页加载
237
+ - 智能缓存策略,减少重复请求
238
+ - 支持断点续传和错误重试
239
+ - 内存使用优化,避免内存泄漏
240
+ - 支持多种认证方式
241
+
242
+ ## 工具函数
243
+
244
+ ### parseFile
245
+
246
+ 通用文件解析函数,自动检测文件类型并调用相应的解析器。
185
247
 
186
248
  ```tsx
187
- // 自定义加载组件
188
- const CustomLoading = ({ status, theme }) => (
189
- <div style={{ color: theme.colors.primary }}>
190
- 自定义加载: {status}
191
- </div>
192
- );
193
-
194
- // 自定义错误组件
195
- const CustomError = ({ error, theme }) => (
196
- <div style={{ color: theme.colors.error }}>
197
- 自定义错误: {error}
198
- </div>
199
- );
200
-
201
- <GientechStreamReader
202
- // ... 其他属性
203
- customComponents={{
204
- LoadingComponent: CustomLoading,
205
- ErrorComponent: CustomError
206
- }}
207
- />
249
+ import { parseFile } from '@mxmweb/fviewer';
250
+
251
+ const result = await parseFile(fileData, {
252
+ fileName: 'document.pdf',
253
+ fileType: 'pdf'
254
+ });
208
255
  ```
209
256
 
210
- ## 开发指南
257
+ ### parsePdfFile
211
258
 
212
- ### 添加新的文件类型支持
259
+ 专门用于解析PDF文件的函数。
260
+
261
+ ```tsx
262
+ import { parsePdfFile } from '@mxmweb/fviewer';
213
263
 
214
- 1. **在Fviewer中添加类型检测**:
215
- ```typescript
216
- // src/core/Fviewer.tsx
217
- const detectFileType = (data: any): FileType => {
218
- // 添加新的类型检测逻辑
219
- if (fileName.toLowerCase().endsWith('.newtype')) {
220
- return 'newtype';
221
- }
222
- // ...
223
- };
264
+ const pdfResult = await parsePdfFile(pdfArrayBuffer, {
265
+ fileName: 'document.pdf'
266
+ });
224
267
  ```
225
268
 
226
- 2. **添加渲染函数**:
227
- ```typescript
228
- const renderNewTypeContent = (data: any, props: FviewerProps) => {
229
- return (
230
- <div>
231
- {/* 新类型的渲染逻辑 */}
232
- </div>
233
- );
234
- };
269
+ ### parseImageFile
270
+
271
+ 图片文件解析函数。
272
+
273
+ ```tsx
274
+ import { parseImageFile } from '@mxmweb/fviewer';
275
+
276
+ const imageResult = await parseImageFile(imageBlob, {
277
+ fileName: 'image.jpg'
278
+ });
235
279
  ```
236
280
 
237
- 3. **在renderContent中添加case**:
238
- ```typescript
239
- case 'newtype':
240
- return renderNewTypeContent(data, props);
281
+ ### parseTextFile
282
+
283
+ 文本文件解析函数。
284
+
285
+ ```tsx
286
+ import { parseTextFile } from '@mxmweb/fviewer';
287
+
288
+ const textResult = await parseTextFile(textContent, {
289
+ fileName: 'document.txt'
290
+ });
241
291
  ```
242
292
 
243
- ### 添加新的业务适配器
293
+ ### parseMarkdownFile
244
294
 
245
- 1. **创建适配器组件**:
246
- ```typescript
247
- // src/adopters/NewBusinessReader.tsx
248
- const NewBusinessReader: React.FC<NewBusinessReaderProps> = (props) => {
249
- // 业务逻辑处理
250
- return (
251
- <Fviewer
252
- data={processedData}
253
- eventsEmit={handleEvents}
254
- // ... 其他属性
255
- />
256
- );
257
- };
295
+ Markdown文件解析函数。
296
+
297
+ ```tsx
298
+ import { parseMarkdownFile } from '@mxmweb/fviewer';
299
+
300
+ const mdResult = await parseMarkdownFile(markdownContent, {
301
+ fileName: 'readme.md'
302
+ });
258
303
  ```
259
304
 
260
- 2. **遵循HOC模式**: 适配器应该包装核心组件,处理业务逻辑
305
+ ### detectFileType
261
306
 
262
- ### 主题定制
307
+ 文件类型检测函数。
263
308
 
264
- ```typescript
265
- const customTheme: AppTheme = {
266
- colors: {
267
- primary: '#your-primary-color',
268
- background: '#your-background-color',
269
- text: '#your-text-color',
270
- // ... 其他颜色
271
- },
272
- space: {
273
- radius: 'md',
274
- padding: 'md',
275
- // ... 其他间距
276
- }
277
- };
309
+ ```tsx
310
+ import { detectFileType } from '@mxmweb/fviewer';
311
+
312
+ const fileType = detectFileType('document.pdf', 'pdf');
313
+ // 返回: 'pdf'
314
+ ```
315
+
316
+ ### registerPDFWorker
317
+
318
+ PDF Worker注册函数。
319
+
320
+ ```tsx
321
+ import { registerPDFWorker } from '@mxmweb/fviewer';
322
+
323
+ // 注册PDF Worker
324
+ registerPDFWorker('/worker/pdf.worker.min.js');
325
+ ```
326
+
327
+ ### isPDFWorkerRegistered
328
+
329
+ 检查PDF Worker是否已注册的函数。
330
+
331
+ ```tsx
332
+ import { isPDFWorkerRegistered } from '@mxmweb/fviewer';
333
+
334
+ const isRegistered = isPDFWorkerRegistered();
335
+ console.log('PDF Worker已注册:', isRegistered);
336
+ ```
337
+
338
+ ### getPDFWorkerPath
339
+
340
+ 获取当前PDF Worker路径的函数。
341
+
342
+ ```tsx
343
+ import { getPDFWorkerPath } from '@mxmweb/fviewer';
344
+
345
+ const workerPath = getPDFWorkerPath();
346
+ console.log('当前PDF Worker路径:', workerPath);
347
+ ```
348
+
349
+ ## 类型定义
350
+
351
+ ### StaticFileReaderProps
352
+
353
+ 静态文件阅读器组件的属性接口。
354
+
355
+ ```tsx
356
+ interface StaticFileReaderProps {
357
+ // 文件相关
358
+ fileUrl: string;
359
+ fileType?: string;
360
+ fileName?: string;
361
+ token?: string;
362
+ initialPage?: number;
363
+ annotations?: (Annotation | MDAnnotation | TableAnnotation)[];
364
+ // 直接数据传递
365
+ data?: any;
366
+ // 事件回调
367
+ eventsEmit?: (name: string, data?: any, innerFn?: any) => void;
368
+ // 样式配置
369
+ styles?: {
370
+ theme?: AppTheme;
371
+ mode?: 'light' | 'dark';
372
+ };
373
+ // 工具配置
374
+ tools?: ToolsConfig;
375
+ // 自定义组件
376
+ customComponents?: {
377
+ LoadingComponent?: React.ComponentType<{
378
+ status: string;
379
+ theme: AppTheme;
380
+ }>;
381
+ ErrorComponent?: React.ComponentType<{
382
+ error: string;
383
+ theme: AppTheme;
384
+ }>;
385
+ };
386
+ // 自定义类名
387
+ className?: string;
388
+ headerClass?: string;
389
+ contentClass?: string;
390
+ }
391
+ ```
392
+
393
+ ### GientechStreamReaderProps
394
+
395
+ 流式文件阅读器组件的属性接口。
396
+
397
+ ```tsx
398
+ interface GientechStreamReaderProps {
399
+ // 文件相关
400
+ convertedFilePath: string;
401
+ csrfToken?: string;
402
+ fileName?: string;
403
+ fileType: string;
404
+ initialPage?: number;
405
+ totalPages?: number;
406
+ annotations?: (Annotation | MDAnnotation | TableAnnotation)[];
407
+ // 用户信息
408
+ userName?: string;
409
+ userId?: string;
410
+ pageSize?: number;
411
+ // API配置
412
+ streamApiUrl?: string;
413
+ authorization?: string;
414
+ // 事件回调
415
+ eventsEmit?: (name: string, data?: any, innerFn?: any) => void;
416
+ // 工具配置
417
+ tools?: Partial<ToolsConfig>;
418
+ // 样式配置
419
+ styles?: Styles;
420
+ // 自定义组件
421
+ customComponents?: {
422
+ LoadingComponent?: React.ComponentType<{
423
+ status: string;
424
+ theme: AppTheme;
425
+ }>;
426
+ ErrorComponent?: React.ComponentType<{
427
+ error: string;
428
+ theme: AppTheme;
429
+ }>;
430
+ };
431
+ // 自定义类名
432
+ className?: string;
433
+ headerClass?: string;
434
+ contentClass?: string;
435
+ }
436
+ ```
437
+
438
+ ### PdfRenderProps
439
+
440
+ PDF渲染组件的属性接口。
441
+
442
+ ```tsx
443
+ interface PdfRenderProps {
444
+ data: ArrayBuffer | string;
445
+ pageNumber?: number;
446
+ scale?: number;
447
+ annotations?: Annotation[];
448
+ onPageChange?: (pageNumber: number) => void;
449
+ onScaleChange?: (scale: number) => void;
450
+ }
278
451
  ```
279
452
 
280
- ## API参考
453
+ ### Annotation
454
+
455
+ PDF标注数据接口。
281
456
 
282
- ### 事件类型
457
+ ```tsx
458
+ interface Annotation {
459
+ id: string;
460
+ pageNumber: number;
461
+ x: number;
462
+ y: number;
463
+ width: number;
464
+ height: number;
465
+ content?: string;
466
+ color?: string;
467
+ }
468
+ ```
283
469
 
284
- | 事件名 | 描述 | 数据格式 |
285
- |--------|------|----------|
286
- | `pageChange` | 页面变化 | `{ pageNumber: number, totalPages: number }` |
287
- | `markdown_scroll` | Markdown滚动 | `{ scrollTop: number, scrollHeight: number }` |
288
- | `zoomChange` | 缩放变化 | `{ scale: number }` |
289
- | `annotationChange` | 标注变化 | `{ annotation: Annotation }` |
290
- | `viewer:close` | 关闭查看器 | `undefined` |
470
+ ### MDAnnotation
471
+
472
+ Markdown标注数据接口。
473
+
474
+ ```tsx
475
+ interface MDAnnotation {
476
+ id: string;
477
+ start: number;
478
+ end: number;
479
+ content?: string;
480
+ color?: string;
481
+ }
482
+ ```
291
483
 
292
- ### 工具配置
484
+ ### TableAnnotation
293
485
 
294
- ```typescript
486
+ 表格标注数据接口。
487
+
488
+ ```tsx
489
+ interface TableAnnotation {
490
+ id: string;
491
+ offsets: [number, number][];
492
+ content?: string;
493
+ color?: string;
494
+ }
495
+ ```
496
+
497
+ ### ToolsConfig
498
+
499
+ 工具配置接口。
500
+
501
+ ```tsx
295
502
  interface ToolsConfig {
296
- annotation?: boolean; // 标注功能
297
- download?: boolean; // 下载功能
298
- zoom?: boolean; // 缩放功能
299
- close?: boolean; // 关闭功能
300
- navigation?: boolean; // 导航功能
503
+ annotation?: boolean; // 标注功能
504
+ download?: boolean; // 下载功能
505
+ zoom?: boolean; // 缩放功能
506
+ close?: boolean; // 关闭功能
507
+ navigation?: boolean; // 导航功能
508
+ rotate?: boolean; // 旋转功能(主要用于图片)
301
509
  }
302
510
  ```
303
511
 
304
- ## 技术栈
512
+ ### AppTheme
305
513
 
306
- - **React 18**: 核心框架
307
- - **TypeScript**: 类型安全
308
- - **styled-components v6**: CSS-in-JS样式
309
- - **PDF.js**: PDF渲染
310
- - **axios**: HTTP请求
311
- - **@mxmweb/rtext**: 富文本渲染
514
+ 应用主题接口。
312
515
 
313
- ## 开发环境
516
+ ```tsx
517
+ interface AppTheme {
518
+ colors: {
519
+ primary: string;
520
+ secondary: string;
521
+ success: string;
522
+ warning: string;
523
+ error: string;
524
+ info: string;
525
+ background: string;
526
+ text: string;
527
+ border: string;
528
+ disabled: string;
529
+ disabledBackground: string;
530
+ disabledText: string;
531
+ [key: string]: any;
532
+ };
533
+ space: {
534
+ sidebar: string;
535
+ size: string;
536
+ radius: string;
537
+ padding: string;
538
+ margin: string;
539
+ shadow: string;
540
+ lineHeight: string;
541
+ [key: string]: any;
542
+ };
543
+ [key: string]: any;
544
+ }
545
+ ```
314
546
 
315
- ```bash
316
- # 安装依赖
317
- npm install
547
+ ### Styles
548
+
549
+ 样式配置接口,来自 @mxmweb/zui 包。
550
+
551
+ ```tsx
552
+ import { Styles } from '@mxmweb/zui';
553
+
554
+ // Styles 是一个通用的样式配置接口
555
+ // 用于配置组件的主题和样式
556
+ ```
318
557
 
319
- # 启动开发服务器
320
- npm run dev
558
+ ### ParseResult
321
559
 
322
- # 构建生产版本
323
- npm run build
560
+ 文件解析结果接口。
324
561
 
325
- # 类型检查
326
- npm run type-check
562
+ ```tsx
563
+ interface ParseResult {
564
+ type: FileType;
565
+ content: any;
566
+ fileName?: string;
567
+ fileType?: string;
568
+ totalPages?: number;
569
+ error?: string;
570
+ }
327
571
  ```
328
572
 
329
- ## 注意事项
573
+ ### ParseOptions
574
+
575
+ 文件解析选项接口。
576
+
577
+ ```tsx
578
+ interface ParseOptions {
579
+ fileName?: string;
580
+ fileType?: string;
581
+ token?: string;
582
+ }
583
+ ```
330
584
 
331
- 1. **缓存策略**: Stream业务流使用5分钟缓存过期时间,可根据需要调整
332
- 2. **无限滚动**: Markdown模式下的无限滚动需要后端支持块级数据返回
333
- 3. **主题配置**: 建议使用统一的主题配置,确保UI一致性
334
- 4. **错误处理**: 所有网络请求都有错误处理,建议在业务层添加重试机制
585
+ ### FileType
335
586
 
336
- ## 更新日志
587
+ 文件类型枚举。
337
588
 
338
- ### v1.0.0
339
- - 初始版本发布
340
- - 支持PDF、Markdown、图片、文本、HTML格式
341
- - 实现Stream业务流和静态文件两种适配器
342
- - 支持无限滚动和智能缓存
343
- - 完整的主题化支持
589
+ ```tsx
590
+ type FileType = 'pdf' | 'image' | 'text' | 'markdown' | 'markdown_table' | 'html' | 'unknown';
591
+ ```