Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions core/app/repo/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ISettingRepo interface {
GetValueByKey(key string) (string, error)
Create(key, value string) error
Update(key, value string) error
UpdateIfMatch(key, oldValue, value string) (bool, error)
UpdateOrCreate(key, value string) error
DefaultMenu() error
}
Expand Down Expand Up @@ -89,6 +90,20 @@ func (u *SettingRepo) Update(key, value string) error {
return nil
}

func (u *SettingRepo) UpdateIfMatch(key, oldValue, value string) (bool, error) {
result := global.DB.Model(&model.Setting{}).
Where("key = ? AND value = ?", key, oldValue).
Updates(map[string]interface{}{"value": value})
if result.Error != nil {
return false, result.Error
}
if result.RowsAffected == 0 {
return false, nil
}
settingCache.Set(key, value, settingTTL)
return true, nil
}

func (u *SettingRepo) UpdateOrCreate(key, value string) error {
var setting model.Setting
result := global.DB.Where("key = ?", key).First(&setting)
Expand Down
63 changes: 44 additions & 19 deletions core/app/service/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/1Panel-dev/1Panel/core/utils/controller"
"github.com/1Panel-dev/1Panel/core/utils/encrypt"
"github.com/1Panel-dev/1Panel/core/utils/firewall"
"github.com/1Panel-dev/1Panel/core/utils/menutree"
"github.com/1Panel-dev/1Panel/core/utils/passkey"
"github.com/1Panel-dev/1Panel/core/utils/req_helper/proxy_local"
"github.com/1Panel-dev/1Panel/core/utils/xpack"
Expand Down Expand Up @@ -80,15 +81,7 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) {
for _, set := range setting {
settingMap[set.Key] = set.Value
}
if hideMenu, ok := settingMap["HideMenu"]; ok && len(hideMenu) > 0 {
var menus []dto.ShowMenu
if err := json.Unmarshal([]byte(hideMenu), &menus); err == nil {
sortShowMenus(menus)
if sortedBytes, err := json.Marshal(menus); err == nil {
settingMap["HideMenu"] = string(sortedBytes)
}
}
}
repairAndSortHideMenu(settingMap)
var info dto.SettingInfo
arr, err := json.Marshal(settingMap)
if err != nil {
Expand Down Expand Up @@ -123,15 +116,7 @@ func (u *SettingService) GetSettingBaseInfo() (*dto.SettingBaseInfo, error) {
for _, set := range setting {
settingMap[set.Key] = set.Value
}
if hideMenu, ok := settingMap["HideMenu"]; ok && len(hideMenu) > 0 {
var menus []dto.ShowMenu
if err := json.Unmarshal([]byte(hideMenu), &menus); err == nil {
sortShowMenus(menus)
if sortedBytes, err := json.Marshal(menus); err == nil {
settingMap["HideMenu"] = string(sortedBytes)
}
}
}
repairAndSortHideMenu(settingMap)
var info dto.SettingBaseInfo
arr, err := json.Marshal(settingMap)
if err != nil {
Expand All @@ -152,6 +137,36 @@ func (u *SettingService) GetSettingBaseInfo() (*dto.SettingBaseInfo, error) {
return &info, err
}

func repairAndSortHideMenu(settingMap map[string]string) {
hideMenu, ok := settingMap["HideMenu"]
if !ok || strings.TrimSpace(hideMenu) == "" {
return
}
var menus []dto.ShowMenu
if err := json.Unmarshal([]byte(hideMenu), &menus); err != nil || len(menus) == 0 {
return
}

menus, changed := menutree.EnsureXpackAppMenus(menus, nil)
if changed {
repairedBytes, err := json.Marshal(menus)
if err != nil {
global.LOG.Warnf("marshal repaired HideMenu failed, err: %v", err)
} else {
updated, err := settingRepo.UpdateIfMatch("HideMenu", hideMenu, string(repairedBytes))
if err != nil {
global.LOG.Warnf("persist repaired HideMenu failed, err: %v", err)
} else if !updated {
global.LOG.Debug("skip persisting repaired HideMenu because the setting changed concurrently")
}
}
}
sortShowMenus(menus)
if sortedBytes, err := json.Marshal(menus); err == nil {
settingMap["HideMenu"] = string(sortedBytes)
}
}

func sortShowMenus(menus []dto.ShowMenu) {
for i := range menus {
if len(menus[i].Children) > 0 {
Expand All @@ -171,7 +186,7 @@ func (u *SettingService) Update(c *gin.Context, key, value string) error {
if err != nil {
return err
}
if oldVal.Value == value {
if oldVal.Value == value && key != "HideMenu" {
return nil
}
sessionLifeTime := 0
Expand All @@ -192,6 +207,13 @@ func (u *SettingService) Update(c *gin.Context, key, value string) error {
if err := json.Unmarshal([]byte(value), &menus); err != nil {
return err
}
var previousMenus []dto.ShowMenu
_ = json.Unmarshal([]byte(oldVal.Value), &previousMenus)
menus, _ = menutree.PreserveMissingMenus(menus, previousMenus)
if len(menus) == 0 {
return fmt.Errorf("hide menu cannot be empty")
}
menus, _ = menutree.EnsureXpackAppMenus(menus, previousMenus)
for i := 0; i < len(menus); i++ {
if menus[i].Label == "Home-Menu" || menus[i].Label == "App-Menu" || menus[i].Label == "Setting-Menu" {
menus[i].IsShow = true
Expand All @@ -203,6 +225,9 @@ func (u *SettingService) Update(c *gin.Context, key, value string) error {
}
value = string(menuItem)
}
if oldVal.Value == value {
return nil
}

if err := settingRepo.Update(key, value); err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions core/init/migration/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func Init() {
migrations.AddMenuAccordionSetting,
migrations.AddAPITrustedProxiesSetting,
migrations.AddWebsiteTemplateMenu,
migrations.RepairXpackAppMenus,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
Expand Down
37 changes: 37 additions & 0 deletions core/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/1Panel-dev/1Panel/core/utils/common"
"github.com/1Panel-dev/1Panel/core/utils/ctl_conf"
"github.com/1Panel-dev/1Panel/core/utils/encrypt"
"github.com/1Panel-dev/1Panel/core/utils/menutree"
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)
Expand Down Expand Up @@ -1314,3 +1315,39 @@ var AddWebsiteTemplateMenu = &gormigrate.Migration{
}, "SSL")
},
}

var RepairXpackAppMenus = &gormigrate.Migration{
ID: "20260818-repair-xapp-upage-hide-menu",
Migrate: func(tx *gorm.DB) error {
var setting model.Setting
if err := tx.Where("key = ?", "HideMenu").First(&setting).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return tx.Create(&model.Setting{Key: "HideMenu", Value: helper.LoadMenus()}).Error
}
return err
}

updateValue := func(value string) error {
return tx.Model(&setting).Update("value", value).Error
}

if strings.TrimSpace(setting.Value) == "" {
return updateValue(helper.LoadMenus())
}

var menus []dto.ShowMenu
if err := json.Unmarshal([]byte(setting.Value), &menus); err != nil || len(menus) == 0 {
return updateValue(helper.LoadMenus())
}

updatedMenus, changed := menutree.EnsureXpackAppMenus(menus, nil)
if !changed {
return nil
}
updatedJSON, err := json.Marshal(updatedMenus)
if err != nil {
return err
}
return updateValue(string(updatedJSON))
},
}
Loading
Loading