diff --git a/core/app/api/v2/setting.go b/core/app/api/v2/setting.go index ca16ea1af..c246fea24 100644 --- a/core/app/api/v2/setting.go +++ b/core/app/api/v2/setting.go @@ -184,6 +184,22 @@ func (b *BaseApi) UpdateMenu(c *gin.Context) { helper.Success(c) } +// @Tags Menu Setting +// @Summary Default menu +// @Accept json +// @Success 200 +// @Security ApiKeyAuth +// @Security Timestamp +// @Router /core/settings/menu/default [post] +// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"初始化菜单","formatEN":"Init menu."} +func (b *BaseApi) DefaultMenu(c *gin.Context) { + if err := settingService.DefaultMenu(); err != nil { + helper.InternalServer(c, err) + return + } + helper.Success(c) +} + // @Tags System Setting // @Summary Update system password // @Accept json diff --git a/core/app/repo/setting.go b/core/app/repo/setting.go index f3ea2f448..8d41c5f2c 100644 --- a/core/app/repo/setting.go +++ b/core/app/repo/setting.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/1Panel-dev/1Panel/core/app/model" "github.com/1Panel-dev/1Panel/core/global" + "github.com/1Panel-dev/1Panel/core/init/migration/helper" "gorm.io/gorm" ) @@ -16,6 +17,7 @@ type ISettingRepo interface { Create(key, value string) error Update(key, value string) error UpdateOrCreate(key, value string) error + DefaultMenu() error } func NewISettingRepo() ISettingRepo { @@ -73,3 +75,9 @@ func (u *SettingRepo) UpdateOrCreate(key, value string) error { } return global.DB.Model(&setting).UpdateColumn("value", value).Error } + +func (u *SettingRepo) DefaultMenu() error { + return global.DB.Model(&model.Setting{}). + Where("key = ?", "HideMenu"). + Update("value", helper.LoadMenus()).Error +} diff --git a/core/app/service/setting.go b/core/app/service/setting.go index 9600de552..88bc548fb 100644 --- a/core/app/service/setting.go +++ b/core/app/service/setting.go @@ -63,6 +63,7 @@ type ISettingService interface { UpdateAppstoreConfig(req dto.AppstoreUpdate) error GetAppstoreConfig() (*dto.AppstoreConfig, error) + DefaultMenu() error } func NewISettingService() ISettingService { @@ -764,3 +765,7 @@ func checkProxy(req dto.ProxyUpdate) error { defer resp.Body.Close() return nil } + +func (u *SettingService) DefaultMenu() error { + return settingRepo.DefaultMenu() +} diff --git a/core/init/migration/helper/menu.go b/core/init/migration/helper/menu.go index 04d41e3a4..26698fbb9 100644 --- a/core/init/migration/helper/menu.go +++ b/core/init/migration/helper/menu.go @@ -3,55 +3,56 @@ package helper import ( "encoding/json" "fmt" + "github.com/1Panel-dev/1Panel/core/app/dto" "github.com/1Panel-dev/1Panel/core/app/model" "gorm.io/gorm" "strings" - - "github.com/1Panel-dev/1Panel/core/app/dto" ) func LoadMenus() string { item := []dto.ShowMenu{ - {ID: "1", Disabled: true, Title: "menu.home", IsShow: true, Label: "Home-Menu", Path: "/"}, - {ID: "2", Disabled: true, Title: "menu.apps", IsShow: true, Label: "App-Menu", Path: "/apps/all"}, - {ID: "3", Disabled: false, Title: "menu.website", IsShow: true, Label: "Website-Menu", Path: "/websites", + {ID: "1", Disabled: true, Title: "menu.home", IsShow: true, Label: "Home-Menu", Path: "/", Sort: 100}, + {ID: "2", Disabled: true, Title: "menu.apps", IsShow: true, Label: "App-Menu", Path: "/apps/all", Sort: 200}, + {ID: "3", Disabled: false, Title: "menu.website", IsShow: true, Label: "Website-Menu", Path: "/websites", Sort: 300, Children: []dto.ShowMenu{ - {ID: "31", Disabled: false, Title: "menu.website", IsShow: true, Label: "Website", Path: "/websites"}, - {ID: "32", Disabled: false, Title: "menu.ssl", IsShow: true, Label: "SSL", Path: "/websites/ssl"}, - {ID: "33", Disabled: false, Title: "menu.runtime", IsShow: true, Label: "PHP", Path: "/websites/runtimes/php"}, + {ID: "31", Disabled: false, Title: "menu.website", IsShow: true, Label: "Website", Path: "/websites", Sort: 100}, + {ID: "32", Disabled: false, Title: "menu.ssl", IsShow: true, Label: "SSL", Path: "/websites/ssl", Sort: 200}, + {ID: "33", Disabled: false, Title: "menu.runtime", IsShow: true, Label: "PHP", Path: "/websites/runtimes/php", Sort: 300}, }}, - {ID: "4", Disabled: false, Title: "menu.aiTools", IsShow: true, Label: "AI-Menu", Path: "/ai/model", + {ID: "4", Disabled: false, Title: "menu.aiTools", IsShow: true, Label: "AI-Menu", Path: "/ai/model", Sort: 400, Children: []dto.ShowMenu{ - {ID: "41", Disabled: false, Title: "aiTools.model.model", IsShow: true, Label: "OllamaModel", Path: "/ai/model"}, - {ID: "42", Disabled: false, Title: "menu.mcp", IsShow: true, Label: "MCPServer", Path: "/ai/mcp"}, - {ID: "43", Disabled: false, Title: "aiTools.gpu.gpu", IsShow: true, Label: "GPU", Path: "/ai/gpu"}, + {ID: "41", Disabled: false, Title: "aiTools.model.model", IsShow: true, Label: "OllamaModel", Path: "/ai/model", Sort: 100}, + {ID: "42", Disabled: false, Title: "menu.mcp", IsShow: true, Label: "MCPServer", Path: "/ai/mcp", Sort: 200}, + {ID: "43", Disabled: false, Title: "aiTools.gpu.gpu", IsShow: true, Label: "GPU", Path: "/ai/gpu", Sort: 300}, }}, - {ID: "5", Disabled: false, Title: "menu.database", IsShow: true, Label: "Database-Menu", Path: "/databases"}, - {ID: "6", Disabled: false, Title: "menu.container", IsShow: true, Label: "Container-Menu", Path: "/containers"}, - {ID: "7", Disabled: false, Title: "menu.system", IsShow: true, Label: "System-Menu", Path: "/hosts/files", + {ID: "5", Disabled: false, Title: "menu.database", IsShow: true, Label: "Database-Menu", Path: "/databases", Sort: 500}, + {ID: "6", Disabled: false, Title: "menu.container", IsShow: true, Label: "Container-Menu", Path: "/containers", Sort: 600}, + {ID: "7", Disabled: false, Title: "menu.system", IsShow: true, Label: "System-Menu", Path: "/hosts/files", Sort: 700, Children: []dto.ShowMenu{ - {ID: "71", Disabled: false, Title: "menu.files", IsShow: true, Label: "File", Path: "/hosts/files"}, - {ID: "72", Disabled: false, Title: "menu.monitor", IsShow: true, Label: "Monitorx", Path: "/hosts/monitor/monitor"}, - {ID: "74", Disabled: false, Title: "menu.firewall", IsShow: true, Label: "FirewallPort", Path: "/hosts/firewall/port"}, - {ID: "75", Disabled: false, Title: "menu.processManage", IsShow: true, Label: "Process", Path: "/hosts/process/process"}, - {ID: "76", Disabled: false, Title: "menu.ssh", IsShow: true, Label: "SSH", Path: "/hosts/ssh/ssh"}, + {ID: "71", Disabled: false, Title: "menu.files", IsShow: true, Label: "File", Path: "/hosts/files", Sort: 100}, + {ID: "72", Disabled: false, Title: "menu.monitor", IsShow: true, Label: "Monitorx", Path: "/hosts/monitor/monitor", Sort: 200}, + {ID: "74", Disabled: false, Title: "menu.firewall", IsShow: true, Label: "FirewallPort", Path: "/hosts/firewall/port", Sort: 300}, + {ID: "75", Disabled: false, Title: "menu.processManage", IsShow: true, Label: "Process", Path: "/hosts/process/process", Sort: 400}, + {ID: "76", Disabled: false, Title: "menu.ssh", IsShow: true, Label: "SSH", Path: "/hosts/ssh/ssh", Sort: 500}, + {ID: "77", Disabled: false, Title: "menu.disk", IsShow: true, Label: "Disk", Path: "/hosts/disk", Sort: 600}, }}, - {ID: "8", Disabled: false, Title: "menu.terminal", IsShow: true, Label: "Terminal-Menu", Path: "/hosts/terminal"}, - {ID: "10", Disabled: false, Title: "menu.cronjob", IsShow: true, Label: "Cronjob-Menu", Path: "/cronjobs"}, - {ID: "9", Disabled: false, Title: "menu.toolbox", IsShow: true, Label: "Toolbox-Menu", Path: "/toolbox"}, - {ID: "11", Disabled: false, Title: "xpack.menu", IsShow: true, Label: "Xpack-Menu", + {ID: "8", Disabled: false, Title: "menu.terminal", IsShow: true, Label: "Terminal-Menu", Path: "/hosts/terminal", Sort: 800}, + {ID: "10", Disabled: false, Title: "menu.cronjob", IsShow: true, Label: "Cronjob-Menu", Path: "/cronjobs", Sort: 900}, + {ID: "9", Disabled: false, Title: "menu.toolbox", IsShow: true, Label: "Toolbox-Menu", Path: "/toolbox", Sort: 1000}, + {ID: "11", Disabled: false, Title: "xpack.menu", IsShow: true, Label: "Xpack-Menu", Sort: 1100, Children: []dto.ShowMenu{ - {ID: "118", Disabled: false, Title: "xpack.app.app", IsShow: true, Label: "XApp", Path: "/xpack/app"}, - {ID: "112", Disabled: false, Title: "xpack.waf.name", IsShow: true, Label: "Dashboard", Path: "/xpack/waf/dashboard"}, - {ID: "111", Disabled: false, Title: "xpack.node.nodeManagement", IsShow: true, Label: "Node", Path: "/xpack/node"}, - {ID: "119", Disabled: false, Title: "xpack.upage", IsShow: true, Label: "Upage", Path: "/xpack/upage"}, - {ID: "113", Disabled: false, Title: "xpack.monitor.name", IsShow: true, Label: "MonitorDashboard", Path: "/xpack/monitor/dashboard"}, - {ID: "114", Disabled: false, Title: "xpack.tamper.tamper", IsShow: true, Label: "Tamper", Path: "/xpack/tamper"}, - {ID: "115", Disabled: false, Title: "xpack.exchange.exchange", IsShow: true, Label: "FileExange", Path: "/xpack/exchange/file"}, - {ID: "117", Disabled: false, Title: "xpack.setting.setting", IsShow: true, Label: "XSetting", Path: "/xpack/setting"}, + {ID: "118", Disabled: false, Title: "xpack.app.app", IsShow: true, Label: "XApp", Path: "/xpack/app", Sort: 100}, + {ID: "112", Disabled: false, Title: "xpack.waf.name", IsShow: true, Label: "Dashboard", Path: "/xpack/waf/dashboard", Sort: 200}, + {ID: "111", Disabled: false, Title: "xpack.node.nodeManagement", IsShow: true, Label: "Node", Path: "/xpack/node", Sort: 300}, + {ID: "119", Disabled: false, Title: "xpack.upage", IsShow: true, Label: "Upage", Path: "/xpack/upage", Sort: 400}, + {ID: "113", Disabled: false, Title: "xpack.monitor.name", IsShow: true, Label: "MonitorDashboard", Path: "/xpack/monitor/dashboard", Sort: 500}, + {ID: "114", Disabled: false, Title: "xpack.tamper.tamper", IsShow: true, Label: "Tamper", Path: "/xpack/tamper", Sort: 600}, + {ID: "120", Disabled: false, Title: "xpack.cluster.cluster", IsShow: true, Label: "Cluster", Path: "/xpack/cluster", Sort: 700}, + {ID: "115", Disabled: false, Title: "xpack.exchange.exchange", IsShow: true, Label: "FileExange", Path: "/xpack/exchange/file", Sort: 800}, + {ID: "117", Disabled: false, Title: "xpack.setting.setting", IsShow: true, Label: "XSetting", Path: "/xpack/setting", Sort: 900}, }}, - {ID: "12", Disabled: false, Title: "menu.logs", IsShow: true, Label: "Log-Menu", Path: "/logs"}, - {ID: "13", Disabled: true, Title: "menu.settings", IsShow: true, Label: "Setting-Menu", Path: "/settings"}, + {ID: "12", Disabled: false, Title: "menu.logs", IsShow: true, Label: "Log-Menu", Path: "/logs", Sort: 1200}, + {ID: "13", Disabled: true, Title: "menu.settings", IsShow: true, Label: "Setting-Menu", Path: "/settings", Sort: 1300}, } menu, _ := json.Marshal(item) return string(menu) diff --git a/core/router/ro_setting.go b/core/router/ro_setting.go index 87b1dddda..5e9deb739 100644 --- a/core/router/ro_setting.go +++ b/core/router/ro_setting.go @@ -27,6 +27,7 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) { settingRouter.POST("/terminal/update", baseApi.UpdateTerminalSetting) settingRouter.GET("/interface", baseApi.LoadInterfaceAddr) settingRouter.POST("/menu/update", baseApi.UpdateMenu) + settingRouter.POST("/menu/default", baseApi.DefaultMenu) settingRouter.POST("/proxy/update", baseApi.UpdateProxy) settingRouter.POST("/bind/update", baseApi.UpdateBindInfo) settingRouter.POST("/port/update", baseApi.UpdatePort) diff --git a/frontend/src/api/modules/setting.ts b/frontend/src/api/modules/setting.ts index bf5c13a7a..275746e5a 100644 --- a/frontend/src/api/modules/setting.ts +++ b/frontend/src/api/modules/setting.ts @@ -94,6 +94,9 @@ export const updateSetting = (param: Setting.SettingUpdate) => { export const updateMenu = (param: Setting.SettingUpdate) => { return http.post(`/core/settings/menu/update`, param); }; +export const defaultMenu = () => { + return http.post(`/core/settings/menu/default`); +}; export const updateProxy = (params: Setting.ProxyUpdate) => { let request = deepCopy(params) as Setting.ProxyUpdate; if (request.proxyPasswd) { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index b819ef17e..52e2a28cc 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2045,6 +2045,7 @@ const message = { ifShow: 'Whether to Show', menu: 'Menu', confirmMessage: 'The page will be refreshed to update the advanced menu list. Continue?', + recoverMessage: 'The page will be refreshed and restore the menu list to its initial state. Continue?', compressPassword: 'Compression password', backupRecoverMessage: 'Please enter the compression or decompression password (leave blank to not set)', }, diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index 497a8ab43..e54bb75e6 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -2052,6 +2052,8 @@ const message = { ifShow: 'Mostrar o no', menu: 'Menú', confirmMessage: 'La página se actualizará para refrescar la lista de menús avanzados. ¿Deseas continuar?', + recoverMessage: + 'La página se actualizará y la lista de menús se restaurará a su estado inicial. ¿Desea continuar?', compressPassword: 'Contraseña de compresión', backupRecoverMessage: 'Introduce la contraseña de compresión o descompresión (déjalo en blanco para no establecerla)', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index de5e6b9a1..eb6bb1967 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -1960,6 +1960,7 @@ const message = { ifShow: '表示するかどうか', menu: 'メニュー', confirmMessage: 'ページは更新されて、高度なメニューリストを更新します。続く?', + recoverMessage: 'ページが更新され、メニューリストが初期状態に戻ります。続行しますか?', compressPassword: '圧縮パスワード', backupRecoverMessage: '圧縮または減圧パスワードを入力してください(設定しないように空白のままにしてください)', }, diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 85f13648a..0673ca9b4 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -1928,6 +1928,7 @@ const message = { ifShow: '표시 여부', menu: '메뉴', confirmMessage: '고급 메뉴 목록을 업데이트하려면 페이지가 새로 고쳐집니다. 계속하시겠습니까?', + recoverMessage: '페이지가 새로고침되어 메뉴 목록이 초기 상태로 복원됩니다. 계속하시겠습니까?', compressPassword: '압축 비밀번호', backupRecoverMessage: '압축 또는 압축 해제 비밀번호를 입력하세요 (설정하지 않으려면 비워 두세요)', }, diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index c5e5abb2f..2fd1516a4 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -2020,6 +2020,7 @@ const message = { ifShow: 'Sama ada untuk Dipaparkan', menu: 'Menu', confirmMessage: 'Halaman akan disegarkan untuk mengemas kini senarai menu lanjutan. Teruskan?', + recoverMessage: 'Halaman akan disegarkan dan senarai menu akan dipulihkan ke keadaan asal. Teruskan?', compressPassword: 'Kata laluan mampatan', backupRecoverMessage: 'Sila masukkan kata laluan mampatan atau nyahmampatan (biarkan kosong jika tidak menetapkan)', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 82aed9963..12e8fe432 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -2011,6 +2011,8 @@ const message = { ifShow: 'Exibir?', menu: 'Menu', confirmMessage: 'A página será atualizada para atualizar a lista de menus avançados. Continuar?', + recoverMessage: + 'A página será atualizada e a lista de menus será restaurada ao estado inicial. Deseja continuar?', compressPassword: 'Senha de compressão', backupRecoverMessage: 'Por favor, insira a senha de compressão ou descompressão (deixe em branco para não definir)', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 43d24b9da..c5b974e49 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -2010,6 +2010,8 @@ const message = { ifShow: 'Показывать', menu: 'Меню', confirmMessage: 'Страница будет обновлена для обновления списка расширенного меню. Продолжить?', + recoverMessage: + 'Страница будет обновлена, и список меню будет восстановлен до исходного состояния. Продолжить?', compressPassword: 'Пароль сжатия', backupRecoverMessage: 'Пожалуйста, введите пароль для сжатия или распаковки (оставьте пустым, чтобы не устанавливать)', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index 722ff09ba..de1b79913 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -2066,6 +2066,8 @@ const message = { ifShow: 'Gösterme Durumu', menu: 'Menü', confirmMessage: 'Gelişmiş menü listesini güncellemek için sayfa yenilenecek. Devam etmek istiyor musunuz?', + recoverMessage: + 'Sayfa yenilenecek ve menü listesi başlangıç durumuna geri yüklenecektir. Devam etmek istiyor musunuz?', compressPassword: 'Sıkıştırma parolası', backupRecoverMessage: 'Lütfen sıkıştırma veya sıkıştırma açma parolasını girin (ayarlamamak için boş bırakın)', }, diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index fab51e853..99f0b8e80 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -1910,6 +1910,7 @@ const message = { ifShow: '是否顯示', menu: '選單', confirmMessage: '即將重新整理頁面更新進階功能選單列表,是否繼續?', + recoverMessage: '即将重新整理頁面,並恢復選單列表至初始狀態。是否繼續?', compressPassword: '壓縮密碼', backupRecoverMessage: '請輸入壓縮或解壓縮密碼(留空則不設定)', }, diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 3bd3eb2b0..ddb6daf91 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -1903,6 +1903,7 @@ const message = { ifShow: '是否显示', menu: '菜单', confirmMessage: '即将刷新页面更新高级功能菜单列表,是否继续?', + recoverMessage: '即将刷新页面恢复菜单列表到初始状态,是否继续?', compressPassword: '压缩密码', backupRecoverMessage: '请输入压缩或解压缩密码(留空则不设置)', }, diff --git a/frontend/src/layout/components/Sidebar/components/SubItem.vue b/frontend/src/layout/components/Sidebar/components/SubItem.vue index 2dc98aa7d..0acba3413 100644 --- a/frontend/src/layout/components/Sidebar/components/SubItem.vue +++ b/frontend/src/layout/components/Sidebar/components/SubItem.vue @@ -1,5 +1,5 @@