package appconfig import ( "errors" "fmt" "strings" "unicode" "hyapp-admin-server/internal/model" "hyapp-admin-server/internal/repository" ) const h5LinkGroup = "h5-links" var h5LinkDefinitions = []H5LinkDefinition{ {Key: "host-center", Label: "Host Center"}, {Key: "bd-center", Label: "BD Center"}, {Key: "bd-leader-center", Label: "BD Leader Center"}, {Key: "agency-center", Label: "Agency Center"}, {Key: "invite-user", Label: "Invite User"}, } type AppConfigService struct { store *repository.Store } type H5LinkDefinition struct { Key string `json:"key"` Label string `json:"label"` } type H5Link struct { Key string `json:"key"` Label string `json:"label"` URL string `json:"url"` UpdatedAtMs int64 `json:"updatedAtMs"` } func NewService(store *repository.Store) *AppConfigService { return &AppConfigService{store: store} } func (s *AppConfigService) ListH5Links() ([]H5Link, error) { configs, err := s.store.ListAppConfigs(h5LinkGroup) if err != nil { return nil, err } configByKey := make(map[string]model.AppConfig, len(configs)) for _, config := range configs { configByKey[config.Key] = config } items := make([]H5Link, 0, len(h5LinkDefinitions)) for _, definition := range h5LinkDefinitions { item := H5Link{ Key: definition.Key, Label: definition.Label, } if config, ok := configByKey[definition.Key]; ok { item.URL = config.Value item.UpdatedAtMs = config.UpdatedAt.UnixMilli() } items = append(items, item) } return items, nil } func (s *AppConfigService) UpdateH5Links(request updateH5LinksRequest) ([]H5Link, error) { if len(request.Items) == 0 { return nil, errors.New("items are required") } allowed := h5LinkDefinitionSet() items := make([]model.AppConfig, 0, len(request.Items)) seen := make(map[string]struct{}, len(request.Items)) for _, item := range request.Items { key := strings.TrimSpace(item.Key) if _, ok := allowed[key]; !ok { return nil, fmt.Errorf("invalid h5 link key: %s", key) } if _, ok := seen[key]; ok { return nil, fmt.Errorf("duplicate h5 link key: %s", key) } seen[key] = struct{}{} link := strings.TrimSpace(item.URL) if err := validateH5URL(link); err != nil { return nil, err } items = append(items, model.AppConfig{ Group: h5LinkGroup, Key: key, Value: link, Description: allowed[key], }) } if err := s.store.UpsertAppConfigs(items); err != nil { return nil, err } return s.ListH5Links() } func h5LinkDefinitionSet() map[string]string { out := make(map[string]string, len(h5LinkDefinitions)) for _, definition := range h5LinkDefinitions { out[definition.Key] = definition.Label } return out } func validateH5URL(value string) error { if value == "" { return nil } if len(value) > 2048 { return errors.New("h5 link is too long") } for _, char := range value { if unicode.IsSpace(char) { return errors.New("h5 link cannot contain whitespace") } } return nil }