diff --git a/internal/tasks/task_check_updates.go b/internal/tasks/task_check_updates.go index 078e4efd..62f86d8b 100644 --- a/internal/tasks/task_check_updates.go +++ b/internal/tasks/task_check_updates.go @@ -119,7 +119,7 @@ func (this *CheckUpdatesTask) Loop() error { var vMap = maps.NewMap(version) if vMap.GetString("code") == "admin" { var latestVersion = vMap.GetString("version") - if stringutil.VersionCompare(teaconst.Version, latestVersion) < 0 { + if stringutil.VersionCompare(teaconst.Version, latestVersion) < 0 && (len(config.IgnoredVersion) == 0 || stringutil.VersionCompare(latestVersion, config.IgnoredVersion) > 0) { teaconst.NewVersionCode = latestVersion teaconst.NewVersionDownloadURL = dlHost + vMap.GetString("url") return nil diff --git a/internal/web/actions/default/settings/updates/ignoreVersion.go b/internal/web/actions/default/settings/updates/ignoreVersion.go new file mode 100644 index 00000000..7e8959a5 --- /dev/null +++ b/internal/web/actions/default/settings/updates/ignoreVersion.go @@ -0,0 +1,61 @@ +// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . + +package updates + +import ( + "encoding/json" + teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs" +) + +type IgnoreVersionAction struct { + actionutils.ParentAction +} + +func (this *IgnoreVersionAction) RunPost(params struct { + Version string +}) { + defer this.CreateLogInfo("忽略升级版本 %s", params.Version) + + if len(params.Version) == 0 { + this.Fail("请输入要忽略的版本号") + return + } + + valueResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{Code: systemconfigs.SettingCodeCheckUpdates}) + if err != nil { + this.ErrorPage(err) + return + } + var valueJSON = valueResp.ValueJSON + var config = systemconfigs.NewCheckUpdatesConfig() + if len(valueJSON) > 0 { + err = json.Unmarshal(valueJSON, config) + if err != nil { + this.ErrorPage(err) + return + } + } + config.IgnoredVersion = params.Version + configJSON, err := json.Marshal(config) + if err != nil { + this.ErrorPage(err) + return + } + + _, err = this.RPC().SysSettingRPC().UpdateSysSetting(this.AdminContext(), &pb.UpdateSysSettingRequest{ + Code: systemconfigs.SettingCodeCheckUpdates, + ValueJSON: configJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + + // 清除状态 + teaconst.NewVersionCode = "" + + this.Success() +} diff --git a/internal/web/actions/default/settings/updates/index.go b/internal/web/actions/default/settings/updates/index.go index 8ec6dcbd..3bf19af0 100644 --- a/internal/web/actions/default/settings/updates/index.go +++ b/internal/web/actions/default/settings/updates/index.go @@ -4,12 +4,12 @@ package updates import ( "encoding/json" + "fmt" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs" "github.com/iwind/TeaGo/maps" - "github.com/iwind/TeaGo/types" stringutil "github.com/iwind/TeaGo/utils/string" "io" "net/http" @@ -25,8 +25,18 @@ func (this *IndexAction) Init() { this.Nav("", "updates", "") } -func (this *IndexAction) RunGet(params struct{}) { +func (this *IndexAction) RunGet(params struct { + DoCheck bool +}) { this.Data["version"] = teaconst.Version + this.Data["doCheck"] = params.DoCheck + + // 是否正在升级 + this.Data["isUpgrading"] = isUpgrading + this.Data["upgradeProgress"] = fmt.Sprintf("%.2f", upgradeProgress * 100) + if isUpgrading { + this.Data["doCheck"] = false + } valueResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{Code: systemconfigs.SettingCodeCheckUpdates}) if err != nil { @@ -34,7 +44,7 @@ func (this *IndexAction) RunGet(params struct{}) { return } var valueJSON = valueResp.ValueJSON - var config = &systemconfigs.CheckUpdatesConfig{AutoCheck: false} + var config = systemconfigs.NewCheckUpdatesConfig() if len(valueJSON) > 0 { err = json.Unmarshal(valueJSON, config) if err != nil { @@ -49,6 +59,21 @@ func (this *IndexAction) RunGet(params struct{}) { func (this *IndexAction) RunPost(params struct { }) { + valueResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{Code: systemconfigs.SettingCodeCheckUpdates}) + if err != nil { + this.ErrorPage(err) + return + } + var valueJSON = valueResp.ValueJSON + var config = systemconfigs.NewCheckUpdatesConfig() + if len(valueJSON) > 0 { + err = json.Unmarshal(valueJSON, config) + if err != nil { + this.ErrorPage(err) + return + } + } + type Response struct { Code int `json:"code"` Message string `json:"message"` @@ -66,6 +91,7 @@ func (this *IndexAction) RunPost(params struct { "message": "读取更新信息失败:" + err.Error(), } this.Success() + return } defer func() { @@ -78,6 +104,7 @@ func (this *IndexAction) RunPost(params struct { "message": "读取更新信息失败:" + err.Error(), } this.Success() + return } var apiResponse = &Response{} @@ -88,6 +115,7 @@ func (this *IndexAction) RunPost(params struct { "message": "解析更新信息失败:" + err.Error(), } this.Success() + return } if apiResponse.Code != 200 { @@ -96,6 +124,7 @@ func (this *IndexAction) RunPost(params struct { "message": "解析更新信息失败:" + apiResponse.Message, } this.Success() + return } var m = maps.NewMap(apiResponse.Data) @@ -107,19 +136,30 @@ func (this *IndexAction) RunPost(params struct { if vMap.GetString("code") == "admin" { var latestVersion = vMap.GetString("version") if stringutil.VersionCompare(teaconst.Version, latestVersion) < 0 { + // 是否已忽略 + if len(config.IgnoredVersion) > 0 && stringutil.VersionCompare(config.IgnoredVersion, latestVersion) >= 0 { + continue + } + this.Data["result"] = maps.Map{ - "isOk": true, - "message": "有最新的版本v" + types.String(latestVersion) + "可以更新", - "hasNew": true, - "dlURL": dlHost + vMap.GetString("url"), + "isOk": true, + "version": latestVersion, + "message": "有最新的版本 v" + latestVersion + " 可以更新", + "hasNew": true, + "dlURL": dlHost + vMap.GetString("url"), + "day": vMap.GetString("day"), + "description": vMap.GetString("description"), + "docURL": vMap.GetString("docURL"), } this.Success() + return } else { this.Data["result"] = maps.Map{ "isOk": true, "message": "你已安装最新版本,无需更新", } this.Success() + return } } } @@ -127,7 +167,7 @@ func (this *IndexAction) RunPost(params struct { this.Data["result"] = maps.Map{ "isOk": false, - "message": "找不到更新信息", + "message": "没有发现更新的版本", } this.Success() diff --git a/internal/web/actions/default/settings/updates/init.go b/internal/web/actions/default/settings/updates/init.go index f9df6999..e67b3c2a 100644 --- a/internal/web/actions/default/settings/updates/init.go +++ b/internal/web/actions/default/settings/updates/init.go @@ -15,6 +15,9 @@ func init() { Prefix("/settings/updates"). GetPost("", new(IndexAction)). Post("/update", new(UpdateAction)). + Post("/ignoreVersion", new(IgnoreVersionAction)). + Post("/resetIgnoredVersion", new(ResetIgnoredVersionAction)). + GetPost("/upgrade", new(UpgradeAction)). EndAll() }) } diff --git a/internal/web/actions/default/settings/updates/resetIgnoredVersion.go b/internal/web/actions/default/settings/updates/resetIgnoredVersion.go new file mode 100644 index 00000000..106a5bb0 --- /dev/null +++ b/internal/web/actions/default/settings/updates/resetIgnoredVersion.go @@ -0,0 +1,50 @@ +// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . + +package updates + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs" +) + +type ResetIgnoredVersionAction struct { + actionutils.ParentAction +} + +func (this *ResetIgnoredVersionAction) RunPost(params struct{}) { + defer this.CreateLogInfo("重置忽略升级版本") + + valueResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{Code: systemconfigs.SettingCodeCheckUpdates}) + if err != nil { + this.ErrorPage(err) + return + } + var valueJSON = valueResp.ValueJSON + var config = systemconfigs.NewCheckUpdatesConfig() + if len(valueJSON) > 0 { + err = json.Unmarshal(valueJSON, config) + if err != nil { + this.ErrorPage(err) + return + } + } + config.IgnoredVersion = "" + configJSON, err := json.Marshal(config) + if err != nil { + this.ErrorPage(err) + return + } + + _, err = this.RPC().SysSettingRPC().UpdateSysSetting(this.AdminContext(), &pb.UpdateSysSettingRequest{ + Code: systemconfigs.SettingCodeCheckUpdates, + ValueJSON: configJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Success() +} diff --git a/internal/web/actions/default/settings/updates/update.go b/internal/web/actions/default/settings/updates/update.go index ca929a7a..e3863f3e 100644 --- a/internal/web/actions/default/settings/updates/update.go +++ b/internal/web/actions/default/settings/updates/update.go @@ -17,13 +17,16 @@ type UpdateAction struct { func (this *UpdateAction) RunPost(params struct { AutoCheck bool }) { + defer this.CreateLogInfo("修改检查更新设置") + + // 读取当前设置 valueResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{Code: systemconfigs.SettingCodeCheckUpdates}) if err != nil { this.ErrorPage(err) return } var valueJSON = valueResp.ValueJSON - var config = &systemconfigs.CheckUpdatesConfig{AutoCheck: false} + var config = systemconfigs.NewCheckUpdatesConfig() if len(valueJSON) > 0 { err = json.Unmarshal(valueJSON, config) if err != nil { @@ -40,6 +43,7 @@ func (this *UpdateAction) RunPost(params struct { return } + // 修改设置 _, err = this.RPC().SysSettingRPC().UpdateSysSetting(this.AdminContext(), &pb.UpdateSysSettingRequest{ Code: systemconfigs.SettingCodeCheckUpdates, ValueJSON: configJSON, diff --git a/internal/web/actions/default/settings/updates/upgrade.go b/internal/web/actions/default/settings/updates/upgrade.go new file mode 100644 index 00000000..6b0b50f1 --- /dev/null +++ b/internal/web/actions/default/settings/updates/upgrade.go @@ -0,0 +1,73 @@ +// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . + +package updates + +import ( + "fmt" + "github.com/TeaOSLab/EdgeAdmin/internal/utils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "os" + "os/exec" + "time" +) + +var upgradeProgress float32 +var isUpgrading = false + +type UpgradeAction struct { + actionutils.ParentAction +} + +func (this *UpgradeAction) RunGet(params struct { +}) { + this.Data["isUpgrading"] = isUpgrading + this.Data["upgradeProgress"] = fmt.Sprintf("%.2f", upgradeProgress*100) + this.Success() +} + +func (this *UpgradeAction) RunPost(params struct { + Url string +}) { + if isUpgrading { + this.Success() + return + } + + isUpgrading = true + upgradeProgress = 0 + + defer func() { + isUpgrading = false + }() + + var manager = utils.NewUpgradeManager("admin", params.Url) + var ticker = time.NewTicker(1 * time.Second) + go func() { + for range ticker.C { + if manager.IsDownloading() { + var progress = manager.Progress() + if progress >= 0 { + upgradeProgress = progress + } + } else { + return + } + } + }() + err := manager.Start() + if err != nil { + this.Fail("下载失败:" + err.Error()) + return + } + + // restart + exe, _ := os.Executable() + if len(exe) > 0 { + go func() { + var cmd = exec.Command(exe, "restart") + _ = cmd.Run() + }() + } + + this.Success() +} diff --git a/web/views/@default/dashboard/index.html b/web/views/@default/dashboard/index.html index 936363aa..90d51de6 100644 --- a/web/views/@default/dashboard/index.html +++ b/web/views/@default/dashboard/index.html @@ -18,7 +18,7 @@
diff --git a/web/views/@default/settings/updates/index.css b/web/views/@default/settings/updates/index.css new file mode 100644 index 00000000..9a25a94b --- /dev/null +++ b/web/views/@default/settings/updates/index.css @@ -0,0 +1,5 @@ +.version-box { + line-height: 1.8; + color: #21ba45; +} +/*# sourceMappingURL=index.css.map */ \ No newline at end of file diff --git a/web/views/@default/settings/updates/index.css.map b/web/views/@default/settings/updates/index.css.map new file mode 100644 index 00000000..8d9fba9c --- /dev/null +++ b/web/views/@default/settings/updates/index.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACC,gBAAA;EACA,cAAA","file":"index.css"} \ No newline at end of file diff --git a/web/views/@default/settings/updates/index.html b/web/views/@default/settings/updates/index.html index f2e42918..cde76d6c 100644 --- a/web/views/@default/settings/updates/index.html +++ b/web/views/@default/settings/updates/index.html @@ -1,32 +1,68 @@ {$layout} - \ No newline at end of file +