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