add router for get statistic by date
This commit is contained in:
parent
f5e143c044
commit
476e6ff59c
@ -455,3 +455,39 @@ func UpdateModerationSettings(donatService model.DonatService) echo.HandlerFunc
|
|||||||
return request.JSON(http.StatusOK, "Success update")
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -88,6 +88,8 @@ func IncludeDonatHandlers(
|
|||||||
|
|
||||||
server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService))
|
server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService))
|
||||||
server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService))
|
server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService))
|
||||||
|
|
||||||
|
server.GET(PREFIX+"/donat/period-stat", GetDonationsStats(donatService))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IncludeWidgetHandlers(
|
func IncludeWidgetHandlers(
|
||||||
|
@ -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}": {
|
"/donat/{streamer-login}": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Create donat",
|
"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": {
|
"donat-widget_internal_model.FilterSettingResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -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}": {
|
"/donat/{streamer-login}": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Create donat",
|
"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": {
|
"donat-widget_internal_model.FilterSettingResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -66,6 +66,15 @@ definitions:
|
|||||||
streamer_id:
|
streamer_id:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
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:
|
donat-widget_internal_model.FilterSettingResponse:
|
||||||
properties:
|
properties:
|
||||||
enable_links:
|
enable_links:
|
||||||
@ -424,6 +433,48 @@ paths:
|
|||||||
summary: Create donat
|
summary: Create donat
|
||||||
tags:
|
tags:
|
||||||
- Donate
|
- 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:
|
/files:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
@ -98,6 +98,8 @@ type DonatService interface {
|
|||||||
|
|
||||||
GetModerationSettings(ctx context.Context, streamerID int) (ModerationResponse, error)
|
GetModerationSettings(ctx context.Context, streamerID int) (ModerationResponse, error)
|
||||||
UpdateModerationSettings(ctx context.Context, streamerID int, updateModel UpdateModeration) error
|
UpdateModerationSettings(ctx context.Context, streamerID int, updateModel UpdateModeration) error
|
||||||
|
|
||||||
|
GetDonationsStats(ctx context.Context, streamerID int, period string) ([]DonationStatResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DonatRepo interface {
|
type DonatRepo interface {
|
||||||
@ -147,6 +149,8 @@ type DonatRepo interface {
|
|||||||
|
|
||||||
GetModeration(ctx context.Context, streamerID int) (ModerationResponse, error)
|
GetModeration(ctx context.Context, streamerID int) (ModerationResponse, error)
|
||||||
UpdateModeration(ctx context.Context, streamerID int, enable *bool, duration *int) 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 {
|
type TargetService interface {
|
||||||
|
@ -255,6 +255,18 @@ type CreateDonatBody struct {
|
|||||||
DonatUser string `json:"donatUser"`
|
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 {
|
//func (widget *GetWidgetDb) GetMediaUrl(mediaType MediaType) MediaUrl {
|
||||||
// var mediaUrl MediaUrl
|
// var mediaUrl MediaUrl
|
||||||
// if mediaType == "background_url" {
|
// if mediaType == "background_url" {
|
||||||
|
@ -313,3 +313,67 @@ WHERE streamer_id = @streamer_id;
|
|||||||
`
|
`
|
||||||
var GetModeration = `
|
var GetModeration = `
|
||||||
SELECT enable, duration FROM moderation WHERE streamer_id = @streamer_id;`
|
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;
|
||||||
|
`
|
||||||
|
@ -604,3 +604,42 @@ func (repoDonat *RepoDonat) UpdateModeration(
|
|||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
@ -455,3 +455,26 @@ func (donatService *ServiceDonat) UpdateModerationSettings(
|
|||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user