diff --git a/internal/api/http/handlers/donat/donat.go b/internal/api/http/handlers/donat/donat.go index 5ad0d91..183dbb8 100644 --- a/internal/api/http/handlers/donat/donat.go +++ b/internal/api/http/handlers/donat/donat.go @@ -248,14 +248,29 @@ func UpdateDonatePage(donatService model.DonatService, fileService model.FileSer // @Tags Donate // @Accept json // @Produce json +// @Security BearerAuth // @Success 200 {object} model.VoiceSettingsResponse "Current voice settings" // @Failure 400 {object} echo.HTTPError "Bad request" // @Failure 401 {object} echo.HTTPError "Unauthorized or expired token" // @Failure 422 {object} echo.HTTPError "Validation error" // @Router /voice-settings [get] func GetVoiceSettings(donatService model.DonatService) echo.HandlerFunc { - return func(c echo.Context) error { - return nil + return func(request echo.Context) error { + authData, err := donatService.CheckToken(request) + if err != nil { + slog.Error("Unauthorized") + return echo.NewHTTPError(http.StatusUnauthorized, err.Error()) + } + ctx := context.Background() + + voiceSettings, err := donatService.GetVoiceSettings(ctx, authData.AccountID) + if err != nil { + slog.Error("Failed to get voice settings", "error", err) + return echo.NewHTTPError(http.StatusInternalServerError, "Internal server error") + } + + // Возвращаем настройки голоса в JSON + return request.JSON(http.StatusOK, voiceSettings) } } diff --git a/internal/app/http/app.go b/internal/app/http/app.go index ff6b0ec..aa8f9a1 100644 --- a/internal/app/http/app.go +++ b/internal/app/http/app.go @@ -74,6 +74,7 @@ func IncludeDonatHandlers( server.GET(PREFIX+"/inner-donate-page", GetInnerDonatePage(donatService)) server.GET(PREFIX+"/outer-donate-page/:streamer-login", GetOuterDonatePage(donatService)) server.PATCH(PREFIX+"/donat-page", UpdateDonatePage(donatService, fileService)) + server.GET(PREFIX+"/voice-settings", GetVoiceSettings(donatService)) server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService)) diff --git a/internal/docs/docs.go b/internal/docs/docs.go index 2429059..685c244 100644 --- a/internal/docs/docs.go +++ b/internal/docs/docs.go @@ -527,6 +527,11 @@ const docTemplate = `{ }, "/voice-settings": { "get": { + "security": [ + { + "BearerAuth": [] + } + ], "description": "Get donat voice settings", "consumes": [ "application/json" @@ -1023,6 +1028,23 @@ const docTemplate = `{ } } }, + "donat-widget_internal_model.Language": { + "type": "object", + "properties": { + "en_name": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "iso_code": { + "type": "string" + }, + "ru_name": { + "type": "string" + } + } + }, "donat-widget_internal_model.ModerationResponse": { "type": "object", "properties": { @@ -1150,6 +1172,13 @@ const docTemplate = `{ "donat-widget_internal_model.VoiceSettingsResponse": { "type": "object", "properties": { + "languages": { + "description": "Новое поле", + "type": "array", + "items": { + "$ref": "#/definitions/donat-widget_internal_model.Language" + } + }, "min_price": { "type": "integer" }, diff --git a/internal/docs/swagger.json b/internal/docs/swagger.json index f22d563..a7f2af1 100644 --- a/internal/docs/swagger.json +++ b/internal/docs/swagger.json @@ -520,6 +520,11 @@ }, "/voice-settings": { "get": { + "security": [ + { + "BearerAuth": [] + } + ], "description": "Get donat voice settings", "consumes": [ "application/json" @@ -1016,6 +1021,23 @@ } } }, + "donat-widget_internal_model.Language": { + "type": "object", + "properties": { + "en_name": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "iso_code": { + "type": "string" + }, + "ru_name": { + "type": "string" + } + } + }, "donat-widget_internal_model.ModerationResponse": { "type": "object", "properties": { @@ -1143,6 +1165,13 @@ "donat-widget_internal_model.VoiceSettingsResponse": { "type": "object", "properties": { + "languages": { + "description": "Новое поле", + "type": "array", + "items": { + "$ref": "#/definitions/donat-widget_internal_model.Language" + } + }, "min_price": { "type": "integer" }, diff --git a/internal/docs/swagger.yaml b/internal/docs/swagger.yaml index 383ad68..cc82e80 100644 --- a/internal/docs/swagger.yaml +++ b/internal/docs/swagger.yaml @@ -165,6 +165,17 @@ definitions: example: image/png type: string type: object + donat-widget_internal_model.Language: + properties: + en_name: + type: string + id: + type: integer + iso_code: + type: string + ru_name: + type: string + type: object donat-widget_internal_model.ModerationResponse: properties: duration: @@ -252,6 +263,11 @@ definitions: type: object donat-widget_internal_model.VoiceSettingsResponse: properties: + languages: + description: Новое поле + items: + $ref: '#/definitions/donat-widget_internal_model.Language' + type: array min_price: type: integer scenery: @@ -627,6 +643,8 @@ paths: description: Validation error schema: $ref: '#/definitions/echo.HTTPError' + security: + - BearerAuth: [] summary: Get donat voice settings tags: - Donate diff --git a/internal/model/interfaces.go b/internal/model/interfaces.go index 2a5151a..efcda84 100644 --- a/internal/model/interfaces.go +++ b/internal/model/interfaces.go @@ -90,7 +90,7 @@ type DonatService interface { background multipart.FileHeader, headImg multipart.FileHeader, ) error - GetVoiceSettings(ctx context.Context, streamerID StreamerID) (VoiceSettingsResponse, error) + GetVoiceSettings(ctx context.Context, streamerID int) (VoiceSettingsResponse, error) UpdateVoiceSettings(ctx context.Context, streamerID StreamerID, updateModel UpdateVoiceSettings) error GetFiltersSettings(ctx context.Context, streamerID StreamerID) (FilterSettingResponse, error) @@ -120,6 +120,8 @@ type DonatRepo interface { description *string, textAfterDonation *string, ) error + GetVoiceSettingsByStreamerID(ctx context.Context, streamerID int) (VoiceSettingsResponse, error) + GetLanguagesByStreamerID(ctx context.Context, streamerID int) ([]Language, error) } type TargetService interface { diff --git a/internal/model/models.go b/internal/model/models.go index df7c1cd..32294de 100644 --- a/internal/model/models.go +++ b/internal/model/models.go @@ -170,13 +170,6 @@ type VoiceSettings struct { MinPrice int `db:"min_price"` } -type Language struct { - ID int `db:"id"` - IsoCode string `db:"iso_code"` - RuName string `db:"ru_name"` - EnName string `db:"en_name"` -} - type VoiceLanguage struct { ID int `db:"id"` VoiceSettingID int `db:"voice_setting_id"` @@ -190,11 +183,19 @@ type UpdateDonatPage struct { PageBackground *string `json:"page_background,omitempty" form:"page_background" example:"#13161E" description:"Color code"` } +type Language struct { + ID int `json:"id" db:"language_id"` + ISOCode string `json:"iso_code" db:"iso_code"` + RUName string `json:"ru_name" db:"ru_name"` + ENName string `json:"en_name" db:"en_name"` +} + type VoiceSettingsResponse struct { - VoiceSpeed int `json:"voice_speed"` - Scenery string `json:"scenery"` - VoiceSoundPercent int `json:"voice_sound_percent"` - MinPrice int `json:"min_price"` + VoiceSpeed int `json:"voice_speed"` + Scenery string `json:"scenery"` + VoiceSoundPercent int `json:"voice_sound_percent"` + MinPrice int `json:"min_price"` + Languages []Language `json:"languages"` // Новое поле } type UpdateVoiceSettings struct { diff --git a/internal/model/sql/query.go b/internal/model/sql/query.go index 7fc51d1..e329d9b 100644 --- a/internal/model/sql/query.go +++ b/internal/model/sql/query.go @@ -226,3 +226,25 @@ SET WHERE streamer_id = @streamer_id RETURNING *; ` + +var GetVoiceSettingsByStreamerID = ` +SELECT + voice_speed, + scenery, + voice_sound_percent, + min_price +FROM voice_settings +WHERE streamer_id = (@streamer_id); +` + +var GetLanguagesByStreamerID = ` + SELECT + l.id AS language_id, + l.iso_code, + l.ru_name, + l.en_name + FROM languages l + JOIN voices_languages vl ON l.id = vl.language_id + JOIN voice_settings vs ON vl.voice_setting_id = vs.id + WHERE vs.streamer_id = (@streamer_id); +` diff --git a/internal/repository/donat/donat.go b/internal/repository/donat/donat.go index 7ab35f2..5333774 100644 --- a/internal/repository/donat/donat.go +++ b/internal/repository/donat/donat.go @@ -218,3 +218,64 @@ func (repoDonat *RepoDonat) UpdateDonatePage( return nil } + +func (repoDonat *RepoDonat) GetLanguagesByStreamerID(ctx context.Context, streamerID int) ([]model.Language, error) { + args := pgx.NamedArgs{ + "streamer_id": streamerID, + } + + // Выполняем SQL-запрос + rows, err := repoDonat.db.Select(ctx, sql.GetLanguagesByStreamerID, args) + if err != nil { + slog.Error("Failed to execute query", "error", err) + return nil, err + } + + // Сканируем результаты в структуру Language + var languages []*model.Language + err = pgxscan.ScanAll(&languages, rows) + if err != nil { + slog.Error("Failed to scan rows", "error", err) + return nil, err + } + + // Проверяем ошибки, которые могли возникнуть при итерации по строкам + if err := rows.Err(); err != nil { + slog.Error("Error during rows iteration", "error", err) + return nil, err + } + + // Преобразуем []*model.Language в []model.Language + result := make([]model.Language, len(languages)) + for i, lang := range languages { + result[i] = *lang + } + + return result, nil +} + +func (repoDonat *RepoDonat) GetVoiceSettingsByStreamerID( + ctx context.Context, + streamerID int, +) (model.VoiceSettingsResponse, error) { + args := pgx.NamedArgs{ + "streamer_id": streamerID, + } + rows, err := repoDonat.db.Select(ctx, sql.GetVoiceSettingsByStreamerID, args) + if err != nil { + slog.Error(err.Error()) + return model.VoiceSettingsResponse{}, err + } + + var voiceSettings []*model.VoiceSettingsResponse + err = pgxscan.ScanAll(&voiceSettings, rows) + if err != nil { + slog.Error(err.Error()) + return model.VoiceSettingsResponse{}, err + } + if len(voiceSettings) == 0 { + return model.VoiceSettingsResponse{}, errors.New("voice settings not found") + } + + return *voiceSettings[0], nil +} diff --git a/internal/service/donat/donat.go b/internal/service/donat/donat.go index 2188473..19482b6 100644 --- a/internal/service/donat/donat.go +++ b/internal/service/donat/donat.go @@ -282,9 +282,30 @@ func (donatService *ServiceDonat) UpdateDonatePage( func (donatService *ServiceDonat) GetVoiceSettings( ctx context.Context, - streamerID model.StreamerID, + streamerID int, ) (model.VoiceSettingsResponse, error) { - return model.VoiceSettingsResponse{}, nil + voiceSettings, err := donatService.donatRepo.GetVoiceSettingsByStreamerID(ctx, streamerID) + if err != nil { + slog.Error("Failed to get voice settings", "error", err) + return model.VoiceSettingsResponse{}, err + } + + languages, err := donatService.donatRepo.GetLanguagesByStreamerID(ctx, streamerID) + if err != nil { + slog.Error("Failed to get languages", "error", err) + return model.VoiceSettingsResponse{}, err + } + + // Расширяем структуру VoiceSettingsResponse + response := model.VoiceSettingsResponse{ + VoiceSpeed: voiceSettings.VoiceSpeed, + Scenery: voiceSettings.Scenery, + VoiceSoundPercent: voiceSettings.VoiceSoundPercent, + MinPrice: voiceSettings.MinPrice, + Languages: languages, + } + + return response, nil } func (donatService *ServiceDonat) UpdateVoiceSettings(