add handler for voice settings

This commit is contained in:
harold 2025-03-08 23:01:41 +05:00
parent bd2843ff4e
commit 9f8bf11a82
10 changed files with 215 additions and 16 deletions

View File

@ -248,14 +248,29 @@ func UpdateDonatePage(donatService model.DonatService, fileService model.FileSer
// @Tags Donate // @Tags Donate
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Security BearerAuth
// @Success 200 {object} model.VoiceSettingsResponse "Current voice settings" // @Success 200 {object} model.VoiceSettingsResponse "Current voice settings"
// @Failure 400 {object} echo.HTTPError "Bad request" // @Failure 400 {object} echo.HTTPError "Bad request"
// @Failure 401 {object} echo.HTTPError "Unauthorized or expired token" // @Failure 401 {object} echo.HTTPError "Unauthorized or expired token"
// @Failure 422 {object} echo.HTTPError "Validation error" // @Failure 422 {object} echo.HTTPError "Validation error"
// @Router /voice-settings [get] // @Router /voice-settings [get]
func GetVoiceSettings(donatService model.DonatService) echo.HandlerFunc { func GetVoiceSettings(donatService model.DonatService) echo.HandlerFunc {
return func(c echo.Context) error { return func(request echo.Context) error {
return nil 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)
} }
} }

View File

@ -74,6 +74,7 @@ func IncludeDonatHandlers(
server.GET(PREFIX+"/inner-donate-page", GetInnerDonatePage(donatService)) server.GET(PREFIX+"/inner-donate-page", GetInnerDonatePage(donatService))
server.GET(PREFIX+"/outer-donate-page/:streamer-login", GetOuterDonatePage(donatService)) server.GET(PREFIX+"/outer-donate-page/:streamer-login", GetOuterDonatePage(donatService))
server.PATCH(PREFIX+"/donat-page", UpdateDonatePage(donatService, fileService)) server.PATCH(PREFIX+"/donat-page", UpdateDonatePage(donatService, fileService))
server.GET(PREFIX+"/voice-settings", GetVoiceSettings(donatService))
server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService)) server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService))

View File

@ -527,6 +527,11 @@ const docTemplate = `{
}, },
"/voice-settings": { "/voice-settings": {
"get": { "get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get donat voice settings", "description": "Get donat voice settings",
"consumes": [ "consumes": [
"application/json" "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": { "donat-widget_internal_model.ModerationResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -1150,6 +1172,13 @@ const docTemplate = `{
"donat-widget_internal_model.VoiceSettingsResponse": { "donat-widget_internal_model.VoiceSettingsResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
"languages": {
"description": "Новое поле",
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.Language"
}
},
"min_price": { "min_price": {
"type": "integer" "type": "integer"
}, },

View File

@ -520,6 +520,11 @@
}, },
"/voice-settings": { "/voice-settings": {
"get": { "get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get donat voice settings", "description": "Get donat voice settings",
"consumes": [ "consumes": [
"application/json" "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": { "donat-widget_internal_model.ModerationResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -1143,6 +1165,13 @@
"donat-widget_internal_model.VoiceSettingsResponse": { "donat-widget_internal_model.VoiceSettingsResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
"languages": {
"description": "Новое поле",
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.Language"
}
},
"min_price": { "min_price": {
"type": "integer" "type": "integer"
}, },

View File

@ -165,6 +165,17 @@ definitions:
example: image/png example: image/png
type: string type: string
type: object 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: donat-widget_internal_model.ModerationResponse:
properties: properties:
duration: duration:
@ -252,6 +263,11 @@ definitions:
type: object type: object
donat-widget_internal_model.VoiceSettingsResponse: donat-widget_internal_model.VoiceSettingsResponse:
properties: properties:
languages:
description: Новое поле
items:
$ref: '#/definitions/donat-widget_internal_model.Language'
type: array
min_price: min_price:
type: integer type: integer
scenery: scenery:
@ -627,6 +643,8 @@ paths:
description: Validation error description: Validation error
schema: schema:
$ref: '#/definitions/echo.HTTPError' $ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Get donat voice settings summary: Get donat voice settings
tags: tags:
- Donate - Donate

View File

@ -90,7 +90,7 @@ type DonatService interface {
background multipart.FileHeader, background multipart.FileHeader,
headImg multipart.FileHeader, headImg multipart.FileHeader,
) error ) 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 UpdateVoiceSettings(ctx context.Context, streamerID StreamerID, updateModel UpdateVoiceSettings) error
GetFiltersSettings(ctx context.Context, streamerID StreamerID) (FilterSettingResponse, error) GetFiltersSettings(ctx context.Context, streamerID StreamerID) (FilterSettingResponse, error)
@ -120,6 +120,8 @@ type DonatRepo interface {
description *string, description *string,
textAfterDonation *string, textAfterDonation *string,
) error ) error
GetVoiceSettingsByStreamerID(ctx context.Context, streamerID int) (VoiceSettingsResponse, error)
GetLanguagesByStreamerID(ctx context.Context, streamerID int) ([]Language, error)
} }
type TargetService interface { type TargetService interface {

View File

@ -170,13 +170,6 @@ type VoiceSettings struct {
MinPrice int `db:"min_price"` 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 { type VoiceLanguage struct {
ID int `db:"id"` ID int `db:"id"`
VoiceSettingID int `db:"voice_setting_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"` 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 { type VoiceSettingsResponse struct {
VoiceSpeed int `json:"voice_speed"` VoiceSpeed int `json:"voice_speed"`
Scenery string `json:"scenery"` Scenery string `json:"scenery"`
VoiceSoundPercent int `json:"voice_sound_percent"` VoiceSoundPercent int `json:"voice_sound_percent"`
MinPrice int `json:"min_price"` MinPrice int `json:"min_price"`
Languages []Language `json:"languages"` // Новое поле
} }
type UpdateVoiceSettings struct { type UpdateVoiceSettings struct {

View File

@ -226,3 +226,25 @@ SET
WHERE streamer_id = @streamer_id WHERE streamer_id = @streamer_id
RETURNING *; 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);
`

View File

@ -218,3 +218,64 @@ func (repoDonat *RepoDonat) UpdateDonatePage(
return nil 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
}

View File

@ -282,9 +282,30 @@ func (donatService *ServiceDonat) UpdateDonatePage(
func (donatService *ServiceDonat) GetVoiceSettings( func (donatService *ServiceDonat) GetVoiceSettings(
ctx context.Context, ctx context.Context,
streamerID model.StreamerID, streamerID int,
) (model.VoiceSettingsResponse, error) { ) (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( func (donatService *ServiceDonat) UpdateVoiceSettings(