Files
cneicy ceddfd3d6b feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
2026-09-26 04:49:11 +08:00

91 lines
2.8 KiB
Go

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
}