@mxmweb/fviewer 1.1.16 → 1.2.16
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 +343 -1
- package/adopters/GientechStreamReader.d.ts +2 -4
- package/index.js +7946 -19521
- package/lib_enter.d.ts +2 -12
- package/package.json +4 -1
- package/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1 +1,343 @@
|
|
|
1
|
-
#
|
|
1
|
+
# FViewer - 文件查看器组件库
|
|
2
|
+
|
|
3
|
+
## 项目概述
|
|
4
|
+
|
|
5
|
+
FViewer 是一个基于 React 的文件查看器组件库,支持多种文件格式的预览和交互。项目采用分层架构设计,遵循 adopter_develop 规范,使用 HOC 模式封装核心组件。
|
|
6
|
+
|
|
7
|
+
### 支持的文件格式
|
|
8
|
+
- **PDF**: 支持分页查看、缩放、旋转
|
|
9
|
+
- **Markdown**: 支持格式化渲染、无限滚动
|
|
10
|
+
- **图片**: 支持常见图片格式(JPG、PNG、GIF等)
|
|
11
|
+
- **文本**: 支持纯文本文件
|
|
12
|
+
- **HTML**: 支持网页内容预览
|
|
13
|
+
|
|
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
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 架构设计原则
|
|
36
|
+
|
|
37
|
+
1. **分层架构**:
|
|
38
|
+
- `/core/`: 核心UI组件,只负责渲染和基础交互
|
|
39
|
+
- `/adopters/`: 业务适配层,处理数据获取、缓存、业务逻辑
|
|
40
|
+
|
|
41
|
+
2. **HOC模式**: 业务层通过高阶组件模式扩展核心组件功能
|
|
42
|
+
|
|
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
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**事件**:
|
|
72
|
+
- `markdown_scroll`: Markdown滚动事件
|
|
73
|
+
- `pageChange`: 页面变化事件
|
|
74
|
+
- `zoomChange`: 缩放变化事件
|
|
75
|
+
- `annotationChange`: 标注变化事件
|
|
76
|
+
|
|
77
|
+
### PdfRender (PDF渲染器)
|
|
78
|
+
|
|
79
|
+
**位置**: `src/core/PdfRender/index.tsx`
|
|
80
|
+
|
|
81
|
+
**功能**: PDF文档渲染、页面导航、缩放控制
|
|
82
|
+
|
|
83
|
+
**特性**:
|
|
84
|
+
- 支持分页PDF的页码映射
|
|
85
|
+
- 基于PDF.js实现
|
|
86
|
+
- 支持标注功能
|
|
87
|
+
|
|
88
|
+
## 业务适配器
|
|
89
|
+
|
|
90
|
+
### GientechStreamReader (Stream业务流适配器)
|
|
91
|
+
|
|
92
|
+
**位置**: `src/adopters/GientechStreamReader.tsx`
|
|
93
|
+
|
|
94
|
+
**功能**: 基于Stream API的文件读取器,支持分页获取和缓存
|
|
95
|
+
|
|
96
|
+
**特性**:
|
|
97
|
+
- **PDF支持**: 分页加载、智能缓存、页码映射
|
|
98
|
+
- **Markdown支持**: 无限滚动、块级缓存、双向加载
|
|
99
|
+
- **缓存机制**: 页面级和块级缓存,5分钟过期
|
|
100
|
+
- **加载状态**: 初始加载、页面加载、无限滚动加载
|
|
101
|
+
|
|
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;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
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业务流使用
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import GientechStreamReader from './adopters/GientechStreamReader';
|
|
141
|
+
|
|
142
|
+
function App() {
|
|
143
|
+
const handleEvents = (name: string, data: any) => {
|
|
144
|
+
switch (name) {
|
|
145
|
+
case 'pageChange':
|
|
146
|
+
console.log('页面变化:', data);
|
|
147
|
+
break;
|
|
148
|
+
case 'markdown_scroll':
|
|
149
|
+
console.log('Markdown滚动:', data);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<GientechStreamReader
|
|
156
|
+
convertedFilePath="/path/to/file"
|
|
157
|
+
fileName="document.pdf"
|
|
158
|
+
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}
|
|
165
|
+
styles={{
|
|
166
|
+
theme: {
|
|
167
|
+
colors: {
|
|
168
|
+
primary: '#007bff',
|
|
169
|
+
background: '#f8f9fa',
|
|
170
|
+
text: '#343a40'
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}}
|
|
174
|
+
tools={{
|
|
175
|
+
zoom: true,
|
|
176
|
+
navigation: true,
|
|
177
|
+
close: true
|
|
178
|
+
}}
|
|
179
|
+
/>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 自定义组件
|
|
185
|
+
|
|
186
|
+
```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
|
+
/>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 开发指南
|
|
211
|
+
|
|
212
|
+
### 添加新的文件类型支持
|
|
213
|
+
|
|
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
|
+
};
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
2. **添加渲染函数**:
|
|
227
|
+
```typescript
|
|
228
|
+
const renderNewTypeContent = (data: any, props: FviewerProps) => {
|
|
229
|
+
return (
|
|
230
|
+
<div>
|
|
231
|
+
{/* 新类型的渲染逻辑 */}
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
};
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
3. **在renderContent中添加case**:
|
|
238
|
+
```typescript
|
|
239
|
+
case 'newtype':
|
|
240
|
+
return renderNewTypeContent(data, props);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 添加新的业务适配器
|
|
244
|
+
|
|
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
|
+
};
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
2. **遵循HOC模式**: 适配器应该包装核心组件,处理业务逻辑
|
|
261
|
+
|
|
262
|
+
### 主题定制
|
|
263
|
+
|
|
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
|
+
};
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## API参考
|
|
281
|
+
|
|
282
|
+
### 事件类型
|
|
283
|
+
|
|
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` |
|
|
291
|
+
|
|
292
|
+
### 工具配置
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
interface ToolsConfig {
|
|
296
|
+
annotation?: boolean; // 标注功能
|
|
297
|
+
download?: boolean; // 下载功能
|
|
298
|
+
zoom?: boolean; // 缩放功能
|
|
299
|
+
close?: boolean; // 关闭功能
|
|
300
|
+
navigation?: boolean; // 导航功能
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## 技术栈
|
|
305
|
+
|
|
306
|
+
- **React 18**: 核心框架
|
|
307
|
+
- **TypeScript**: 类型安全
|
|
308
|
+
- **styled-components v6**: CSS-in-JS样式
|
|
309
|
+
- **PDF.js**: PDF渲染
|
|
310
|
+
- **axios**: HTTP请求
|
|
311
|
+
- **@mxmweb/rtext**: 富文本渲染
|
|
312
|
+
|
|
313
|
+
## 开发环境
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# 安装依赖
|
|
317
|
+
npm install
|
|
318
|
+
|
|
319
|
+
# 启动开发服务器
|
|
320
|
+
npm run dev
|
|
321
|
+
|
|
322
|
+
# 构建生产版本
|
|
323
|
+
npm run build
|
|
324
|
+
|
|
325
|
+
# 类型检查
|
|
326
|
+
npm run type-check
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## 注意事项
|
|
330
|
+
|
|
331
|
+
1. **缓存策略**: Stream业务流使用5分钟缓存过期时间,可根据需要调整
|
|
332
|
+
2. **无限滚动**: Markdown模式下的无限滚动需要后端支持块级数据返回
|
|
333
|
+
3. **主题配置**: 建议使用统一的主题配置,确保UI一致性
|
|
334
|
+
4. **错误处理**: 所有网络请求都有错误处理,建议在业务层添加重试机制
|
|
335
|
+
|
|
336
|
+
## 更新日志
|
|
337
|
+
|
|
338
|
+
### v1.0.0
|
|
339
|
+
- 初始版本发布
|
|
340
|
+
- 支持PDF、Markdown、图片、文本、HTML格式
|
|
341
|
+
- 实现Stream业务流和静态文件两种适配器
|
|
342
|
+
- 支持无限滚动和智能缓存
|
|
343
|
+
- 完整的主题化支持
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { AppTheme, Annotation, MDAnnotation, TableAnnotation, ToolsConfig } from '../core/types';
|
|
3
|
+
import { Styles } from '@mxmweb/zui';
|
|
3
4
|
export interface GientechStreamReaderProps {
|
|
4
5
|
convertedFilePath: string;
|
|
5
6
|
csrfToken?: string;
|
|
@@ -15,10 +16,7 @@ export interface GientechStreamReaderProps {
|
|
|
15
16
|
authorization?: string;
|
|
16
17
|
eventsEmit?: (name: string, data?: any, innerFn?: any) => void;
|
|
17
18
|
tools?: Partial<ToolsConfig>;
|
|
18
|
-
styles?:
|
|
19
|
-
theme?: AppTheme;
|
|
20
|
-
mode?: 'light' | 'dark';
|
|
21
|
-
};
|
|
19
|
+
styles?: Styles;
|
|
22
20
|
customComponents?: {
|
|
23
21
|
LoadingComponent?: React.ComponentType<{
|
|
24
22
|
status: string;
|