perf: 优化客户端升级

This commit is contained in:
kuaifan 2024-11-15 09:04:47 +08:00
parent ca1028921a
commit fbb74e09e8
3 changed files with 137 additions and 73 deletions

View File

@ -138,7 +138,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Use Node.js 20.x - name: Use Node.js 20.x
uses: actions/setup-node@v1 uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 20.x

View File

@ -269,7 +269,8 @@ class IndexController extends InvokeController
if (strtolower($name) === 'latest') { if (strtolower($name) === 'latest') {
$name = $latestVersion; $name = $latestVersion;
} }
// 上传
// 上传header 中包含 publish-version
if (preg_match("/^\d+\.\d+\.\d+$/", $publishVersion)) { if (preg_match("/^\d+\.\d+\.\d+$/", $publishVersion)) {
// 判断密钥 // 判断密钥
$publishKey = Request::header('publish-key'); $publishKey = Request::header('publish-key');
@ -277,55 +278,70 @@ class IndexController extends InvokeController
return Base::retError("key error"); return Base::retError("key error");
} }
// 判断版本 // 判断版本
if (version_compare($publishVersion, $latestVersion) > -1) { // 限制上传版本必须 ≥ 当前版本 $action = Request::get('action');
$action = Request::get('action'); $draftPath = "uploads/desktop-draft/{$publishVersion}/";
$draftPath = "uploads/desktop-draft/{$publishVersion}/"; if ($action === 'release') {
if ($action === 'release') { // 将草稿版本发布为正式版本
// 将草稿版本发布为正式版本 $draftPath = public_path($draftPath);
$draftPath = public_path($draftPath); $releasePath = public_path("uploads/desktop/{$publishVersion}/");
$releasePath = public_path("uploads/desktop/{$publishVersion}/"); if (!file_exists($draftPath)) {
if (!file_exists($draftPath)) { return Base::retError("draft version not exists");
return Base::retError("draft version not exists");
}
if (file_exists($releasePath)) {
Base::deleteDirAndFile($releasePath);
}
Base::copyDirectory($draftPath, $releasePath);
file_put_contents($latestFile, $publishVersion);
// 删除旧版本
Base::deleteDirAndFile(public_path("uploads/desktop-draft"));
$dirs = Base::recursiveDirs(public_path("uploads/desktop"), false);
sort($dirs);
$num = 0;
foreach ($dirs as $dir) {
if (!preg_match("/\/\d+\.\d+\.\d+$/", $dir)) {
continue;
}
$num++;
if ($num < 2) {
continue;
}
$time = filemtime($dir);
if ($time < time() - 3600 * 24 * 30) {
Base::deleteDirAndFile($dir);
}
}
return Base::retSuccess('success');
} }
// 上传草稿版本 if (file_exists($releasePath)) {
return Base::upload([ Base::deleteDirAndFile($releasePath);
"file" => Request::file('file'), }
"type" => 'publish', Base::copyDirectory($draftPath, $releasePath);
"path" => $draftPath, file_put_contents($latestFile, $publishVersion);
"fileName" => true, // 删除旧版本
"quality" => 100 Base::deleteDirAndFile(public_path("uploads/desktop-draft"));
]); $dirs = Base::recursiveDirs(public_path("uploads/desktop"), false);
sort($dirs);
$num = 0;
foreach ($dirs as $dir) {
if (!preg_match("/\/\d+\.\d+\.\d+$/", $dir)) {
continue;
}
$num++;
if ($num < 5) {
continue; // 保留最新的5个版本
}
if (filemtime($dir) > time() - 3600 * 24 * 30) {
continue; // 保留最近30天的版本
}
Base::deleteDirAndFile($dir);
}
return Base::retSuccess('success');
} }
// 上传草稿版本
return Base::upload([
"file" => Request::file('file'),
"type" => 'publish',
"path" => $draftPath,
"fileName" => true,
"quality" => 100
]);
} }
// 列表
if (preg_match("/^\d+\.\d+\.\d+$/", $name)) { // 列表(访问路径 desktop/publish/{version}
$path = "uploads/desktop/{$name}"; if (preg_match("/^v*(\d+\.\d+\.\d+)$/", $name, $match)) {
$dirPath = public_path($path); $paths = [
"uploads/desktop/{$match[1]}/",
"uploads/desktop/v{$match[1]}/",
"uploads/desktop-draft/{$match[1]}/",
"uploads/desktop-draft/v{$match[1]}/",
];
$avaiPath = null;
foreach ($paths as $path) {
$dirPath = public_path($path);
$isDraft = str_contains($path, 'draft');
if (is_dir($dirPath)) {
$avaiPath = $path;
break;
}
}
if (empty($avaiPath)) {
abort(404);
}
$lists = Base::recursiveFiles($dirPath, false); $lists = Base::recursiveFiles($dirPath, false);
$files = []; $files = [];
foreach ($lists as $file) { foreach ($lists as $file) {
@ -338,22 +354,43 @@ class IndexController extends InvokeController
'name' => $fileName, 'name' => $fileName,
'time' => date("Y-m-d H:i:s", filemtime($file)), 'time' => date("Y-m-d H:i:s", filemtime($file)),
'size' => $fileSize > 0 ? Base::readableBytes($fileSize) : 0, 'size' => $fileSize > 0 ? Base::readableBytes($fileSize) : 0,
'url' => Base::fillUrl(Base::joinPath($path, $fileName)), 'url' => Base::fillUrl(Base::joinPath($avaiPath, $fileName)),
];
}
$otherVersion = [];
$dirs = Base::recursiveDirs(public_path("uploads/desktop"), false);
foreach ($dirs as $dir) {
if (!preg_match("/\/\d+\.\d+\.\d+$/", $dir)) {
continue;
}
$version = basename($dir);
if ($version === $match[1]) {
continue;
}
$otherVersion[] = [
'version' => $version,
'url' => Base::fillUrl("desktop/publish/{$version}"),
]; ];
} }
// //
return view('desktop', ['version' => $name, 'files' => $files]); return view('desktop', [
'version' => $match[1],
'files' => $files,
'is_draft' => $isDraft,
'latest_version' => $latestVersion,
'other_version' => array_reverse($otherVersion),
]);
} }
// 下载
if ($name && file_exists($latestFile)) { // 下载Latest 版本内的文件,访问路径 desktop/publish/{fileName}
$publishVersion = file_get_contents($latestFile); if ($name) {
if (preg_match("/^\d+\.\d+\.\d+$/", $publishVersion)) { $filePath = public_path("uploads/desktop/{$latestVersion}/{$name}");
$filePath = public_path("uploads/desktop/{$publishVersion}/{$name}"); if (file_exists($filePath)) {
if (file_exists($filePath)) { return Response::download($filePath);
return Response::download($filePath);
}
} }
} }
// 404
abort(404); abort(404);
} }

