add rotuer for get donats

This commit is contained in:
harold 2025-03-12 11:26:25 +05:00
parent 5bebbd7521
commit aa993278b9
14 changed files with 922 additions and 217 deletions

View File

@ -6,7 +6,6 @@ import (
_ "donat-widget/internal/model/api"
"donat-widget/pkg/custom_response"
"donat-widget/pkg/validator"
"fmt"
"github.com/labstack/echo/v4"
"log/slog"
"mime/multipart"
@ -56,16 +55,46 @@ func CreateDonat(donatService model.DonatService) echo.HandlerFunc {
}
}
// GetDonat godoc
// @Summary Get donats
// @Description Получает список донатов для указанного стримера с пагинацией
// @Tags Donate
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "Номер страницы (по умолчанию 1)" default(1)
// @Param limit query int false "Количество элементов на странице (по умолчанию 10)" default(10)
// @Success 200 {array} model.Donat "Успешный возврат списка донатов"
// @Failure 400 {object} echo.HTTPError "Некорректный формат streamerID"
// @Failure 500 {object} echo.HTTPError "Внутренняя ошибка сервера"
// @Router /donat [get]
func GetDonat(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error {
ctx := context.Background()
streamerID, err := strconv.Atoi(request.Param("streamerID"))
fmt.Println(streamerID)
page, err := strconv.Atoi(request.QueryParam("page"))
if page == 0 || err != nil {
page = 1
}
limit, err := strconv.Atoi(request.QueryParam("limit"))
if limit == 0 || err != nil {
limit = 20
}
authData, err := donatService.CheckToken(request)
if err != nil {
slog.Error("Unauthorized")
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
}
if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
}
donats, err := donatService.GetDonatByStreamerID(ctx, model.StreamerID(streamerID))
donats, err := donatService.GetDonatsByStreamerID(
ctx,
authData.AccountID,
page,
limit,
)
if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
@ -79,7 +108,7 @@ func GetDonat(donatService model.DonatService) echo.HandlerFunc {
func MarkDonatPaid(donatService model.DonatService) echo.HandlerFunc {
type MarkDonatPaidBody struct {
OrderID model.OrderID `json:"orderID"`
OrderID string `json:"orderID"`
}
return func(request echo.Context) error {
ctx := context.Background()
@ -113,7 +142,7 @@ func MarkDonatView(donatService model.DonatService) echo.HandlerFunc {
err = donatService.MarkDonatView(
ctx,
model.DonatID(donatID),
donatID,
)
if err != nil {
return request.JSON(500, err.Error())
@ -145,7 +174,7 @@ func GetInnerDonatePage(donatService model.DonatService) echo.HandlerFunc {
ctx := context.Background()
var innerPage model.InnerDonatePageResponse
innerPage, err = donatService.GetInnerDonatPage(ctx, model.StreamerID(authData.AccountID))
innerPage, err = donatService.GetInnerDonatPage(ctx, authData.AccountID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
@ -447,11 +476,16 @@ func UpdateModerationSettings(donatService model.DonatService) echo.HandlerFunc
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
}
donatService.UpdateModerationSettings(
err = donatService.UpdateModerationSettings(
ctx,
authData.AccountID,
body,
)
if err != nil {
slog.Error("Failed to update moderation settings", "error", err)
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to update moderation settings")
}
return request.JSON(http.StatusOK, "Success update")
}
}
@ -492,7 +526,7 @@ func GetDonationsStats(donatService model.DonatService) echo.HandlerFunc {
}
}
// DonateModeration godoc
// GetDonateModeration godoc
// @Summary Get the latest donation in moderation
// @Description Get the latest donation with status 'moderation' sorted by updated_at
// @Tags Donate
@ -504,8 +538,8 @@ func GetDonationsStats(donatService model.DonatService) echo.HandlerFunc {
// @Failure 401 {object} echo.HTTPError "Unauthorized or expired token"
// @Failure 404 {object} echo.HTTPError "No donations in moderation found"
// @Failure 500 {object} echo.HTTPError "Internal server error"
// @Router /donat/latest-moderation [get]
func DonateModeration(donatService model.DonatService) echo.HandlerFunc {
// @Router /donat-moderate/latest-moderation [get]
func GetDonateModeration(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error {
authData, err := donatService.CheckToken(request)
if err != nil {
@ -526,3 +560,56 @@ func DonateModeration(donatService model.DonatService) echo.HandlerFunc {
return request.JSON(http.StatusOK, donation)
}
}
// ModerateDonat godoc
// @Summary Update donat settings
// @Description Update donat settings such as accepted, show_text, play_content, show_name
// @Tags Donate
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param donat-id path int true "ID доната"
// @Param request body model.ModerationDonat true "Update fields"
// @Success 200 {string} string "Donat settings updated successfully"
// @Failure 400 {object} echo.HTTPError "Bad request"
// @Failure 401 {object} echo.HTTPError "Unauthorized or expired token"
// @Failure 422 {object} echo.HTTPError "Validation error"
// @Router /donat-moderate/{donat-id} [patch]
func ModerateDonat(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error {
ctx := context.Background()
donatID, err := strconv.Atoi(request.Param("donat-id"))
if err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(http.StatusUnprocessableEntity, "Incorrect donat id")
}
var body model.ModerationDonat
err = validator.ParseAndValidate(&body, request)
if err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(http.StatusUnprocessableEntity, "Unprocessable Entity")
}
authData, err := donatService.CheckToken(request)
if err != nil {
slog.Error("Unauthorized")
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
}
// Проверка прав доступа (например, что пользователь является стримером)
// Это зависит от вашей бизнес-логики
err = donatService.ModerateDonation(
ctx,
donatID,
authData.AccountID,
body,
)
if err != nil {
slog.Error("Failed to update donat settings", "error", err)
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to update donat settings")
}
return request.JSON(http.StatusOK, "Donat settings updated successfully")
}
}

View File

@ -10,11 +10,11 @@ import (
func CreateTarget(targetService model.TargetService, authClient model.AuthClient) echo.HandlerFunc {
type CreateTargetBody struct {
Amount model.DonatAmount `json:"amount"`
Text string `json:"text"`
Amount int `json:"amount"`
Text string `json:"text"`
}
type CreateTargetResponse struct {
TargetID model.TargetID `json:"targetID"`
TargetID int `json:"targetID"`
}
return func(request echo.Context) error {
ctx := context.Background()
@ -34,8 +34,8 @@ func CreateTarget(targetService model.TargetService, authClient model.AuthClient
return request.JSON(http.StatusInternalServerError, err.Error())
}
targetID, err := targetService.CreateTarget(ctx, model.StreamerID(
model.StreamerID(authData.AccountID)),
targetID, err := targetService.CreateTarget(ctx,
authData.AccountID,
body.Amount,
body.Text,
)
@ -49,7 +49,7 @@ func CreateTarget(targetService model.TargetService, authClient model.AuthClient
func GetAllTarget(targetService model.TargetService) echo.HandlerFunc {
type GetAllTargetBody struct {
StreamerID model.StreamerID `json:"streamerID"`
StreamerID int `json:"streamerID"`
}
return func(request echo.Context) error {
ctx := context.Background()
@ -83,7 +83,7 @@ func AddAmountTarget(
donatService model.DonatService,
) echo.HandlerFunc {
type AddAmountTargetBody struct {
OrderID model.OrderID `json:"orderID"`
OrderID string `json:"orderID"`
}
return func(request echo.Context) error {
ctx := context.Background()

View File

@ -84,14 +84,15 @@ func IncludeDonatHandlers(
server.GET(PREFIX+"/moderation-settings", GetModerationSettings(donatService))
server.PATCH(PREFIX+"/moderation-settings", UpdateModerationSettings(donatService))
server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService))
server.GET(PREFIX+"/donat", GetDonat(donatService))
server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService))
server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService))
server.GET(PREFIX+"/donat/period-stat", GetDonationsStats(donatService))
server.GET(PREFIX+"/donat/latest-moderation", DonateModeration(donatService))
server.GET(PREFIX+"/donat-moderate/latest-moderation", GetDonateModeration(donatService))
server.PATCH(PREFIX+"/donat-moderate/:donat-id", ModerateDonat(donatService))
}
func IncludeWidgetHandlers(

View File

@ -15,6 +15,181 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/donat": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Получает список донатов для указанного стримера с пагинацией",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get donats",
"parameters": [
{
"type": "integer",
"default": 1,
"description": "Номер страницы (по умолчанию 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 10,
"description": "Количество элементов на странице (по умолчанию 10)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Успешный возврат списка донатов",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.Donat"
}
}
},
"400": {
"description": "Некорректный формат streamerID",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Внутренняя ошибка сервера",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat-moderate/latest-moderation": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the latest donation with status 'moderation' sorted by updated_at",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get the latest donation in moderation",
"responses": {
"200": {
"description": "Latest donation in moderation",
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.DonationModeration"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"404": {
"description": "No donations in moderation found",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat-moderate/{donat-id}": {
"patch": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update donat settings such as accepted, show_text, play_content, show_name",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Update donat settings",
"parameters": [
{
"type": "integer",
"description": "ID доната",
"name": "donat-id",
"in": "path",
"required": true
},
{
"description": "Update fields",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.ModerationDonat"
}
}
],
"responses": {
"200": {
"description": "Donat settings updated successfully",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"422": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat-page": {
"patch": {
"security": [
@ -93,58 +268,6 @@ const docTemplate = `{
}
}
},
"/donat/latest-moderation": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the latest donation with status 'moderation' sorted by updated_at",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get the latest donation in moderation",
"responses": {
"200": {
"description": "Latest donation in moderation",
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.DonationModeration"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"404": {
"description": "No donations in moderation found",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat/period-stat": {
"get": {
"security": [
@ -1099,6 +1222,66 @@ const docTemplate = `{
}
}
},
"donat-widget_internal_model.Donat": {
"type": "object",
"properties": {
"accepted_time": {
"type": "string",
"format": "date-time",
"example": "2025-03-12T15:04:05Z"
},
"amount": {
"type": "integer",
"example": 500
},
"donat_user": {
"type": "string",
"example": "Anonymous"
},
"id": {
"type": "integer",
"example": 1
},
"order_id": {
"type": "string",
"format": "uuid",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
"play_content": {
"type": "boolean",
"example": true
},
"show_name": {
"type": "boolean",
"example": true
},
"show_text": {
"type": "boolean",
"example": true
},
"showed_time": {
"type": "string",
"format": "date-time",
"example": "2025-03-12T15:05:10Z"
},
"status": {
"type": "string",
"example": "pending"
},
"target_id": {
"type": "integer",
"example": 2002
},
"text": {
"type": "string",
"example": "Thank you for the stream!"
},
"widget_id": {
"type": "integer",
"example": 5
}
}
},
"donat-widget_internal_model.DonationModeration": {
"type": "object",
"properties": {
@ -1376,6 +1559,23 @@ const docTemplate = `{
}
}
},
"donat-widget_internal_model.ModerationDonat": {
"type": "object",
"properties": {
"accepted": {
"type": "boolean"
},
"play_content": {
"type": "boolean"
},
"show_name": {
"type": "boolean"
},
"show_text": {
"type": "boolean"
}
}
},
"donat-widget_internal_model.ModerationResponse": {
"type": "object",
"properties": {

View File

@ -8,6 +8,181 @@
},
"basePath": "/api/widget",
"paths": {
"/donat": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Получает список донатов для указанного стримера с пагинацией",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get donats",
"parameters": [
{
"type": "integer",
"default": 1,
"description": "Номер страницы (по умолчанию 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 10,
"description": "Количество элементов на странице (по умолчанию 10)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Успешный возврат списка донатов",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.Donat"
}
}
},
"400": {
"description": "Некорректный формат streamerID",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Внутренняя ошибка сервера",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat-moderate/latest-moderation": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the latest donation with status 'moderation' sorted by updated_at",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get the latest donation in moderation",
"responses": {
"200": {
"description": "Latest donation in moderation",
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.DonationModeration"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"404": {
"description": "No donations in moderation found",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat-moderate/{donat-id}": {
"patch": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update donat settings such as accepted, show_text, play_content, show_name",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Update donat settings",
"parameters": [
{
"type": "integer",
"description": "ID доната",
"name": "donat-id",
"in": "path",
"required": true
},
{
"description": "Update fields",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.ModerationDonat"
}
}
],
"responses": {
"200": {
"description": "Donat settings updated successfully",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"422": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat-page": {
"patch": {
"security": [
@ -86,58 +261,6 @@
}
}
},
"/donat/latest-moderation": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the latest donation with status 'moderation' sorted by updated_at",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get the latest donation in moderation",
"responses": {
"200": {
"description": "Latest donation in moderation",
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.DonationModeration"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"404": {
"description": "No donations in moderation found",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat/period-stat": {
"get": {
"security": [
@ -1092,6 +1215,66 @@
}
}
},
"donat-widget_internal_model.Donat": {
"type": "object",
"properties": {
"accepted_time": {
"type": "string",
"format": "date-time",
"example": "2025-03-12T15:04:05Z"
},
"amount": {
"type": "integer",
"example": 500
},
"donat_user": {
"type": "string",
"example": "Anonymous"
},
"id": {
"type": "integer",
"example": 1
},
"order_id": {
"type": "string",
"format": "uuid",
"example": "550e8400-e29b-41d4-a716-446655440000"
},
"play_content": {
"type": "boolean",
"example": true
},
"show_name": {
"type": "boolean",
"example": true
},
"show_text": {
"type": "boolean",
"example": true
},
"showed_time": {
"type": "string",
"format": "date-time",
"example": "2025-03-12T15:05:10Z"
},
"status": {
"type": "string",
"example": "pending"
},
"target_id": {
"type": "integer",
"example": 2002
},
"text": {
"type": "string",
"example": "Thank you for the stream!"
},
"widget_id": {
"type": "integer",
"example": 5
}
}
},
"donat-widget_internal_model.DonationModeration": {
"type": "object",
"properties": {
@ -1369,6 +1552,23 @@
}
}
},
"donat-widget_internal_model.ModerationDonat": {
"type": "object",
"properties": {
"accepted": {
"type": "boolean"
},
"play_content": {
"type": "boolean"
},
"show_name": {
"type": "boolean"
},
"show_text": {
"type": "boolean"
}
}
},
"donat-widget_internal_model.ModerationResponse": {
"type": "object",
"properties": {

View File

@ -69,6 +69,51 @@ definitions:
streamer_id:
type: integer
type: object
donat-widget_internal_model.Donat:
properties:
accepted_time:
example: "2025-03-12T15:04:05Z"
format: date-time
type: string
amount:
example: 500
type: integer
donat_user:
example: Anonymous
type: string
id:
example: 1
type: integer
order_id:
example: 550e8400-e29b-41d4-a716-446655440000
format: uuid
type: string
play_content:
example: true
type: boolean
show_name:
example: true
type: boolean
show_text:
example: true
type: boolean
showed_time:
example: "2025-03-12T15:05:10Z"
format: date-time
type: string
status:
example: pending
type: string
target_id:
example: 2002
type: integer
text:
example: Thank you for the stream!
type: string
widget_id:
example: 5
type: integer
type: object
donat-widget_internal_model.DonationModeration:
properties:
accepted:
@ -272,6 +317,17 @@ definitions:
ru_name:
type: string
type: object
donat-widget_internal_model.ModerationDonat:
properties:
accepted:
type: boolean
play_content:
type: boolean
show_name:
type: boolean
show_text:
type: boolean
type: object
donat-widget_internal_model.ModerationResponse:
properties:
duration:
@ -415,6 +471,119 @@ info:
title: Donate Auth Documentation
version: "3.0"
paths:
/donat:
get:
consumes:
- application/json
description: Получает список донатов для указанного стримера с пагинацией
parameters:
- default: 1
description: Номер страницы (по умолчанию 1)
in: query
name: page
type: integer
- default: 10
description: Количество элементов на странице (по умолчанию 10)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: Успешный возврат списка донатов
schema:
items:
$ref: '#/definitions/donat-widget_internal_model.Donat'
type: array
"400":
description: Некорректный формат streamerID
schema:
$ref: '#/definitions/echo.HTTPError'
"500":
description: Внутренняя ошибка сервера
schema:
$ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Get donats
tags:
- Donate
/donat-moderate/{donat-id}:
patch:
consumes:
- application/json
description: Update donat settings such as accepted, show_text, play_content,
show_name
parameters:
- description: ID доната
in: path
name: donat-id
required: true
type: integer
- description: Update fields
in: body
name: request
required: true
schema:
$ref: '#/definitions/donat-widget_internal_model.ModerationDonat'
produces:
- application/json
responses:
"200":
description: Donat settings updated successfully
schema:
type: string
"400":
description: Bad request
schema:
$ref: '#/definitions/echo.HTTPError'
"401":
description: Unauthorized or expired token
schema:
$ref: '#/definitions/echo.HTTPError'
"422":
description: Validation error
schema:
$ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Update donat settings
tags:
- Donate
/donat-moderate/latest-moderation:
get:
consumes:
- application/json
description: Get the latest donation with status 'moderation' sorted by updated_at
produces:
- application/json
responses:
"200":
description: Latest donation in moderation
schema:
$ref: '#/definitions/donat-widget_internal_model.DonationModeration'
"400":
description: Bad request
schema:
$ref: '#/definitions/echo.HTTPError'
"401":
description: Unauthorized or expired token
schema:
$ref: '#/definitions/echo.HTTPError'
"404":
description: No donations in moderation found
schema:
$ref: '#/definitions/echo.HTTPError'
"500":
description: Internal server error
schema:
$ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Get the latest donation in moderation
tags:
- Donate
/donat-page:
patch:
description: Update personal streamer donate page with optional background and
@ -505,39 +674,6 @@ paths:
summary: Create donat
tags:
- Donate
/donat/latest-moderation:
get:
consumes:
- application/json
description: Get the latest donation with status 'moderation' sorted by updated_at
produces:
- application/json
responses:
"200":
description: Latest donation in moderation
schema:
$ref: '#/definitions/donat-widget_internal_model.DonationModeration'
"400":
description: Bad request
schema:
$ref: '#/definitions/echo.HTTPError'
"401":
description: Unauthorized or expired token
schema:
$ref: '#/definitions/echo.HTTPError'
"404":
description: No donations in moderation found
schema:
$ref: '#/definitions/echo.HTTPError'
"500":
description: Internal server error
schema:
$ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Get the latest donation in moderation
tags:
- Donate
/donat/period-stat:
get:
consumes:

View File

@ -77,13 +77,13 @@ type DonatService interface {
CreateDonat(ctx context.Context, streamerLogin, text, donatUser string, targetID, amount int) (api.CreatePaymentResponse, error)
GetDonatByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Donat, error)
GetDonatByOrderID(ctx context.Context, orderID OrderID) (*Donat, error)
GetDonatsByStreamerID(ctx context.Context, streamerID, page, limit int) ([]*Donat, error)
GetDonatByOrderID(ctx context.Context, orderID string) (*Donat, error)
MarkDonatPaid(ctx context.Context, orderID OrderID) error
MarkDonatView(ctx context.Context, DonatID DonatID) error
MarkDonatPaid(ctx context.Context, orderID string) error
MarkDonatView(ctx context.Context, donatID int) error
GetInnerDonatPage(ctx context.Context, streamerID StreamerID) (InnerDonatePageResponse, error)
GetInnerDonatPage(ctx context.Context, streamerID int) (InnerDonatePageResponse, error)
GetOuterDonatPage(ctx context.Context, streamerLogin string) (OuterDonatePageResponse, error)
UpdateDonatePage(
ctx context.Context,
@ -104,6 +104,7 @@ type DonatService interface {
GetDonationsStats(ctx context.Context, streamerID int, period string) (DonationSummaryResponse, error)
GetDonatModeration(ctx context.Context, streamerID int) (DonationModeration, error)
ModerateDonation(ctx context.Context, donatID, streamerID int, updateModel ModerationDonat) error
}
type DonatRepo interface {
@ -118,13 +119,13 @@ type DonatRepo interface {
donatUser string,
) error
GetDonatByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Donat, error)
GetDonatByOrderID(ctx context.Context, orderID OrderID) (*Donat, error)
GetDonatsByStreamerID(ctx context.Context, streamerID, page, limit int) ([]*Donat, error)
GetDonatByOrderID(ctx context.Context, orderID string) (*Donat, error)
MarkDonatPaid(ctx context.Context, orderID OrderID) error
MarkDonatView(ctx context.Context, DonatID DonatID) error
MarkDonatPaid(ctx context.Context, orderID string) error
MarkDonatView(ctx context.Context, DonatID int) error
GetDonatPage(ctx context.Context, streamerID StreamerID) (DonatePage, error)
GetDonatPage(ctx context.Context, streamerID int) (DonatePage, error)
GetDonatPageByLogin(ctx context.Context, streamerLogin string) (DonatePage, error)
UpdateDonatePage(
@ -158,20 +159,21 @@ type DonatRepo interface {
GetDonationsSummary(ctx context.Context, streamerID int, period string) (DonationSummary, error)
GetDonatModeration(ctx context.Context, streamerID int) (DonationModeration, error)
ModerateDonation(ctx context.Context, donatID, streamerID int, updateModel ModerationDonat) error
}
type TargetService interface {
CheckToken(request echo.Context) (api.CheckTokenResponse, error)
CreateTarget(ctx context.Context, streamerID StreamerID, amount DonatAmount, text string) (TargetID, error)
GetAllTarget(ctx context.Context, streamerID StreamerID) ([]*Target, error)
AddAmountToTarget(ctx context.Context, targetID TargetID, amount DonatAmount) error
CreateTarget(ctx context.Context, streamerID int, amount int, text string) (int, error)
GetAllTarget(ctx context.Context, streamerID int) ([]*Target, error)
AddAmountToTarget(ctx context.Context, targetID, amount int) error
}
type TargetRepo interface {
CreateTarget(ctx context.Context, streamerID StreamerID, amount DonatAmount, text string) (TargetID, error)
GetAllTarget(ctx context.Context, streamerID StreamerID) ([]*Target, error)
AddAmountToTarget(ctx context.Context, targetID TargetID, amount DonatAmount) error
CreateTarget(ctx context.Context, streamerID int, amount int, text string) (int, error)
GetAllTarget(ctx context.Context, streamerID int) ([]*Target, error)
AddAmountToTarget(ctx context.Context, targetID int, amount int) error
}
type Error interface {

View File

@ -59,20 +59,22 @@ type UpdateWidget struct {
}
type Donat struct {
ID DonatID `db:"id"`
StreamerID StreamerID `db:"streamer_id"`
WidgetID WidgetID `db:"widget_id"`
OrderID OrderID `db:"order_id"`
TargetID TargetID `db:"target_id"`
Text string `db:"text"`
DonatUser string `db:"donat_user"`
Amount DonatAmount `db:"amount"`
status string `db:"status"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
ID int `db:"id" json:"id" example:"1" description:"Unique identifier of the donation"`
WidgetID int `db:"widget_id" json:"widget_id" example:"5" description:"ID of the widget"`
StreamerID int `db:"streamer_id" json:"-" example:"1" description:"ID of the streamer"`
OrderID string `db:"order_id" json:"order_id" format:"uuid" example:"550e8400-e29b-41d4-a716-446655440000" description:"Unique order identifier"`
TargetID int `db:"target_id" json:"target_id,omitempty" example:"2002" description:"Optional target ID"`
Status string `db:"status" json:"status" example:"pending" description:"Donation status (e.g., pending, accepted, rejected)"`
Text string `db:"text" json:"text" example:"Thank you for the stream!" description:"Donation message text"`
Amount int `db:"amount" json:"amount" example:"500" description:"Donation amount in cents"`
DonatUser string `db:"donat_user" json:"donat_user" example:"Anonymous" description:"Name of the donator (or 'Anonymous')"`
AcceptedTime *time.Time `db:"accepted_time" json:"accepted_time,omitempty" format:"date-time" example:"2025-03-12T15:04:05Z" description:"Timestamp when the donation was accepted"`
ShowName bool `db:"show_name" json:"show_name" example:"true" description:"Whether to show the donator's name"`
ShowText bool `db:"show_text" json:"show_text" example:"true" description:"Whether to show the donation message"`
PlayContent bool `db:"play_content" json:"play_content" example:"true" description:"Whether to play media content (e.g., TTS, sound)"`
ShowedTime *time.Time `db:"showed_time" json:"showed_time" format:"date-time" example:"2025-03-12T15:05:10Z" description:"Timestamp when the donation was displayed on stream"`
CreatedAt time.Time `db:"created_at" json:"-" format:"date-time" example:"2025-03-12T15:04:05Z" description:"Timestamp when the donation was created"`
UpdatedAt time.Time `db:"updated_at" json:"-" format:"date-time" example:"2025-03-12T15:04:05Z" description:"Timestamp when the donation was last updated"`
}
type Target struct {
@ -293,6 +295,13 @@ type DonationModeration struct {
UpdatedAt time.Time `db:"updated_at" json:"updated_at" example:"2025-03-09T12:49:21.75005Z"` // Дата последнего обновления
}
type ModerationDonat struct {
Accepted *bool `json:"accepted"`
ShowText *bool `json:"show_text"`
PlayContent *bool `json:"play_content"`
ShowName *bool `json:"show_name"`
}
//func (widget *GetWidgetDb) GetMediaUrl(mediaType MediaType) MediaUrl {
// var mediaUrl MediaUrl
// if mediaType == "background_url" {

View File

@ -44,12 +44,12 @@ CREATE TABLE IF NOT EXISTS donats (
amount INTEGER NOT NULL,
donat_user TEXT NOT NULL,
accepted BOOLEAN NOT NULL DEFAULT 'false',
accepted_time TIMESTAMP,
show_name BOOLEAN NOT NULL DEFAULT 'true',
show_text BOOLEAN NOT NULL DEFAULT 'true',
play_content BOOLEAN NOT NULL DEFAULT 'true',
showed BOOLEAN NOT NULL DEFAULT 'false',
showed_time TIMESTAMP,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP

View File

@ -60,8 +60,12 @@ WHERE order_id = (@order_id);
`
var GetDonatByStreamerID = `
SELECT * FROM donats
WHERE streamer_id = (@streamer_id) AND paid = (@paid) AND view = (@view);
WHERE streamer_id = @streamer_id
AND accepted_time IS NOT NULL
ORDER BY created_at DESC
LIMIT @limit OFFSET @offset;
`
var GetDonatByOrderID = `
SELECT * FROM donats
WHERE order_id = (@order_id);
@ -445,3 +449,12 @@ ORDER BY
updated_at DESC
LIMIT 1;
`
var ModerateDonat = `
UPDATE donats
SET
accepted = @accepted,
show_text = @show_text,
play_content = @play_content,
show_name = @show_name
WHERE id = @donat_id AND streamer_id = @streamer_id AND status = 'moderation'`

View File

@ -52,14 +52,18 @@ func (repoDonat *RepoDonat) CreateDonat(
return nil
}
func (repoDonat *RepoDonat) GetDonatByStreamerID(
func (repoDonat *RepoDonat) GetDonatsByStreamerID(
ctx context.Context,
streamerID model.StreamerID,
streamerID int,
page int,
limit int,
) ([]*model.Donat, error) {
offset := (page - 1) * limit
args := pgx.NamedArgs{
"streamer_id": streamerID,
"paid": true,
"view": false,
"offset": offset,
"page": page,
}
rows, err := repoDonat.db.Select(ctx, sql.GetDonatByStreamerID, args)
if err != nil {
@ -79,7 +83,7 @@ func (repoDonat *RepoDonat) GetDonatByStreamerID(
func (repoDonat *RepoDonat) GetDonatByOrderID(
ctx context.Context,
orderID model.OrderID,
orderID string,
) (*model.Donat, error) {
args := pgx.NamedArgs{
"order_id": orderID,
@ -105,7 +109,7 @@ func (repoDonat *RepoDonat) GetDonatByOrderID(
func (repoDonat *RepoDonat) MarkDonatView(
ctx context.Context,
donatID model.DonatID,
donatID int,
) error {
args := pgx.NamedArgs{
"id": donatID,
@ -122,7 +126,7 @@ func (repoDonat *RepoDonat) MarkDonatView(
func (repoDonat *RepoDonat) MarkDonatPaid(
ctx context.Context,
orderID model.OrderID,
orderID string,
) error {
args := pgx.NamedArgs{
"order_id": orderID,
@ -139,7 +143,7 @@ func (repoDonat *RepoDonat) MarkDonatPaid(
func (repoDonat *RepoDonat) GetDonatPage(
ctx context.Context,
streamerID model.StreamerID,
streamerID int,
) (model.DonatePage, error) {
args := pgx.NamedArgs{
"streamer_id": streamerID,
@ -719,3 +723,26 @@ func (repoDonat *RepoDonat) GetDonatModeration(
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,
"accepted": updateModel.Accepted,
"show_name": updateModel.ShowName,
"show_text": updateModel.ShowText,
"play_content": updateModel.PlayContent,
}
err := repoDonat.db.Exec(ctx, sql.ModerateDonat, args)
if err != nil {
slog.Error("Failed to update donat", "error", err)
return err
}
return nil
}

View File

@ -21,10 +21,10 @@ type RepoTarget struct {
func (targetRepo *RepoTarget) CreateTarget(
ctx context.Context,
streamerID model.StreamerID,
amount model.DonatAmount,
streamerID int,
amount int,
text string,
) (model.TargetID, error) {
) (int, error) {
args := pgx.NamedArgs{
"streamer_id": streamerID,
"amount": amount,
@ -36,12 +36,12 @@ func (targetRepo *RepoTarget) CreateTarget(
slog.Error(err.Error())
return 0, err
}
return model.TargetID(targetID.(int)), nil
return targetID.(int), nil
}
func (targetRepo *RepoTarget) GetAllTarget(
ctx context.Context,
streamerID model.StreamerID,
streamerID int,
) ([]*model.Target, error) {
args := pgx.NamedArgs{
"streamer_id": streamerID,
@ -65,8 +65,8 @@ func (targetRepo *RepoTarget) GetAllTarget(
func (targetRepo *RepoTarget) AddAmountToTarget(
ctx context.Context,
targetID model.TargetID,
amount model.DonatAmount,
targetID int,
amount int,
) error {
args := pgx.NamedArgs{
"target_id": targetID,

View File

@ -111,11 +111,21 @@ func (donatService *ServiceDonat) CreateDonat(
return api.CreatePaymentResponse{}, err
}
func (donatService *ServiceDonat) GetDonatByStreamerID(
func (donatService *ServiceDonat) GetDonatsByStreamerID(
ctx context.Context,
streamerID model.StreamerID,
streamerID int,
page int,
limit int,
) ([]*model.Donat, error) {
donats, err := donatService.donatRepo.GetDonatByStreamerID(ctx, streamerID)
donats, err := donatService.donatRepo.GetDonatsByStreamerID(
ctx,
streamerID,
page,
limit,
)
if len(donats) == 0 {
return []*model.Donat{}, nil
}
if err != nil {
slog.Error(err.Error())
return nil, err
@ -125,7 +135,7 @@ func (donatService *ServiceDonat) GetDonatByStreamerID(
func (donatService *ServiceDonat) GetDonatByOrderID(
ctx context.Context,
orderID model.OrderID,
orderID string,
) (*model.Donat, error) {
donat, err := donatService.donatRepo.GetDonatByOrderID(ctx, orderID)
if err != nil {
@ -137,7 +147,7 @@ func (donatService *ServiceDonat) GetDonatByOrderID(
func (donatService *ServiceDonat) MarkDonatPaid(
ctx context.Context,
orderID model.OrderID,
orderID string,
) error {
err := donatService.donatRepo.MarkDonatPaid(
ctx,
@ -152,7 +162,7 @@ func (donatService *ServiceDonat) MarkDonatPaid(
func (donatService *ServiceDonat) MarkDonatView(
ctx context.Context,
donatID model.DonatID,
donatID int,
) error {
err := donatService.donatRepo.MarkDonatView(
ctx,
@ -167,7 +177,7 @@ func (donatService *ServiceDonat) MarkDonatView(
func (donatService *ServiceDonat) GetInnerDonatPage(
ctx context.Context,
streamerID model.StreamerID,
streamerID int,
) (model.InnerDonatePageResponse, error) {
// Получаем данные страницы доната из репозитория
donatePage, err := donatService.donatRepo.GetDonatPage(ctx, streamerID)
@ -505,3 +515,23 @@ func (donatService *ServiceDonat) GetDonatModeration(
return donation, nil
}
func (donatService *ServiceDonat) ModerateDonation(
ctx context.Context,
donatID int,
streamerID int,
updateModel model.ModerationDonat,
) error {
err := donatService.donatRepo.ModerateDonation(
ctx,
donatID,
streamerID,
updateModel,
)
if err != nil {
slog.Error("Failed to update donat", "error", err)
return err
}
return nil
}

View File

@ -26,10 +26,10 @@ type ServiceTarget struct {
func (targetService *ServiceTarget) CreateTarget(
ctx context.Context,
streamerID model.StreamerID,
amount model.DonatAmount,
streamerID int,
amount int,
text string,
) (model.TargetID, error) {
) (int, error) {
targetID, err := targetService.targetRepo.CreateTarget(ctx, streamerID, amount, text)
if err != nil {
slog.Error(err.Error())
@ -40,7 +40,7 @@ func (targetService *ServiceTarget) CreateTarget(
func (targetService *ServiceTarget) GetAllTarget(
ctx context.Context,
streamerID model.StreamerID,
streamerID int,
) ([]*model.Target, error) {
targets, err := targetService.targetRepo.GetAllTarget(ctx, streamerID)
if err != nil {
@ -53,8 +53,8 @@ func (targetService *ServiceTarget) GetAllTarget(
func (targetService *ServiceTarget) AddAmountToTarget(
ctx context.Context,
targetID model.TargetID,
amount model.DonatAmount,
targetID int,
amount int,
) error {
err := targetService.targetRepo.AddAmountToTarget(ctx, targetID, amount)
if err != nil {