From 95f0e0d536193943b2f5be26816d4c9ec1ea282e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Thu, 10 Oct 2024 02:26:32 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=BA=94=E7=94=A8=E6=B8=A0?= =?UTF-8?q?=E9=81=93=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/apps/init.go | 2 +- internal/apps/{percona => mysql}/init.go | 4 +- internal/apps/{percona => mysql}/request.go | 2 +- internal/apps/{percona => mysql}/service.go | 26 +++---- internal/biz/app.go | 22 +++--- internal/biz/setting.go | 22 +++--- internal/data/app.go | 68 ++++++++++-------- internal/data/website.go | 4 +- internal/http/request/app.go | 4 +- internal/service/app.go | 43 +++++++----- internal/service/info.go | 2 +- pkg/api/app.go | 6 +- pkg/types/app.go | 22 +++--- web/src/api/panel/app/index.ts | 7 +- web/src/i18n/en.json | 9 ++- web/src/i18n/zh_CN.json | 5 +- web/src/views/app/IndexView.vue | 76 +++++++++++---------- web/src/views/app/VersionModal.vue | 74 ++++++++++++++++++++ web/src/views/app/types.ts | 18 ++++- 19 files changed, 266 insertions(+), 150 deletions(-) rename internal/apps/{percona => mysql}/init.go (94%) rename internal/apps/{percona => mysql}/request.go (90%) rename internal/apps/{percona => mysql}/service.go (86%) create mode 100644 web/src/views/app/VersionModal.vue diff --git a/internal/apps/init.go b/internal/apps/init.go index aaafa0eb..55be8fb5 100644 --- a/internal/apps/init.go +++ b/internal/apps/init.go @@ -6,8 +6,8 @@ import ( _ "github.com/TheTNB/panel/internal/apps/fail2ban" _ "github.com/TheTNB/panel/internal/apps/frp" _ "github.com/TheTNB/panel/internal/apps/gitea" + _ "github.com/TheTNB/panel/internal/apps/mysql" _ "github.com/TheTNB/panel/internal/apps/openresty" - _ "github.com/TheTNB/panel/internal/apps/percona" _ "github.com/TheTNB/panel/internal/apps/php" _ "github.com/TheTNB/panel/internal/apps/phpmyadmin" _ "github.com/TheTNB/panel/internal/apps/podman" diff --git a/internal/apps/percona/init.go b/internal/apps/mysql/init.go similarity index 94% rename from internal/apps/percona/init.go rename to internal/apps/mysql/init.go index 782b4f9b..4667326d 100644 --- a/internal/apps/percona/init.go +++ b/internal/apps/mysql/init.go @@ -1,4 +1,4 @@ -package percona +package mysql import ( "github.com/go-chi/chi/v5" @@ -9,7 +9,7 @@ import ( func init() { apploader.Register(&types.App{ - Slug: "percona", + Slug: "mysql", Route: func(r chi.Router) { service := NewService() r.Get("/load", service.Load) diff --git a/internal/apps/percona/request.go b/internal/apps/mysql/request.go similarity index 90% rename from internal/apps/percona/request.go rename to internal/apps/mysql/request.go index c2138dd4..018f2501 100644 --- a/internal/apps/percona/request.go +++ b/internal/apps/mysql/request.go @@ -1,4 +1,4 @@ -package percona +package mysql type UpdateConfig struct { Config string `form:"config" json:"config"` diff --git a/internal/apps/percona/service.go b/internal/apps/mysql/service.go similarity index 86% rename from internal/apps/percona/service.go rename to internal/apps/mysql/service.go index becb1f80..96551efe 100644 --- a/internal/apps/percona/service.go +++ b/internal/apps/mysql/service.go @@ -1,4 +1,4 @@ -package percona +package mysql import ( "fmt" @@ -33,7 +33,7 @@ func NewService() *Service { func (s *Service) GetConfig(w http.ResponseWriter, r *http.Request) { config, err := io.Read(app.Root + "/server/mysql/conf/my.cnf") if err != nil { - service.Error(w, http.StatusInternalServerError, "获取 Percona 配置失败") + service.Error(w, http.StatusInternalServerError, "获取配置失败") return } @@ -49,12 +49,12 @@ func (s *Service) UpdateConfig(w http.ResponseWriter, r *http.Request) { } if err := io.Write(app.Root+"/server/mysql/conf/my.cnf", req.Config, 0644); err != nil { - service.Error(w, http.StatusInternalServerError, "写入 Percona 配置失败") + service.Error(w, http.StatusInternalServerError, "写入配置失败") return } if err := systemctl.Reload("mysqld"); err != nil { - service.Error(w, http.StatusInternalServerError, "重载 Percona 失败") + service.Error(w, http.StatusInternalServerError, "重载失败") return } @@ -63,14 +63,14 @@ func (s *Service) UpdateConfig(w http.ResponseWriter, r *http.Request) { // Load 获取负载 func (s *Service) Load(w http.ResponseWriter, r *http.Request) { - rootPassword, err := s.settingRepo.Get(biz.SettingKeyPerconaRootPassword) + rootPassword, err := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword) if err != nil { - service.Error(w, http.StatusInternalServerError, "获取 Percona root密码失败") + service.Error(w, http.StatusInternalServerError, "获取root密码失败") return } if len(rootPassword) == 0 { - service.Error(w, http.StatusUnprocessableEntity, "Percona root密码为空") + service.Error(w, http.StatusUnprocessableEntity, "root密码为空") return } @@ -82,7 +82,7 @@ func (s *Service) Load(w http.ResponseWriter, r *http.Request) { raw, err := shell.Execf(`mysqladmin -u root -p "%s" extended-status`, rootPassword) if err != nil { - service.Error(w, http.StatusInternalServerError, "获取 Percona 负载失败") + service.Error(w, http.StatusInternalServerError, "获取负载失败") return } @@ -180,13 +180,13 @@ func (s *Service) ClearSlowLog(w http.ResponseWriter, r *http.Request) { // GetRootPassword 获取root密码 func (s *Service) GetRootPassword(w http.ResponseWriter, r *http.Request) { - rootPassword, err := s.settingRepo.Get(biz.SettingKeyPerconaRootPassword) + rootPassword, err := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword) if err != nil { - service.Error(w, http.StatusInternalServerError, "获取 Percona root密码失败") + service.Error(w, http.StatusInternalServerError, "获取root密码失败") return } if len(rootPassword) == 0 { - service.Error(w, http.StatusUnprocessableEntity, "Percona root密码为空") + service.Error(w, http.StatusUnprocessableEntity, "root密码为空") return } @@ -201,7 +201,7 @@ func (s *Service) SetRootPassword(w http.ResponseWriter, r *http.Request) { return } - oldRootPassword, _ := s.settingRepo.Get(biz.SettingKeyPerconaRootPassword) + oldRootPassword, _ := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword) mysql, err := db.NewMySQL("root", oldRootPassword, s.getSock(), "unix") if err != nil { // 尝试安全模式直接改密 @@ -215,7 +215,7 @@ func (s *Service) SetRootPassword(w http.ResponseWriter, r *http.Request) { return } } - if err = s.settingRepo.Set(biz.SettingKeyPerconaRootPassword, req.Password); err != nil { + if err = s.settingRepo.Set(biz.SettingKeyMySQLRootPassword, req.Password); err != nil { service.Error(w, http.StatusInternalServerError, fmt.Sprintf("设置保存失败: %v", err)) return } diff --git a/internal/biz/app.go b/internal/biz/app.go index 564f1e2a..b27db9fa 100644 --- a/internal/biz/app.go +++ b/internal/biz/app.go @@ -7,14 +7,14 @@ import ( ) type App struct { - ID uint `gorm:"primaryKey" json:"id"` - Slug string `gorm:"not null;unique" json:"slug"` - VersionSlug string `gorm:"not null" json:"version_slug"` - Version string `gorm:"not null" json:"version"` - Show bool `gorm:"not null" json:"show"` - ShowOrder int `gorm:"not null" json:"show_order"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID uint `gorm:"primaryKey" json:"id"` + Slug string `gorm:"not null;unique" json:"slug"` + Channel string `gorm:"not null" json:"channel"` + Version string `gorm:"not null" json:"version"` + Show bool `gorm:"not null" json:"show"` + ShowOrder int `gorm:"not null" json:"show_order"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type AppRepo interface { @@ -26,9 +26,9 @@ type AppRepo interface { GetInstalledAll(query string, cond ...string) ([]*App, error) GetHomeShow() ([]map[string]string, error) IsInstalled(query string, cond ...string) (bool, error) - Install(slug, versionSlug string) error - Uninstall(slug, versionSlug string) error - Update(slug, versionSlug string) error + Install(channel, slug string) error + Uninstall(slug string) error + Update(slug string) error UpdateShow(slug string, show bool) error UpdateCache() error } diff --git a/internal/biz/setting.go b/internal/biz/setting.go index 0d496dbf..5b50d0f5 100644 --- a/internal/biz/setting.go +++ b/internal/biz/setting.go @@ -10,17 +10,17 @@ import ( type SettingKey string const ( - SettingKeyName SettingKey = "name" - SettingKeyVersion SettingKey = "version" - SettingKeyMonitor SettingKey = "monitor" - SettingKeyMonitorDays SettingKey = "monitor_days" - SettingKeyBackupPath SettingKey = "backup_path" - SettingKeyWebsitePath SettingKey = "website_path" - SettingKeyPerconaRootPassword SettingKey = "percona_root_password" - SettingKeySshHost SettingKey = "ssh_host" - SettingKeySshPort SettingKey = "ssh_port" - SettingKeySshUser SettingKey = "ssh_user" - SettingKeySshPassword SettingKey = "ssh_password" + SettingKeyName SettingKey = "name" + SettingKeyVersion SettingKey = "version" + SettingKeyMonitor SettingKey = "monitor" + SettingKeyMonitorDays SettingKey = "monitor_days" + SettingKeyBackupPath SettingKey = "backup_path" + SettingKeyWebsitePath SettingKey = "website_path" + SettingKeyMySQLRootPassword SettingKey = "mysql_root_password" + SettingKeySshHost SettingKey = "ssh_host" + SettingKeySshPort SettingKey = "ssh_port" + SettingKeySshUser SettingKey = "ssh_user" + SettingKeySshPassword SettingKey = "ssh_password" ) type Setting struct { diff --git a/internal/data/app.go b/internal/data/app.go index eed25f42..bbdcc783 100644 --- a/internal/data/app.go +++ b/internal/data/app.go @@ -62,9 +62,9 @@ func (r *appRepo) UpdateExist(slug string) bool { return false } - for v := range slices.Values(item.Versions) { - if v.Slug == installed.VersionSlug { - current := str.FirstElement(v.Subs) + for channel := range slices.Values(item.Channels) { + if channel.Slug == installed.Channel { + current := str.FirstElement(channel.Subs) if current != nil && current.Version != installed.Version { return true } @@ -141,7 +141,7 @@ func (r *appRepo) IsInstalled(query string, cond ...string) (bool, error) { return count > 0, nil } -func (r *appRepo) Install(slug, versionSlug string) error { +func (r *appRepo) Install(channel, slug string) error { item, err := r.Get(slug) if err != nil { return err @@ -155,17 +155,19 @@ func (r *appRepo) Install(slug, versionSlug string) error { return errors.New("应用已安装") } - var shellUrl string - for v := range slices.Values(item.Versions) { - vs, err := version.NewVersion(v.Panel) + shellUrl, shellChannel, shellVersion := "", "", "" + for ch := range slices.Values(item.Channels) { + vs, err := version.NewVersion(ch.Panel) if err != nil { continue } - if v.Slug == versionSlug { + if ch.Slug == channel { if vs.GreaterThan(panel) { - return fmt.Errorf("应用 %s 需要面板版本 %s,当前版本 %s", item.Name, v.Panel, app.Version) + return fmt.Errorf("应用 %s 需要面板版本 %s,当前版本 %s", item.Name, ch.Panel, app.Version) } - shellUrl = v.Install + shellUrl = ch.Install + shellChannel = ch.Slug + shellVersion = str.FirstElement(ch.Subs).Version break } } @@ -180,7 +182,7 @@ func (r *appRepo) Install(slug, versionSlug string) error { task := new(biz.Task) task.Name = "安装应用 " + item.Name task.Status = biz.TaskStatusWaiting - task.Shell = fmt.Sprintf("%s >> /tmp/%s.log 2>&1", shellUrl, item.Slug) + task.Shell = fmt.Sprintf(`curl -s "%s" | bash -s -- "%s" "%s" >> /tmp/%s.log 2>&1`, shellUrl, shellChannel, shellVersion, item.Slug) task.Log = "/tmp/" + item.Slug + ".log" if err = r.taskRepo.Push(task); err != nil { return err @@ -189,7 +191,7 @@ func (r *appRepo) Install(slug, versionSlug string) error { return err } -func (r *appRepo) Uninstall(slug, versionSlug string) error { +func (r *appRepo) Uninstall(slug string) error { item, err := r.Get(slug) if err != nil { return err @@ -202,18 +204,24 @@ func (r *appRepo) Uninstall(slug, versionSlug string) error { if installed, _ := r.IsInstalled(slug); !installed { return errors.New("应用未安装") } + installed, err := r.GetInstalled(slug) + if err != nil { + return err + } - var shellUrl string - for v := range slices.Values(item.Versions) { - vs, err := version.NewVersion(v.Panel) + shellUrl, shellChannel, shellVersion := "", "", "" + for ch := range slices.Values(item.Channels) { + vs, err := version.NewVersion(ch.Panel) if err != nil { continue } - if v.Slug == versionSlug { + if ch.Slug == installed.Channel { if vs.GreaterThan(panel) { - return fmt.Errorf("应用 %s 需要面板版本 %s,当前版本 %s", item.Name, v.Panel, app.Version) + return fmt.Errorf("应用 %s 需要面板版本 %s,当前版本 %s", item.Name, ch.Panel, app.Version) } - shellUrl = v.Uninstall + shellUrl = ch.Uninstall + shellChannel = ch.Slug + shellVersion = installed.Version break } } @@ -228,7 +236,7 @@ func (r *appRepo) Uninstall(slug, versionSlug string) error { task := new(biz.Task) task.Name = "卸载应用 " + item.Name task.Status = biz.TaskStatusWaiting - task.Shell = fmt.Sprintf("%s >> /tmp/%s.log 2>&1", shellUrl, item.Slug) + task.Shell = fmt.Sprintf(`curl -s "%s" | bash -s -- "%s" "%s" >> /tmp/%s.log 2>&1`, shellUrl, shellChannel, shellVersion, item.Slug) task.Log = "/tmp/" + item.Slug + ".log" if err = r.taskRepo.Push(task); err != nil { return err @@ -237,7 +245,7 @@ func (r *appRepo) Uninstall(slug, versionSlug string) error { return err } -func (r *appRepo) Update(slug, versionSlug string) error { +func (r *appRepo) Update(slug string) error { item, err := r.Get(slug) if err != nil { return err @@ -250,18 +258,24 @@ func (r *appRepo) Update(slug, versionSlug string) error { if installed, _ := r.IsInstalled(slug); !installed { return errors.New("应用未安装") } + installed, err := r.GetInstalled(slug) + if err != nil { + return err + } - var shellUrl string - for v := range slices.Values(item.Versions) { - vs, err := version.NewVersion(v.Panel) + shellUrl, shellChannel, shellVersion := "", "", "" + for ch := range slices.Values(item.Channels) { + vs, err := version.NewVersion(ch.Panel) if err != nil { continue } - if v.Slug == versionSlug { + if ch.Slug == installed.Channel { if vs.GreaterThan(panel) { - return fmt.Errorf("应用 %s 需要面板版本 %s,当前版本 %s", item.Name, v.Panel, app.Version) + return fmt.Errorf("应用 %s 需要面板版本 %s,当前版本 %s", item.Name, ch.Panel, app.Version) } - shellUrl = v.Update + shellUrl = ch.Update + shellChannel = ch.Slug + shellVersion = str.FirstElement(ch.Subs).Version break } } @@ -276,7 +290,7 @@ func (r *appRepo) Update(slug, versionSlug string) error { task := new(biz.Task) task.Name = "更新应用 " + item.Name task.Status = biz.TaskStatusWaiting - task.Shell = fmt.Sprintf("%s >> /tmp/%s.log 2>&1", shellUrl, item.Slug) + task.Shell = fmt.Sprintf(`curl -s "%s" | bash -s -- "%s" "%s" >> /tmp/%s.log 2>&1`, shellUrl, shellChannel, shellVersion, item.Slug) task.Log = "/tmp/" + item.Slug + ".log" if err = r.taskRepo.Push(task); err != nil { return err diff --git a/internal/data/website.go b/internal/data/website.go index cbf8d20d..6b155d5f 100644 --- a/internal/data/website.go +++ b/internal/data/website.go @@ -332,7 +332,7 @@ server return nil, err } - rootPassword, err := r.settingRepo.Get(biz.SettingKeyPerconaRootPassword) + rootPassword, err := r.settingRepo.Get(biz.SettingKeyMySQLRootPassword) if err == nil && req.DB && req.DBType == "mysql" { mysql, err := db.NewMySQL("root", rootPassword, "/tmp/mysql.sock", "unix") if err != nil { @@ -610,7 +610,7 @@ func (r *websiteRepo) Delete(req *request.WebsiteDelete) error { _ = io.Remove(website.Path) } if req.DB { - rootPassword, err := r.settingRepo.Get(biz.SettingKeyPerconaRootPassword) + rootPassword, err := r.settingRepo.Get(biz.SettingKeyMySQLRootPassword) if err != nil { return err } diff --git a/internal/http/request/app.go b/internal/http/request/app.go index 908c934b..fa1ccc4a 100644 --- a/internal/http/request/app.go +++ b/internal/http/request/app.go @@ -1,8 +1,8 @@ package request type App struct { - Slug string `json:"slug" form:"slug"` - VersionSlug string `json:"version_slug" form:"version_slug"` + Slug string `json:"slug" form:"slug"` + Channel string `json:"channel" form:"channel"` } type AppSlug struct { diff --git a/internal/service/app.go b/internal/service/app.go index ee3b651b..983e19db 100644 --- a/internal/service/app.go +++ b/internal/service/app.go @@ -36,24 +36,35 @@ func (s *AppService) List(w http.ResponseWriter, r *http.Request) { var apps []types.StoreApp for _, item := range all { - installed, installedVersion, installedVersionSlug, updateExist, show := false, "", "", false, false + installed, installedChannel, installedVersion, updateExist, show := false, "", "", false, false if _, ok := installedAppMap[item.Slug]; ok { installed = true + installedChannel = installedAppMap[item.Slug].Channel installedVersion = installedAppMap[item.Slug].Version - installedVersionSlug = installedAppMap[item.Slug].VersionSlug updateExist = s.appRepo.UpdateExist(item.Slug) show = installedAppMap[item.Slug].Show } apps = append(apps, types.StoreApp{ - Name: item.Name, - Description: item.Description, - Slug: item.Slug, - Versions: item.Versions, - Installed: installed, - InstalledVersion: installedVersion, - InstalledVersionSlug: installedVersionSlug, - UpdateExist: updateExist, - Show: show, + Name: item.Name, + Description: item.Description, + Slug: item.Slug, + Channels: []struct { + Slug string `json:"slug"` + Name string `json:"name"` + Panel string `json:"panel"` + Install string `json:"-"` + Uninstall string `json:"-"` + Update string `json:"-"` + Subs []struct { + Log string `json:"log"` + Version string `json:"version"` + } `json:"subs"` + }(item.Channels), + Installed: installed, + InstalledChannel: installedChannel, + InstalledVersion: installedVersion, + UpdateExist: updateExist, + Show: show, }) } @@ -72,7 +83,7 @@ func (s *AppService) Install(w http.ResponseWriter, r *http.Request) { return } - if err = s.appRepo.Install(req.Slug, req.VersionSlug); err != nil { + if err = s.appRepo.Install(req.Channel, req.Slug); err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } @@ -81,13 +92,13 @@ func (s *AppService) Install(w http.ResponseWriter, r *http.Request) { } func (s *AppService) Uninstall(w http.ResponseWriter, r *http.Request) { - req, err := Bind[request.App](r) + req, err := Bind[request.AppSlug](r) if err != nil { Error(w, http.StatusUnprocessableEntity, err.Error()) return } - if err = s.appRepo.Uninstall(req.Slug, req.VersionSlug); err != nil { + if err = s.appRepo.Uninstall(req.Slug); err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } @@ -96,13 +107,13 @@ func (s *AppService) Uninstall(w http.ResponseWriter, r *http.Request) { } func (s *AppService) Update(w http.ResponseWriter, r *http.Request) { - req, err := Bind[request.App](r) + req, err := Bind[request.AppSlug](r) if err != nil { Error(w, http.StatusUnprocessableEntity, err.Error()) return } - if err = s.appRepo.Update(req.Slug, req.VersionSlug); err != nil { + if err = s.appRepo.Update(req.Slug); err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } diff --git a/internal/service/info.go b/internal/service/info.go index 31b687a2..af063971 100644 --- a/internal/service/info.go +++ b/internal/service/info.go @@ -87,7 +87,7 @@ func (s *InfoService) CountInfo(w http.ResponseWriter, r *http.Request) { } var databaseCount int64 if mysqlInstalled { - rootPassword, _ := s.settingRepo.Get(biz.SettingKeyPerconaRootPassword) + rootPassword, _ := s.settingRepo.Get(biz.SettingKeyMySQLRootPassword) mysql, err := db.NewMySQL("root", rootPassword, "/tmp/mysql.sock") if err == nil { defer mysql.Close() diff --git a/pkg/api/app.go b/pkg/api/app.go index 8564a8ef..9dd385a0 100644 --- a/pkg/api/app.go +++ b/pkg/api/app.go @@ -14,7 +14,7 @@ type App struct { Description string `json:"description"` Categories []string `json:"categories"` Depends string `json:"depends"` - Versions []struct { + Channels []struct { Slug string `json:"slug"` Name string `json:"name"` Panel string `json:"panel"` @@ -24,8 +24,8 @@ type App struct { Subs []struct { Log string `json:"log"` Version string `json:"version"` - } `json:"versions"` - } `json:"versions"` + } `json:"subs"` + } `json:"channels"` Order int `json:"order"` } diff --git a/pkg/types/app.go b/pkg/types/app.go index 62697abe..fba070c3 100644 --- a/pkg/types/app.go +++ b/pkg/types/app.go @@ -13,21 +13,21 @@ type StoreApp struct { Name string `json:"name"` Description string `json:"description"` Slug string `json:"slug"` - Versions []struct { + Channels []struct { Slug string `json:"slug"` Name string `json:"name"` Panel string `json:"panel"` - Install string `json:"install"` - Uninstall string `json:"uninstall"` - Update string `json:"update"` + Install string `json:"-"` + Uninstall string `json:"-"` + Update string `json:"-"` Subs []struct { Log string `json:"log"` Version string `json:"version"` - } `json:"versions"` - } `json:"versions"` - Installed bool `json:"installed"` - InstalledVersion string `json:"installed_version"` - InstalledVersionSlug string `json:"installed_version_slug"` - UpdateExist bool `json:"update_exist"` - Show bool `json:"show"` + } `json:"subs"` + } `json:"channels"` + Installed bool `json:"installed"` + InstalledChannel string `json:"installed_channel"` + InstalledVersion string `json:"installed_version"` + UpdateExist bool `json:"update_exist"` + Show bool `json:"show"` } diff --git a/web/src/api/panel/app/index.ts b/web/src/api/panel/app/index.ts index aee650da..587338f9 100644 --- a/web/src/api/panel/app/index.ts +++ b/web/src/api/panel/app/index.ts @@ -7,7 +7,8 @@ export default { list: (page: number, limit: number): Promise> => request.get('/app/list', { params: { page, limit } }), // 安装应用 - install: (slug: string): Promise> => request.post('/app/install', { slug }), + install: (slug: string, channel: string): Promise> => + request.post('/app/install', { slug, channel }), // 卸载应用 uninstall: (slug: string): Promise> => request.post('/app/uninstall', { slug }), @@ -18,5 +19,7 @@ export default { request.post('/app/updateShow', { slug, show }), // 应用是否已安装 isInstalled: (slug: string): Promise> => - request.get('/app/isInstalled', { params: { slug } }) + request.get('/app/isInstalled', { params: { slug } }), + // 更新缓存 + updateCache: (): Promise> => request.get('/app/updateCache') } diff --git a/web/src/i18n/en.json b/web/src/i18n/en.json index a99f6f4c..a928aad2 100644 --- a/web/src/i18n/en.json +++ b/web/src/i18n/en.json @@ -130,29 +130,28 @@ "appIndex": { "title": "Apps", "alerts": { - "info": "Click the button once, please do not click it repeatedly to avoid repeated execution!", - "warning": "It is strongly recommended to take a backup/snapshot before upgrading the plug-in to avoid being unable to roll back if problems arise!", + "cache": "Cache updated successfully", + "warning": "It is strongly recommended to take a backup/snapshot before upgrading the app to avoid being unable to roll back if problems arise!", "setup": "Setup successful", "install": "The task has been submitted, please check the task progress later", "update": "The task has been submitted, please go to the task center to check the task progress", "uninstall": "The task has been submitted, please go to the task center to check the task progress" }, "buttons": { + "updateCache": "Update cache", "install": "Install", "manage": "Manage", "update": "Upgrade", "uninstall": "Uninstall" }, "confirm": { - "install": "Are you sure you want to install the app {app}?", - "update": "Upgrading the {app} plug-in may reset related configurations to the default state. Are you sure you want to continue?", + "update": "Upgrading the {app} app may reset related configurations to the default state. Are you sure you want to continue?", "uninstall": "Are you sure you want to uninstall the app {app}?" }, "columns": { "name": "Name", "description": "Description", "installedVersion": "Installed Version", - "version": "Latest Version", "show": "Homepage Display", "actions": "Actions" } diff --git a/web/src/i18n/zh_CN.json b/web/src/i18n/zh_CN.json index 0acc812d..f0bb10b8 100644 --- a/web/src/i18n/zh_CN.json +++ b/web/src/i18n/zh_CN.json @@ -130,7 +130,7 @@ "appIndex": { "title": "应用市场", "alerts": { - "info": "按钮点击一次即可,请勿重复点击以免重复执行!", + "cache": "缓存更新成功", "warning": "升级应用前强烈建议先备份/快照,以免出现问题时无法回滚!", "setup": "设置成功", "install": "任务已提交,请稍后查看任务进度", @@ -138,13 +138,13 @@ "uninstall": "任务已提交,请前往任务中心查看任务进度" }, "buttons": { + "updateCache": "更新缓存", "install": "安装", "manage": "管理", "update": "升级", "uninstall": "卸载" }, "confirm": { - "install": "确定安装应用 {app} 吗?", "update": "升级 {app} 应用可能会重置相关配置到默认状态,确定继续吗?", "uninstall": "确定卸载应用 {app} 吗?" }, @@ -152,7 +152,6 @@ "name": "应用名", "description": "描述", "installedVersion": "已装版本", - "version": "最新版本", "show": "首页显示", "actions": "操作" } diff --git a/web/src/views/app/IndexView.vue b/web/src/views/app/IndexView.vue index 5d659f4d..4b402cf0 100644 --- a/web/src/views/app/IndexView.vue +++ b/web/src/views/app/IndexView.vue @@ -1,4 +1,6 @@ + + + + diff --git a/web/src/views/app/types.ts b/web/src/views/app/types.ts index 50c6ddf8..e742d8a2 100644 --- a/web/src/views/app/types.ts +++ b/web/src/views/app/types.ts @@ -2,10 +2,22 @@ export interface App { name: string description: string slug: string - version: string - requires: string - excludes: string + channels: Channel[] installed: boolean + installed_channel: string installed_version: string + update_exist: boolean show: boolean } + +export interface Channel { + slug: string + name: string + panel: string + subs: Sub[] +} + +export interface Sub { + log: string + version: string +}