View File

@ -24,13 +24,15 @@
.mirror { .mirror {
overflow: auto; overflow: auto;
width: 1180px; max-width: 1180px;
margin: 0 auto 20px margin: 0 auto 20px;
padding: 0 20px;
} }
.mirror-nav { .mirror-nav {
width: 1180px; max-width: 1180px;
margin: 20px auto 10px; margin: 20px auto 10px;
padding: 0 20px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
@ -88,33 +90,55 @@
} }
.download-other-btn { .download-other-btn {
flex-shrink: 0;
padding: 2px 12px; padding: 2px 12px;
color: #088acb; color: #088acb;
border-radius: 8px; border-radius: 8px;
margin-top: 2px; margin-top: 2px;
margin-left: 12px;
border: 1px solid #088acb; border: 1px solid #088acb;
font-size: 14px; font-size: 14px;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.fileDate, .fileName, .fileSize { .fileDate, .fileName, .fileSize {
padding-left: 8px padding-left: 8px;
line-height: 44px;
} }
.date, .fileDate { .date, .link, .size {
line-height: 26px
}
.fileDate,
.date {
width: 25%; width: 25%;
line-height: 26px
} }
.fileName, .link { .fileName,
.link {
width: 55%; width: 55%;
line-height: 26px
} }
.fileSize, .size { .fileSize,
.size {
width: 20%; width: 20%;
line-height: 26px }
.other-version {
display: flex;
flex-wrap: wrap;
justify-content: center;
font-size: 11pt;
padding: 0 24px;
}
.other-version a {
padding: 0 12px;
color: #088acb
} }
@media (max-width: 768px) { @media (max-width: 768px) {
@ -168,10 +192,6 @@
a:hover { a:hover {
color: #ff791a color: #ff791a
} }
.mirror-nav {
padding-left: 15px
}
} }
</style> </style>
</head> </head>
@ -180,7 +200,7 @@
@extends('ie') @extends('ie')
<h1 class="mirror-nav"> <h1 class="mirror-nav">
<p>Download of v{{ $version }}</p> <span>Download of v{{ $version }}{{ $version === $latest_version ? ' (Latest)' : '' }}{{ $is_draft ? ' (Draft)' : '' }}</span>
<a class="download-other-btn" href="https://github.com/kuaifan/dootask/releases" target="_blank">More Versions</a> <a class="download-other-btn" href="https://github.com/kuaifan/dootask/releases" target="_blank">More Versions</a>
</h1> </h1>
<div class="mirror"> <div class="mirror">
@ -215,6 +235,13 @@
</tbody> </tbody>
</table> </table>
</div> </div>
@if ($other_version)
<div class="other-version">
@foreach($other_version as $item)
<a href="{{ $item['url'] }}">v{{ $item['version'] }}{{ $item['version'] === $latest_version ? ' (Latest)' : '' }}</a>
@endforeach
</div>
@endif
</body> </body>
<script> <script>
function getUrlParam(name, url) { function getUrlParam(name, url) {