feat: 完成升级功能

This commit is contained in:
ssongliu 2023-01-30 21:05:20 +08:00 committed by ssongliu
parent 2652e7089b
commit 905999cdf0
22 changed files with 493 additions and 77 deletions

View File

@ -45,4 +45,5 @@ var (
logService = service.ServiceGroupApp.LogService
snapshotService = service.ServiceGroupApp.SnapshotService
upgradeService = service.ServiceGroupApp.UpgradeService
)

View File

@ -25,10 +25,45 @@ func (b *BaseApi) GetUpgradeInfo(c *gin.Context) {
}
info := dto.UpgradeInfo{
NewVersion: string(*stats.Name),
Tag: string(*stats.TagName),
ReleaseNote: string(*stats.Body),
CreatedAt: github.Timestamp(*stats.CreatedAt).Format("2006-01-02 15:04:05"),
PublishedAt: github.Timestamp(*stats.PublishedAt).Format("2006-01-02 15:04:05"),
}
helper.SuccessWithData(c, info)
}
// @Tags System Setting
// @Summary Load upgrade info
// @Description 从 OSS 加载系统更新信息
// @Success 200 {object} dto.UpgradeInfo
// @Security ApiKeyAuth
// @Router /settings/upgrade [get]
func (b *BaseApi) GetUpgradeInfoByOSS(c *gin.Context) {
info, err := upgradeService.SearchUpgrade()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, info)
}
// @Tags System Setting
// @Summary Upgrade
// @Description 系统更新
// @Accept json
// @Param request body dto.Upgrade true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /settings/upgrade [post]
// @x-panel-log {"bodyKeys":["version"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新系统 => [version]","formatEN":"upgrade service => [version]"}
func (b *BaseApi) Upgrade(c *gin.Context) {
var req dto.Upgrade
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := upgradeService.Upgrade(req.Version); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}

View File

@ -76,8 +76,9 @@ type SnapshotInfo struct {
type UpgradeInfo struct {
NewVersion string `json:"newVersion"`
Tag string `json:"tag"`
ReleaseNote string `json:"releaseNote"`
CreatedAt string `json:"createdAt"`
PublishedAt string `json:"publishedAt"`
}
type Upgrade struct {
Version string `json:"version"`
}

View File

@ -4,8 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
"github.com/1Panel-dev/1Panel/backend/buserr"
"io/ioutil"
"math"
"net/http"
@ -16,6 +14,9 @@ import (
"strings"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/constant"
@ -490,7 +491,7 @@ func handleErr(install model.AppInstall, err error, out string) error {
}
func getAppFromOss() error {
res, err := http.Get(global.CONF.System.AppOss)
res, err := http.Get(global.CONF.System.AppOss + "/apps/apps.json")
if err != nil {
return err
}

View File

@ -38,6 +38,7 @@ type ServiceGroup struct {
LogService
SnapshotService
UpgradeService
}
var ServiceGroupApp = new(ServiceGroup)

View File

@ -95,7 +95,6 @@ func (u *SnapshotService) SnapshotCreate(req dto.SnapshotCreate) error {
_ = snapshotRepo.Create(&snap)
go func() {
defer func() {
global.LOG.Info("zhengque zoudao le zheli")
_ = os.RemoveAll(rootDir)
}()
fileOp := files.NewFileOp()
@ -157,10 +156,8 @@ func (u *SnapshotService) SnapshotCreate(req dto.SnapshotCreate) error {
return
}
_ = snapshotRepo.Update(snap.ID, map[string]interface{}{"status": constant.StatusSuccess})
_ = os.RemoveAll(rootDir)
_ = os.RemoveAll(fmt.Sprintf("%s/system/1panel_snapshot_%s.tar.gz", localDir, timeNow))
updateSnapshotStatus(snap.ID, constant.StatusSuccess, "")
global.LOG.Infof("upload snapshot to %s success", backup.Type)
}()
return nil
@ -313,17 +310,11 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
}
isReTry = false
}
fmt.Println(000)
_ = os.RemoveAll(rootDir)
fmt.Println(111)
global.LOG.Info("recover successful")
fmt.Println(222)
_, _ = cmd.Exec("systemctl daemon-reload")
fmt.Println(333)
_, _ = cmd.Exec("systemctl restart 1panel.service")
fmt.Println(444)
updateRecoverStatus(snap.ID, "", constant.StatusSuccess, "")
fmt.Println(555)
}()
return nil
}
@ -435,17 +426,11 @@ func (u *SnapshotService) SnapshotRollback(req dto.SnapshotRecover) error {
return nil
}
fmt.Println(000)
_ = os.RemoveAll(rootDir)
fmt.Println(111)
global.LOG.Info("rollback successful")
fmt.Println(222)
_, _ = cmd.Exec("systemctl daemon-reload")
fmt.Println(333)
_, _ = cmd.Exec("systemctl restart 1panel.service")
fmt.Println(444)
updateRollbackStatus(snap.ID, constant.StatusSuccess, "")
fmt.Println(555)
return nil
}

