mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-14 12:42:51 +00:00
perf: 优化实现文件夹下载以及多文件压缩下载功能
This commit is contained in:
parent
92beb20455
commit
43cee0eb4a
@ -972,7 +972,43 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/download/zip 19. 压缩下载
|
* @api {get} api/file/download/check 19. 检测下载
|
||||||
|
*
|
||||||
|
* @apiDescription 需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup file
|
||||||
|
* @apiName download__check
|
||||||
|
*
|
||||||
|
* @apiParam {Array} [ids] 文件ID,格式: [id, id2, id3]
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function download__check(){
|
||||||
|
$user = User::auth();
|
||||||
|
$ids = Request::input('ids');
|
||||||
|
|
||||||
|
if (!is_array($ids) || empty($ids)) {
|
||||||
|
return Base::retError('请选择下载的文件或文件夹');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($ids) > 100) {
|
||||||
|
return Base::retError('一次最多只能下载100个文件或文件夹');
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = [];
|
||||||
|
AbstractModel::transaction(function() use ($user, $ids, &$files) {
|
||||||
|
foreach ($ids as $id) {
|
||||||
|
$files[] = File::getFilesTree(intval($id), $user, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Base::retSuccess('success');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/file/download/zip 20. 压缩下载
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -989,13 +1025,6 @@ class FileController extends AbstractController
|
|||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
$ids = Request::input('ids');
|
$ids = Request::input('ids');
|
||||||
if (!is_array($ids) || empty($ids)) {
|
|
||||||
return Base::retError('Please select the downloaded file or folder');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($ids) > 100) {
|
|
||||||
return Base::retError('You can only download up to 100 files or folders at a time');
|
|
||||||
}
|
|
||||||
|
|
||||||
$files = [];
|
$files = [];
|
||||||
AbstractModel::transaction(function() use ($user, $ids, &$files) {
|
AbstractModel::transaction(function() use ($user, $ids, &$files) {
|
||||||
@ -1005,12 +1034,14 @@ class FileController extends AbstractController
|
|||||||
});
|
});
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
$zip = new \ZipArchive();
|
||||||
$zipName = 'temp/download/' . date("Ym") . '/' . $user->userid . '/file_' . date("YmdHis") . '.zip';
|
// 下载文件名
|
||||||
|
$downName = count($ids) > 1 ? 'file_'. date("YmdHis") : $files[0]->name;
|
||||||
|
$zipName = 'temp/download/' . date("Ym") . '/' . $user->userid . '/' . $downName . '.zip';
|
||||||
$zipPath = storage_path('app/'.$zipName);
|
$zipPath = storage_path('app/'.$zipName);
|
||||||
Base::makeDir(dirname($zipPath));
|
Base::makeDir(dirname($zipPath));
|
||||||
|
|
||||||
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
||||||
return Base::retError('创建压缩文件失败');
|
return Base::retError('Failed to create compressed file');
|
||||||
}
|
}
|
||||||
|
|
||||||
array_walk($files, function($file) use ($zip) {
|
array_walk($files, function($file) use ($zip) {
|
||||||
@ -1019,6 +1050,6 @@ class FileController extends AbstractController
|
|||||||
|
|
||||||
$zip->close();
|
$zip->close();
|
||||||
|
|
||||||
return response()->download($zipPath, 'file_'. date("YmdHis") .'.zip')->deleteFileAfterSend(true);
|
return response()->download($zipPath, $downName .'.zip')->deleteFileAfterSend(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -834,15 +834,16 @@ class File extends AbstractModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件树
|
* 获取文件树并计算文件总大小
|
||||||
*
|
*
|
||||||
* @param int $fileId
|
* @param int $fileId
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @param int $permission
|
* @param int $permission
|
||||||
* @param string $path
|
* @param string $path
|
||||||
|
* @param int $totalSize
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public static function getFilesTree(int $fileId, User $user, $permission = 1, $path = '') {
|
public static function getFilesTree(int $fileId, User $user, $permission = 1, $path = '', &$totalSize = 0) {
|
||||||
$file = File::permissionFind($fileId, $user, $permission);
|
$file = File::permissionFind($fileId, $user, $permission);
|
||||||
$file->path = ltrim($path . '/' . $file->name, '/');
|
$file->path = ltrim($path . '/' . $file->name, '/');
|
||||||
$file->children = [];
|
$file->children = [];
|
||||||
@ -851,34 +852,21 @@ class File extends AbstractModel
|
|||||||
foreach ($files as &$childFile) {
|
foreach ($files as &$childFile) {
|
||||||
$childFile['path'] = $file->path . '/' . $childFile['name'];
|
$childFile['path'] = $file->path . '/' . $childFile['name'];
|
||||||
if ($childFile['type'] == 'folder') {
|
if ($childFile['type'] == 'folder') {
|
||||||
$childFile['children'] = self::getFilesTree($childFile['id'], $user, $permission, $file->path);
|
$childFile['children'] = self::getFilesTree($childFile['id'], $user, $permission, $file->path, $totalSize);
|
||||||
|
} else {
|
||||||
|
$totalSize += $childFile['size'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$file->children = $files;
|
$file->children = $files;
|
||||||
}
|
|
||||||
$totalSize = self::calculateTotalSize($file);
|
|
||||||
if ($totalSize > 1024 * 1024 * 1024) { // 1GB
|
|
||||||
throw new ApiException('The total file size has exceeded 1GB, please download in batches');
|
|
||||||
}
|
|
||||||
return $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算文件夹文件总大小
|
|
||||||
*
|
|
||||||
* @param [type] $fileTree
|
|
||||||
* @return float|int
|
|
||||||
*/
|
|
||||||
public static function calculateTotalSize($fileTree) {
|
|
||||||
$totalSize = 0;
|
|
||||||
if ($fileTree->type != 'folder') {
|
|
||||||
$totalSize += $fileTree->size;
|
|
||||||
} else {
|
} else {
|
||||||
foreach ($fileTree->children as $childFile) {
|
$totalSize += $file->size;
|
||||||
$totalSize += self::calculateTotalSize((object)$childFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $totalSize;
|
|
||||||
|
if ($totalSize > 1024 * 1024 * 1024) { // 1GB
|
||||||
|
throw new ApiException('文件总大小已超过1GB,请分批下载');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1419,8 +1419,21 @@ export default {
|
|||||||
content: `你确定要下载${fileName}吗?`,
|
content: `你确定要下载${fileName}吗?`,
|
||||||
okText: '立即下载',
|
okText: '立即下载',
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
const idsParam = ids.join('&ids[]=');
|
return new Promise((resolve, reject) => {
|
||||||
this.$store.dispatch('downUrl', $A.apiUrl(`file/download/zip?ids[]=${idsParam}`));
|
this.$store.dispatch("call", {
|
||||||
|
url: 'file/download/check',
|
||||||
|
data: {
|
||||||
|
ids,
|
||||||
|
},
|
||||||
|
}).then(({msg}) => {
|
||||||
|
const idsParam = ids.join('&ids[]=');
|
||||||
|
this.$store.dispatch('downUrl', $A.apiUrl(`file/download/zip?ids[]=${idsParam}`));
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg)
|
||||||
|
reject(msg);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user