forked from opentiny/tiny-engine
feat(download-code): support download zip for not support browsers (#703)
* feat(download-code): support download zip for not support browsers * feat(download-code): support download zip for not support browsers - review * feat(download-code): support download zip for not support browsers - review
This commit is contained in:
parent
0d36f2d344
commit
3a204624af
|
@ -89,7 +89,6 @@
|
|||
"eslint-linter-browserify": "8.57.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jszip": "^3.10.1",
|
||||
"monaco-editor": "0.33.0",
|
||||
"prettier": "2.7.1",
|
||||
"sortablejs": "^1.14.0",
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
"vite": "^4.3.7",
|
||||
"vitest": "^1.4.0"
|
||||
},
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"jszip": "^3.10.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentiny/vue-renderless": "^3.14.0",
|
||||
"vue": "^3.4.15"
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
*/
|
||||
|
||||
// browser File System Access API encapsulation
|
||||
import JSZIP from 'jszip'
|
||||
|
||||
/**
|
||||
* 下载文件到本地
|
||||
* @param {Blob} blobData 文件二进制数据
|
||||
* @param {string} fileName 文件名
|
||||
*/
|
||||
export function saveAs(blobData, fileName) {
|
||||
const zipLink = document.createElement('a')
|
||||
zipLink.download = fileName
|
||||
zipLink.style.display = 'none'
|
||||
zipLink.href = URL.createObjectURL(blobData)
|
||||
document.body.appendChild(zipLink)
|
||||
zipLink.click()
|
||||
document.body.removeChild(zipLink)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个zip
|
||||
*/
|
||||
export const createZip = () => {
|
||||
return new JSZIP()
|
||||
}
|
||||
|
||||
/**
|
||||
* 往zip里面写入文件夹和文件
|
||||
* @param {Array<FileInfo>} filesInfo 文件信息
|
||||
* FileInfo.filePath 文件相对路径,以'/'相连
|
||||
* FileInfo.fileContent 文件内容
|
||||
* @param {ZipExtraInfo} ZipExtraInfo zip额外信息
|
||||
* {string} zipName 打出来的zip名称
|
||||
* {JSZIP} zipHandle 创建好的zip句柄,可以不传,不传就用新的
|
||||
*/
|
||||
export const writeZip = (filesInfo, { zipHandle, zipName } = {}) => {
|
||||
let zip = zipHandle
|
||||
if (!zipHandle) {
|
||||
zip = createZip()
|
||||
}
|
||||
filesInfo.forEach(({ filePath, fileContent }) => {
|
||||
const file = filePath.split('/')
|
||||
const fileName = file.pop()
|
||||
const path = file.join('/')
|
||||
if (path) {
|
||||
zip.folder(path).file(fileName, fileContent)
|
||||
} else {
|
||||
zip.file(fileName, fileContent)
|
||||
}
|
||||
})
|
||||
// 把打包的内容异步转成blob二进制格式
|
||||
return zip.generateAsync({ type: 'blob' }).then((content) => {
|
||||
// content就是blob数据
|
||||
saveAs(content, `${zipName}.zip`)
|
||||
})
|
||||
}
|
|
@ -1,17 +1,23 @@
|
|||
/**
|
||||
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
*/
|
||||
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
*/
|
||||
|
||||
// browser File System Access API encapsulation
|
||||
|
||||
import { createZip, writeZip } from './fszip'
|
||||
|
||||
// 支持file system api的条件:存在这个方法 && 不处于iframe中
|
||||
export const isSupportFileSystemAccess =
|
||||
Object.prototype.hasOwnProperty.call(window, 'showDirectoryPicker') && window.self === window.top
|
||||
|
||||
/**
|
||||
* 获取用户选择并授权的文件夹根路径
|
||||
* @param {*} options
|
||||
|
@ -20,7 +26,7 @@
|
|||
*/
|
||||
export const getUserBaseDirHandle = async (options = {}) => {
|
||||
if (!window.showOpenFilePicker) {
|
||||
throw new Error('不支持的浏览器!')
|
||||
return createZip()
|
||||
}
|
||||
const dirHandle = await window.showDirectoryPicker({ mode: 'readwrite', ...options })
|
||||
return dirHandle
|
||||
|
@ -166,16 +172,29 @@ export const writeFile = async (handle, { filePath, fileContent }) => {
|
|||
* @param {Array<FileInfo>} filesInfo 文件信息
|
||||
* FileInfo.filePath 文件相对路径
|
||||
* FileInfo.fileContent 文件内容
|
||||
* @param {Boolean} supportZipCache 是否支持zip缓存,zip缓存可能会导致文件不能及时更新,默认不缓存
|
||||
*
|
||||
*/
|
||||
export const writeFiles = async (baseDirHandle, filesInfo) => {
|
||||
export const writeFiles = async (
|
||||
baseDirHandle,
|
||||
filesInfo,
|
||||
zipName = 'tiny-engine-generate-code',
|
||||
supportZipCache = false
|
||||
) => {
|
||||
if (!filesInfo?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isSupportFileSystemAccess) {
|
||||
const zipInfo = { zipName, zipHandle: supportZipCache && baseDirHandle }
|
||||
await writeZip(filesInfo, zipInfo)
|
||||
return
|
||||
}
|
||||
|
||||
let directoryHandle = baseDirHandle
|
||||
if (!directoryHandle) {
|
||||
directoryHandle = await window.showDirectoryPicker({ mode: 'readwrite' })
|
||||
}
|
||||
|
||||
await Promise.all(filesInfo.map((fileInfo) => writeFile(baseDirHandle, fileInfo)))
|
||||
await Promise.all(filesInfo.map((fileInfo) => writeFile(directoryHandle, fileInfo)))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue