From 846fdcf1456ef9a9f22ebaaff21f3012ca44c73c Mon Sep 17 00:00:00 2001 From: kuaifan Date: Wed, 3 Jan 2024 20:48:49 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=89=93=E5=8C=85?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/FileController.php | 87 ++++++++++--------- .../Controllers/Api/ProjectController.php | 16 ++-- composer.json | 1 + language/original-web.txt | 4 +- language/translate.json | 13 +-- .../js/pages/manage/components/TaskExport.vue | 2 +- resources/assets/js/pages/manage/file.vue | 57 +++++------- 7 files changed, 84 insertions(+), 96 deletions(-) diff --git a/app/Http/Controllers/Api/FileController.php b/app/Http/Controllers/Api/FileController.php index d949de748..7c75bb4b7 100755 --- a/app/Http/Controllers/Api/FileController.php +++ b/app/Http/Controllers/Api/FileController.php @@ -13,6 +13,8 @@ use App\Models\User; use App\Module\Base; use App\Module\Ihttp; +use Response; +use Session; use Swoole\Coroutine; use Carbon\Carbon; use Redirect; @@ -991,9 +993,33 @@ public function link() */ public function download__pack() { + $key = Request::input('key'); + if ($key) { + $userid = Session::get('file::pack:userid'); + if (empty($userid)) { + return Base::ajaxError("请求已过期,请重新导出!", [], 0, 502); + } + // + $array = Base::string2array(base64_decode(urldecode($key))); + $file = $array['file']; + if (empty($file) || !file_exists(storage_path($file))) { + return Base::ajaxError("文件不存在!", [], 0, 502); + } + return Response::download(storage_path($file)); + } + $user = User::auth(); $ids = Request::input('ids'); - $downName = Request::input('name'); + $fileName = Request::input('name'); + $fileName = preg_replace("/[\/\\\:\*\?\"\<\>\|]/", "", $fileName); + if (empty($fileName)) { + $fileName = 'Package_' . $user->userid; + } + $fileName .= '_' . Base::time() . '.zip'; + + $filePath = "temp/file/pack/" . date("Ym", Base::time()); + $zipFile = "app/" . $filePath . "/" . $fileName; + $zipPath = storage_path($zipFile); if (!is_array($ids) || empty($ids)) { return Base::retError('请选择下载的文件或文件夹'); @@ -1001,9 +1027,6 @@ public function download__pack() if (count($ids) > 100) { return Base::retError('一次最多可以下载100个文件或文件夹'); } - if (count($ids) > 100) { - return Base::retError('一次最多可以下载100个文件或文件夹'); - } $files = []; $totalSize = 0; @@ -1017,23 +1040,28 @@ public function download__pack() return Base::retError('文件总大小已超过1GB,请分批下载'); } + $base64 = base64_encode(Base::array2string([ + 'file' => $zipFile, + ])); + $fileUrl = Base::fillUrl('api/file/download/pack?key=' . urlencode($base64)); + Session::put('file::pack:userid', $user->userid); + $zip = new \ZipArchive(); - $zipName = 'tmp/file/' . date("Ym") . '/' . $user->userid . '/' . $downName; - $zipPath = public_path($zipName); Base::makeDir(dirname($zipPath)); if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { return Base::retError('创建压缩文件失败'); } - go(function() use ($user, $zip, $files, $downName, $zipName) { + go(function () use ($zipPath, $fileUrl, $user, $zip, $files, $fileName, $zipFile) { Coroutine::sleep(0.1); // 压缩进度 $progress = 0; - $zip->registerProgressCallback(0.05, function($ratio) use ($downName, &$progress) { + $zip->registerProgressCallback(0.05, function ($ratio) use ($fileUrl, $fileName, &$progress) { $progress = round($ratio * 100); File::filePushMsg('compress', [ - 'name'=> $downName, + 'name' => $fileName, + 'url' => $fileUrl, 'progress' => $progress ]); }); @@ -1045,7 +1073,8 @@ public function download__pack() // if ($progress < 100) { File::filePushMsg('compress', [ - 'name'=> $downName, + 'name' => $fileName, + 'url' => $fileUrl, 'progress' => 100 ]); } @@ -1057,39 +1086,17 @@ public function download__pack() if ($dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid)) { $text = "文件下载打包已完成。"; $text .= "\n\n"; - $text .= "文件名:{$downName}"; + $text .= "文件名:{$fileName}"; $text .= "\n"; - $text .= "下载地址:".Base::fillUrl($zipName); + $text .= "文件大小:".Base::twoFloat(filesize($zipPath) / 1024, true)."KB"; + $text .= "\n"; + $text .= ''; WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', ['text' => $text], $botUser->userid, false, false, true); } }); - - return Base::retSuccess('success'); - } - - /** - * @api {get} api/file/download/confirm 20. 确认下载 - * - * @apiDescription 需要token身份 - * @apiVersion 1.0.0 - * @apiGroup file - * @apiName download__confirm - * - * @apiParam {String} [name] 下载文件名 - * - * @apiSuccess {Number} ret 返回状态码(1正确、0错误) - * @apiSuccess {String} msg 返回信息(错误描述) - * @apiSuccess {Object} data 返回数据 - */ - public function download__confirm() - { - $user = User::auth(); - $downName = Request::input('name'); - $zipName = 'tmp/file/' . date("Ym") . '/' . $user->userid . '/' . $downName; - $zipPath = public_path($zipName); - if (!file_exists($zipPath)) { - abort(403, "The file does not exist."); - } - return response()->download($zipPath); + return Base::retSuccess('success', [ + 'name' => $fileName, + 'url' => $fileUrl, + ]); } } diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 3e0123593..414c65915 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -1200,7 +1200,7 @@ public function task__export() if (Carbon::parse($time[1])->timestamp - Carbon::parse($time[0])->timestamp > 90 * 86400) { return Base::retError('时间范围限制最大90天'); } - go(function() use ($user, $userid, $time, $type) { + go(function () use ($user, $userid, $time, $type) { Coroutine::sleep(0.1); $headings = []; $headings[] = '任务ID'; @@ -1324,10 +1324,10 @@ public function task__export() $sheets = []; foreach ($userid as $ownerid) { $data = $datas[$ownerid] ?? [ - 'nickname' => Base::filterEmoji(User::userid2nickname($ownerid)), - 'styles' => ["A1:P1" => ["font" => ["bold" => true]]], - 'data' => [], - ]; + 'nickname' => Base::filterEmoji(User::userid2nickname($ownerid)), + 'styles' => ["A1:P1" => ["font" => ["bold" => true]]], + 'data' => [], + ]; $title = (count($sheets) + 1) . "." . ($data['nickname'] ?: $ownerid); $sheets[] = BillExport::create()->setTitle($title)->setHeadings($headings)->setData($data['data'])->setStyles($data['styles']); } @@ -1369,14 +1369,14 @@ public function task__export() $text .= "\n\n"; $text .= "文件名:{$fileName}"; $text .= "\n"; - $text .= "文件大小:".Base::twoFloat(filesize($zipPath) / 1024, true)."KB"; + $text .= "文件大小:" . Base::twoFloat(filesize($zipPath) / 1024, true) . "KB"; $text .= "\n"; - $text .= ''; + $text .= ''; WebSocketDialogMsg::sendMsg(null, $dialog->id, 'text', ['text' => $text], $botUser->userid, false, false, true); } } }); - return Base::retSuccess('success',['msg' => '正在打包,请留意系统消息']); + return Base::retSuccess('success', ['msg' => '正在打包,请留意系统消息。']); } /** diff --git a/composer.json b/composer.json index d7b40f62e..e310deb21 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "ext-libxml": "*", "ext-openssl": "*", "ext-simplexml": "*", + "ext-zip": "*", "directorytree/ldaprecord-laravel": "^2.7", "fideloper/proxy": "^4.4.1", "firebase/php-jwt": "^6.9", diff --git a/language/original-web.txt b/language/original-web.txt index 16d5c99d1..663cdd4b2 100644 --- a/language/original-web.txt +++ b/language/original-web.txt @@ -1491,7 +1491,7 @@ APP推送 LDAP License Key 你确定要打包下载【(*)】文件夹吗? -正在打包,请留意系统消息 +正在打包,请留意系统消息。 发起,参与接龙目前共(*)人 选择会员 @@ -1500,3 +1500,5 @@ License Key 置顶人员 置顶了 你确定取消置顶吗? + +打包下载(*) diff --git a/language/translate.json b/language/translate.json index 611cc4fdc..f0c6c0b71 100644 --- a/language/translate.json +++ b/language/translate.json @@ -19392,17 +19392,6 @@ "fr": "Êtes-vous sûr de vouloir emballer le dossier download [Bigw]?", "id": "Kau yakin ingin berkemas untuk download?" }, - { - "key": "正在打包,请留意系统消息", - "zh": "", - "zh-CHT": "正在打包,請留意系統消息", - "en": "Packing, please pay attention to the system message", - "ko": "압축하고 있습니다. 시스템 메시지를 확인하십시오", - "ja": "パッケージ化中ですので、システムメッセージにご注意ください。", - "de": "Bereits am packen, geben sie eine nachricht nach system ab", - "fr": "Emballage en cours, gardez un oeil sur les messages du système", - "id": "Paket sedang dikemas" - }, { "key": "创建一个全新的会议视频会议,与会者可以在实时中进行面对面的视听交流。", "zh": "", @@ -19513,4 +19502,4 @@ "fr": "Êtes-vous sûr de supprimer le plafond?", "id": "Kau yakin mau membatalkan toplesnya?" } -] \ No newline at end of file +] diff --git a/resources/assets/js/pages/manage/components/TaskExport.vue b/resources/assets/js/pages/manage/components/TaskExport.vue index f4853dbae..fe051cb38 100644 --- a/resources/assets/js/pages/manage/components/TaskExport.vue +++ b/resources/assets/js/pages/manage/components/TaskExport.vue @@ -102,7 +102,7 @@ export default { data: this.formData, }).then(({data}) => { this.show = false; - $A.messageSuccess(data.msg); + $A.modalSuccess(data.msg); }).catch(({msg}) => { $A.modalError(msg); }).finally(_ => { diff --git a/resources/assets/js/pages/manage/file.vue b/resources/assets/js/pages/manage/file.vue index 1f36b0480..e06a27f42 100644 --- a/resources/assets/js/pages/manage/file.vue +++ b/resources/assets/js/pages/manage/file.vue @@ -254,7 +254,7 @@
  • {{item.name}} - {{item.name}} + {{item.name}} {{item.response.msg}} @@ -1468,40 +1468,30 @@ export default { this.packShow = false; }, - async startPack(filePackName) { - const file = { name: filePackName, status: 'packing', percentage: 0 }; - this.packList.push(file); + async startPack(data) { + this.packList.push(Object.assign(data, { + status: 'packing', + percentage: 0 + })); this.uploadShow = false; // 隐藏上传列表 this.packShow = true; // 显示打包列表 }, - updatePackProgress () { - this.packList.forEach(file=>{ + updatePackProgress() { + this.packList.forEach(file => { const pack = this.filePackLists.find(({name}) => name == file.name) - if(pack){ + if (pack) { + if (typeof file.percentage === "number" && file.percentage >= 100) { + return + } file.percentage = Math.max(1, pack.progress); - if (file.status != 'finished' && file.percentage >= 100) { + if (file.percentage >= 100) { file.status = 'finished'; - this.downloadPackFile(file.name); } } }) }, - downloadPackFile(filePackName) { - const downloadUrl = $A.apiUrl(`file/download/confirm?name=${filePackName}&token=${this.userToken}`); - if (!$A.Electron && !$A.isEEUiApp) { - const link = document.createElement('a'); - link.setAttribute('href', downloadUrl); - link.setAttribute('download', `${filePackName}`); - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - }else{ - this.$store.dispatch('downUrl', downloadUrl) - } - }, - downloadZipFile(ids){ if (ids.length === 0) { return @@ -1510,26 +1500,25 @@ export default { const allFolder = !ids.some(id => this.fileLists.some(({ type, id: itemId }) => type !== 'folder' && itemId === id)); const typeName = allFolder ? "文件夹" : "文件"; const fileName = ids.length === 1 ? `【${firstFile.name}】${typeName}` : `【${firstFile.name}】等${ids.length}个${typeName}`; - const filePackName = `file_${$A.formatDate("YmdHis")}.zip`; $A.modalConfirm({ title: '打包下载', content: `你确定要打包下载${fileName}吗?`, okText: '确定', - onOk: async () => { - if( this.packList.find(({ status }) => status === 'packing') ){ + onOk: () => { + if (this.packList.find(({status}) => status === 'packing')) { $A.messageWarning("请等待打包完成"); return; } - try { - await this.$store.dispatch("call", { - url: 'file/download/pack', - data: { ids, name: filePackName }, - }); - this.startPack(filePackName); - } catch ({ msg }) { + const name = this.$L(`打包下载${fileName}`) + this.$store.dispatch("call", { + url: 'file/download/pack', + data: {ids, name}, + }).then(({data}) => { + this.startPack(data); + }).catch(({msg}) => { $A.modalError(msg); - } + }); } }); },