package service import ( "strings" "gorm.io/gorm" "nl-pms-api/internal/commonservice" "nl-pms-api/internal/model" ) // SettingsService 用户设置与全局资源(fest_img:* / file_storage)。 type SettingsService struct { DB *gorm.DB } func isGlobalSetting(name string) bool { return name == "file_storage" || strings.HasPrefix(name, "fest_img:") } func settingOwner(userID int64, name string) int64 { if isGlobalSetting(name) { return commonservice.AdminUserID } return userID } // GetSetting 读取单条设置;全局键从管理员账号读。 func (s *SettingsService) GetSetting(userID int64, name string) (*model.SyncSetting, error) { name = strings.TrimSpace(name) if name == "" { return nil, commonservice.BadRequest("SETTING_NAME_REQUIRED") } owner := settingOwner(userID, name) var row model.SyncSetting if err := s.DB.Where("user_id = ? AND name = ?", owner, name).First(&row).Error; err != nil { if err == gorm.ErrRecordNotFound { return nil, commonservice.NotFound("NOT_FOUND") } return nil, commonservice.Internal("QUERY_FAILED") } return &row, nil } // ListByPrefix 按前缀批量拉取(如 fest_img:),全局前缀从管理员账号读。 func (s *SettingsService) ListByPrefix(userID int64, prefix string) ([]model.SyncSetting, error) { prefix = strings.TrimSpace(prefix) if prefix == "" { return nil, commonservice.BadRequest("SETTING_PREFIX_REQUIRED") } owner := userID if strings.HasPrefix(prefix, "fest_img:") || prefix == "fest_img:" { owner = commonservice.AdminUserID } var rows []model.SyncSetting if err := s.DB.Where("user_id = ? AND name LIKE ?", owner, prefix+"%"). Order("name").Find(&rows).Error; err != nil { return nil, commonservice.Internal("QUERY_FAILED") } if rows == nil { rows = []model.SyncSetting{} } return rows, nil } // GetGlobal 读取挂在管理员名下的全局设置。 func (s *SettingsService) GetGlobal(name string) (*model.SyncSetting, error) { return s.GetSetting(commonservice.AdminUserID, name) } // PutSetting LWW 写入;全局键仅管理员可写,且落在 user_id=1。 func (s *SettingsService) PutSetting(userID int64, name, value, updatedAt string) error { name = strings.TrimSpace(name) if name == "" { return commonservice.BadRequest("SETTING_NAME_REQUIRED") } if updatedAt == "" { updatedAt = commonservice.NowRFC() } owner := userID if isGlobalSetting(name) { if userID != commonservice.AdminUserID { return commonservice.Forbidden("FORBIDDEN") } owner = commonservice.AdminUserID } q := `INSERT INTO sync_settings(user_id,name,value,updated_at) VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE value=IF(VALUES(updated_at)>updated_at,VALUES(value),value), updated_at=IF(VALUES(updated_at)>updated_at,VALUES(updated_at),updated_at)` if err := s.DB.Exec(q, owner, name, value, updatedAt).Error; err != nil { return commonservice.Internal("SAVE_FAILED") } return nil }