SFTP支持上传嵌套文件夹

This commit is contained in:
chaos-zhu 2024-08-13 15:51:14 +08:00
parent afda15de68
commit 9889528070
2 changed files with 40 additions and 28 deletions

View File

@ -55,10 +55,12 @@ function listenInput(sftpClient, socket) {
}) })
// socket.on('down_dir', async (path) => { // socket.on('down_dir', async (path) => {
// const exists = await sftpClient.exists(path) // const exists = await sftpClient.exists(path)
// if(!exists) return socket.emit('not_exists_dir', '文件夹不存在或当前不可访问') // if(!exists) return socket.emit('not_exists_dir', '目录不存在或当前不可访问')
// let res = await sftpClient.downloadDir(path, sftpCacheDir) // let res = await sftpClient.downloadDir(path, sftpCacheDir)
// socket.emit('down_dir_success', res) // socket.emit('down_dir_success', res)
// }) // })
// 下载
socket.on('down_file', async ({ path, name, size, target = 'down' }) => { socket.on('down_file', async ({ path, name, size, target = 'down' }) => {
// target: down or preview // target: down or preview
const exists = await sftpClient.exists(path) const exists = await sftpClient.exists(path)
@ -94,10 +96,12 @@ function listenInput(sftpClient, socket) {
socket.emit('sftp_error', error.message) socket.emit('sftp_error', error.message)
} }
}) })
// 上传
socket.on('up_file', async ({ targetPath, fullPath, name, file }) => { socket.on('up_file', async ({ targetPath, fullPath, name, file }) => {
// console.log({ targetPath, fullPath, name, file }) // console.log({ targetPath, fullPath, name, file })
const exists = await sftpClient.exists(targetPath) const exists = await sftpClient.exists(targetPath)
if(!exists) return socket.emit('not_exists_dir', '文件夹不存在或当前不可访问') if(!exists) return socket.emit('not_exists_dir', '目录不存在或当前不可访问')
try { try {
const localPath = rawPath.join(sftpCacheDir, name) const localPath = rawPath.join(sftpCacheDir, name)
fs.writeFileSync(localPath, file) fs.writeFileSync(localPath, file)
@ -110,30 +114,35 @@ function listenInput(sftpClient, socket) {
} }
}) })
// 上传文件夹先在目标sftp服务器创建文件夹 // 上传目录先在目标sftp服务器创建目录
socket.on('create_remote_dir', async ({ targetDirPath, folderName }) => { socket.on('create_remote_dir', async ({ targetDirPath, foldersName }) => {
let fullPath = rawPath.posix.join(targetDirPath, folderName) let baseFolderPath = rawPath.posix.join(targetDirPath, foldersName[0].split('/')[0])
consola.info('创建远程服务器文件夹:', fullPath) let baseFolderPathExists = await sftpClient.exists(baseFolderPath)
const exists = await sftpClient.exists(fullPath) if (baseFolderPathExists) return socket.emit('create_remote_dir_exists', `远程目录已存在: ${ baseFolderPath }`)
if(exists) return socket.emit('is_exists_dir', '上传文件夹失败,文件夹已存在') consola.info('准备创建远程服务器目录:', foldersName)
let res = await sftpClient.mkdir(fullPath) for (const folderName of foldersName) {
consola.success('创建远程服务器文件夹成功:', fullPath) const fullPath = rawPath.posix.join(targetDirPath, folderName)
socket.emit('create_remote_dir_success', res) const exists = await sftpClient.exists(fullPath)
if (exists) continue
await sftpClient.mkdir(fullPath, true)
consola.info('创建目录:', fullPath)
}
socket.emit('create_remote_dir_success')
}) })
/** 分片上传 */ /** 分片上传 */
// 1. 创建本地缓存文件夹 // 1. 创建本地缓存目录
let md5List = [] let md5List = []
socket.on('create_cache_dir', async ({ targetDirPath, name }) => { socket.on('create_cache_dir', async ({ targetDirPath, name }) => {
// console.log({ targetDirPath, name }) // console.log({ targetDirPath, name })
const exists = await sftpClient.exists(targetDirPath) const exists = await sftpClient.exists(targetDirPath)
if(!exists) return socket.emit('not_exists_dir', '文件夹不存在或当前不可访问') if(!exists) return socket.emit('not_exists_dir', '目录不存在或当前不可访问')
md5List = [] md5List = []
const localPath = rawPath.join(sftpCacheDir, name) const localPath = rawPath.join(sftpCacheDir, name)
fs.emptyDirSync(localPath) // 不存在会创建,存在则清空 fs.emptyDirSync(localPath) // 不存在会创建,存在则清空
socket.emit('create_cache_success') socket.emit('create_cache_success')
}) })
// 2. 上传分片 // 2. 上传分片到面板服务
socket.on('up_file_slice', async ({ name, sliceFile, fileIndex }) => { socket.on('up_file_slice', async ({ name, sliceFile, fileIndex }) => {
// console.log('up_file_slice:', fileIndex, name) // console.log('up_file_slice:', fileIndex, name)
try { try {
@ -147,7 +156,7 @@ function listenInput(sftpClient, socket) {
socket.emit('up_file_slice_fail', error.message) socket.emit('up_file_slice_fail', error.message)
} }
}) })
// 3. 完成上传 // 3. 合并分片上传到服务器
socket.on('up_file_slice_over', async ({ name, targetFilePath, range, size }) => { socket.on('up_file_slice_over', async ({ name, targetFilePath, range, size }) => {
const md5CacheDirPath = rawPath.join(sftpCacheDir, name) const md5CacheDirPath = rawPath.join(sftpCacheDir, name)
const resultFilePath = rawPath.join(sftpCacheDir, name, name) const resultFilePath = rawPath.join(sftpCacheDir, name, name)

View File

@ -459,15 +459,22 @@ const handleUploadDir = async (event) => {
if (showFileProgress.value) return $message.warning('需等待当前任务完成') if (showFileProgress.value) return $message.warning('需等待当前任务完成')
let { files } = event.target let { files } = event.target
if(files.length === 0) return $message.warning('不允许上传空文件夹') if(files.length === 0) return $message.warning('不允许上传空文件夹')
let folderName = files[0].webkitRelativePath.split('/')[0] files = Array.from(files)
console.log(folderName) // console.log(files)
console.log(files) // ,
let foldersName = files.map(file => file.webkitRelativePath.split('/').slice(0, -1).join('/'))
if (foldersName.length === 0) return $message.warning('不允许上传空文件夹')
// console.log(foldersName)
let targetDirPath = curPath.value let targetDirPath = curPath.value
socket.value.emit('create_remote_dir', { targetDirPath, folderName }) socket.value.emit('create_remote_dir', { targetDirPath, foldersName })
socket.value.once('is_exists_dir', (res) => { $message.error(res) }) socket.value.once('create_remote_dir_exists', (res) => {
$message.error(res)
uploadDirRef.value = null
})
socket.value.once('create_remote_dir_success', async () => { socket.value.once('create_remote_dir_success', async () => {
for (let file of files) { for (let [index, file,] of files.entries()) {
let fullFilePath = getPath(`${ folderName }/${ file.name }`) let fullFilePath = getPath(`${ foldersName[index] }/${ file.name }`)
console.log('fullFilePath: ', fullFilePath)
try { try {
await uploadFile(file, fullFilePath) await uploadFile(file, fullFilePath)
} catch (error) { } catch (error) {
@ -481,16 +488,13 @@ const handleUploadDir = async (event) => {
const uploadFile = (file, targetFilePath) => { const uploadFile = (file, targetFilePath) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!file) return reject('file is not defined') if (!file) return reject('file is not defined')
// if ((file.size / 1024 / 1024) > 1000) {
// $message.warn('?')
// }
let reader = new FileReader() let reader = new FileReader()
reader.onload = async () => { reader.onload = async () => {
const { name } = file const { name } = file
const targetDirPath = curPath.value const targetDirPath = curPath.value
curUploadFileName.value = name curUploadFileName.value = name
const size = file.size const size = file.size
if(size === 0) return reject('文件大小为0KB, 无法上传') if (size === 0) return reject('文件大小为0KB, 无法上传')
socket.value.emit('create_cache_dir', { targetDirPath, name }) socket.value.emit('create_cache_dir', { targetDirPath, name })
socket.value.once('create_cache_success', async () => { socket.value.once('create_cache_success', async () => {
let start = 0 let start = 0
@ -501,7 +505,7 @@ const uploadFile = (file, targetFilePath) => {
try { try {
upFileProgress.value = 0 upFileProgress.value = 0
showFileProgress.value = true showFileProgress.value = true
childDirLoading.value = true // childDirLoading.value = true
const totalSliceCount = Math.ceil(size / range) const totalSliceCount = Math.ceil(size / range)
while (end < size) { while (end < size) {
fileIndex++ fileIndex++
@ -563,7 +567,6 @@ const uploadSliceFile = (fileInfo) => {
} }
const openDir = (path = '', tips = true) => { const openDir = (path = '', tips = true) => {
if (showFileProgress.value) return $message.warning('需等待当前任务完成')
childDirLoading.value = true childDirLoading.value = true
curTarget.value = null curTarget.value = null
socket.value.emit('open_dir', path || curPath.value, tips) socket.value.emit('open_dir', path || curPath.value, tips)