View File

@ -4,16 +4,26 @@ import (
"context"
"fmt"
"io/ioutil"
"strings"
"testing"
"time"
"github.com/1Panel-dev/1Panel/backend/init/log"
"github.com/1Panel-dev/1Panel/backend/init/viper"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/google/go-github/github"
)
func TestDi(t *testing.T) {
docker := "var/lib/docker"
fmt.Println(docker[strings.LastIndex(docker, "/"):])
fmt.Println(docker[:strings.LastIndex(docker, "/")])
viper.Init()
log.Init()
ti := time.Now().Format("20060102150405")
oss := "https://1panel.oss-cn-hangzhou.aliyuncs.com"
tmpPath := fmt.Sprintf("/opt/1Panel/data/tmp/%s_upgrade.tar.gz", ti)
fileOp := files.NewFileOp()
downloadPath := fmt.Sprintf("%s/releases/v1.0.1/v1.0.1.tar.gz", oss)
if err := fileOp.DownloadFile(downloadPath, tmpPath); err != nil {
fmt.Println(err)
}
}
func TestGit(t *testing.T) {

View File

@ -0,0 +1,176 @@
package service
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
"github.com/1Panel-dev/1Panel/backend/utils/files"
)
type latestVersion struct {
Version string `json:"version"`
UpdateTime string `json:"update_time"`
}
type UpgradeService struct{}
type IUpgradeService interface {
Upgrade(version string) error
SearchUpgrade() (*dto.UpgradeInfo, error)
}
func NewIUpgradeService() IUpgradeService {
return &UpgradeService{}
}
func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) {
res, err := http.Get(global.CONF.System.AppOss + "/releases/latest.json")
if err != nil {
return nil, err
}
resByte, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var latest latestVersion
if err := json.Unmarshal(resByte, &latest); err != nil {
return nil, err
}
setting, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion"))
if err != nil {
return nil, err
}
if latest.Version != setting.Value {
notes, err := http.Get(global.CONF.System.AppOss + fmt.Sprintf("/releases/%s/release_notes.md", latest.Version))
if err != nil {
return nil, err
}
noteBytes, err := ioutil.ReadAll(notes.Body)
if err != nil {
return nil, err
}
return &dto.UpgradeInfo{
NewVersion: latest.Version,
CreatedAt: latest.UpdateTime,
ReleaseNote: string(noteBytes),
}, nil
}
return nil, nil
}
func (u *UpgradeService) Upgrade(version string) error {
global.LOG.Info("start to upgrade now...")
fileOp := files.NewFileOp()
timeStr := time.Now().Format("20060102150405")
filePath := fmt.Sprintf("%s/%s.tar.gz", constant.TmpDir, timeStr)
rootDir := constant.TmpDir + "/" + timeStr
originalDir := fmt.Sprintf("%s/%s/original", constant.TmpDir, timeStr)
downloadPath := fmt.Sprintf("%s/releases/%s/%s.tar.gz", global.CONF.System.AppOss, version, version)
setting, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion"))
if err != nil {
return err
}
u.changeStatus(constant.StatusWaiting, nil)
go func() {
if err := os.MkdirAll(originalDir, os.ModePerm); err != nil {
u.changeStatus(setting.Value, err)
return
}
if err := fileOp.DownloadFile(downloadPath, filePath); err != nil {
u.changeStatus(setting.Value, fmt.Errorf("download file failed, err: %v", err))
return
}
global.LOG.Info("download file from oss successful!")
defer func() {
_ = os.Remove(filePath)
}()
if err := fileOp.Decompress(filePath, rootDir, files.TarGz); err != nil {
u.changeStatus(setting.Value, fmt.Errorf("decompress file failed, err: %v", err))
return
}
if err := u.handleBackup(fileOp, originalDir); err != nil {
u.changeStatus(setting.Value, fmt.Errorf("handle backup original file failed, err: %v", err))
return
}
global.LOG.Info("backup original data successful, now start to upgrade!")
if err := cpBinary(rootDir+"/1panel", "/usr/local/bin/1panel"); err != nil {
u.handleRollback(fileOp, originalDir, 1)
u.changeStatus(setting.Value, fmt.Errorf("upgrade 1panel failed, err: %v", err))
return
}
if err := cpBinary(rootDir+"/1pctl", "/usr/local/bin/1pctl"); err != nil {
u.handleRollback(fileOp, originalDir, 2)
u.changeStatus(setting.Value, fmt.Errorf("upgrade 1pctl failed, err: %v", err))
return
}
if err := cpBinary(rootDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil {
u.handleRollback(fileOp, originalDir, 3)
u.changeStatus(setting.Value, fmt.Errorf("upgrade 1panel.service failed, err: %v", err))
return
}
global.LOG.Info("upgrade successful!")
u.changeStatus(version, nil)
_, _ = cmd.Exec("systemctl restart 1panel.service")
}()
return nil
}
func (u *UpgradeService) handleBackup(fileOp files.FileOp, originalDir string) error {
if err := fileOp.Copy("/usr/local/bin/1panel", originalDir); err != nil {
return err
}
if err := fileOp.Copy("/usr/local/bin/1pctl", originalDir); err != nil {
return err
}
if err := fileOp.Copy("/etc/systemd/system/1panel.service", originalDir); err != nil {
return err
}
dbPath := global.CONF.System.DbPath + "/" + global.CONF.System.DbFile
if err := fileOp.Copy(dbPath, originalDir); err != nil {
return err
}
return nil
}
func (u *UpgradeService) handleRollback(fileOp files.FileOp, originalDir string, errStep int) {
dbPath := global.CONF.System.DbPath + "/1Panel.db"
if err := cpBinary(originalDir+"/1Panel.db", dbPath); err != nil {
global.LOG.Errorf("rollback 1panel failed, err: %v", err)
}
if err := cpBinary(originalDir+"/1panel", "/usr/local/bin/1panel"); err != nil {
global.LOG.Errorf("rollback 1pctl failed, err: %v", err)
}
if errStep == 1 {
return
}
if err := cpBinary(originalDir+"/1pctl", "/usr/local/bin/1pctl"); err != nil {
global.LOG.Errorf("rollback 1panel failed, err: %v", err)
}
if errStep == 2 {
return
}
if err := cpBinary(originalDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil {
global.LOG.Errorf("rollback 1panel failed, err: %v", err)
}
}
func (u *UpgradeService) changeStatus(status string, err error) {
if err != nil {
global.LOG.Error(err.Error())
}
if err := settingRepo.Update("SystemVersion", status); err != nil {
global.LOG.Errorf("update system version failed, err: %v", err)
}
}

View File

@ -1,11 +1,12 @@
package viper
import (
"bytes"
"fmt"
"path"
"github.com/1Panel-dev/1Panel/backend/configs"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/cmd/server/conf"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
@ -13,15 +14,12 @@ import (
func Init() {
baseDir := "/opt"
v := viper.NewWithOptions()
v.SetConfigName("app")
v.SetConfigType("yaml")
v.AddConfigPath(path.Dir(baseDir + "/1Panel/conf/app.yaml"))
if err := v.ReadInConfig(); err != nil {
reader := bytes.NewReader(conf.AppYaml)
if err := v.ReadConfig(reader); err != nil {
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("config file changed:", e.Name)
if err := v.Unmarshal(&global.CONF); err != nil {
panic(err)
}

View File

@ -29,7 +29,9 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
settingRouter.POST("/snapshot/del", baseApi.DeleteSnapshot)
settingRouter.POST("/snapshot/recover", baseApi.RecoverSnapshot)
settingRouter.POST("/snapshot/rollback", baseApi.RollbackSnapshot)
settingRouter.POST("/upgrade", baseApi.Upgrade)
settingRouter.GET("/upgrade", baseApi.GetUpgradeInfo)
settingRouter.GET("/upgrade/byoss", baseApi.GetUpgradeInfoByOSS)
settingRouter.GET("/basedir", baseApi.LoadBaseDir)
}
}

View File

@ -26,8 +26,8 @@ import (
)
func Start() {
app.Init()
viper.Init()
app.Init()
log.Init()
db.Init()
migration.Init()

View File

@ -4,10 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/mholt/archiver/v4"
"github.com/pkg/errors"
"github.com/spf13/afero"
"io"
"io/fs"
"net/http"
@ -17,6 +13,11 @@ import (
"strconv"
"sync"
"time"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/mholt/archiver/v4"
"github.com/pkg/errors"
"github.com/spf13/afero"
)
type FileOp struct {
@ -170,16 +171,18 @@ func (f FileOp) DownloadFileWithProcess(url, dst, key string) error {
func (f FileOp) DownloadFile(url, dst string) error {
resp, err := http.Get(url)
if err != nil {
global.LOG.Errorf("get download file [%s] error, err %s", dst, err.Error())
return fmt.Errorf("get download file [%s] error, err %s", dst, err.Error())
}
defer resp.Body.Close()
out, err := os.Create(dst)
if err != nil {
global.LOG.Errorf("create download file [%s] error, err %s", dst, err.Error())
return fmt.Errorf("create download file [%s] error, err %s", dst, err.Error())
}
defer out.Close()
if _, err = io.Copy(out, resp.Body); err != nil {
global.LOG.Errorf("save download file [%s] error, err %s", dst, err.Error())
return fmt.Errorf("save download file [%s] error, err %s", dst, err.Error())
}
out.Close()
resp.Body.Close()

View File

@ -1,7 +1,7 @@
system:
port: 9999
db_file: 1Panel.db
app_oss: "https://1panel.oss-cn-hangzhou.aliyuncs.com/apps/list.json"
app_oss: "https://1panel.oss-cn-hangzhou.aliyuncs.com"
log:
level: debug

6
cmd/server/conf/conf.go Normal file
View File

@ -0,0 +1,6 @@
package conf
import _ "embed"
//go:embed app.yaml
var AppYaml []byte

View File

@ -5976,6 +5976,28 @@ var doc = `{
}
}
},
"/settings/basedir": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取安装根目录",
"tags": [
"System Setting"
],
"summary": "Load local backup dir",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
}
},
"/settings/expired/handle": {
"post": {
"security": [
@ -6519,7 +6541,7 @@ var doc = `{
"ApiKeyAuth": []
}
],
"description": "加载系统更新信息",
"description": "从 OSS 加载系统更新信息",
"tags": [
"System Setting"
],
@ -6532,6 +6554,46 @@ var doc = `{
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "系统更新",
"consumes": [
"application/json"
],
"tags": [
"System Setting"
],
"summary": "Upgrade",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.Upgrade"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"version"
],
"formatEN": "upgrade service =\u003e [version]",
"formatZH": "更新系统 =\u003e [version]",
"paramKeys": []
}
}
},
"/websites": {
@ -10318,6 +10380,14 @@ var doc = `{
}
}
},
"dto.Upgrade": {
"type": "object",
"properties": {
"version": {
"type": "string"
}
}
},
"dto.UpgradeInfo": {
"type": "object",
"properties": {
@ -10327,14 +10397,8 @@ var doc = `{
"newVersion": {
"type": "string"
},
"publishedAt": {
"type": "string"
},
"releaseNote": {
"type": "string"
},
"tag": {
"type": "string"
}
}
},

View File

@ -5962,6 +5962,28 @@
}
}
},
"/settings/basedir": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "获取安装根目录",
"tags": [
"System Setting"
],
"summary": "Load local backup dir",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
}
},
"/settings/expired/handle": {
"post": {
"security": [
@ -6505,7 +6527,7 @@
"ApiKeyAuth": []
}
],
"description": "加载系统更新信息",
"description": "从 OSS 加载系统更新信息",
"tags": [
"System Setting"
],
@ -6518,6 +6540,46 @@
}
}
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "系统更新",
"consumes": [
"application/json"
],
"tags": [
"System Setting"
],
"summary": "Upgrade",
"parameters": [
{
"description": "request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.Upgrade"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"x-panel-log": {
"BeforeFuntions": [],
"bodyKeys": [
"version"
],
"formatEN": "upgrade service =\u003e [version]",
"formatZH": "更新系统 =\u003e [version]",
"paramKeys": []
}
}
},
"/websites": {
@ -10304,6 +10366,14 @@
}
}
},
"dto.Upgrade": {
"type": "object",
"properties": {
"version": {
"type": "string"
}
}
},
"dto.UpgradeInfo": {
"type": "object",
"properties": {
@ -10313,14 +10383,8 @@
"newVersion": {
"type": "string"
},
"publishedAt": {
"type": "string"
},
"releaseNote": {
"type": "string"
},
"tag": {
"type": "string"
}
}
},

View File

@ -1334,18 +1334,19 @@ definitions:
required:
- id
type: object
dto.Upgrade:
properties:
version:
type: string
type: object
dto.UpgradeInfo:
properties:
createdAt:
type: string
newVersion:
type: string
publishedAt:
type: string
releaseNote:
type: string
tag:
type: string
type: object
dto.UploadRecover:
properties:
@ -6367,6 +6368,19 @@ paths:
formatEN: Update nginx conf [domain]
formatZH: 更新 nginx 配置 [domain]
paramKeys: []
/settings/basedir:
get:
description: 获取安装根目录
responses:
"200":
description: OK
schema:
type: string
security:
- ApiKeyAuth: []
summary: Load local backup dir
tags:
- System Setting
/settings/expired/handle:
post:
consumes:
@ -6713,7 +6727,7 @@ paths:
paramKeys: []
/settings/upgrade:
get:
description: 加载系统更新信息
description: 从 OSS 加载系统更新信息
responses:
"200":
description: OK
@ -6724,6 +6738,32 @@ paths:
summary: Load upgrade info
tags:
- System Setting
post:
consumes:
- application/json
description: 系统更新
parameters:
- description: request
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.Upgrade'
responses:
"200":
description: ""
security:
- ApiKeyAuth: []
summary: Upgrade
tags:
- System Setting
x-panel-log:
BeforeFuntions: []
bodyKeys:
- version
formatEN: upgrade service => [version]
formatZH: 更新系统 => [version]
paramKeys: []
/websites:
post:
consumes:

View File

@ -77,9 +77,7 @@ export namespace Setting {
}
export interface UpgradeInfo {
newVersion: string;
tag: string;
releaseNote: string;
createdAt: string;
publishedAt: string;
}
}

View File

@ -67,3 +67,9 @@ export const searchSnapshotPage = (param: ReqPage) => {
export const loadUpgradeInfo = () => {
return http.get<Setting.UpgradeInfo>(`/settings/upgrade`);
};
export const loadUpgradeInfoByOSS = () => {
return http.get<Setting.UpgradeInfo>(`/settings/upgrade/byoss`);
};
export const upgrade = (version: string) => {
return http.post(`/settings/upgrade`, { version: version });
};

View File

@ -762,9 +762,11 @@ export default {
'This recovery is about to be rolled back, which will replace all the files recovered this time. In the process, docker and 1panel services may need to be restarted. Do you want to continue?',
upgrade: 'Upgrade',
upgrading: 'Please wait while the upgrade is underway...',
upgradeHelper: 'The upgrade requires a service restart. Do you want to continue?',
noUpgrade: 'This is the latest version. You do not need to update it',
newVersion: 'NewVersion',
upgradeCheck: 'Check for updates',
tag: 'Tag',
upgradeNotes: 'Release note',
upgradeNow: 'Upgrade now',

View File

@ -756,9 +756,11 @@ export default {
'即将回滚本次恢复回滚将替换所有本次恢复的文件过程中可能需要重启 docker 以及 1panel 服务是否继续',
upgrade: '升级',
upgrading: '正在升级中请稍候...',
upgradeHelper: '升级操作需要重启服务是否继续',
noUpgrade: '当前已是最新版本无需更新',
newVersion: '新版本',
upgradeCheck: '检查更新',
tag: '标签',
upgradeNotes: '更新内容',
upgradeNow: '立即更新',

View File

@ -1,5 +1,5 @@
<template>
<div>
<div v-loading="loading">
<Submenu activeName="about" />
<el-card style="margin-top: 20px">
<LayoutContent :header="$t('setting.about')">
@ -10,9 +10,10 @@
<h3>{{ $t('setting.description') }}</h3>
<h3>
{{ version }}
<el-button type="primary" link @click="onLoadUpgradeInfo">
<el-button v-if="version !== 'Waiting'" type="primary" link @click="onLoadUpgradeInfo">
{{ $t('setting.upgradeCheck') }}
</el-button>
<el-tag v-else round style="margin-left: 10px">{{ $t('setting.upgrading') }}</el-tag>
</h3>
<div style="margin-top: 10px">
<el-link @click="toGithub">
@ -40,20 +41,14 @@
<el-form-item :label="$t('setting.newVersion')">
<el-tag>{{ upgradeInfo.newVersion }}</el-tag>
</el-form-item>
<el-form-item :label="$t('setting.tag')">
<el-tag>{{ upgradeInfo.tag }}</el-tag>
</el-form-item>
<el-form-item :label="$t('setting.upgradeNotes')">
<MdEditor style="height: 450px" v-model="upgradeInfo.releaseNote" previewOnly />
</el-form-item>
<el-form-item :label="$t('commons.table.createdAt')">
<el-tag>{{ upgradeInfo.createdAt }}</el-tag>
</el-form-item>
<el-form-item :label="$t('commons.table.publishedAt')">
<el-tag>{{ upgradeInfo.publishedAt }}</el-tag>
<el-form-item :label="$t('setting.upgradeNotes')">
<MdEditor style="height: calc(100vh - 260px)" v-model="upgradeInfo.releaseNote" previewOnly />
</el-form-item>
<el-form-item>
<el-button type="primary">{{ $t('setting.upgradeNow') }}</el-button>
<el-button type="primary" @click="onUpgrade">{{ $t('setting.upgradeNow') }}</el-button>
</el-form-item>
</el-form>
</el-drawer>
@ -62,17 +57,20 @@
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import { getSettingInfo, loadUpgradeInfo } from '@/api/modules/setting';
import { getSettingInfo, loadUpgradeInfoByOSS, upgrade } from '@/api/modules/setting';
import Submenu from '@/views/setting/index.vue';
import { onMounted, ref } from 'vue';
import MdEditor from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import { ElMessage, ElMessageBox } from 'element-plus';
import i18n from '@/lang';
const version = ref();
const upgradeInfo = ref();
const drawerShow = ref();
const refresh = ref();
const loading = ref();
const search = async () => {
const res = await getSettingInfo();
version.value = res.data.systemVersion;
@ -92,10 +90,33 @@ const toGithubStar = () => {
};
const onLoadUpgradeInfo = async () => {
const res = await loadUpgradeInfo();
const res = await loadUpgradeInfoByOSS();
if (!res.data) {
ElMessage.success(i18n.global.t('setting.noUpgrade'));
return;
}
upgradeInfo.value = res.data;
drawerShow.value = true;
};
const onUpgrade = async () => {
ElMessageBox.confirm(i18n.global.t('setting.upgradeHelper', i18n.global.t('setting.upgrade')), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(() => {
loading.value = true;
upgrade(upgradeInfo.value.newVersion)
.then(() => {
loading.value = false;
drawerShow.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
search();
})
.catch(() => {
loading.value = false;
});
});
};
onMounted(() => {
search();