From 8a41730b63eb3a027556ee70e6a9cdff0f910cda Mon Sep 17 00:00:00 2001 From: kuaifan Date: Tue, 14 Feb 2023 10:37:37 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=AF=BC=E5=87=BA=E6=89=80=E6=9C=89?= =?UTF-8?q?=E8=B6=85=E6=9C=9F=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Api/ProjectController.php | 109 ++++++++++++++++++ resources/assets/js/pages/manage.vue | 26 +++++ 2 files changed, 135 insertions(+) diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 8458ef973..bf6ac704c 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -1164,6 +1164,115 @@ class ProjectController extends AbstractController } } + /** + * @api {get} api/project/task/exportoverdue 19. 导出超期任务(限管理员) + * + * @apiDescription 导出指定范围任务(已完成、未完成、已归档),返回下载地址,需要token身份 + * @apiVersion 1.0.0 + * @apiGroup project + * @apiName task__exportoverdue + * + * @apiSuccess {Number} ret 返回状态码(1正确、0错误) + * @apiSuccess {String} msg 返回信息(错误描述) + * @apiSuccess {Object} data 返回数据 + */ + public function task__exportoverdue() + { + $user = User::auth('admin'); + // + $headings = []; + $headings[] = '任务ID'; + $headings[] = '父级任务ID'; + $headings[] = '所属项目'; + $headings[] = '任务标题'; + $headings[] = '任务开始时间'; + $headings[] = '任务结束时间'; + $headings[] = '任务计划用时'; + $headings[] = '超时时间'; + $headings[] = '负责人'; + $headings[] = '创建人'; + $data = []; + // + ProjectTask::whereNotNull('end_at') + ->where('end_at', '<=', Carbon::now()) + ->orderBy('end_at') + ->chunk(100, function ($tasks) use (&$data) { + /** @var ProjectTask $task */ + foreach ($tasks as $task) { + $taskStartTime = $task->start_at ? Carbon::parse($task->start_at)->timestamp : Carbon::parse($task->created_at)->timestamp; + $taskCompleteTime = $task->complete_at ? Carbon::parse($task->complete_at)->timestamp : time(); + $totalTime = $taskCompleteTime - $taskStartTime; //开发测试总用时 + $planTime = '-';//任务计划用时 + $overTime = '-';//超时时间 + if ($task->end_at) { + $startTime = Carbon::parse($task->start_at)->timestamp; + $endTime = Carbon::parse($task->end_at)->timestamp; + $planTotalTime = $endTime - $startTime; + $residueTime = $planTotalTime - $totalTime; + if ($residueTime < 0) { + $overTime = Base::timeFormat(abs($residueTime)); + } + $planTime = Base::timeDiff($startTime, $endTime); + } + $ownerIds = $task->taskUser->where('owner', 1)->pluck('userid')->toArray(); + $ownerNames = []; + foreach ($ownerIds as $ownerId) { + $ownerNames[] = Base::filterEmoji(User::userid2nickname($ownerId)) . " (ID: {$ownerId})"; + } + $data[] = [ + $task->id, + $task->parent_id ?: '-', + Base::filterEmoji($task->project?->name) ?: '-', + Base::filterEmoji($task->name), + $task->start_at ?: '-', + $task->end_at ?: '-', + $planTime ?: '-', + $overTime, + implode("、", $ownerNames), + Base::filterEmoji(User::userid2nickname($task->userid)) . " (ID: {$task->userid})", + ]; + } + }); + if (empty($data)) { + return Base::retError('没有任何数据'); + } + // + $sheets = [ + BillExport::create()->setTitle("超期任务")->setHeadings($headings)->setData($data)->setStyles(["A1:J1" => ["font" => ["bold" => true]]]) + ]; + // + $fileName = '超期任务_' . Base::time() . '.xls'; + $filePath = "temp/task/export/" . date("Ym", Base::time()); + $export = new BillMultipleExport($sheets); + $res = $export->store($filePath . "/" . $fileName); + if ($res != 1) { + return Base::retError('导出失败,' . $fileName . '!'); + } + $xlsPath = storage_path("app/" . $filePath . "/" . $fileName); + $zipFile = "app/" . $filePath . "/" . Base::rightDelete($fileName, '.xls') . ".zip"; + $zipPath = storage_path($zipFile); + if (file_exists($zipPath)) { + Base::deleteDirAndFile($zipPath, true); + } + try { + Madzipper::make($zipPath)->add($xlsPath)->close(); + } catch (\Throwable) { + } + // + if (file_exists($zipPath)) { + $base64 = base64_encode(Base::array2string([ + 'file' => $zipFile, + ])); + Session::put('task::export:userid', $user->userid); + return Base::retSuccess('success', [ + 'size' => Base::twoFloat(filesize($zipPath) / 1024, true), + 'url' => Base::fillUrl('api/project/task/down?key=' . urlencode($base64)), + ]); + } else { + return Base::retError('打包失败,请稍后再试...'); + } + } + /** * @api {get} api/project/task/down 20. 下载导出的任务 * diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue index 6ced330d3..fbbc1f96b 100644 --- a/resources/assets/js/pages/manage.vue +++ b/resources/assets/js/pages/manage.vue @@ -70,6 +70,7 @@ {{$L('导出任务统计')}} + {{$L('导出超期任务')}} {{$L('导出签到数据')}} @@ -713,6 +714,9 @@ export default { case 'exportTask': this.exportTaskShow = true; return; + case 'exportOverdueTask': + this.exportOverdueTask(); + return; case 'exportCheckin': this.exportCheckinShow = true; return; @@ -746,6 +750,28 @@ export default { } }, + exportOverdueTask() { + $A.modalConfirm({ + title: '导出任务', + content: '你确定要导出所有超期任务吗?', + loading: true, + onOk: () => { + return new Promise((resolve, reject) => { + this.$store.dispatch("call", { + url: 'project/task/exportoverdue', + }).then(({data}) => { + resolve(); + this.$store.dispatch('downUrl', { + url: data.url + }); + }).catch(({msg}) => { + reject(msg); + }); + }) + }, + }); + }, + menuVisibleChange(visible) { this.visibleMenu = visible },