diff --git a/backend/app/api/v1/upgrade.go b/backend/app/api/v1/upgrade.go index 610526ffd..997342542 100644 --- a/backend/app/api/v1/upgrade.go +++ b/backend/app/api/v1/upgrade.go @@ -1,43 +1,19 @@ package v1 import ( - "context" - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/gin-gonic/gin" - "github.com/google/go-github/github" ) // @Tags System Setting // @Summary Load upgrade info -// @Description 加载系统更新信息 +// @Description 系统更新信息 // @Success 200 {object} dto.UpgradeInfo // @Security ApiKeyAuth // @Router /settings/upgrade [get] func (b *BaseApi) GetUpgradeInfo(c *gin.Context) { - client := github.NewClient(nil) - stats, _, err := client.Repositories.GetLatestRelease(context.Background(), "KubeOperator", "KubeOperator") - if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) - return - } - info := dto.UpgradeInfo{ - NewVersion: string(*stats.Name), - ReleaseNote: string(*stats.Body), - CreatedAt: github.Timestamp(*stats.CreatedAt).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) @@ -61,7 +37,7 @@ func (b *BaseApi) Upgrade(c *gin.Context) { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - if err := upgradeService.Upgrade(req.Version); err != nil { + if err := upgradeService.Upgrade(req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } diff --git a/backend/app/dto/setting.go b/backend/app/dto/setting.go index b87bc603e..d64d42913 100644 --- a/backend/app/dto/setting.go +++ b/backend/app/dto/setting.go @@ -75,10 +75,12 @@ type SnapshotInfo struct { } type UpgradeInfo struct { + ID int64 `json:"id"` NewVersion string `json:"newVersion"` ReleaseNote string `json:"releaseNote"` CreatedAt string `json:"createdAt"` } type Upgrade struct { + Source string `json:"source" validate:"required,oneof=github gitee"` Version string `json:"version"` } diff --git a/backend/app/service/setting.go b/backend/app/service/setting.go index ddc712962..40a179ada 100644 --- a/backend/app/service/setting.go +++ b/backend/app/service/setting.go @@ -65,11 +65,10 @@ func (u *SettingService) UpdatePort(port uint) error { if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil { return err } - _ = settingRepo.Update("SystemStatus", "Restarting") go func() { _, err := cmd.Exec("systemctl restart 1panel.service") if err != nil { - global.LOG.Errorf("restart system port failed, err: %v") + global.LOG.Errorf("restart system port failed, err: %v", err) } }() return nil diff --git a/backend/app/service/upgrade.go b/backend/app/service/upgrade.go index 8c6b1f144..97904de82 100644 --- a/backend/app/service/upgrade.go +++ b/backend/app/service/upgrade.go @@ -1,29 +1,27 @@ package service import ( - "encoding/json" + "context" "fmt" - "io/ioutil" - "net/http" "os" + "runtime" + "strconv" + "strings" "time" + "gitee.com/openeuler/go-gitee/gitee" "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" + "github.com/google/go-github/github" ) -type latestVersion struct { - Version string `json:"version"` - UpdateTime string `json:"update_time"` -} - type UpgradeService struct{} type IUpgradeService interface { - Upgrade(version string) error + Upgrade(req dto.Upgrade) error SearchUpgrade() (*dto.UpgradeInfo, error) } @@ -32,64 +30,67 @@ func NewIUpgradeService() IUpgradeService { } func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) { - res, err := http.Get(global.CONF.System.AppOss + "/releases/latest.json") + currentVerion, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion")) if err != nil { return nil, err } - resByte, err := ioutil.ReadAll(res.Body) + infoFromGithub, err := u.loadLatestFromGithub() 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 { + global.LOG.Error(err) + } else { + isNew, err := compareVersion(currentVerion.Value, infoFromGithub.NewVersion) + if !isNew || 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 infoFromGithub, nil } - return nil, nil + + infoFromGitee, err := u.loadLatestFromGitee() + if err != nil { + global.LOG.Error(err) + return nil, err + } + isNew, err := compareVersion(currentVerion.Value, infoFromGitee.NewVersion) + if !isNew && err != nil { + return nil, err + } + return infoFromGitee, nil } -func (u *UpgradeService) Upgrade(version string) error { +func (u *UpgradeService) Upgrade(req dto.Upgrade) 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) + rootDir := fmt.Sprintf("%s/upgrade_%s/downloads", constant.TmpDir, timeStr) + originalDir := fmt.Sprintf("%s/upgrade_%s/original", constant.TmpDir, timeStr) + if err := os.MkdirAll(rootDir, os.ModePerm); err != nil { + return err + } + if err := os.MkdirAll(originalDir, os.ModePerm); err != nil { + return err + } + downloadPath := fmt.Sprintf("https://gitee.com/%s/%s/releases/download/%s/", "wanghe-fit2cloud", "1Panel", req.Version) + if req.Source == "github" { + downloadPath = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/", "wanghe-fit2cloud", "1Panel", req.Version) + } + panelName := fmt.Sprintf("1panel-%s-%s", "linux", runtime.GOARCH) + fileName := fmt.Sprintf("1panel-online-installer-%s.tar.gz", req.Version) _ = settingRepo.Update("SystemStatus", "Upgrading") go func() { - if err := os.MkdirAll(originalDir, os.ModePerm); err != nil { - global.LOG.Error(err.Error()) + if err := fileOp.DownloadFile(downloadPath+panelName, rootDir+"/1panel"); err != nil { + global.LOG.Errorf("download panel file failed, err: %v", err) return } - if err := fileOp.DownloadFile(downloadPath, filePath); err != nil { - global.LOG.Errorf("download file failed, err: %v", err) + if err := fileOp.DownloadFile(downloadPath+fileName, rootDir+"/service.tar.gz"); err != nil { + global.LOG.Errorf("download service file failed, err: %v", err) return } - global.LOG.Info("download file from oss successful!") + global.LOG.Info("download all file successful!") defer func() { - _ = os.Remove(filePath) + _ = os.Remove(rootDir) }() - if err := fileOp.Decompress(filePath, rootDir, files.TarGz); err != nil { + if err := fileOp.Decompress(rootDir+"/service.tar.gz", rootDir, files.TarGz); err != nil { global.LOG.Errorf("decompress file failed, err: %v", err) return } @@ -105,21 +106,31 @@ func (u *UpgradeService) Upgrade(version string) error { global.LOG.Errorf("upgrade 1panel failed, err: %v", err) return } - if err := cpBinary(rootDir+"/1pctl", "/usr/local/bin/1pctl"); err != nil { + if err := fileOp.Chmod("/usr/local/bin/1panel", 0755); err != nil { + u.handleRollback(fileOp, originalDir, 1) + global.LOG.Errorf("chmod 1panel failed, err: %v", err) + return + } + if err := cpBinary(fmt.Sprintf("%s/1panel-online-installer-%s/1pctl", rootDir, req.Version), "/usr/local/bin/1pctl"); err != nil { u.handleRollback(fileOp, originalDir, 2) global.LOG.Errorf("upgrade 1pctl failed, err: %v", err) return } - if err := cpBinary(rootDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil { + if err := fileOp.Chmod("/usr/local/bin/1pctl", 0755); err != nil { + u.handleRollback(fileOp, originalDir, 1) + global.LOG.Errorf("chmod 1pctl failed, err: %v", err) + return + } + if err := cpBinary(fmt.Sprintf("%s/1panel-online-installer-%s/1panel/conf/1panel.service", rootDir, req.Version), "/etc/systemd/system/1panel.service"); err != nil { u.handleRollback(fileOp, originalDir, 3) global.LOG.Errorf("upgrade 1panel.service failed, err: %v", err) return } global.LOG.Info("upgrade successful!") - _ = settingRepo.Update("SystemStatus", "Upgrade") - _ = settingRepo.Update("SystemVersion", version) - _, _ = cmd.Exec("systemctl restart 1panel.service") + _ = settingRepo.Update("SystemVersion", req.Version) + _ = settingRepo.Update("SystemStatus", "Free") + _, _ = cmd.Exec("systemctl daemon-reload && systemctl restart 1panel.service") }() return nil } @@ -162,3 +173,75 @@ func (u *UpgradeService) handleRollback(fileOp files.FileOp, originalDir string, global.LOG.Errorf("rollback 1panel failed, err: %v", err) } } + +func (u *UpgradeService) loadLatestFromGithub() (*dto.UpgradeInfo, error) { + client := github.NewClient(nil) + ctx, cancle := context.WithTimeout(context.Background(), 3*time.Second) + defer cancle() + stats, res, err := client.Repositories.GetLatestRelease(ctx, "wanghe-fit2cloud", "1Panel") + if res.StatusCode != 200 || err != nil { + return nil, fmt.Errorf("load upgrade info from github failed, err: %v", err) + } + info := dto.UpgradeInfo{ + NewVersion: string(*stats.Name), + ReleaseNote: string(*stats.Body), + CreatedAt: github.Timestamp(*stats.CreatedAt).Format("2006-01-02 15:04:05"), + } + return &info, nil +} + +func (u *UpgradeService) loadLatestFromGitee() (*dto.UpgradeInfo, error) { + client := gitee.NewAPIClient(gitee.NewConfiguration()) + ctx, cancle := context.WithTimeout(context.Background(), 3*time.Second) + defer cancle() + stats, res, err := client.RepositoriesApi.GetV5ReposOwnerRepoReleasesLatest(ctx, "wanghe-fit2cloud", "1Panel", &gitee.GetV5ReposOwnerRepoReleasesLatestOpts{}) + if res.StatusCode != 200 || err != nil { + return nil, fmt.Errorf("load upgrade info from gitee failed, err: %v", err) + } + info := dto.UpgradeInfo{ + NewVersion: string(stats.Name), + ReleaseNote: string(stats.Body), + CreatedAt: stats.CreatedAt.Format("2006-01-02 15:04:05"), + } + return &info, nil +} + +func compareVersion(version, newVersion string) (bool, error) { + if version == newVersion { + return false, nil + } + if len(version) == 0 || len(newVersion) == 0 { + return false, fmt.Errorf("incorrect version or new version entered %v -- %v", version, newVersion) + } + versions := strings.Split(strings.ReplaceAll(version, "v", ""), ".") + if len(versions) != 3 { + return false, fmt.Errorf("incorrect version input %v", version) + } + newVersions := strings.Split(strings.ReplaceAll(newVersion, "v", ""), ".") + if len(newVersions) != 3 { + return false, fmt.Errorf("incorrect newVersions input %v", version) + } + version1, _ := strconv.Atoi(versions[0]) + newVersion1, _ := strconv.Atoi(newVersions[0]) + if newVersion1 > version1 { + return true, nil + } else if newVersion1 == version1 { + version2, _ := strconv.Atoi(versions[1]) + newVersion2, _ := strconv.Atoi(newVersions[1]) + if newVersion2 > version2 { + return true, nil + } else if newVersion2 == version2 { + version3, _ := strconv.Atoi(versions[2]) + newVersion3, _ := strconv.Atoi(newVersions[2]) + if newVersion3 > version3 { + return true, nil + } else { + return false, nil + } + } else { + return false, nil + } + } else { + return false, nil + } +} diff --git a/backend/init/viper/viper.go b/backend/init/viper/viper.go index eb8069174..9e819c702 100644 --- a/backend/init/viper/viper.go +++ b/backend/init/viper/viper.go @@ -14,7 +14,7 @@ import ( ) func Init() { - stdout, err := cmd.Exec("grep '^BASE_DIR=' /Users/slooop/Downloads/1pctl | cut -d'=' -f2") + stdout, err := cmd.Exec("grep '^BASE_DIR=' /usr/bin/1pctl | cut -d'=' -f2") if err != nil { panic(err) } diff --git a/backend/router/ro_setting.go b/backend/router/ro_setting.go index 36047dbcf..e37cc5b68 100644 --- a/backend/router/ro_setting.go +++ b/backend/router/ro_setting.go @@ -32,7 +32,6 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) { 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) } } diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 5165cf256..29b4478a3 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -10,7 +10,6 @@ declare module 'vue' { AppLayout: typeof import('./src/components/app-layout/index.vue')['default'] AppStatus: typeof import('./src/components/app-status/index.vue')['default'] BackButton: typeof import('./src/components/back-button/index.vue')['default'] - Bread: typeof import('./src/components/bread-crumbs/bread.vue')['default'] BreadCrumbs: typeof import('./src/components/bread-crumbs/index.vue')['default'] BreadCrumbsItem: typeof import('./src/components/bread-crumbs/bread-crumbs-item.vue')['default'] CardWithHeader: typeof import('./src/components/card-with-header/index.vue')['default'] @@ -44,7 +43,6 @@ declare module 'vue' { ElFooter: typeof import('element-plus/es')['ElFooter'] ElForm: typeof import('element-plus/es')['ElForm'] ElFormItem: typeof import('element-plus/es')['ElFormItem'] - ElHeader: typeof import('element-plus/es')['ElHeader'] ElIcon: typeof import('element-plus/es')['ElIcon'] ElImage: typeof import('element-plus/es')['ElImage'] ElInput: typeof import('element-plus/es')['ElInput'] @@ -79,7 +77,6 @@ declare module 'vue' { InfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] Loading: typeof import('element-plus/es')['ElLoadingDirective'] Logo: typeof import('./src/components/app-layout/menu/components/Logo.vue')['default'] - LogoNew: typeof import('./src/components/app-layout/menu/components/logo-new.vue')['default'] Menu: typeof import('./src/components/app-layout/menu/index.vue')['default'] Popover: typeof import('element-plus/es')['ElPopoverDirective'] RouterButton: typeof import('./src/components/router-button/index.vue')['default'] diff --git a/frontend/src/api/interface/setting.ts b/frontend/src/api/interface/setting.ts index bf3c5f372..34db0c3aa 100644 --- a/frontend/src/api/interface/setting.ts +++ b/frontend/src/api/interface/setting.ts @@ -80,4 +80,8 @@ export namespace Setting { releaseNote: string; createdAt: string; } + export interface Upgrade { + source: string; + version: string; + } } diff --git a/frontend/src/api/modules/setting.ts b/frontend/src/api/modules/setting.ts index fd64d7dfb..0e5aea07a 100644 --- a/frontend/src/api/modules/setting.ts +++ b/frontend/src/api/modules/setting.ts @@ -70,9 +70,6 @@ export const searchSnapshotPage = (param: ReqPage) => { export const loadUpgradeInfo = () => { return http.get(`/settings/upgrade`); }; -export const loadUpgradeInfoByOSS = () => { - return http.get(`/settings/upgrade/byoss`); -}; -export const upgrade = (version: string) => { - return http.post(`/settings/upgrade`, { version: version }); +export const upgrade = (param: Setting.Upgrade) => { + return http.post(`/settings/upgrade`, param); }; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 77cd8d0dd..e3ca655b7 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -753,6 +753,7 @@ export default { mfaHelper3: 'Enter six digits from the app', snapshot: 'Snapshot', + thirdPartySupport: 'Only third-party accounts are supported', recoverDetail: 'Recover detail', createSnapshot: 'Create snapshot', recover: 'Recover', @@ -776,6 +777,7 @@ export default { upgradeCheck: 'Check for updates', upgradeNotes: 'Release note', upgradeNow: 'Upgrade now', + source: 'Download source', monitor: 'Monitor', enableMonitor: 'Enable', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 39d710c18..4e313577d 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -747,6 +747,7 @@ export default { path: '路径', snapshot: '快照', + thirdPartySupport: '仅支持第三方账号', recoverDetail: '恢复详情', createSnapshot: '创建快照', recover: '恢复', @@ -773,6 +774,7 @@ export default { upgradeCheck: '检查更新', upgradeNotes: '更新内容', upgradeNow: '立即更新', + source: '下载源', safe: '安全', safeEntrance: '安全入口', diff --git a/frontend/src/views/host/monitor/index.vue b/frontend/src/views/host/monitor/index.vue index ae4bb96e9..9a6fdefec 100644 --- a/frontend/src/views/host/monitor/index.vue +++ b/frontend/src/views/host/monitor/index.vue @@ -226,7 +226,24 @@ const search = async (param: string) => { let cpuData = item.value.map(function (item: any) { return item.cpu.toFixed(2); }); - let yDatasOfCpu = { name: 'CPU', type: 'line', data: cpuData, showSymbol: false }; + let yDatasOfCpu = { + name: 'CPU', + type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(0, 94, 235, .5)', + }, + { + offset: 1, + color: 'rgba(0, 94, 235, 0)', + }, + ]), + }, + data: cpuData, + showSymbol: false, + }; initCharts('loadCPUChart', baseDate, yDatasOfCpu, 'CPU', '%'); } if (param === 'memory' || param === 'all') { @@ -236,6 +253,18 @@ const search = async (param: string) => { let yDatasOfMem = { name: i18n.global.t('monitor.memory'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(0, 94, 235, .5)', + }, + { + offset: 1, + color: 'rgba(0, 94, 235, 0)', + }, + ]), + }, data: memoryData, showSymbol: false, }; @@ -258,6 +287,18 @@ const search = async (param: string) => { let yDatasOfUp = { name: i18n.global.t('monitor.up'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(0, 94, 235, .5)', + }, + { + offset: 1, + color: 'rgba(0, 94, 235, 0)', + }, + ]), + }, data: networkUp, showSymbol: false, }; @@ -267,6 +308,18 @@ const search = async (param: string) => { let yDatasOfDown = { name: i18n.global.t('monitor.down'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(27, 143, 60, .5)', + }, + { + offset: 1, + color: 'rgba(27, 143, 60, 0)', + }, + ]), + }, data: networkOut, showSymbol: false, }; @@ -353,6 +406,18 @@ function initLoadCharts(item: Monitor.MonitorData) { { name: '1 ' + i18n.global.t('monitor.min'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(0, 94, 235, .5)', + }, + { + offset: 1, + color: 'rgba(0, 94, 235, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return item.cpuLoad1.toFixed(2); @@ -361,6 +426,18 @@ function initLoadCharts(item: Monitor.MonitorData) { { name: '5 ' + i18n.global.t('monitor.min'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(27, 143, 60, .5)', + }, + { + offset: 1, + color: 'rgba(27, 143, 60, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return item.cpuLoad5.toFixed(2); @@ -369,6 +446,18 @@ function initLoadCharts(item: Monitor.MonitorData) { { name: '15 ' + i18n.global.t('monitor.min'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(249, 199, 79, .5)', + }, + { + offset: 1, + color: 'rgba(249, 199, 79, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return item.cpuLoad15.toFixed(2); @@ -377,6 +466,18 @@ function initLoadCharts(item: Monitor.MonitorData) { { name: i18n.global.t('monitor.resourceUsage'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(255, 173, 177, 0.5)', + }, + { + offset: 1, + color: 'rgba(255, 173, 177, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return item.loadUsage.toFixed(2); @@ -446,6 +547,18 @@ function initIOCharts(item: Monitor.MonitorData) { { name: i18n.global.t('monitor.read'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(0, 94, 235, .5)', + }, + { + offset: 1, + color: 'rgba(0, 94, 235, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return (item.read / 1024).toFixed(2); @@ -454,6 +567,18 @@ function initIOCharts(item: Monitor.MonitorData) { { name: i18n.global.t('monitor.write'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(27, 143, 60, .5)', + }, + { + offset: 1, + color: 'rgba(27, 143, 60, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return (item.write / 1024).toFixed(2); @@ -462,6 +587,18 @@ function initIOCharts(item: Monitor.MonitorData) { { name: i18n.global.t('monitor.readWriteCount'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(249, 199, 79, .5)', + }, + { + offset: 1, + color: 'rgba(249, 199, 79, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return item.count; @@ -471,6 +608,18 @@ function initIOCharts(item: Monitor.MonitorData) { { name: i18n.global.t('monitor.readWriteTime'), type: 'line', + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(255, 173, 177, 0.5)', + }, + { + offset: 1, + color: 'rgba(255, 173, 177, 0)', + }, + ]), + }, showSymbol: false, data: item.value.map(function (item: any) { return item.time; diff --git a/frontend/src/views/login/components/login-form.vue b/frontend/src/views/login/components/login-form.vue index 1bf1c4269..1791de905 100644 --- a/frontend/src/views/login/components/login-form.vue +++ b/frontend/src/views/login/components/login-form.vue @@ -55,6 +55,8 @@