package model import ( "context" "encoding/hex" "strings" "time" "github.com/QuantumNous/new-api/common" "gorm.io/gorm" "gorm.io/gorm/clause" ) const statusPageOptionPrefix = "StatusPageGroup:" type StatusPageGroup struct { Alias string `json:"alias"` Hidden bool `json:"hidden"` ResetBefore int64 `json:"reset_before"` } func GetStatusPageGroups(ctx context.Context) (map[string]StatusPageGroup, error) { var rows []Option if err := DB.WithContext(ctx).Where(clause.Like{Column: clause.Column{Name: "key"}, Value: statusPageOptionPrefix + "%"}).Find(&rows).Error; err != nil { return nil, err } groups := make(map[string]StatusPageGroup, len(rows)) for _, row := range rows { name, err := hex.DecodeString(strings.TrimPrefix(row.Key, statusPageOptionPrefix)) if err != nil { return nil, err } var settings StatusPageGroup if err := common.UnmarshalJsonStr(row.Value, &settings); err != nil { return nil, err } groups[string(name)] = settings } return groups, nil } // One persisted cutoff per group preserves shared-channel history and the // detection wallet ledger. Runs started before a reset stay excluded on completion. func SaveStatusPageGroup(ctx context.Context, group string, display *StatusPageGroup) error { key := statusPageOptionPrefix + hex.EncodeToString([]byte(group)) return DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&Option{Key: key, Value: "{}"}).Error; err != nil { return err } var row Option if err := lockForUpdate(tx).Where(&Option{Key: key}).First(&row).Error; err != nil { return err } var settings StatusPageGroup if err := common.UnmarshalJsonStr(row.Value, &settings); err != nil { return err } if display == nil { settings.ResetBefore = max(settings.ResetBefore, time.Now().Unix()) } else { settings.Alias, settings.Hidden = display.Alias, display.Hidden } encoded, err := common.Marshal(settings) if err != nil { return err } return tx.Model(&Option{}).Where(&Option{Key: key}).Update("value", string(encoded)).Error }) } func GetStatusPageModels(ctx context.Context, channels []StatusChannel) (map[string][]string, error) { ids := make([]int, 0, len(channels)) for _, channel := range channels { if channel.Status == common.ChannelStatusEnabled { ids = append(ids, channel.Id) } } result := map[string][]string{} if len(ids) == 0 { return result, nil } var abilities []Ability if err := DB.WithContext(ctx).Select("group", "model").Where("enabled = ? AND channel_id IN ?", true, ids).Distinct().Order("model").Find(&abilities).Error; err != nil { return nil, err } for _, ability := range abilities { result[ability.Group] = append(result[ability.Group], ability.Model) } return result, nil }