feat(settings): 增加全局表格分页配置,支持自定义
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
@@ -160,6 +161,8 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
|
||||
SettingKeyHideCcsImportButton,
|
||||
SettingKeyPurchaseSubscriptionEnabled,
|
||||
SettingKeyPurchaseSubscriptionURL,
|
||||
SettingKeyTableDefaultPageSize,
|
||||
SettingKeyTablePageSizeOptions,
|
||||
SettingKeyCustomMenuItems,
|
||||
SettingKeyCustomEndpoints,
|
||||
SettingKeyLinuxDoConnectEnabled,
|
||||
@@ -184,6 +187,10 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
|
||||
registrationEmailSuffixWhitelist := ParseRegistrationEmailSuffixWhitelist(
|
||||
settings[SettingKeyRegistrationEmailSuffixWhitelist],
|
||||
)
|
||||
tableDefaultPageSize, tablePageSizeOptions := parseTablePreferences(
|
||||
settings[SettingKeyTableDefaultPageSize],
|
||||
settings[SettingKeyTablePageSizeOptions],
|
||||
)
|
||||
|
||||
return &PublicSettings{
|
||||
RegistrationEnabled: settings[SettingKeyRegistrationEnabled] == "true",
|
||||
@@ -205,6 +212,8 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
|
||||
HideCcsImportButton: settings[SettingKeyHideCcsImportButton] == "true",
|
||||
PurchaseSubscriptionEnabled: settings[SettingKeyPurchaseSubscriptionEnabled] == "true",
|
||||
PurchaseSubscriptionURL: strings.TrimSpace(settings[SettingKeyPurchaseSubscriptionURL]),
|
||||
TableDefaultPageSize: tableDefaultPageSize,
|
||||
TablePageSizeOptions: tablePageSizeOptions,
|
||||
CustomMenuItems: settings[SettingKeyCustomMenuItems],
|
||||
CustomEndpoints: settings[SettingKeyCustomEndpoints],
|
||||
LinuxDoOAuthEnabled: linuxDoEnabled,
|
||||
@@ -252,6 +261,8 @@ func (s *SettingService) GetPublicSettingsForInjection(ctx context.Context) (any
|
||||
HideCcsImportButton bool `json:"hide_ccs_import_button"`
|
||||
PurchaseSubscriptionEnabled bool `json:"purchase_subscription_enabled"`
|
||||
PurchaseSubscriptionURL string `json:"purchase_subscription_url,omitempty"`
|
||||
TableDefaultPageSize int `json:"table_default_page_size"`
|
||||
TablePageSizeOptions []int `json:"table_page_size_options"`
|
||||
CustomMenuItems json.RawMessage `json:"custom_menu_items"`
|
||||
CustomEndpoints json.RawMessage `json:"custom_endpoints"`
|
||||
LinuxDoOAuthEnabled bool `json:"linuxdo_oauth_enabled"`
|
||||
@@ -277,6 +288,8 @@ func (s *SettingService) GetPublicSettingsForInjection(ctx context.Context) (any
|
||||
HideCcsImportButton: settings.HideCcsImportButton,
|
||||
PurchaseSubscriptionEnabled: settings.PurchaseSubscriptionEnabled,
|
||||
PurchaseSubscriptionURL: settings.PurchaseSubscriptionURL,
|
||||
TableDefaultPageSize: settings.TableDefaultPageSize,
|
||||
TablePageSizeOptions: settings.TablePageSizeOptions,
|
||||
CustomMenuItems: filterUserVisibleMenuItems(settings.CustomMenuItems),
|
||||
CustomEndpoints: safeRawJSONArray(settings.CustomEndpoints),
|
||||
LinuxDoOAuthEnabled: settings.LinuxDoOAuthEnabled,
|
||||
@@ -471,6 +484,16 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet
|
||||
updates[SettingKeyHideCcsImportButton] = strconv.FormatBool(settings.HideCcsImportButton)
|
||||
updates[SettingKeyPurchaseSubscriptionEnabled] = strconv.FormatBool(settings.PurchaseSubscriptionEnabled)
|
||||
updates[SettingKeyPurchaseSubscriptionURL] = strings.TrimSpace(settings.PurchaseSubscriptionURL)
|
||||
tableDefaultPageSize, tablePageSizeOptions := normalizeTablePreferences(
|
||||
settings.TableDefaultPageSize,
|
||||
settings.TablePageSizeOptions,
|
||||
)
|
||||
updates[SettingKeyTableDefaultPageSize] = strconv.Itoa(tableDefaultPageSize)
|
||||
tablePageSizeOptionsJSON, err := json.Marshal(tablePageSizeOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal table page size options: %w", err)
|
||||
}
|
||||
updates[SettingKeyTablePageSizeOptions] = string(tablePageSizeOptionsJSON)
|
||||
updates[SettingKeyCustomMenuItems] = settings.CustomMenuItems
|
||||
updates[SettingKeyCustomEndpoints] = settings.CustomEndpoints
|
||||
|
||||
@@ -824,6 +847,8 @@ func (s *SettingService) InitializeDefaultSettings(ctx context.Context) error {
|
||||
SettingKeySiteLogo: "",
|
||||
SettingKeyPurchaseSubscriptionEnabled: "false",
|
||||
SettingKeyPurchaseSubscriptionURL: "",
|
||||
SettingKeyTableDefaultPageSize: "20",
|
||||
SettingKeyTablePageSizeOptions: "[10,20,50,100]",
|
||||
SettingKeyCustomMenuItems: "[]",
|
||||
SettingKeyCustomEndpoints: "[]",
|
||||
SettingKeyDefaultConcurrency: strconv.Itoa(s.cfg.Default.UserConcurrency),
|
||||
@@ -893,6 +918,10 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
|
||||
CustomEndpoints: settings[SettingKeyCustomEndpoints],
|
||||
BackendModeEnabled: settings[SettingKeyBackendModeEnabled] == "true",
|
||||
}
|
||||
result.TableDefaultPageSize, result.TablePageSizeOptions = parseTablePreferences(
|
||||
settings[SettingKeyTableDefaultPageSize],
|
||||
settings[SettingKeyTablePageSizeOptions],
|
||||
)
|
||||
|
||||
// 解析整数类型
|
||||
if port, err := strconv.Atoi(settings[SettingKeySMTPPort]); err == nil {
|
||||
@@ -1036,6 +1065,59 @@ func parseDefaultSubscriptions(raw string) []DefaultSubscriptionSetting {
|
||||
return normalized
|
||||
}
|
||||
|
||||
func parseTablePreferences(defaultPageSizeRaw, optionsRaw string) (int, []int) {
|
||||
defaultPageSize := 20
|
||||
if v, err := strconv.Atoi(strings.TrimSpace(defaultPageSizeRaw)); err == nil {
|
||||
defaultPageSize = v
|
||||
}
|
||||
|
||||
var options []int
|
||||
if strings.TrimSpace(optionsRaw) != "" {
|
||||
_ = json.Unmarshal([]byte(optionsRaw), &options)
|
||||
}
|
||||
|
||||
return normalizeTablePreferences(defaultPageSize, options)
|
||||
}
|
||||
|
||||
func normalizeTablePreferences(defaultPageSize int, options []int) (int, []int) {
|
||||
const minPageSize = 5
|
||||
const maxPageSize = 1000
|
||||
const fallbackPageSize = 20
|
||||
|
||||
seen := make(map[int]struct{}, len(options))
|
||||
normalizedOptions := make([]int, 0, len(options))
|
||||
for _, option := range options {
|
||||
if option < minPageSize || option > maxPageSize {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[option]; ok {
|
||||
continue
|
||||
}
|
||||
seen[option] = struct{}{}
|
||||
normalizedOptions = append(normalizedOptions, option)
|
||||
}
|
||||
sort.Ints(normalizedOptions)
|
||||
|
||||
if defaultPageSize < minPageSize || defaultPageSize > maxPageSize {
|
||||
defaultPageSize = fallbackPageSize
|
||||
}
|
||||
|
||||
if len(normalizedOptions) == 0 {
|
||||
normalizedOptions = []int{10, 20, 50}
|
||||
}
|
||||
|
||||
return defaultPageSize, normalizedOptions
|
||||
}
|
||||
|
||||
func containsInt(values []int, target int) bool {
|
||||
for _, value := range values {
|
||||
if value == target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// getStringOrDefault 获取字符串值或默认值
|
||||
func (s *SettingService) getStringOrDefault(settings map[string]string, key, defaultValue string) string {
|
||||
if value, ok := settings[key]; ok && value != "" {
|
||||
|
||||
Reference in New Issue
Block a user