925 lines
20 KiB
Go
925 lines
20 KiB
Go
package donat
|
|
|
|
import (
|
|
"context"
|
|
"donat-widget/internal/model"
|
|
"donat-widget/internal/model/sql"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/georgysavva/scany/v2/pgxscan"
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5"
|
|
"log/slog"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func New(db model.Db) *RepoDonat {
|
|
return &RepoDonat{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
type RepoDonat struct {
|
|
db model.Db
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) CreateDonat(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
targetID *int,
|
|
widgetID int,
|
|
orderID uuid.UUID,
|
|
amount int,
|
|
text string,
|
|
donatUser string,
|
|
status string,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
"widget_id": widgetID,
|
|
"order_id": orderID,
|
|
"target_id": targetID,
|
|
"text": text,
|
|
"amount": amount,
|
|
"status": status,
|
|
"donat_user": donatUser,
|
|
"is_test": false,
|
|
}
|
|
|
|
if status == "test_donat" {
|
|
args["is_test"] = true
|
|
args["paid_time"] = time.Now().UTC()
|
|
}
|
|
|
|
_, err := repoDonat.db.Insert(ctx, sql.CreateDonat, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonatsByStreamerID(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
page int,
|
|
limit int,
|
|
) ([]*model.Donat, error) {
|
|
offset := (page - 1) * limit
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
"paid": true,
|
|
"offset": offset,
|
|
"page": page,
|
|
}
|
|
rows, err := repoDonat.db.Select(ctx, sql.GetDonatByStreamerID, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var donats []*model.Donat
|
|
err = pgxscan.ScanAll(&donats, rows)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return nil, err
|
|
}
|
|
|
|
return donats, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonatByOrderID(
|
|
ctx context.Context,
|
|
orderID string,
|
|
) (*model.Donat, error) {
|
|
args := pgx.NamedArgs{
|
|
"order_id": orderID,
|
|
}
|
|
rows, err := repoDonat.db.Select(ctx, sql.GetDonatByOrderID, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var donats []*model.Donat
|
|
err = pgxscan.ScanAll(&donats, rows)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return nil, err
|
|
}
|
|
if len(donats) == 0 {
|
|
return nil, errors.New("donat not found")
|
|
}
|
|
|
|
return donats[0], nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) MarkDonatView(
|
|
ctx context.Context,
|
|
orderID string,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"order_id": orderID,
|
|
}
|
|
err := repoDonat.db.Update(ctx, sql.MarkDonatView, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) MarkDonatPaid(
|
|
ctx context.Context,
|
|
orderID string,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"order_id": orderID,
|
|
}
|
|
err := repoDonat.db.Update(ctx, sql.MarkDonatPaid, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonatPage(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (model.DonatePage, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
rows, err := repoDonat.db.Select(ctx, sql.GetDonationPage, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return model.DonatePage{}, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var donatePage []*model.DonatePage
|
|
err = pgxscan.ScanAll(&donatePage, rows)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return model.DonatePage{}, err
|
|
}
|
|
if len(donatePage) == 0 {
|
|
return model.DonatePage{}, errors.New("donat not found")
|
|
}
|
|
|
|
return *donatePage[0], nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonatPageByLogin(
|
|
ctx context.Context,
|
|
streamerLogin string,
|
|
) (model.DonatePage, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_login": streamerLogin,
|
|
}
|
|
rows, err := repoDonat.db.Select(ctx, sql.GetDonationPageByLogin, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return model.DonatePage{}, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var donatePage []*model.DonatePage
|
|
err = pgxscan.ScanAll(&donatePage, rows)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return model.DonatePage{}, err
|
|
}
|
|
if len(donatePage) == 0 {
|
|
return model.DonatePage{}, nil
|
|
}
|
|
|
|
return *donatePage[0], nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) UpdateDonatePage(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
backgroundFileID *string,
|
|
headImgFileID *string,
|
|
avatarFileID *string,
|
|
description *string,
|
|
textAfterDonation *string,
|
|
profileAvatar *bool,
|
|
pageBackground *string,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
if backgroundFileID != nil {
|
|
args["background_img"] = *backgroundFileID
|
|
}
|
|
if headImgFileID != nil {
|
|
args["head_img"] = *headImgFileID
|
|
}
|
|
if avatarFileID != nil {
|
|
args["avatar"] = *avatarFileID
|
|
}
|
|
if description != nil {
|
|
args["description"] = *description
|
|
}
|
|
if textAfterDonation != nil {
|
|
args["text_after_donat"] = *textAfterDonation
|
|
}
|
|
if pageBackground != nil {
|
|
args["page_background"] = *pageBackground
|
|
}
|
|
if profileAvatar != nil {
|
|
args["profile_avatar"] = *profileAvatar
|
|
}
|
|
|
|
err := repoDonat.db.Exec(ctx, sql.UpdateDonatePage, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return err
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
// Сканируем результаты в структуру 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
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
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
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) DeleteLanguagesByVoiceSettingID(
|
|
ctx context.Context,
|
|
voiceSettingID int,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"voice_setting_id": voiceSettingID,
|
|
}
|
|
|
|
err := repoDonat.db.Exec(ctx, sql.DeleteLanguage, args)
|
|
if err != nil {
|
|
slog.Error("Failed to delete languages", "error", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) InsertLanguagesForVoiceSetting(
|
|
ctx context.Context,
|
|
voiceSettingID int,
|
|
languageIDs []int,
|
|
) error {
|
|
if len(languageIDs) == 0 {
|
|
return nil // Нет языков для вставки
|
|
}
|
|
|
|
// Формируем список значений для вставки
|
|
var valueStrings []string
|
|
var valueArgs []interface{}
|
|
for i, languageID := range languageIDs {
|
|
valueStrings = append(valueStrings, fmt.Sprintf("($%d, $%d)", i*2+1, i*2+2))
|
|
valueArgs = append(valueArgs, voiceSettingID, languageID)
|
|
}
|
|
|
|
query := fmt.Sprintf(sql.InsertLanguagesForVoiceSetting, strings.Join(valueStrings, ","))
|
|
err := repoDonat.db.Exec(ctx, query, valueArgs...)
|
|
if err != nil {
|
|
slog.Error("Failed to insert languages", "error", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetLanguageIDsByISOCodes(
|
|
ctx context.Context,
|
|
isoCodes []string,
|
|
) ([]int, error) {
|
|
args := pgx.NamedArgs{
|
|
"iso_codes": isoCodes,
|
|
}
|
|
|
|
rows, err := repoDonat.db.Select(ctx, sql.GetLangByISO, args)
|
|
if err != nil {
|
|
slog.Error("Failed to get language IDs by ISO codes", "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var languageIDs []int
|
|
for rows.Next() {
|
|
var languageID int
|
|
err := rows.Scan(&languageID)
|
|
if err != nil {
|
|
slog.Error("Failed to scan language ID", "error", err)
|
|
return nil, err
|
|
}
|
|
languageIDs = append(languageIDs, languageID)
|
|
}
|
|
|
|
if err := rows.Err(); err != nil {
|
|
slog.Error("Error during rows iteration", "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
return languageIDs, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetVoiceSettingIDByStreamerID(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (int, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
var voiceSettingID int
|
|
row := repoDonat.db.SelectOne(ctx, sql.VoiceIDByStreamer, args)
|
|
|
|
err := row.Scan(&voiceSettingID)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return 0, err
|
|
}
|
|
|
|
return voiceSettingID, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) UpdateVoiceSettings(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
settings model.UpdateVoiceSettings,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
// Добавляем только те поля, которые не nil
|
|
if settings.Enable != nil {
|
|
args["enable"] = *settings.Enable
|
|
}
|
|
if settings.VoiceSpeed != nil {
|
|
args["voice_speed"] = *settings.VoiceSpeed
|
|
}
|
|
if settings.Scenery != nil {
|
|
args["scenery"] = *settings.Scenery
|
|
}
|
|
if settings.VoiceSoundPercent != nil {
|
|
args["voice_sound_percent"] = *settings.VoiceSoundPercent
|
|
}
|
|
if settings.MinPrice != nil {
|
|
args["min_price"] = *settings.MinPrice
|
|
}
|
|
|
|
// Выполняем SQL-запрос
|
|
err := repoDonat.db.Update(ctx, sql.UpdateVoiceSettings, args)
|
|
if err != nil {
|
|
slog.Error("Failed to update voice settings", "error", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetFilterSettingsByStreamerID(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (int, bool, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
row := repoDonat.db.SelectOne(ctx, sql.GetFilterSettings, args)
|
|
|
|
var filterSettingID int
|
|
var enableLinks bool
|
|
err := row.Scan(&filterSettingID, &enableLinks)
|
|
if err != nil {
|
|
slog.Error("Failed to scan filter settings", "error", err)
|
|
return 0, false, err
|
|
}
|
|
|
|
return filterSettingID, enableLinks, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetFilteredWords(
|
|
ctx context.Context,
|
|
filterId int,
|
|
) ([]string, error) {
|
|
args := pgx.NamedArgs{
|
|
"donat_filter_id": filterId,
|
|
}
|
|
rows, err := repoDonat.db.Select(ctx, sql.GetFilterWords, args)
|
|
if err != nil {
|
|
slog.Error("Failed to get filter settings", "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var filterWords []string
|
|
err = pgxscan.ScanAll(&filterWords, rows)
|
|
if err != nil {
|
|
slog.Error("Failed to scan filter settings", "error", err)
|
|
return nil, err
|
|
}
|
|
|
|
return filterWords, nil
|
|
}
|
|
|
|
func (repoDonat RepoDonat) UpdateFilterSettings(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
enableLinks *bool,
|
|
) error {
|
|
if enableLinks != nil {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
"enable_links": enableLinks,
|
|
}
|
|
|
|
err := repoDonat.db.Exec(ctx, sql.UpdateFilterSettings, args)
|
|
if err != nil {
|
|
slog.Error("Failed to update filter settings", "error", err)
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetFilterIDByStreamer(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (int, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
row := repoDonat.db.SelectOne(ctx, sql.GetFilterIdByStreamerID, args)
|
|
var filterID int
|
|
err := row.Scan(&filterID)
|
|
if err != nil {
|
|
slog.Error("Failed to scan filter settings", "error", err)
|
|
return 0, err
|
|
}
|
|
|
|
return filterID, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) AddFilteredWords(
|
|
ctx context.Context,
|
|
filterID int,
|
|
words []string,
|
|
) error {
|
|
if len(words) == 0 {
|
|
return nil
|
|
}
|
|
|
|
var valueStrings []string
|
|
var valueArgs []interface{}
|
|
for i, word := range words {
|
|
valueStrings = append(valueStrings, fmt.Sprintf("($%d, $%d)", i*2+1, i*2+2))
|
|
valueArgs = append(valueArgs, filterID, word)
|
|
}
|
|
|
|
query := fmt.Sprintf(sql.InsertFilteredWordsBatch, strings.Join(valueStrings, ","))
|
|
|
|
err := repoDonat.db.Exec(ctx, query, valueArgs...)
|
|
if err != nil {
|
|
slog.Error("Failed to add filtered words", "error", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) RemoveFilteredWords(
|
|
ctx context.Context,
|
|
filterID int,
|
|
words []string,
|
|
) error {
|
|
if len(words) == 0 {
|
|
return nil // Нет слов для удаления
|
|
}
|
|
|
|
args := pgx.NamedArgs{
|
|
"donat_filter_id": filterID,
|
|
"words": words,
|
|
}
|
|
|
|
err := repoDonat.db.Exec(ctx, sql.DeleteFilteredWordsBatch, args)
|
|
if err != nil {
|
|
slog.Error("Failed to remove filtered words", "error", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetModeration(ctx context.Context, streamerID int) (model.ModerationResponse, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
row := repoDonat.db.SelectOne(ctx, sql.GetModeration, args)
|
|
|
|
var response model.ModerationResponse
|
|
err := row.Scan(&response.Enable, &response.Duration)
|
|
if err != nil {
|
|
slog.Error("Failed to get moderation state", "error", err)
|
|
return model.ModerationResponse{}, err
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) UpdateModeration(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
enable *bool,
|
|
duration *int,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
if enable != nil {
|
|
args["enable"] = enable
|
|
}
|
|
if duration != nil {
|
|
args["duration"] = duration
|
|
}
|
|
err := repoDonat.db.Exec(ctx, sql.UpdateModeration, args)
|
|
if err != nil {
|
|
slog.Error("Failed to update moderation state", "error", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonationsStats(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
period string, // "24h", "7d", "1m", "1y"
|
|
) ([]model.DonationStat, error) {
|
|
var query string
|
|
switch period {
|
|
case "24h":
|
|
query = sql.GetDonationsLast24Hours
|
|
case "7d":
|
|
query = sql.GetDonationsLast7Days
|
|
case "1m":
|
|
query = sql.GetDonationsLastMonth
|
|
case "1y":
|
|
query = sql.GetDonationsLastYear
|
|
default:
|
|
return nil, errors.New("invalid period")
|
|
}
|
|
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
rows, err := repoDonat.db.Select(ctx, query, args)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
defer rows.Close()
|
|
|
|
var stats []model.DonationStat
|
|
err = pgxscan.ScanAll(&stats, rows)
|
|
if err != nil {
|
|
slog.Error(err.Error())
|
|
return nil, err
|
|
}
|
|
|
|
return stats, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonationsSummary(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
period string, // "24h", "7d", "1m", "1y"
|
|
) (model.DonationSummary, error) {
|
|
var query string
|
|
switch period {
|
|
case "24h":
|
|
query = sql.GetDonationsSummaryLast24Hours
|
|
case "7d":
|
|
query = sql.GetDonationsSummaryLast7Days
|
|
case "1m":
|
|
query = sql.GetDonationsSummaryLastMonth
|
|
case "1y":
|
|
query = sql.GetDonationsSummaryLastYear
|
|
default:
|
|
return model.DonationSummary{}, errors.New("invalid period")
|
|
}
|
|
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
|
|
var summary model.DonationSummary
|
|
row := repoDonat.db.SelectOne(ctx, query, args)
|
|
|
|
err := row.Scan(&summary.TotalAmount, &summary.DonationsCount)
|
|
if err != nil {
|
|
slog.Error("Failed to get donations summary", "error", err)
|
|
return model.DonationSummary{}, err
|
|
}
|
|
|
|
return summary, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetDonatModeration(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (model.DonationModeration, error) {
|
|
var donation model.DonationModeration
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
row := repoDonat.db.SelectOne(ctx, sql.GetLastModeration, args)
|
|
|
|
if row == nil {
|
|
return model.DonationModeration{}, nil
|
|
}
|
|
err := row.Scan(
|
|
&donation.ID,
|
|
&donation.TargetID,
|
|
&donation.Status,
|
|
&donation.Text,
|
|
&donation.Amount,
|
|
&donation.DonatUser,
|
|
&donation.AcceptedTime,
|
|
&donation.ShowName,
|
|
&donation.ShowText,
|
|
&donation.PlayContent,
|
|
&donation.CreatedAt,
|
|
&donation.UpdatedAt,
|
|
)
|
|
if err != nil {
|
|
slog.Error("Failed to get latest donation in moderation", "error", err)
|
|
return model.DonationModeration{}, err
|
|
}
|
|
|
|
return donation, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) ModerateDonation(
|
|
ctx context.Context,
|
|
donatID int,
|
|
streamerID int,
|
|
updateModel model.ModerationDonat,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"donat_id": donatID,
|
|
"streamer_id": streamerID,
|
|
"show_name": updateModel.ShowName,
|
|
"show_text": updateModel.ShowText,
|
|
"play_content": updateModel.PlayContent,
|
|
}
|
|
if updateModel.Accepted != nil {
|
|
if *updateModel.Accepted {
|
|
args["accepted_time"] = time.Now()
|
|
args["status"] = "accepted_moderation"
|
|
} else {
|
|
args["rejected_time"] = time.Now()
|
|
args["status"] = "rejected_moderation"
|
|
}
|
|
}
|
|
|
|
err := repoDonat.db.Exec(ctx, sql.ModerateDonat, args)
|
|
if err != nil {
|
|
slog.Error("Failed to update donat", "error", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) InitNewStreamer(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
login string,
|
|
defaultAvatar string,
|
|
defaultBackground string,
|
|
defaultHead string,
|
|
) error {
|
|
donateArgs := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
"streamer_login": login,
|
|
"avatar": defaultAvatar,
|
|
"background_img": defaultBackground,
|
|
"head_img": defaultHead,
|
|
}
|
|
if err := repoDonat.db.Exec(ctx, sql.InitDonatePage, donateArgs); err != nil {
|
|
slog.Error("Failed to init donate page", "error", err)
|
|
return fmt.Errorf("failed to create donate page: %w", err)
|
|
}
|
|
|
|
if err := repoDonat.db.Exec(ctx, sql.InitFilters, pgx.NamedArgs{"streamer_id": streamerID}); err != nil {
|
|
slog.Error("Failed to init filters", "error", err)
|
|
return fmt.Errorf("failed to create filters: %w", err)
|
|
}
|
|
|
|
if err := repoDonat.db.Exec(ctx, sql.InitModeration, pgx.NamedArgs{"streamer_id": streamerID}); err != nil {
|
|
slog.Error("Failed to init moderation", "error", err)
|
|
return fmt.Errorf("failed to create moderation: %w", err)
|
|
}
|
|
|
|
voiceArgs := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
"voice_speed": "medium",
|
|
"voice_sound_percent": 80,
|
|
"min_price": 100,
|
|
}
|
|
if err := repoDonat.db.Exec(ctx, sql.InitVoiceSettings, voiceArgs); err != nil {
|
|
slog.Error("Failed to init voice settings", "error", err)
|
|
return fmt.Errorf("failed to create voice settings: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetPlayingDonat(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (model.PlayingDonat, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
row := repoDonat.db.SelectOne(ctx, sql.GetPlayingDonats, args)
|
|
|
|
if row == nil {
|
|
return model.PlayingDonat{}, nil
|
|
}
|
|
var donatForPlaying model.PlayingDonat
|
|
err := row.Scan(
|
|
&donatForPlaying.Duration,
|
|
&donatForPlaying.Image,
|
|
&donatForPlaying.Audio,
|
|
&donatForPlaying.Text,
|
|
&donatForPlaying.Amount,
|
|
&donatForPlaying.OrderID,
|
|
&donatForPlaying.DonatUser,
|
|
&donatForPlaying.PlayContent,
|
|
&donatForPlaying.ShowName,
|
|
&donatForPlaying.ShowText,
|
|
)
|
|
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return model.PlayingDonat{}, nil
|
|
}
|
|
slog.Error("Failed to get playing donats", "error", err)
|
|
return model.PlayingDonat{}, err
|
|
}
|
|
return donatForPlaying, nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) UpdateStreamerLogin(
|
|
ctx context.Context,
|
|
streamerLogin string,
|
|
streamerID int,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
"streamer_login": streamerLogin,
|
|
}
|
|
row := repoDonat.db.InsertReturningObj(ctx, sql.UpdateStreamerLogin, args)
|
|
|
|
var updatedStreamerLogin string
|
|
err := row.Scan(&updatedStreamerLogin)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if updatedStreamerLogin != streamerLogin {
|
|
return errors.New("streamer login mismatch")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) CreateStreamerOnline(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) error {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
err := repoDonat.db.Exec(ctx, sql.InsertStreamerOnline, args)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (repoDonat *RepoDonat) GetLastStreamerOnline(
|
|
ctx context.Context,
|
|
streamerID int,
|
|
) (time.Time, error) {
|
|
args := pgx.NamedArgs{
|
|
"streamer_id": streamerID,
|
|
}
|
|
row := repoDonat.db.SelectOne(ctx, sql.GetLastStreamerOnline, args)
|
|
|
|
var StreamerOnline time.Time
|
|
|
|
err := row.Scan(&StreamerOnline)
|
|
if err != nil {
|
|
return StreamerOnline, err
|
|
}
|
|
return StreamerOnline, nil
|
|
}
|