package service import ( "encoding/json" "fmt" "io" "log" "net/http" "time" ) // UpdateService 更新服务 type UpdateService struct { checkURL string // 版本检查接口 URL } // NewUpdateService 创建更新服务 func NewUpdateService(checkURL string) *UpdateService { return &UpdateService{ checkURL: checkURL, } } // RemoteVersionInfo 远程版本信息 type RemoteVersionInfo struct { Version string `json:"version"` DownloadURL string `json:"download_url"` Changelog string `json:"changelog"` ForceUpdate bool `json:"force_update"` ReleaseDate string `json:"release_date"` } // CheckUpdate 检查更新 func (s *UpdateService) CheckUpdate() (*UpdateCheckResult, error) { log.Printf("[更新检查] 开始检查更新,检查地址: %s", s.checkURL) // 加载配置 config, err := LoadUpdateConfig() if err != nil { log.Printf("[更新检查] 加载配置失败: %v", err) return nil, fmt.Errorf("加载配置失败: %v", err) } // 获取当前版本(优先使用服务获取的最新版本号,而不是配置中可能过期的版本号) currentVersionStr := GetCurrentVersion() if currentVersionStr == "" { // 如果服务获取失败,回退到配置中的版本号 currentVersionStr = config.CurrentVersion log.Printf("[更新检查] 使用配置中的版本号: %s", currentVersionStr) } else { log.Printf("[更新检查] 使用服务获取的版本号: %s", currentVersionStr) // 如果配置中的版本号不一致,更新配置 if config.CurrentVersion != currentVersionStr { log.Printf("[更新检查] 配置中的版本号 (%s) 与当前版本号 (%s) 不一致,更新配置", config.CurrentVersion, currentVersionStr) config.CurrentVersion = currentVersionStr if err := SaveUpdateConfig(config); err != nil { log.Printf("[更新检查] 更新配置失败: %v", err) } } } currentVersion, err := ParseVersion(currentVersionStr) if err != nil { log.Printf("[更新检查] 解析当前版本失败: %v", err) return nil, fmt.Errorf("解析当前版本失败: %v", err) } // 请求远程版本信息 remoteInfo, err := s.fetchRemoteVersionInfo() if err != nil { log.Printf("[更新检查] 获取远程版本信息失败: %v", err) return nil, fmt.Errorf("获取远程版本信息失败: %v", err) } log.Printf("[更新检查] 远程版本信息: 版本=%s, 下载地址=%s, 强制更新=%v", remoteInfo.Version, remoteInfo.DownloadURL, remoteInfo.ForceUpdate) // 解析远程版本号 remoteVersion, err := ParseVersion(remoteInfo.Version) if err != nil { log.Printf("[更新检查] 解析远程版本号失败: %v", err) return nil, fmt.Errorf("解析远程版本号失败: %v", err) } // 比较版本 hasUpdate := remoteVersion.IsNewerThan(currentVersion) log.Printf("[更新检查] 版本比较: 当前=%s, 远程=%s, 有更新=%v", currentVersion.String(), remoteVersion.String(), hasUpdate) // 更新最后检查时间 config.UpdateLastCheckTime() result := &UpdateCheckResult{ HasUpdate: hasUpdate, CurrentVersion: currentVersionStr, LatestVersion: remoteInfo.Version, DownloadURL: remoteInfo.DownloadURL, Changelog: remoteInfo.Changelog, ForceUpdate: remoteInfo.ForceUpdate, ReleaseDate: remoteInfo.ReleaseDate, } log.Printf("[更新检查] 检查完成: 有更新=%v", hasUpdate) return result, nil } // fetchRemoteVersionInfo 获取远程版本信息 func (s *UpdateService) fetchRemoteVersionInfo() (*RemoteVersionInfo, error) { if s.checkURL == "" { log.Printf("[远程版本] 版本检查 URL 未配置") return nil, fmt.Errorf("版本检查 URL 未配置,请先设置检查地址") } log.Printf("[远程版本] 请求远程版本信息: %s", s.checkURL) // 创建 HTTP 客户端,设置超时 client := &http.Client{ Timeout: 10 * time.Second, } // 发送请求 resp, err := client.Get(s.checkURL) if err != nil { log.Printf("[远程版本] 网络请求失败: %v", err) return nil, fmt.Errorf("网络请求失败: %v", err) } defer resp.Body.Close() log.Printf("[远程版本] HTTP 响应状态码: %d", resp.StatusCode) if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("服务器返回错误状态码: %d", resp.StatusCode) } // 读取响应 body, err := io.ReadAll(resp.Body) if err != nil { log.Printf("[远程版本] 读取响应失败: %v", err) return nil, fmt.Errorf("读取响应失败: %v", err) } log.Printf("[远程版本] 响应内容长度: %d 字节", len(body)) // 解析 JSON var remoteInfo RemoteVersionInfo if err := json.Unmarshal(body, &remoteInfo); err != nil { log.Printf("[远程版本] 解析 JSON 失败: %v, 响应内容: %s", err, string(body)) return nil, fmt.Errorf("解析响应失败: %v", err) } if remoteInfo.Version == "" { log.Printf("[远程版本] 远程版本信息不完整,响应内容: %s", string(body)) return nil, fmt.Errorf("远程版本信息不完整") } log.Printf("[远程版本] 成功获取远程版本信息: %+v", remoteInfo) return &remoteInfo, nil } // UpdateCheckResult 更新检查结果 type UpdateCheckResult struct { HasUpdate bool `json:"has_update"` CurrentVersion string `json:"current_version"` LatestVersion string `json:"latest_version"` DownloadURL string `json:"download_url"` Changelog string `json:"changelog"` ForceUpdate bool `json:"force_update"` ReleaseDate string `json:"release_date"` }