修复: 版本更新与设置面板走查问题
- 更新链路: 检查记录远端SHA256,下载完成事件回传,安装时带哈希校验 - 续传: 服务器忽略Range返回200时截断重下防追加损坏,文件名去query - 定时器: 自动检查可重入,配置变更免重启生效,关闭即停,下载加互斥 - 前端: 支持跳过此版本并按版本去重,手动检查不受门禁限制,启动未就绪延时重试 - 更新面板: 新增自动检查开关/间隔/地址配置与进度条状态映射 - 版本历史: cache参数强制刷新与加载超时重试兜底 - 配置: 侧边栏分区全链路持久化,保存请求复用api类型防字段丢失 - 侧边栏: 区块定位改显式类名,不再依赖排序位置 - 绑定: 重新生成并与镜像目录同步
This commit is contained in:
@@ -33,11 +33,15 @@ type TabDefinition struct {
|
||||
|
||||
// TabConfig Tab 配置
|
||||
type TabConfig struct {
|
||||
AvailableTabs []TabDefinition `json:"available_tabs"`
|
||||
VisibleTabs []string `json:"visible_tabs"`
|
||||
DefaultTab string `json:"default_tab"`
|
||||
AvailableTabs []TabDefinition `json:"available_tabs"`
|
||||
VisibleTabs []string `json:"visible_tabs"`
|
||||
DefaultTab string `json:"default_tab"`
|
||||
SidebarSections []string `json:"sidebar_sections"`
|
||||
}
|
||||
|
||||
// 默认侧边栏分区
|
||||
var defaultSidebarSections = []string{"server", "favorites", "help"}
|
||||
|
||||
// 默认 Tab 配置
|
||||
var defaultTabConfig = TabConfig{
|
||||
AvailableTabs: []TabDefinition{
|
||||
@@ -45,8 +49,9 @@ var defaultTabConfig = TabConfig{
|
||||
{Key: "markdown-editor", Title: "Markdown", Enabled: true},
|
||||
{Key: "version", Title: "版本历史", Enabled: true},
|
||||
},
|
||||
VisibleTabs: []string{"file-system", "markdown-editor", "version"},
|
||||
DefaultTab: "file-system",
|
||||
VisibleTabs: []string{"file-system", "markdown-editor", "version"},
|
||||
DefaultTab: "file-system",
|
||||
SidebarSections: defaultSidebarSections,
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -79,6 +84,11 @@ func (s *ConfigService) GetTabConfig() (*TabConfig, error) {
|
||||
return &defaultTabConfig, nil
|
||||
}
|
||||
|
||||
// 侧边栏分区为空时回退默认值(兼容旧配置)
|
||||
if len(tabConfig.SidebarSections) == 0 {
|
||||
tabConfig.SidebarSections = defaultSidebarSections
|
||||
}
|
||||
|
||||
return &tabConfig, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ type RemoteVersionInfo struct {
|
||||
ForceUpdate bool `json:"force_update"`
|
||||
ReleaseDate string `json:"release_date"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
SHA256 string `json:"sha256"`
|
||||
}
|
||||
|
||||
// UpdateCheckResult 更新检查结果
|
||||
@@ -42,6 +43,7 @@ type UpdateCheckResult struct {
|
||||
ForceUpdate bool `json:"force_update"`
|
||||
ReleaseDate string `json:"release_date"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
SHA256 string `json:"sha256"`
|
||||
}
|
||||
|
||||
// InstallResult 安装结果
|
||||
@@ -99,6 +101,7 @@ func (s *UpdateService) CheckUpdate() (*UpdateCheckResult, error) {
|
||||
ForceUpdate: remoteInfo.ForceUpdate,
|
||||
ReleaseDate: remoteInfo.ReleaseDate,
|
||||
FileSize: remoteInfo.FileSize,
|
||||
SHA256: remoteInfo.SHA256,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"u-desk/internal/common"
|
||||
@@ -41,9 +42,13 @@ func DownloadUpdate(downloadURL string, progressCallback DownloadProgress) (*Dow
|
||||
return nil, fmt.Errorf("创建下载目录失败: %v", err)
|
||||
}
|
||||
|
||||
// 从 URL 提取文件名
|
||||
filename := filepath.Base(downloadURL)
|
||||
if filename == "" || filename == "." {
|
||||
// 从 URL 提取文件名(去除 query 参数与 # 片段)
|
||||
cleanURL := downloadURL
|
||||
if idx := strings.IndexAny(cleanURL, "?#"); idx != -1 {
|
||||
cleanURL = cleanURL[:idx]
|
||||
}
|
||||
filename := filepath.Base(cleanURL)
|
||||
if filename == "" || filename == "." || filename == "/" {
|
||||
filename = fmt.Sprintf("update-%d.exe", time.Now().Unix())
|
||||
}
|
||||
|
||||
@@ -127,6 +132,15 @@ func DownloadUpdate(downloadURL string, progressCallback DownloadProgress) (*Dow
|
||||
return nil, fmt.Errorf("服务器返回错误状态码: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 服务器忽略 Range 返回 200 时,本地已下载部分不能追加,必须截断从头写,否则文件损坏
|
||||
if resp.StatusCode == http.StatusOK && downloadedSize > 0 {
|
||||
if err := file.Truncate(0); err != nil {
|
||||
return nil, fmt.Errorf("重置下载文件失败: %v", err)
|
||||
}
|
||||
downloadedSize = 0
|
||||
log.Printf("[下载] 服务器不支持断点续传(返回 200),从头下载")
|
||||
}
|
||||
|
||||
// 获取文件总大小
|
||||
contentLength := resp.ContentLength
|
||||
gotTotalFromRange := false
|
||||
|
||||
Reference in New Issue
Block a user