160 lines
3.7 KiB
Go
160 lines
3.7 KiB
Go
package service
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"path/filepath"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
// ==================== 常量定义 ====================
|
||
|
||
// AppVersion 应用版本号(发布时直接修改此处)
|
||
const AppVersion = "0.1.1"
|
||
|
||
// ==================== 类型定义 ====================
|
||
|
||
// Version 版本号结构
|
||
type Version struct {
|
||
Major int
|
||
Minor int
|
||
Patch int
|
||
}
|
||
|
||
// WailsConfig Wails 配置文件结构
|
||
type WailsConfig struct {
|
||
Version string `json:"version"`
|
||
}
|
||
|
||
// ==================== 版本号解析和比较 ====================
|
||
|
||
// ParseVersion 解析版本号字符串(支持 v1.0.0 或 1.0.0 格式)
|
||
func ParseVersion(versionStr string) (*Version, error) {
|
||
versionStr = strings.TrimPrefix(versionStr, "v")
|
||
parts := strings.Split(versionStr, ".")
|
||
if len(parts) != 3 {
|
||
return nil, fmt.Errorf("版本号格式错误,应为 x.y.z 格式")
|
||
}
|
||
|
||
major, err := strconv.Atoi(parts[0])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("主版本号解析失败: %v", err)
|
||
}
|
||
|
||
minor, err := strconv.Atoi(parts[1])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("次版本号解析失败: %v", err)
|
||
}
|
||
|
||
patch, err := strconv.Atoi(parts[2])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("修订号解析失败: %v", err)
|
||
}
|
||
|
||
return &Version{Major: major, Minor: minor, Patch: patch}, nil
|
||
}
|
||
|
||
// String 返回版本号字符串(格式:v1.0.0)
|
||
func (v *Version) String() string {
|
||
return fmt.Sprintf("v%d.%d.%d", v.Major, v.Minor, v.Patch)
|
||
}
|
||
|
||
// Compare 比较版本号
|
||
// 返回值:-1 表示当前版本小于目标版本,0 表示相等,1 表示大于
|
||
func (v *Version) Compare(other *Version) int {
|
||
if v.Major != other.Major {
|
||
if v.Major < other.Major {
|
||
return -1
|
||
}
|
||
return 1
|
||
}
|
||
if v.Minor != other.Minor {
|
||
if v.Minor < other.Minor {
|
||
return -1
|
||
}
|
||
return 1
|
||
}
|
||
if v.Patch != other.Patch {
|
||
if v.Patch < other.Patch {
|
||
return -1
|
||
}
|
||
return 1
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// IsNewerThan 判断是否比目标版本新
|
||
func (v *Version) IsNewerThan(other *Version) bool {
|
||
return v.Compare(other) > 0
|
||
}
|
||
|
||
// IsOlderThan 判断是否比目标版本旧
|
||
func (v *Version) IsOlderThan(other *Version) bool {
|
||
return v.Compare(other) < 0
|
||
}
|
||
|
||
// ==================== 版本号获取 ====================
|
||
|
||
// GetCurrentVersion 获取当前版本号
|
||
// 优先级:硬编码版本号 > wails.json(开发模式)> 默认值
|
||
func GetCurrentVersion() string {
|
||
if AppVersion != "" {
|
||
log.Printf("[版本] 使用硬编码版本号: %s", AppVersion)
|
||
return AppVersion
|
||
}
|
||
|
||
version := getVersionFromWailsJSON()
|
||
if version != "" {
|
||
log.Printf("[版本] 从 wails.json 获取版本号: %s", version)
|
||
return version
|
||
}
|
||
|
||
log.Printf("[版本] 使用默认版本号: 0.0.1")
|
||
return "0.0.1"
|
||
}
|
||
|
||
// ==================== 配置文件读取 ====================
|
||
|
||
// getVersionFromWailsJSON 从 wails.json 读取版本号(仅开发模式使用)
|
||
func getVersionFromWailsJSON() string {
|
||
wd, err := os.Getwd()
|
||
if err != nil {
|
||
return ""
|
||
}
|
||
|
||
// 尝试当前目录
|
||
if version := readVersionFromFile(filepath.Join(wd, "wails.json")); version != "" {
|
||
return version
|
||
}
|
||
|
||
// 尝试父目录
|
||
if version := readVersionFromFile(filepath.Join(filepath.Dir(wd), "wails.json")); version != "" {
|
||
return version
|
||
}
|
||
|
||
return ""
|
||
}
|
||
|
||
// readVersionFromFile 从指定文件读取版本号
|
||
func readVersionFromFile(filePath string) string {
|
||
data, err := os.ReadFile(filePath)
|
||
if err != nil {
|
||
log.Printf("[版本] 读取文件失败: %s, 错误: %v", filePath, err)
|
||
return ""
|
||
}
|
||
|
||
var config WailsConfig
|
||
if err := json.Unmarshal(data, &config); err != nil {
|
||
log.Printf("[版本] 解析 JSON 失败: %s, 错误: %v", filePath, err)
|
||
return ""
|
||
}
|
||
|
||
if config.Version != "" {
|
||
log.Printf("[版本] 从文件读取版本号: %s -> %s", filePath, config.Version)
|
||
}
|
||
return config.Version
|
||
}
|