mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 03:01:12 +00:00
perf: 优化导出任务功能
This commit is contained in:
parent
31879cb60b
commit
25e82d690e
@ -1258,7 +1258,7 @@ class ProjectController extends AbstractController
|
|||||||
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
|
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
|
||||||
//
|
//
|
||||||
go(function () use ($user, $userid, $time, $type, $botUser, $dialog) {
|
go(function () use ($user, $userid, $time, $type, $botUser, $dialog) {
|
||||||
Coroutine::sleep(0.1);
|
Coroutine::sleep(1);
|
||||||
$headings = [];
|
$headings = [];
|
||||||
$headings[] = Doo::translate('任务ID');
|
$headings[] = Doo::translate('任务ID');
|
||||||
$headings[] = Doo::translate('父级任务ID');
|
$headings[] = Doo::translate('父级任务ID');
|
||||||
@ -1394,7 +1394,7 @@ class ProjectController extends AbstractController
|
|||||||
'type' => 'content',
|
'type' => 'content',
|
||||||
'title' => $content[0]['content'],
|
'title' => $content[0]['content'],
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
], $botUser->userid, false, false, true);
|
], $botUser->userid, true, false, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -1428,7 +1428,7 @@ class ProjectController extends AbstractController
|
|||||||
'type' => 'content',
|
'type' => 'content',
|
||||||
'title' => $content[0]['content'],
|
'title' => $content[0]['content'],
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
], $botUser->userid, false, false, true);
|
], $botUser->userid, true, false, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -1455,7 +1455,7 @@ class ProjectController extends AbstractController
|
|||||||
'name' => $fileName,
|
'name' => $fileName,
|
||||||
'size' => filesize($zipPath),
|
'size' => filesize($zipPath),
|
||||||
'url' => $fileUrl,
|
'url' => $fileUrl,
|
||||||
], $botUser->userid, false, false, true);
|
], $botUser->userid, true, false, true);
|
||||||
} else {
|
} else {
|
||||||
$content[] = [
|
$content[] = [
|
||||||
'content' => "打包失败,请稍后再试...",
|
'content' => "打包失败,请稍后再试...",
|
||||||
@ -1465,9 +1465,15 @@ class ProjectController extends AbstractController
|
|||||||
'type' => 'content',
|
'type' => 'content',
|
||||||
'title' => $content[0]['content'],
|
'title' => $content[0]['content'],
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
], $botUser->userid, false, false, true);
|
], $botUser->userid, true, false, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//
|
||||||
|
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
|
||||||
|
'type' => 'content',
|
||||||
|
'content' => '正在导出任务统计,请稍等...',
|
||||||
|
], $botUser->userid, true, false, true);
|
||||||
|
//
|
||||||
return Base::retSuccess('success');
|
return Base::retSuccess('success');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1487,103 +1493,156 @@ class ProjectController extends AbstractController
|
|||||||
{
|
{
|
||||||
$user = User::auth('admin');
|
$user = User::auth('admin');
|
||||||
//
|
//
|
||||||
$headings = [];
|
$botUser = User::botGetOrCreate('system-msg');
|
||||||
$headings[] = Doo::translate('任务ID');
|
if (empty($botUser)) {
|
||||||
$headings[] = Doo::translate('父级任务ID');
|
return Base::retError('系统机器人不存在');
|
||||||
$headings[] = Doo::translate('所属项目');
|
}
|
||||||
$headings[] = Doo::translate('任务标题');
|
$dialog = WebSocketDialog::checkUserDialog($botUser, $user->userid);
|
||||||
$headings[] = Doo::translate('任务标签');
|
|
||||||
$headings[] = Doo::translate('任务开始时间');
|
|
||||||
$headings[] = Doo::translate('任务结束时间');
|
|
||||||
$headings[] = Doo::translate('任务计划用时');
|
|
||||||
$headings[] = Doo::translate('超时时间');
|
|
||||||
$headings[] = Doo::translate('负责人');
|
|
||||||
$headings[] = Doo::translate('创建人');
|
|
||||||
$data = [];
|
|
||||||
//
|
//
|
||||||
ProjectTask::with(['taskTag'])
|
go(function () use ($botUser, $dialog, $user) {
|
||||||
->whereNull('complete_at')
|
Coroutine::sleep(1);
|
||||||
->whereNotNull('end_at')
|
//
|
||||||
->where('end_at', '<=', Carbon::now())
|
$headings = [];
|
||||||
->orderBy('end_at')
|
$headings[] = Doo::translate('任务ID');
|
||||||
->chunk(100, function ($tasks) use (&$data) {
|
$headings[] = Doo::translate('父级任务ID');
|
||||||
/** @var ProjectTask $task */
|
$headings[] = Doo::translate('所属项目');
|
||||||
foreach ($tasks as $task) {
|
$headings[] = Doo::translate('任务标题');
|
||||||
$taskStartTime = Carbon::parse($task->start_at ?: $task->created_at)->timestamp;
|
$headings[] = Doo::translate('任务标签');
|
||||||
$totalTime = time() - $taskStartTime; //开发测试总用时
|
$headings[] = Doo::translate('任务开始时间');
|
||||||
$planTime = '-';//任务计划用时
|
$headings[] = Doo::translate('任务结束时间');
|
||||||
$overTime = '-';//超时时间
|
$headings[] = Doo::translate('任务计划用时');
|
||||||
if ($task->end_at) {
|
$headings[] = Doo::translate('超时时间');
|
||||||
$startTime = Carbon::parse($task->start_at)->timestamp;
|
$headings[] = Doo::translate('负责人');
|
||||||
$endTime = Carbon::parse($task->end_at)->timestamp;
|
$headings[] = Doo::translate('创建人');
|
||||||
$planTotalTime = $endTime - $startTime;
|
$data = [];
|
||||||
$residueTime = $planTotalTime - $totalTime;
|
//
|
||||||
if ($residueTime < 0) {
|
$content = [];
|
||||||
$overTime = Doo::translate(Timer::timeFormat(abs($residueTime)));
|
$content[] = [
|
||||||
|
'content' => '导出超期任务已完成',
|
||||||
|
'style' => 'font-weight: bold;padding-bottom: 4px;',
|
||||||
|
];
|
||||||
|
//
|
||||||
|
ProjectTask::with(['taskTag'])
|
||||||
|
->whereNull('complete_at')
|
||||||
|
->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 = Carbon::parse($task->start_at ?: $task->created_at)->timestamp;
|
||||||
|
$totalTime = time() - $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 = Doo::translate(Timer::timeFormat(abs($residueTime)));
|
||||||
|
}
|
||||||
|
$planTime = Doo::translate(Timer::timeDiff($startTime, $endTime));
|
||||||
}
|
}
|
||||||
$planTime = Doo::translate(Timer::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->taskTag->map(function ($tag) {
|
||||||
|
return Base::filterEmoji($tag->name);
|
||||||
|
})->join(', ') ?: '-',
|
||||||
|
$task->start_at ?: '-',
|
||||||
|
$task->end_at ?: '-',
|
||||||
|
$planTime,
|
||||||
|
$overTime,
|
||||||
|
implode(', ', $ownerNames),
|
||||||
|
Base::filterEmoji(User::userid2nickname($task->userid)) . " (ID: {$task->userid})",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
$ownerIds = $task->taskUser->where('owner', 1)->pluck('userid')->toArray();
|
});
|
||||||
$ownerNames = [];
|
if (empty($data)) {
|
||||||
foreach ($ownerIds as $ownerId) {
|
$content[] = [
|
||||||
$ownerNames[] = Base::filterEmoji(User::userid2nickname($ownerId)) . " (ID: {$ownerId})";
|
'content' => '没有任何数据',
|
||||||
}
|
'style' => 'color: #ff0000;',
|
||||||
$data[] = [
|
];
|
||||||
$task->id,
|
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
|
||||||
$task->parent_id ?: '-',
|
'type' => 'content',
|
||||||
Base::filterEmoji($task->project?->name) ?: '-',
|
'title' => $content[0]['content'],
|
||||||
Base::filterEmoji($task->name),
|
'content' => $content,
|
||||||
$task->taskTag->map(function ($tag) {
|
], $botUser->userid, true, false, true);
|
||||||
return Base::filterEmoji($tag->name);
|
return;
|
||||||
})->join(', ') ?: '-',
|
}
|
||||||
$task->start_at ?: '-',
|
//
|
||||||
$task->end_at ?: '-',
|
$title = Doo::translate('超期任务');
|
||||||
$planTime,
|
$sheets = [
|
||||||
$overTime,
|
BillExport::create()->setTitle($title)->setHeadings($headings)->setData($data)->setStyles(["A1:J1" => ["font" => ["bold" => true]]])
|
||||||
implode(', ', $ownerNames),
|
];
|
||||||
Base::filterEmoji(User::userid2nickname($task->userid)) . " (ID: {$task->userid})",
|
//
|
||||||
];
|
$fileName = $title . '_' . Timer::time() . '.xls';
|
||||||
}
|
$filePath = "temp/task/export/" . date("Ym", Timer::time());
|
||||||
});
|
$export = new BillMultipleExport($sheets);
|
||||||
if (empty($data)) {
|
$res = $export->store($filePath . "/" . $fileName);
|
||||||
return Base::retError('没有任何数据');
|
if ($res != 1) {
|
||||||
}
|
$content[] = [
|
||||||
|
'content' => "导出失败,{$fileName}!",
|
||||||
|
'style' => 'color: #ff0000;',
|
||||||
|
];
|
||||||
|
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
|
||||||
|
'type' => 'content',
|
||||||
|
'title' => $content[0]['content'],
|
||||||
|
'content' => $content,
|
||||||
|
], $botUser->userid, true, false, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$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,
|
||||||
|
]));
|
||||||
|
$fileUrl = Base::fillUrl('api/project/task/down?key=' . urlencode($base64));
|
||||||
|
Session::put('task::export:userid', $user->userid);
|
||||||
|
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
|
||||||
|
'type' => 'file_download',
|
||||||
|
'title' => '导出超期任务已完成',
|
||||||
|
'name' => $fileName,
|
||||||
|
'size' => filesize($zipPath),
|
||||||
|
'url' => $fileUrl,
|
||||||
|
], $botUser->userid, true, false, true);
|
||||||
|
} else {
|
||||||
|
$content[] = [
|
||||||
|
'content' => "打包失败,请稍后再试...",
|
||||||
|
'style' => 'color: #ff0000;',
|
||||||
|
];
|
||||||
|
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
|
||||||
|
'type' => 'content',
|
||||||
|
'title' => $content[0]['content'],
|
||||||
|
'content' => $content,
|
||||||
|
], $botUser->userid, true, false, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
//
|
//
|
||||||
$title = Doo::translate('超期任务');
|
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
|
||||||
$sheets = [
|
'type' => 'content',
|
||||||
BillExport::create()->setTitle($title)->setHeadings($headings)->setData($data)->setStyles(["A1:J1" => ["font" => ["bold" => true]]])
|
'content' => '正在导出超期任务,请稍等...',
|
||||||
];
|
], $botUser->userid, true, false, true);
|
||||||
//
|
//
|
||||||
$fileName = $title . '_' . Timer::time() . '.xls';
|
return Base::retSuccess('success');
|
||||||
$filePath = "temp/task/export/" . date("Ym", Timer::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('打包失败,请稍后再试...');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -87,6 +87,9 @@
|
|||||||
没有任何数据
|
没有任何数据
|
||||||
导出失败,(*)!
|
导出失败,(*)!
|
||||||
打包失败,请稍后再试...
|
打包失败,请稍后再试...
|
||||||
|
正在导出任务统计,请稍等...
|
||||||
|
导出超期任务已完成
|
||||||
|
正在导出超期任务,请稍等...
|
||||||
任务列表不存在或已被删除
|
任务列表不存在或已被删除
|
||||||
主任务已完成无法添加子任务
|
主任务已完成无法添加子任务
|
||||||
子任务不支持此功能
|
子任务不支持此功能
|
||||||
|
|||||||
@ -1639,6 +1639,9 @@ Token
|
|||||||
导出任务统计已完成
|
导出任务统计已完成
|
||||||
没有任何数据
|
没有任何数据
|
||||||
打包失败,请稍后再试...
|
打包失败,请稍后再试...
|
||||||
|
正在导出任务统计,请稍等...
|
||||||
|
导出超期任务已完成
|
||||||
|
正在导出超期任务,请稍等...
|
||||||
(*)查看了(*)的联系电话
|
(*)查看了(*)的联系电话
|
||||||
标记任务未完成
|
标记任务未完成
|
||||||
标记任务已完成
|
标记任务已完成
|
||||||
|
|||||||
@ -844,11 +844,9 @@ export default {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.$store.dispatch("call", {
|
this.$store.dispatch("call", {
|
||||||
url: 'project/task/exportoverdue',
|
url: 'project/task/exportoverdue',
|
||||||
}).then(({data}) => {
|
}).then(() => {
|
||||||
resolve();
|
resolve();
|
||||||
this.$store.dispatch('downUrl', {
|
$A.modalSuccess('正在打包,请留意系统消息。');
|
||||||
url: data.url
|
|
||||||
});
|
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
reject(msg);
|
reject(msg);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user