add router for get statistic by date

This commit is contained in:
harold 2025-03-09 19:28:16 +05:00
parent f5e143c044
commit 476e6ff59c
10 changed files with 387 additions and 0 deletions

View File

@ -455,3 +455,39 @@ func UpdateModerationSettings(donatService model.DonatService) echo.HandlerFunc
return request.JSON(http.StatusOK, "Success update")
}
}
// GetDonationsStats godoc
// @Summary Get donations statistics
// @Description Get donations statistics for a given period
// @Tags Donate
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param period query string true "Period for statistics" Enums(24h, 7d, 1m, 1y)
// @Success 200 {array} model.DonationStatResponse "Donations statistics"
// @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/period-stat [get]
func GetDonationsStats(donatService model.DonatService) echo.HandlerFunc {
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()
period := request.QueryParam("period")
if period == "" {
return echo.NewHTTPError(http.StatusBadRequest, "period is required")
}
stats, err := donatService.GetDonationsStats(ctx, authData.AccountID, period)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
return request.JSON(http.StatusOK, stats)
}
}

View File

@ -88,6 +88,8 @@ func IncludeDonatHandlers(
server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService))
server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService))
server.GET(PREFIX+"/donat/period-stat", GetDonationsStats(donatService))
}
func IncludeWidgetHandlers(

View File

@ -93,6 +93,70 @@ const docTemplate = `{
}
}
},
"/donat/period-stat": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get donations statistics for a given period",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get donations statistics",
"parameters": [
{
"enum": [
"24h",
"7d",
"1m",
"1y"
],
"type": "string",
"description": "Period for statistics",
"name": "period",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "Donations statistics",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.DonationStatResponse"
}
}
},
"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/{streamer-login}": {
"post": {
"description": "Create donat",
@ -979,6 +1043,20 @@ const docTemplate = `{
}
}
},
"donat-widget_internal_model.DonationStatResponse": {
"type": "object",
"properties": {
"amount_collected": {
"type": "integer"
},
"date": {
"type": "string"
},
"donations_count": {
"type": "integer"
}
}
},
"donat-widget_internal_model.FilterSettingResponse": {
"type": "object",
"properties": {

View File

@ -86,6 +86,70 @@
}
}
},
"/donat/period-stat": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get donations statistics for a given period",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get donations statistics",
"parameters": [
{
"enum": [
"24h",
"7d",
"1m",
"1y"
],
"type": "string",
"description": "Period for statistics",
"name": "period",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "Donations statistics",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/donat-widget_internal_model.DonationStatResponse"
}
}
},
"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/{streamer-login}": {
"post": {
"description": "Create donat",
@ -972,6 +1036,20 @@
}
}
},
"donat-widget_internal_model.DonationStatResponse": {
"type": "object",
"properties": {
"amount_collected": {
"type": "integer"
},
"date": {
"type": "string"
},
"donations_count": {
"type": "integer"
}
}
},
"donat-widget_internal_model.FilterSettingResponse": {
"type": "object",
"properties": {

View File

@ -66,6 +66,15 @@ definitions:
streamer_id:
type: integer
type: object
donat-widget_internal_model.DonationStatResponse:
properties:
amount_collected:
type: integer
date:
type: string
donations_count:
type: integer
type: object
donat-widget_internal_model.FilterSettingResponse:
properties:
enable_links:
@ -424,6 +433,48 @@ paths:
summary: Create donat
tags:
- Donate
/donat/period-stat:
get:
consumes:
- application/json
description: Get donations statistics for a given period
parameters:
- description: Period for statistics
enum:
- 24h
- 7d
- 1m
- 1y
in: query
name: period
required: true
type: string
produces:
- application/json
responses:
"200":
description: Donations statistics
schema:
items:
$ref: '#/definitions/donat-widget_internal_model.DonationStatResponse'
type: array
"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: Get donations statistics
tags:
- Donate
/files:
post:
consumes:

View File

@ -98,6 +98,8 @@ type DonatService interface {
GetModerationSettings(ctx context.Context, streamerID int) (ModerationResponse, error)
UpdateModerationSettings(ctx context.Context, streamerID int, updateModel UpdateModeration) error
GetDonationsStats(ctx context.Context, streamerID int, period string) ([]DonationStatResponse, error)
}
type DonatRepo interface {
@ -147,6 +149,8 @@ type DonatRepo interface {
GetModeration(ctx context.Context, streamerID int) (ModerationResponse, error)
UpdateModeration(ctx context.Context, streamerID int, enable *bool, duration *int) error
GetDonationsStats(ctx context.Context, streamerID int, period string) ([]DonationStat, error)
}
type TargetService interface {

View File

@ -255,6 +255,18 @@ type CreateDonatBody struct {
DonatUser string `json:"donatUser"`
}
type DonationStat struct {
Date time.Time `db:"date"`
AmountCollected int `db:"amount_collected"`
DonationsCount int `db:"donations_count"`
}
type DonationStatResponse struct {
Date time.Time `json:"date"`
AmountCollected int `json:"amount_collected"`
DonationsCount int `json:"donations_count"`
}
//func (widget *GetWidgetDb) GetMediaUrl(mediaType MediaType) MediaUrl {
// var mediaUrl MediaUrl
// if mediaType == "background_url" {

View File

@ -313,3 +313,67 @@ WHERE streamer_id = @streamer_id;
`
var GetModeration = `
SELECT enable, duration FROM moderation WHERE streamer_id = @streamer_id;`
const GetDonationsLast24Hours = `
SELECT
DATE_TRUNC('hour', created_at) AS date, -- Группировка по часам
SUM(amount) AS amount_collected,
COUNT(*) AS donations_count
FROM
public.donats
WHERE
streamer_id = @streamer_id
AND created_at >= NOW() - INTERVAL '24 hours'
GROUP BY
DATE_TRUNC('hour', created_at) -- Группировка по часам
ORDER BY
date;
`
const GetDonationsLast7Days = `
SELECT
DATE(created_at) AS date, -- Группировка по дням
SUM(amount) AS amount_collected,
COUNT(*) AS donations_count
FROM
public.donats
WHERE
streamer_id = @streamer_id
AND created_at >= NOW() - INTERVAL '7 days'
GROUP BY
DATE(created_at) -- Группировка по дням
ORDER BY
date;
`
const GetDonationsLastMonth = `
SELECT
DATE(created_at) AS date, -- Группировка по дням
SUM(amount) AS amount_collected,
COUNT(*) AS donations_count
FROM
public.donats
WHERE
streamer_id = @streamer_id
AND created_at >= NOW() - INTERVAL '1 month'
GROUP BY
DATE(created_at) -- Группировка по дням
ORDER BY
date;
`
const GetDonationsLastYear = `
SELECT
DATE_TRUNC('month', created_at) AS date, -- Группировка по месяцам
SUM(amount) AS amount_collected,
COUNT(*) AS donations_count
FROM
public.donats
WHERE
streamer_id = @streamer_id
AND created_at >= NOW() - INTERVAL '1 year'
GROUP BY
DATE_TRUNC('month', created_at) -- Группировка по месяцам
ORDER BY
date;
`

View File

@ -604,3 +604,42 @@ func (repoDonat *RepoDonat) UpdateModeration(
}
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
}
var stats []model.DonationStat
err = pgxscan.ScanAll(&stats, rows)
if err != nil {
slog.Error(err.Error())
return nil, err
}
return stats, nil
}

View File

@ -455,3 +455,26 @@ func (donatService *ServiceDonat) UpdateModerationSettings(
}
return nil
}
func (donatService *ServiceDonat) GetDonationsStats(
ctx context.Context,
streamerID int,
period string,
) ([]model.DonationStatResponse, error) {
stats, err := donatService.donatRepo.GetDonationsStats(ctx, streamerID, period)
if err != nil {
slog.Error(err.Error())
return nil, err
}
var response []model.DonationStatResponse
for _, stat := range stats {
response = append(response, model.DonationStatResponse{
Date: stat.Date,
AmountCollected: stat.AmountCollected,
DonationsCount: stat.DonationsCount,
})
}
return response, nil
}