修复离线镜像下载
This commit is contained in:
@@ -894,15 +894,21 @@
|
||||
function createResultCard(result) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'result-card';
|
||||
card.onclick = () => viewImageTags(result.repo_name || result.name);
|
||||
card.onclick = () => viewImageTags(result.repo_name || result.name, result.is_official);
|
||||
|
||||
const badges = [];
|
||||
if (result.is_official) badges.push('<span class="badge badge-official">官方</span>');
|
||||
if (result.is_automated) badges.push('<span class="badge badge-automated">自动构建</span>');
|
||||
|
||||
// 只有真正的官方镜像才去掉 library/ 前缀
|
||||
const originalName = result.repo_name || result.name;
|
||||
const displayName = (result.is_official && originalName.startsWith('library/'))
|
||||
? originalName.substring(8)
|
||||
: originalName;
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="result-title">
|
||||
🐳 ${result.repo_name || result.name}
|
||||
🐳 ${displayName}
|
||||
${badges.join('')}
|
||||
</div>
|
||||
<div class="result-description">
|
||||
@@ -926,7 +932,7 @@
|
||||
}
|
||||
|
||||
// 查看镜像标签
|
||||
async function viewImageTags(imageName) {
|
||||
async function viewImageTags(imageName, isOfficial = false) {
|
||||
if (isLoading) return;
|
||||
|
||||
isLoading = true;
|
||||
@@ -952,7 +958,7 @@
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
allTags = data;
|
||||
displayImageTags(imageName, data);
|
||||
displayImageTags(imageName, data, isOfficial);
|
||||
elements.backToSearch.classList.add('show');
|
||||
} else {
|
||||
showToast('获取标签失败:' + (data.error || '未知错误'), 'error');
|
||||
@@ -967,12 +973,17 @@
|
||||
}
|
||||
|
||||
// 显示镜像标签
|
||||
function displayImageTags(imageName, tags) {
|
||||
function displayImageTags(imageName, tags, isOfficial = false) {
|
||||
const fullDomain = window.location.host;
|
||||
|
||||
// 只有真正的官方镜像才去掉 library/ 前缀
|
||||
const displayName = (isOfficial && imageName.startsWith('library/'))
|
||||
? imageName.substring(8)
|
||||
: imageName;
|
||||
|
||||
elements.tagInfo.innerHTML = `
|
||||
<div class="tag-title">
|
||||
🐳 ${imageName}
|
||||
🐳 ${displayName}
|
||||
</div>
|
||||
<div class="tag-description">
|
||||
共 ${tags.length} 个标签版本
|
||||
|
||||
@@ -110,6 +110,9 @@ func initSkopeoRoutes(router *gin.Engine) {
|
||||
|
||||
// 下载文件
|
||||
router.GET("/api/files/:filename", serveFile)
|
||||
|
||||
// 通过任务ID下载文件
|
||||
router.GET("/api/download/:taskId/file", serveFileByTaskId)
|
||||
|
||||
// 启动清理过期文件的goroutine
|
||||
go cleanupTempFiles()
|
||||
@@ -1059,6 +1062,55 @@ func sendTaskUpdate(task *DownloadTask) {
|
||||
}
|
||||
}
|
||||
|
||||
// 通过任务ID提供文件下载
|
||||
func serveFileByTaskId(c *gin.Context) {
|
||||
taskID := c.Param("taskId")
|
||||
|
||||
tasksLock.Lock()
|
||||
task, exists := tasks[taskID]
|
||||
tasksLock.Unlock()
|
||||
|
||||
if !exists {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "任务不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
// 确保任务状态为已完成
|
||||
task.StatusLock.RLock()
|
||||
isCompleted := task.Status == StatusCompleted
|
||||
task.StatusLock.RUnlock()
|
||||
|
||||
if !isCompleted {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "任务尚未完成"})
|
||||
return
|
||||
}
|
||||
|
||||
// 确保所有进度都是100%
|
||||
ensureTaskCompletion(task)
|
||||
|
||||
// 检查文件是否存在
|
||||
filePath := task.OutputFile
|
||||
if filePath == "" || !fileExists(filePath) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
// 获取文件信息
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法获取文件信息"})
|
||||
return
|
||||
}
|
||||
|
||||
// 设置文件名
|
||||
downloadName := filepath.Base(filePath)
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", downloadName))
|
||||
c.Header("Content-Length", fmt.Sprintf("%d", fileInfo.Size()))
|
||||
|
||||
// 返回文件
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// 提供文件下载
|
||||
func serveFile(c *gin.Context) {
|
||||
filename := c.Param("filename")
|
||||
|
||||
Reference in New Issue
Block a user