diff --git a/README.md b/README.md
index dd84e43..adc5686 100644
--- a/README.md
+++ b/README.md
@@ -418,53 +418,61 @@ const BaseExample = createWithRemoteLoader({
modules: ['components-core:Global@PureGlobal', 'components-core:InfoPage']
})(({ remoteModules }) => {
const [PureGlobal, InfoPage] = remoteModules;
- return {
- return { data: { code: 0, data: api.loader() } };
- }, apis: {
- file: {
- staticUrl: getPublicPath('react-file') || window.PUBLIC_URL, getUrl: {
- loader: async ({ params }) => {
- const urlMap = {
- 1: '/mock/resume.png',
- 2: '/mock/resume.pdf',
- 3: '/mock/resume.html',
- 4: '/mock/resume.txt',
- 5: '/mock/audio.wav',
- 6: 'http://ieee802.org:80/secmail/docIZSEwEqHFr.doc'
- };
- return new Promise(resolve => {
- setTimeout(() => {
- resolve(urlMap[params.id]);
- }, 1000);
- });
+ return (
+ {
+ return { data: { code: 0, data: api.loader() } };
+ },
+ apis: {
+ file: {
+ staticUrl: getPublicPath('react-file') || window.PUBLIC_URL,
+ getUrl: {
+ loader: async ({ params }) => {
+ const urlMap = {
+ 1: '/mock/resume.png',
+ 2: '/mock/resume.pdf',
+ 3: '/mock/resume.html',
+ 4: '/mock/resume.txt',
+ 5: '/mock/audio.wav',
+ 6: 'http://ieee802.org:80/secmail/docIZSEwEqHFr.doc',
+ 7: '/mock/example.zip'
+ };
+ return new Promise(resolve => {
+ setTimeout(() => {
+ resolve(urlMap[params.id]);
+ }, 1000);
+ });
+ }
+ }
}
}
- }
- }
- }}>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ;
+ }}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
});
render();
@@ -505,14 +513,14 @@ render();
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|----------|-----------|-----------|----------------------------|
-| accept | string | undefined | 接受的文件类型,如 ".jpg,.png,.pdf" |
-| multiple | boolean | false | 是否支持多文件上传 |
-| onChange | function | - | 文件选择后的回调函数,参数为选择的文件数组 |
-| disabled | boolean | false | 是否禁用上传功能 |
-| maxSize | number | - | 单个文件最大尺寸(字节) |
-| children | ReactNode | - | 自定义上传按钮内容 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| accept | string | undefined | 接受的文件类型,如 ".jpg,.png,.pdf" |
+| multiple | boolean | false | 是否支持多文件上传 |
+| onChange | function | - | 文件选择后的回调函数,参数为选择的文件数组 |
+| disabled | boolean | false | 是否禁用上传功能 |
+| maxSize | number | - | 单个文件最大尺寸(字节) |
+| children | ReactNode | - | 自定义上传按钮内容 |
### MarkdownPreview
@@ -521,24 +529,52 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
| 属性 | 类型 | 默认值 | 描述 |
-|------|------|-------|------|
+|------|------|--------|------|
| url | string | - | Markdown文件的URL地址 |
| className | string | - | 自定义容器类名 |
| maxWidth | string/number | - | 容器最大宽度 |
+### ZipPreview
+
+ZIP压缩包文件预览组件,支持查看压缩包内部的文件列表和目录结构。
+
+#### 属性
+
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| url | string | - | ZIP文件的URL地址 |
+| className | string | - | 自定义容器类名 |
+| maxWidth | string/number | - | 容器最大宽度 |
+
+#### 功能特性
+
+- 支持解析ZIP压缩包内容
+- 以树形结构展示文件和目录
+- 显示文件大小和压缩后大小
+- 支持嵌套目录结构
+- 自动格式化文件大小(B、KB、MB、GB)
+
+#### 支持的压缩格式
+
+- `.zip` - ZIP压缩文件
+- `.rar` - RAR压缩文件
+- `.7z` - 7-Zip压缩文件
+- `.tar` - TAR归档文件
+- `.gz` - Gzip压缩文件
+
### FilePreview
文件预览组件,支持多种文件格式的预览。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|-----------|--------|-----|----------------------|
-| url | string | - | 文件URL |
-| filename | string | - | 文件名,用于确定文件类型 |
-| type | string | - | 文件类型,可选,如不提供则根据文件名推断 |
-| staticUrl | string | - | 静态资源URL前缀 |
-| apis | object | - | API配置对象 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| url | string | - | 文件URL |
+| filename | string | - | 文件名,用于确定文件类型 |
+| type | string | - | 文件类型,可选,如不提供则根据文件名推断 |
+| staticUrl | string | - | 静态资源URL前缀 |
+| apis | object | - | API配置对象 |
### FileList
@@ -546,13 +582,13 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|------------|----------|-----|-------------|
-| files | array | [] | 文件列表数据 |
-| onDelete | function | - | 删除文件的回调函数 |
-| onPreview | function | - | 预览文件的回调函数 |
-| onDownload | function | - | 下载文件的回调函数 |
-| renderItem | function | - | 自定义渲染文件项的函数 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| files | array | [] | 文件列表数据 |
+| onDelete | function | - | 删除文件的回调函数 |
+| onPreview | function | - | 预览文件的回调函数 |
+| onDownload | function | - | 下载文件的回调函数 |
+| renderItem | function | - | 自定义渲染文件项的函数 |
### Download
@@ -560,13 +596,13 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|-----------|-----------|-----|-----------|
-| url | string | - | 下载文件的URL |
-| filename | string | - | 下载后的文件名 |
-| children | ReactNode | - | 触发下载的元素 |
-| onSuccess | function | - | 下载成功的回调函数 |
-| onError | function | - | 下载失败的回调函数 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| url | string | - | 下载文件的URL |
+| filename | string | - | 下载后的文件名 |
+| children | ReactNode | - | 触发下载的元素 |
+| onSuccess | function | - | 下载成功的回调函数 |
+| onError | function | - | 下载失败的回调函数 |
### Image
@@ -574,14 +610,14 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|---------------|----------|-----|-----------------------------------|
-| src | string | - | 图片源URL |
-| alt | string | - | 图片替代文本 |
-| defaultAvatar | string | - | 默认头像类型('male'/'female'/'default') |
-| onError | function | - | 图片加载失败的回调函数 |
-| className | string | - | 自定义类名 |
-| style | object | - | 自定义样式 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| src | string | - | 图片源URL |
+| alt | string | - | 图片替代文本 |
+| defaultAvatar | string | - | 默认头像类型('male'/'female'/'default') |
+| onError | function | - | 图片加载失败的回调函数 |
+| className | string | - | 自定义类名 |
+| style | object | - | 自定义样式 |
### FileButton
@@ -589,12 +625,12 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|-----------|-----------|-------|-----------|
-| onClick | function | - | 点击按钮的回调函数 |
-| disabled | boolean | false | 是否禁用按钮 |
-| children | ReactNode | - | 按钮内容 |
-| className | string | - | 自定义类名 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| onClick | function | - | 点击按钮的回调函数 |
+| disabled | boolean | false | 是否禁用按钮 |
+| children | ReactNode | - | 按钮内容 |
+| className | string | - | 自定义类名 |
### PrintButton
@@ -602,11 +638,11 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|---------------|-----------|-----|----------|
-| onBeforePrint | function | - | 打印前的回调函数 |
-| onAfterPrint | function | - | 打印后的回调函数 |
-| children | ReactNode | - | 按钮内容 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| onBeforePrint | function | - | 打印前的回调函数 |
+| onAfterPrint | function | - | 打印后的回调函数 |
+| children | ReactNode | - | 按钮内容 |
### 类型定义
@@ -669,7 +705,7 @@ const {
计算接受的文件类型。
```typescript
-computedAccept(accept:string | string[]):string
+computedAccept(accept: string | string[]): string
```
#### typeFormatComponent
@@ -677,6 +713,6 @@ computedAccept(accept:string | string[]):string
根据文件名获取对应的预览组件。
```typescript
-typeFormatComponent(filename:string):React.ComponentType
+typeFormatComponent(filename: string): React.ComponentType
```
diff --git a/doc/api.md b/doc/api.md
index 8e8d9d9..68b4bf4 100644
--- a/doc/api.md
+++ b/doc/api.md
@@ -4,14 +4,14 @@
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|----------|-----------|-----------|----------------------------|
-| accept | string | undefined | 接受的文件类型,如 ".jpg,.png,.pdf" |
-| multiple | boolean | false | 是否支持多文件上传 |
-| onChange | function | - | 文件选择后的回调函数,参数为选择的文件数组 |
-| disabled | boolean | false | 是否禁用上传功能 |
-| maxSize | number | - | 单个文件最大尺寸(字节) |
-| children | ReactNode | - | 自定义上传按钮内容 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| accept | string | undefined | 接受的文件类型,如 ".jpg,.png,.pdf" |
+| multiple | boolean | false | 是否支持多文件上传 |
+| onChange | function | - | 文件选择后的回调函数,参数为选择的文件数组 |
+| disabled | boolean | false | 是否禁用上传功能 |
+| maxSize | number | - | 单个文件最大尺寸(字节) |
+| children | ReactNode | - | 自定义上传按钮内容 |
### MarkdownPreview
@@ -20,24 +20,52 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
| 属性 | 类型 | 默认值 | 描述 |
-|------|------|-------|------|
+|------|------|--------|------|
| url | string | - | Markdown文件的URL地址 |
| className | string | - | 自定义容器类名 |
| maxWidth | string/number | - | 容器最大宽度 |
+### ZipPreview
+
+ZIP压缩包文件预览组件,支持查看压缩包内部的文件列表和目录结构。
+
+#### 属性
+
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| url | string | - | ZIP文件的URL地址 |
+| className | string | - | 自定义容器类名 |
+| maxWidth | string/number | - | 容器最大宽度 |
+
+#### 功能特性
+
+- 支持解析ZIP压缩包内容
+- 以树形结构展示文件和目录
+- 显示文件大小和压缩后大小
+- 支持嵌套目录结构
+- 自动格式化文件大小(B、KB、MB、GB)
+
+#### 支持的压缩格式
+
+- `.zip` - ZIP压缩文件
+- `.rar` - RAR压缩文件
+- `.7z` - 7-Zip压缩文件
+- `.tar` - TAR归档文件
+- `.gz` - Gzip压缩文件
+
### FilePreview
文件预览组件,支持多种文件格式的预览。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|-----------|--------|-----|----------------------|
-| url | string | - | 文件URL |
-| filename | string | - | 文件名,用于确定文件类型 |
-| type | string | - | 文件类型,可选,如不提供则根据文件名推断 |
-| staticUrl | string | - | 静态资源URL前缀 |
-| apis | object | - | API配置对象 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| url | string | - | 文件URL |
+| filename | string | - | 文件名,用于确定文件类型 |
+| type | string | - | 文件类型,可选,如不提供则根据文件名推断 |
+| staticUrl | string | - | 静态资源URL前缀 |
+| apis | object | - | API配置对象 |
### FileList
@@ -45,13 +73,13 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|------------|----------|-----|-------------|
-| files | array | [] | 文件列表数据 |
-| onDelete | function | - | 删除文件的回调函数 |
-| onPreview | function | - | 预览文件的回调函数 |
-| onDownload | function | - | 下载文件的回调函数 |
-| renderItem | function | - | 自定义渲染文件项的函数 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| files | array | [] | 文件列表数据 |
+| onDelete | function | - | 删除文件的回调函数 |
+| onPreview | function | - | 预览文件的回调函数 |
+| onDownload | function | - | 下载文件的回调函数 |
+| renderItem | function | - | 自定义渲染文件项的函数 |
### Download
@@ -59,13 +87,13 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|-----------|-----------|-----|-----------|
-| url | string | - | 下载文件的URL |
-| filename | string | - | 下载后的文件名 |
-| children | ReactNode | - | 触发下载的元素 |
-| onSuccess | function | - | 下载成功的回调函数 |
-| onError | function | - | 下载失败的回调函数 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| url | string | - | 下载文件的URL |
+| filename | string | - | 下载后的文件名 |
+| children | ReactNode | - | 触发下载的元素 |
+| onSuccess | function | - | 下载成功的回调函数 |
+| onError | function | - | 下载失败的回调函数 |
### Image
@@ -73,14 +101,14 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|---------------|----------|-----|-----------------------------------|
-| src | string | - | 图片源URL |
-| alt | string | - | 图片替代文本 |
-| defaultAvatar | string | - | 默认头像类型('male'/'female'/'default') |
-| onError | function | - | 图片加载失败的回调函数 |
-| className | string | - | 自定义类名 |
-| style | object | - | 自定义样式 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| src | string | - | 图片源URL |
+| alt | string | - | 图片替代文本 |
+| defaultAvatar | string | - | 默认头像类型('male'/'female'/'default') |
+| onError | function | - | 图片加载失败的回调函数 |
+| className | string | - | 自定义类名 |
+| style | object | - | 自定义样式 |
### FileButton
@@ -88,12 +116,12 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|-----------|-----------|-------|-----------|
-| onClick | function | - | 点击按钮的回调函数 |
-| disabled | boolean | false | 是否禁用按钮 |
-| children | ReactNode | - | 按钮内容 |
-| className | string | - | 自定义类名 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| onClick | function | - | 点击按钮的回调函数 |
+| disabled | boolean | false | 是否禁用按钮 |
+| children | ReactNode | - | 按钮内容 |
+| className | string | - | 自定义类名 |
### PrintButton
@@ -101,11 +129,11 @@ Markdown文件预览组件,支持渲染Markdown格式的文档。
#### 属性
-| 属性 | 类型 | 默认值 | 描述 |
-|---------------|-----------|-----|----------|
-| onBeforePrint | function | - | 打印前的回调函数 |
-| onAfterPrint | function | - | 打印后的回调函数 |
-| children | ReactNode | - | 按钮内容 |
+| 属性 | 类型 | 默认值 | 描述 |
+|------|------|--------|------|
+| onBeforePrint | function | - | 打印前的回调函数 |
+| onAfterPrint | function | - | 打印后的回调函数 |
+| children | ReactNode | - | 按钮内容 |
### 类型定义
@@ -168,7 +196,7 @@ const {
计算接受的文件类型。
```typescript
-computedAccept(accept:string | string[]):string
+computedAccept(accept: string | string[]): string
```
#### typeFormatComponent
@@ -176,5 +204,5 @@ computedAccept(accept:string | string[]):string
根据文件名获取对应的预览组件。
```typescript
-typeFormatComponent(filename:string):React.ComponentType
+typeFormatComponent(filename: string): React.ComponentType
```
diff --git a/doc/preview.js b/doc/preview.js
index f3fb4ff..6c27ecc 100644
--- a/doc/preview.js
+++ b/doc/preview.js
@@ -5,53 +5,61 @@ const BaseExample = createWithRemoteLoader({
modules: ['components-core:Global@PureGlobal', 'components-core:InfoPage']
})(({ remoteModules }) => {
const [PureGlobal, InfoPage] = remoteModules;
- return {
- return { data: { code: 0, data: api.loader() } };
- }, apis: {
- file: {
- staticUrl: getPublicPath('react-file') || window.PUBLIC_URL, getUrl: {
- loader: async ({ params }) => {
- const urlMap = {
- 1: '/mock/resume.png',
- 2: '/mock/resume.pdf',
- 3: '/mock/resume.html',
- 4: '/mock/resume.txt',
- 5: '/mock/audio.wav',
- 6: 'http://ieee802.org:80/secmail/docIZSEwEqHFr.doc'
- };
- return new Promise(resolve => {
- setTimeout(() => {
- resolve(urlMap[params.id]);
- }, 1000);
- });
+ return (
+ {
+ return { data: { code: 0, data: api.loader() } };
+ },
+ apis: {
+ file: {
+ staticUrl: getPublicPath('react-file') || window.PUBLIC_URL,
+ getUrl: {
+ loader: async ({ params }) => {
+ const urlMap = {
+ 1: '/mock/resume.png',
+ 2: '/mock/resume.pdf',
+ 3: '/mock/resume.html',
+ 4: '/mock/resume.txt',
+ 5: '/mock/audio.wav',
+ 6: 'http://ieee802.org:80/secmail/docIZSEwEqHFr.doc',
+ 7: '/mock/example.zip'
+ };
+ return new Promise(resolve => {
+ setTimeout(() => {
+ resolve(urlMap[params.id]);
+ }, 1000);
+ });
+ }
+ }
}
}
- }
- }
- }}>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ;
+ }}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
});
render();
diff --git a/package.json b/package.json
index 5c743e5..2c5e3b1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kne/react-file",
- "version": "0.1.34",
+ "version": "0.1.35",
"description": "提供了文件上传,文件预览,文件批量管理等功能",
"syntax": {
"esmodules": true
@@ -94,13 +94,14 @@
"@kne/iframe-resizer": "^0.1.3",
"@kne/markdown-components-render": "^0.1.10",
"@kne/react-fetch": "^1.5.5",
- "@kne/react-file-type": "^1.0.7",
+ "@kne/react-file-type": "^1.0.9",
"@kne/react-intl": "^0.1.12",
"@kne/use-control-value": "^0.1.8",
"@kne/use-ref-callback": "^0.1.2",
"@kne/use-resize": "^0.1.1",
"classnames": "^2.5.1",
"dayjs": "^1.11.13",
+ "jszip": "^3.10.1",
"lodash": "^4.17.23",
"react-pdf": "^10.2.0",
"react-to-print": "^3.0.5"
diff --git a/src/components/FilePreview/ZipPreview.js b/src/components/FilePreview/ZipPreview.js
new file mode 100644
index 0000000..efccf3f
--- /dev/null
+++ b/src/components/FilePreview/ZipPreview.js
@@ -0,0 +1,188 @@
+import React, { useState, useEffect } from 'react';
+import { Tree, Spin } from 'antd';
+import JSZip from 'jszip';
+import style from './style.module.scss';
+import classnames from 'classnames';
+import { createWithIntlProvider, useIntl } from '@kne/react-intl';
+import zhCn from '../../locale/zh-CN';
+
+const formatFileSize = bytes => {
+ if (bytes === 0) return '0 B';
+ const k = 1024;
+ const sizes = ['B', 'KB', 'MB', 'GB'];
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+};
+
+const ZipPreview = createWithIntlProvider(
+ 'zh-CN',
+ zhCn,
+ 'react-file'
+)(({ url, className, maxWidth }) => {
+ const { formatMessage } = useIntl();
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(false);
+ const [treeData, setTreeData] = useState([]);
+ const [expandedKeys, setExpandedKeys] = useState([]);
+
+ useEffect(() => {
+ const loadZip = async () => {
+ try {
+ setLoading(true);
+ setError(false);
+
+ const response = await fetch(url);
+ if (!response.ok) {
+ throw new Error('Failed to fetch ZIP file');
+ }
+
+ const blob = await response.blob();
+ const zip = await JSZip.loadAsync(blob);
+
+ const files = [];
+ zip.forEach((relativePath, zipEntry) => {
+ files.push({
+ key: relativePath,
+ name: relativePath.split('/').pop() || relativePath,
+ path: relativePath,
+ isDir: zipEntry.dir,
+ size: zipEntry._data ? zipEntry._data.uncompressedSize : 0,
+ compressedSize: zipEntry._data ? zipEntry._data.compressedSize : 0
+ });
+ });
+
+ // 构建树形结构
+ const buildTree = items => {
+ const root = [];
+ const map = {};
+ const dirKeys = [];
+
+ // 先按路径排序
+ items.sort((a, b) => a.path.localeCompare(b.path));
+
+ items.forEach(item => {
+ const parts = item.path.split('/').filter(Boolean);
+ let currentPath = '';
+ let currentLevel = root;
+
+ parts.forEach((part, index) => {
+ currentPath += (currentPath ? '/' : '') + part;
+ const isLast = index === parts.length - 1;
+
+ if (!map[currentPath]) {
+ const isDirectory = !isLast || item.isDir;
+ const node = {
+ key: currentPath,
+ title: (
+
+ {part}
+ {!isDirectory && (
+ <>
+ {formatFileSize(item.size)}
+ ({formatFileSize(item.compressedSize)})
+ >
+ )}
+
+ ),
+ name: part,
+ path: currentPath,
+ isDir: isDirectory,
+ size: isLast ? item.size : 0,
+ compressedSize: isLast ? item.compressedSize : 0,
+ children: []
+ };
+
+ if (isDirectory) {
+ dirKeys.push(currentPath);
+ }
+
+ map[currentPath] = node;
+ currentLevel.push(node);
+ }
+
+ if (!isLast || item.isDir) {
+ currentLevel = map[currentPath].children;
+ }
+ });
+ });
+
+ return { tree: root, dirKeys };
+ };
+
+ const { tree, dirKeys } = buildTree(files);
+ setTreeData(tree);
+ setExpandedKeys(dirKeys);
+ setLoading(false);
+ } catch (err) {
+ console.error('Error loading ZIP file:', err);
+ setLoading(false);
+ setError(true);
+ }
+ };
+
+ if (url) {
+ loadZip();
+ }
+ }, [url]);
+
+ const onExpand = keys => {
+ setExpandedKeys(keys);
+ };
+
+ const onSelect = (selectedKeys, info) => {
+ const selectedKey = selectedKeys[0];
+ if (selectedKey && info.node.isDir) {
+ const isExpanded = expandedKeys.includes(selectedKey);
+ if (isExpanded) {
+ setExpandedKeys(expandedKeys.filter(key => key !== selectedKey));
+ } else {
+ setExpandedKeys([...expandedKeys, selectedKey]);
+ }
+ }
+ };
+
+ return (
+
+ {loading ? (
+
+
+
+ ) : null}
+ {error ? (
+
+
{formatMessage({ id: 'fileLoadedError' })}
+
+ ) : (
+
+
+
+ )}
+
+ );
+});
+
+export default ZipPreview;
diff --git a/src/components/FilePreview/index.js b/src/components/FilePreview/index.js
index d2e64f1..2edd525 100644
--- a/src/components/FilePreview/index.js
+++ b/src/components/FilePreview/index.js
@@ -9,4 +9,5 @@ export { default as OSSFilePreview } from './OSSFilePreview';
export { default as AudioPreview } from './AudioPreview';
export { default as VideoPreview } from './VideoPreview';
export { default as MarkdownPreview } from './MarkdownPreview';
+export { default as ZipPreview } from './ZipPreview';
export { default as typeFormat, typeComponentMapping } from './typeFormat';
diff --git a/src/components/FilePreview/typeFormat.js b/src/components/FilePreview/typeFormat.js
index b6d07e5..b6fa16b 100644
--- a/src/components/FilePreview/typeFormat.js
+++ b/src/components/FilePreview/typeFormat.js
@@ -7,6 +7,7 @@ import ImagePreview from './ImagePreview';
import AudioPreview from './AudioPreview';
import VideoPreview from './VideoPreview';
import MarkdownPreview from './MarkdownPreview';
+import ZipPreview from './ZipPreview';
const typeFormat = url => {
if (typeof url !== 'string') {
@@ -38,6 +39,9 @@ const typeFormat = url => {
if (/.(mp4|avi|mov|mkv|flv)$/.test(_path)) {
return 'video';
}
+ if (/.(zip|rar|7z|tar|gz)$/.test(_path)) {
+ return 'zip';
+ }
return 'unknown';
};
@@ -52,6 +56,7 @@ export const typeComponentMapping = {
office: OfficePreview,
audio: AudioPreview,
video: VideoPreview,
+ zip: ZipPreview,
unknown: UnknownPreview
};
diff --git a/src/index.js b/src/index.js
index d71e1c7..ae0ba88 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,6 @@
export { default } from './components/File';
export { default as Download, useDownload, download, downloadBlobFile } from './components/Download';
-export { default as FilePreview, HtmlPreview, PdfPreview, TextPreview, MarkdownPreview, ImagePreview, UnknownPreview, OfficePreview, OSSFilePreview, AudioPreview, VideoPreview } from './components/FilePreview';
+export { default as FilePreview, ZipPreview, HtmlPreview, PdfPreview, TextPreview, MarkdownPreview, ImagePreview, UnknownPreview, OfficePreview, OSSFilePreview, AudioPreview, VideoPreview } from './components/FilePreview';
export { default as FileButton, useFileModalProps, useFileModal, FileModal } from './components/FileButton';
export { default as Image } from './components/Image';
export { default as PrintButton } from './components/PrintButton';
diff --git a/src/locale/en-US.js b/src/locale/en-US.js
index 1ee92c6..295ea06 100644
--- a/src/locale/en-US.js
+++ b/src/locale/en-US.js
@@ -16,7 +16,10 @@ const locale = {
notFoundFile: 'The downloaded file information was not obtained',
downloadSuccess: 'Downloads successful',
pleaseSetApi: 'Please set the preset.apis.file.getUrl parameter in the Global component',
- filePreview: 'File preview'
+ filePreview: 'File preview',
+ fileName: 'File Name',
+ fileSize: 'File Size',
+ compressedSize: 'Compressed Size'
};
export default locale;
diff --git a/src/locale/zh-CN.js b/src/locale/zh-CN.js
index d2186a0..dbb048e 100644
--- a/src/locale/zh-CN.js
+++ b/src/locale/zh-CN.js
@@ -16,7 +16,10 @@ const locale = {
notFoundFile: '未获取到下载的文件信息',
downloadSuccess: '下载成功',
pleaseSetApi: '请在Global组件设置preset.apis.file.getUrl参数',
- filePreview: '文件预览'
+ filePreview: '文件预览',
+ fileName: '文件名',
+ fileSize: '文件大小',
+ compressedSize: '压缩后大小'
};
export default locale;
diff --git a/template-libs-example/public/mock/example.zip b/template-libs-example/public/mock/example.zip
new file mode 100644
index 0000000..f8cf6d2
Binary files /dev/null and b/template-libs-example/public/mock/example.zip differ