This commit is contained in:
mm 2024-10-29 22:07:14 +05:00
parent d42c9b1d44
commit 1a2cbfb6cd
19 changed files with 308 additions and 606 deletions

View File

@ -1,99 +0,0 @@
// Package docs Code generated by swaggo/swag. DO NOT EDIT
package http
import "github.com/swaggo/swag"
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/user/register": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"parameters": [
{
"description": "Register user",
"name": "input",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/register.requestModel"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/register.responseModel"
}
}
}
}
}
},
"definitions": {
"register.requestModel": {
"type": "object",
"required": [
"password"
],
"properties": {
"email": {
"type": "string"
},
"login": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"register.responseModel": {
"type": "object",
"properties": {
"token": {
"type": "string"
},
"userId": {
"type": "string"
}
}
}
}
}`
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0",
Host: "localhost",
BasePath: "/v2",
Schemes: []string{},
Title: "Template",
Description: "Описание.",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}

View File

@ -1,75 +0,0 @@
{
"swagger": "2.0",
"info": {
"description": "Описание.",
"title": "Template",
"contact": {},
"version": "1.0"
},
"host": "localhost",
"basePath": "/v2",
"paths": {
"/api/user/register": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"parameters": [
{
"description": "Register user",
"name": "input",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/register.requestModel"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/register.responseModel"
}
}
}
}
}
},
"definitions": {
"register.requestModel": {
"type": "object",
"required": [
"password"
],
"properties": {
"email": {
"type": "string"
},
"login": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"register.responseModel": {
"type": "object",
"properties": {
"token": {
"type": "string"
},
"userId": {
"type": "string"
}
}
}
}
}

View File

@ -1,48 +0,0 @@
basePath: /v2
definitions:
register.requestModel:
properties:
email:
type: string
login:
type: string
password:
type: string
required:
- password
type: object
register.responseModel:
properties:
token:
type: string
userId:
type: string
type: object
host: localhost
info:
contact: {}
description: Описание.
title: Template
version: "1.0"
paths:
/api/user/register:
post:
consumes:
- application/json
parameters:
- description: Register user
in: body
name: input
required: true
schema:
$ref: '#/definitions/register.requestModel'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/register.responseModel'
tags:
- Auth
swagger: "2.0"

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"donat-widget/internal/app/http" "donat-widget/internal/app/http"
"donat-widget/internal/config" "donat-widget/internal/config"
"donat-widget/pkg/logger"
) )
import ( import (
@ -23,6 +24,7 @@ import (
) )
func main() { func main() {
logger.New()
cfg := config.Init() cfg := config.Init()
// INFRASTRUCTURE // INFRASTRUCTURE
@ -39,7 +41,7 @@ func main() {
targetRepo := TargetRepo.New(db) targetRepo := TargetRepo.New(db)
// SERVICES // SERVICES
widgetService := WidgetService.New(widgetRepo, donatRepo) widgetService := WidgetService.New(widgetRepo)
donatService := DonatService.New(donatRepo, widgetRepo, paymentClient) donatService := DonatService.New(donatRepo, widgetRepo, paymentClient)
targetService := TargetService.New(targetRepo) targetService := TargetService.New(targetRepo)

View File

@ -3,7 +3,6 @@ package pg
import ( import (
"context" "context"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
"sync" "sync"
) )
@ -33,15 +32,16 @@ func NewPgPool(
return pgInstance return pgInstance
} }
func (pg *Postgres) Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error) { func (pg *Postgres) Insert(ctx context.Context, query string, args ...interface{}) (int64, error) {
result, err := pg.db.Exec(ctx, query, args...) var id int64
err := pg.db.QueryRow(ctx, query, args...).Scan(&id)
if err != nil { if err != nil {
return result, err return 0, err
} }
return result, nil return id, nil
} }
func (pg *Postgres) Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error) { func (pg *Postgres) Select(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error) {
result, err := pg.db.Query(ctx, query, args...) result, err := pg.db.Query(ctx, query, args...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -49,6 +49,22 @@ func (pg *Postgres) Query(ctx context.Context, query string, args ...interface{}
return result, nil return result, nil
} }
func (pg *Postgres) Update(ctx context.Context, query string, args ...interface{}) error {
_, err := pg.db.Query(ctx, query, args...)
if err != nil {
return err
}
return nil
}
func (pg *Postgres) Delete(ctx context.Context, query string, args ...interface{}) error {
_, err := pg.db.Query(ctx, query, args...)
if err != nil {
return err
}
return nil
}
func (pg *Postgres) CreateTable(ctx context.Context, query string) error { func (pg *Postgres) CreateTable(ctx context.Context, query string) error {
_, err := pg.db.Exec(ctx, query) _, err := pg.db.Exec(ctx, query)
if err != nil { if err != nil {

View File

@ -23,11 +23,11 @@ func CreateDonat(donatService model.DonatService) echo.HandlerFunc {
var body CreateDonatBody var body CreateDonatBody
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
orderID := model.OrderID(uuid.New().String()) orderID := model.OrderID(uuid.New().String())
@ -42,13 +42,32 @@ func CreateDonat(donatService model.DonatService) echo.HandlerFunc {
body.DonatUser, body.DonatUser,
) )
if err != nil { if err != nil {
return request.JSON(500, "Create donat error") return request.JSON(http.StatusInternalServerError, err.Error())
} }
return request.JSON(http.StatusCreated, order) return request.JSON(http.StatusCreated, order)
} }
} }
func GetDonat(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error {
ctx := context.Background()
streamerID, err := strconv.Atoi(request.Param("streamerID"))
if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
}
donats, err := donatService.GetDonatByStreamerID(ctx, model.StreamerID(streamerID))
if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
}
return request.JSON(http.StatusNotFound, donats)
}
}
func MarkDonatPaid(donatService model.DonatService) echo.HandlerFunc { func MarkDonatPaid(donatService model.DonatService) echo.HandlerFunc {
type MarkDonatPaidBody struct { type MarkDonatPaidBody struct {
OrderID model.OrderID `json:"orderID"` OrderID model.OrderID `json:"orderID"`
@ -58,17 +77,17 @@ func MarkDonatPaid(donatService model.DonatService) echo.HandlerFunc {
var body MarkDonatPaidBody var body MarkDonatPaidBody
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
err := donatService.MarkDonatPaid(ctx, body.OrderID) err := donatService.MarkDonatPaid(ctx, body.OrderID)
if err != nil { if err != nil {
slog.Error("donatService.MarkDonatPaid error: " + err.Error()) slog.Error(err.Error())
return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
return request.String(200, "Donat paid success") return request.String(200, "Donat paid success")
} }
@ -80,7 +99,7 @@ func MarkDonatView(donatService model.DonatService) echo.HandlerFunc {
donatID, err := strconv.Atoi(request.Param("donatID")) donatID, err := strconv.Atoi(request.Param("donatID"))
if err != nil { if err != nil {
return echo.NewHTTPError(400, "Path parameter 'donatID' is invalid") return request.JSON(400, err.Error())
} }
err = donatService.MarkDonatView( err = donatService.MarkDonatView(
@ -88,7 +107,7 @@ func MarkDonatView(donatService model.DonatService) echo.HandlerFunc {
model.DonatID(donatID), model.DonatID(donatID),
) )
if err != nil { if err != nil {
return echo.NewHTTPError(500, "Delete donat error") return request.JSON(500, err.Error())
} }
slog.Info("Delete donat success") slog.Info("Delete donat success")
return request.String(200, "donat view success") return request.String(200, "donat view success")

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"log/slog"
"net/http" "net/http"
) )
@ -16,20 +17,23 @@ func CreateTarget(targetService model.TargetService, authClient model.AuthClient
ctx := context.Background() ctx := context.Background()
var body CreateTargetBody var body CreateTargetBody
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
authData, err := authClient.CheckToken(request) authData, err := authClient.CheckToken(request)
if err != nil { if err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
err = targetService.CreateTarget(ctx, model.StreamerID(authData.StreamerID), body.Amount, body.Text) err = targetService.CreateTarget(ctx, model.StreamerID(authData.StreamerID), body.Amount, body.Text)
if err != nil { if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err) return request.JSON(http.StatusInternalServerError, err)
} }
return request.String(http.StatusOK, "Created target successfully") return request.String(http.StatusOK, "Created target successfully")
@ -44,15 +48,17 @@ func GetAllTarget(targetService model.TargetService) echo.HandlerFunc {
ctx := context.Background() ctx := context.Background()
var body GetAllTargetBody var body GetAllTargetBody
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
targets, err := targetService.GetAllTarget(ctx, body.StreamerID) targets, err := targetService.GetAllTarget(ctx, body.StreamerID)
if err != nil { if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err) return request.JSON(http.StatusInternalServerError, err)
} }
@ -71,20 +77,23 @@ func AddAmountTarget(
ctx := context.Background() ctx := context.Background()
var body AddAmountTargetBody var body AddAmountTargetBody
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
donat, err := donatService.GetDonatByOrderID(ctx, body.OrderID) donat, err := donatService.GetDonatByOrderID(ctx, body.OrderID)
if err != nil { if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err) return request.JSON(http.StatusInternalServerError, err)
} }
err = targetService.AddAmountToTarget(ctx, donat.TargetID, donat.Amount) err = targetService.AddAmountToTarget(ctx, donat.TargetID, donat.Amount)
if err != nil { if err != nil {
slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err) return request.JSON(http.StatusInternalServerError, err)
} }
return request.JSON(http.StatusOK, "Added target successfully") return request.JSON(http.StatusOK, "Added target successfully")

View File

@ -5,6 +5,7 @@ import (
"donat-widget/internal/model" "donat-widget/internal/model"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"log/slog" "log/slog"
"net/http"
"strconv" "strconv"
) )
@ -22,15 +23,18 @@ func CreateWidget(widgetService model.WidgetService, authClient model.AuthClient
ctx := context.Background() ctx := context.Background()
var body Body var body Body
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
authData, err := authClient.CheckToken(request) authData, err := authClient.CheckToken(request)
if err != nil { if err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
widgetID, err := widgetService.CreateWidget( widgetID, err := widgetService.CreateWidget(
@ -41,7 +45,8 @@ func CreateWidget(widgetService model.WidgetService, authClient model.AuthClient
body.MinAmount, body.MinAmount,
) )
if err != nil { if err != nil {
return request.JSON(422, "Create widget error") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
response := Response{ response := Response{
@ -56,18 +61,21 @@ func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
widgetID, err := strconv.Atoi(request.Param("widgetID")) streamerID, err := strconv.Atoi(request.Param("streamerID"))
if err != nil { if err != nil {
return echo.NewHTTPError(400, "Path parameter 'widgetID' is invalid") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
widgetHTML, err := widgetService.GetWidgetHTML( widgetHTML, err := widgetService.GetWidgetHTML(
ctx, ctx,
model.WidgetID(widgetID), model.StreamerID(streamerID),
) )
if err != nil { if err != nil {
return request.JSON(500, "Get widget HTML error") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
slog.Info("Get widget HTML successfully") slog.Info("Get widget HTML successfully")
return request.HTML(200, string(widgetHTML)) return request.HTML(200, string(widgetHTML))
} }
@ -75,76 +83,29 @@ func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc {
func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc { func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
type Response struct { type Response struct {
AudioUrl model.MediaUrl `json:"audioUrl"` AudioUrl model.MediaUrl `json:"audioUrl"`
ImageUrl model.MediaUrl `json:"imageUrl"` ImageUrl model.MediaUrl `json:"imageUrl"`
Text string `json:"text"` Duration model.Duration `json:"duration"`
Amount model.DonatAmount `json:"amount"`
DonatUser string `json:"donatUser"`
Display model.Display `json:"display"`
Duration model.Duration `json:"duration"`
DonatID model.DonatID `json:"donatID"`
} }
return func(request echo.Context) error { return func(request echo.Context) error {
ctx := context.Background() ctx := context.Background()
widgetID, err := strconv.Atoi(request.Param("widgetID")) widgetID, err := strconv.Atoi(request.Param("widgetID"))
if err != nil { if err != nil {
return echo.NewHTTPError(400, "Path parameter 'widgetID' is invalid") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
donatAndWidget, err := widgetService.GetWidgetInfo(ctx, model.WidgetID(widgetID)) widget, err := widgetService.GetWidgetByID(ctx, model.WidgetID(widgetID))
if err != nil { if err != nil {
return request.JSON(422, "Get widget info error") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
}
if len(widget) == 0 {
return request.JSON(http.StatusNotFound, "widget not found")
} }
if !donatAndWidget.Display { return request.JSON(200, widget)
response := Response{
Display: donatAndWidget.Display,
}
return request.JSON(200, response)
}
response := Response{
AudioUrl: donatAndWidget.Widget.AudioUrl,
ImageUrl: donatAndWidget.Widget.ImageUrl,
Text: donatAndWidget.Donat.Text,
Display: donatAndWidget.Display,
Duration: donatAndWidget.Widget.Duration,
DonatUser: donatAndWidget.Donat.DonatUser,
Amount: donatAndWidget.Donat.Amount,
DonatID: donatAndWidget.Donat.ID,
}
return request.JSON(200, response)
}
}
func UpdateDuration(widgetService model.WidgetService) echo.HandlerFunc {
type Body struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
Duration model.Duration `json:"duration" validate:"required"`
}
return func(request echo.Context) error {
ctx := context.Background()
var body Body
if err := request.Bind(&body); err != nil {
return echo.NewHTTPError(400, err.Error())
}
if err := request.Validate(&body); err != nil {
return echo.NewHTTPError(400, err.Error())
}
err := widgetService.UpdateDuration(
ctx,
body.WidgetID,
body.Duration,
)
if err != nil {
return request.JSON(422, "Update duration error")
}
return request.JSON(200, "Update duration successfully")
} }
} }
@ -154,19 +115,22 @@ func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
widgetID, err := strconv.Atoi(request.FormValue("widgetID")) widgetID, err := strconv.Atoi(request.FormValue("widgetID"))
if err != nil { if err != nil {
return echo.NewHTTPError(404, "Path parameter 'widgetID' is invalid") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
mediaType := request.Param("mediaType") mediaType := request.Param("mediaType")
file, err := request.FormFile("file") file, err := request.FormFile("file")
if err != nil { if err != nil {
return echo.NewHTTPError(404, "Form parameter 'file' is invalid") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
src, err := file.Open() src, err := file.Open()
if err != nil { if err != nil {
return echo.NewHTTPError(500, "File is invalid") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
err = widgetService.SetMediaFile( err = widgetService.SetMediaFile(
@ -179,7 +143,8 @@ func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
"", "",
) )
if err != nil { if err != nil {
return echo.NewHTTPError(500, "File upload is failed") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
slog.Info("set " + mediaType + " file successfully") slog.Info("set " + mediaType + " file successfully")
return request.String(200, "File successfully uploaded") return request.String(200, "File successfully uploaded")
@ -194,9 +159,11 @@ func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
if mediaType != "background" && mediaType != "image" && mediaType != "audio" { if mediaType != "background" && mediaType != "image" && mediaType != "audio" {
return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid") return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid")
} }
widgetID, err := strconv.Atoi(request.Param("widgetID")) widgetID, err := strconv.Atoi(request.Param("widgetID"))
if err != nil { if err != nil {
return echo.NewHTTPError(400, "Path parameter 'widgetID' is invalid") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
file, err := widgetService.GetMediaFile( file, err := widgetService.GetMediaFile(
@ -205,52 +172,15 @@ func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
model.MediaType(mediaType), model.MediaType(mediaType),
) )
if err != nil { if err != nil {
return echo.NewHTTPError(500, "Get File is failed") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
slog.Info("get " + mediaType + " file successfully") slog.Info("get " + mediaType + " file successfully")
return request.Blob(200, "application/octet-stream", file) return request.Blob(200, "application/octet-stream", file)
} }
} }
func UpdateMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error {
ctx := context.Background()
widgetID, err := strconv.Atoi(request.FormValue("widgetID"))
if err != nil {
return echo.NewHTTPError(404, "Path parameter 'widgetID' is invalid")
}
mediaType := request.Param("mediaType")
file, err := request.FormFile("file")
if err != nil {
return echo.NewHTTPError(404, "Form parameter 'file' is invalid")
}
src, err := file.Open()
if err != nil {
return echo.NewHTTPError(500, "File is invalid")
}
err = widgetService.UpdateMediaFile(
ctx,
model.WidgetID(widgetID),
model.MediaType(mediaType),
&src,
file.Filename,
file.Size,
"",
)
if err != nil {
return echo.NewHTTPError(500, "File update is failed")
}
slog.Info("update media file successfully")
return request.String(200, "Media successfully uploaded")
}
}
func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc { func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc {
type Body struct { type Body struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"` WidgetID model.WidgetID `json:"widgetID" validate:"required"`
@ -260,11 +190,12 @@ func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc {
ctx := context.Background() ctx := context.Background()
var body Body var body Body
if err := request.Bind(&body); err != nil { if err := request.Bind(&body); err != nil {
return echo.NewHTTPError(400, err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
if err := request.Validate(&body); err != nil { if err := request.Validate(&body); err != nil {
slog.Error(err.Error())
return echo.NewHTTPError(400, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
mediaType := request.Param("mediaType") mediaType := request.Param("mediaType")
@ -276,7 +207,8 @@ func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc {
body.MediaUrl, body.MediaUrl,
) )
if err != nil { if err != nil {
return echo.NewHTTPError(500, "Set MediaUrl is failed") slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error())
} }
return request.String(200, "Media URL successfully set") return request.String(200, "Media URL successfully set")

View File

@ -59,6 +59,9 @@ func IncludeDonatHandlers(
donatService model.DonatService, donatService model.DonatService,
) { ) {
server.POST(PREFIX+"/donat/create", CreateDonat(donatService)) server.POST(PREFIX+"/donat/create", CreateDonat(donatService))
server.GET(PREFIX+"/donat/:streamerID", GetDonat(donatService))
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))
} }
@ -69,13 +72,14 @@ func IncludeWidgetHandlers(
authClient model.AuthClient, authClient model.AuthClient,
) { ) {
server.POST(PREFIX+"/create", CreateWidget(widgetService, authClient)) server.POST(PREFIX+"/create", CreateWidget(widgetService, authClient))
server.GET(PREFIX+"/html/:widgetID", GetWidgetHTML(widgetService))
server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService))
server.PATCH(PREFIX+"/duration/update", UpdateDuration(widgetService))
server.POST(PREFIX+"/media/:mediaType/upload", SetMediaFile(widgetService)) server.GET(PREFIX+"/html/:streamerID", GetWidgetHTML(widgetService))
server.POST(PREFIX+"/media/:mediaType/set", SetMediaUrl(widgetService)) server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService))
server.GET(PREFIX+"/media/:mediaType/get/:widgetID", GetMediaFile(widgetService))
server.POST(PREFIX+"/media/:mediaType/file/set", SetMediaFile(widgetService))
server.GET(PREFIX+"/media/:mediaType/file/get/:widgetID", GetMediaFile(widgetService))
server.POST(PREFIX+"/media/:mediaType/url/set", SetMediaUrl(widgetService))
} }

View File

@ -5,46 +5,48 @@ import (
"donat-widget/internal/model/api" "donat-widget/internal/model/api"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/jackc/pgx/v5/pgconn"
) )
type WidgetService interface { type WidgetService interface {
CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID, duration Duration, minAmount DonatAmount) (WidgetID, error) CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID, duration Duration, minAmount DonatAmount) (WidgetID, error)
DeleteWidget(ctx context.Context, widgetID WidgetID) error
UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error GetWidgetByID(ctx context.Context, widgetID WidgetID) ([]*Widget, error)
GetWidgetInfo(ctx context.Context, widgetID WidgetID) (*DonatAndWidget, error) GetWidgetHTML(ctx context.Context, streamerID StreamerID) (WidgetHTML, error)
GetWidgetHTML(ctx context.Context, widgetID WidgetID) (WidgetHTML, error) GetMediaFile(ctx context.Context, widgetID WidgetID, mediaType MediaType) (DownloadFile, error)
SetMediaFile(ctx context.Context, mediaType MediaType, widgetID WidgetID, file UploadFile, filename string, size int64, collection string) error SetMediaFile(ctx context.Context, mediaType MediaType, widgetID WidgetID, file UploadFile, filename string, size int64, collection string) error
SetMediaUrl(ctx context.Context, mediaType MediaType, widgetID WidgetID, mediaURL MediaUrl) error SetMediaUrl(ctx context.Context, mediaType MediaType, widgetID WidgetID, mediaURL MediaUrl) error
UpdateMediaFile(ctx context.Context, widgetID WidgetID, mediaType MediaType, file UploadFile, filename string, size int64, collection string) error
GetMediaFile(ctx context.Context, widgetID WidgetID, mediaType MediaType) (DownloadFile, error)
} }
type WidgetRepo interface { type WidgetRepo interface {
CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID, duration Duration, minAmount DonatAmount) (WidgetID, error) CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID, duration Duration, minAmount DonatAmount) (WidgetID, error)
DeleteWidget(ctx context.Context, widgetID WidgetID) error
UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error GetWidgetByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Widget, error)
GetWidget(ctx context.Context, widgetID WidgetID) (*Widget, error) GetWidgetByID(ctx context.Context, widgetID WidgetID) ([]*Widget, error)
GetAllWidget(ctx context.Context, streamerID StreamerID) ([]*Widget, error) GetAllWidget(ctx context.Context, streamerID StreamerID) ([]*Widget, error)
SetMediaFile(file UploadFile, filename string, size int64, collection string) (FileID, error)
GetMediaFile(fileID FileID) (DownloadFile, error) GetMediaFile(fileID FileID) (DownloadFile, error)
GetMediaUrl(ctx context.Context, widgetID WidgetID, mediaType MediaType) (MediaUrl, error) GetMediaUrl(ctx context.Context, widgetID WidgetID, mediaType MediaType) (MediaUrl, error)
SetMediaFile(file UploadFile, filename string, size int64, collection string) (FileID, error)
SetMediaUrl(ctx context.Context, widgetID WidgetID, mediaUrl MediaUrl, mediaType MediaType) error SetMediaUrl(ctx context.Context, widgetID WidgetID, mediaUrl MediaUrl, mediaType MediaType) error
UpdateMediaFile(ctx context.Context, widgetID WidgetID, file UploadFile, fileID FileID, filename string, size int64, collection string, mediaType MediaType) error
} }
type DonatService interface { type DonatService interface {
CreateDonat(ctx context.Context, streamerID StreamerID, orderID OrderID, targetID TargetID, amount DonatAmount, text string, donatUser string) (api.CreatePaymentResponse, error) CreateDonat(ctx context.Context, streamerID StreamerID, orderID OrderID, targetID TargetID, amount DonatAmount, text string, donatUser string) (api.CreatePaymentResponse, error)
GetDonatByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Donat, error)
GetDonatByOrderID(ctx context.Context, orderID OrderID) (*Donat, error) GetDonatByOrderID(ctx context.Context, orderID OrderID) (*Donat, error)
MarkDonatPaid(ctx context.Context, orderID OrderID) error MarkDonatPaid(ctx context.Context, orderID OrderID) error
MarkDonatView(ctx context.Context, DonatID DonatID) error MarkDonatView(ctx context.Context, DonatID DonatID) error
} }
type DonatRepo interface { type DonatRepo interface {
CreateDonat(ctx context.Context, widgetID WidgetID, orderID OrderID, targetID TargetID, amount DonatAmount, text string, donatUser string) error CreateDonat(ctx context.Context, widgetID WidgetID, orderID OrderID, targetID TargetID, amount DonatAmount, text string, donatUser string) error
GetDonat(ctx context.Context, widgetID WidgetID) ([]*Donat, error)
GetDonatByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Donat, error)
GetDonatByOrderID(ctx context.Context, orderID OrderID) (*Donat, error) GetDonatByOrderID(ctx context.Context, orderID OrderID) (*Donat, error)
MarkDonatPaid(ctx context.Context, orderID OrderID) error MarkDonatPaid(ctx context.Context, orderID OrderID) error
MarkDonatView(ctx context.Context, DonatID DonatID) error MarkDonatView(ctx context.Context, DonatID DonatID) error
} }
@ -75,8 +77,11 @@ type PaymentClient interface {
CreatePayment(streamerID StreamerID, amount DonatAmount, orderID OrderID) (api.CreatePaymentResponse, error) CreatePayment(streamerID StreamerID, amount DonatAmount, orderID OrderID) (api.CreatePaymentResponse, error)
} }
type Db interface { type Db interface {
Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error) Insert(ctx context.Context, query string, args ...interface{}) (int64, error)
Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error) Select(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error)
Delete(ctx context.Context, query string, args ...interface{}) error
Update(ctx context.Context, query string, args ...interface{}) error
CreateTable(ctx context.Context, query string) error CreateTable(ctx context.Context, query string) error
DropTable(ctx context.Context, query string) error DropTable(ctx context.Context, query string) error
} }

View File

@ -7,14 +7,14 @@ import (
var CreateWidget = ` var CreateWidget = `
INSERT INTO widgets (streamer_id, template_id, duration, min_amount) INSERT INTO widgets (streamer_id, template_id, duration, min_amount)
VALUES (@streamer_id, @template_id, @duration, @min_amount); VALUES (@streamer_id, @template_id, @duration, @min_amount)
RETURNING id;
` `
var UpdateDuration = ` var GetWidgetByStreamerID = `
UPDATE widgets SELECT * FROM widgets
SET duration = (@duration) WHERE streamer_id = (@streamer_id);
WHERE id = (@id)
` `
var GetWidget = ` var GetWidgetByID = `
SELECT * FROM widgets SELECT * FROM widgets
WHERE id = (@id); WHERE id = (@id);
` `
@ -44,7 +44,8 @@ func GetMediaUrl(mediaType model.MediaType) string {
var CreateDonat = ` var CreateDonat = `
INSERT INTO donats (widget_id, text, amount, donat_user, order_id, target_id) INSERT INTO donats (widget_id, text, amount, donat_user, order_id, target_id)
VALUES (@widget_id, @text, @amount, @donat_user, @order_id, @target_id); VALUES (@widget_id, @text, @amount, @donat_user, @order_id, @target_id)
RETURNING id;
` `
var MarkDonatView = ` var MarkDonatView = `
UPDATE donats UPDATE donats
@ -56,9 +57,9 @@ UPDATE donats
SET paid = (@paid) SET paid = (@paid)
WHERE order_id = (@order_id); WHERE order_id = (@order_id);
` `
var GetDonat = ` var GetDonatByStreamerID = `
SELECT * FROM donats SELECT * FROM donats
WHERE widget_id = (@widget_id) AND paid = (@paid) AND view = (@view); WHERE streamer_id = (@streamer_id) AND paid = (@paid) AND view = (@view);
` `
var GetDonatByOrderID = ` var GetDonatByOrderID = `
SELECT * FROM donats SELECT * FROM donats
@ -67,7 +68,8 @@ WHERE order_id = (@order_id);
var CreateTarget = ` var CreateTarget = `
INSERT INTO targets (streamer_id, text, amount) INSERT INTO targets (streamer_id, text, amount)
VALUES (@streamer_id, @text, @amount); VALUES (@streamer_id, @text, @amount)
RETURNING id;
` `
var GetAllTarget = ` var GetAllTarget = `

View File

@ -3,7 +3,7 @@ package model
import "fmt" import "fmt"
func GetTemplate1( func GetTemplate1(
widgetID WidgetID, streamerID StreamerID,
backgroundUrl MediaUrl, backgroundUrl MediaUrl,
) WidgetHTML { ) WidgetHTML {
@ -41,19 +41,23 @@ func GetTemplate1(
`, backgroundUrl) `, backgroundUrl)
script := fmt.Sprintf(` script := fmt.Sprintf(`
let widgetID = '%v'
let baseUrl = 'http://92.118.114.148:8002/api/widget'
function delay(ms) { function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
async function getWidgetInfo() { async def getDonatInfo(streamerID) {
let response = await fetch(baseUrl + '/info/' + widgetID); let response = await fetch(baseUrl + '/donat/get/' + streamerID);
let donat = await response.json();
}
async function getWidgetInfo(widgetID) {
let response = await fetch(baseUrl + '/widget/info/' + widgetID);
let widget = await response.json(); let widget = await response.json();
return widget return widget
} }
function addImage(imageUrl) { function addImage(imageUrl) {
img = document.createElement('img'); img = document.createElement('img');
img.src = imageUrl + '?t=' + new Date().getTime(); img.src = imageUrl + '?t=' + new Date().getTime();
@ -89,23 +93,31 @@ let audio;
const contentDiv = document.getElementById('content'); const contentDiv = document.getElementById('content');
async function widgetView() { async function widgetView() {
let baseUrl = 'http://92.118.114.148:8002/api'
let streamerID = '%v'
while (true) { while (true) {
let widget = await getWidgetInfo() let donat = await getDonatInfo(streamerID);
console.log(widget);
if (!widget.display) { if (!donat) {
await delay(5 * 1000); await delay(5 * 1000);
continue continue
} }
donat = donat[0]
widgetID = donat.widgwtID
let widget = await getWidgetInfo(widgetID)
addImage(widget.imageUrl) addImage(widget.imageUrl)
addText(widget.text + widget.amount)
addAudio(widget.audioUrl) addAudio(widget.audioUrl)
addText(donat.text + donat.amount)
await delay(widget.duration * 1000); await delay(widget.duration * 1000);
await endDonat(widget.donatID) await endDonat(donat.ID)
} }
} }
widgetView()`, widgetID) widgetView()`, streamerID)
template1 := fmt.Sprintf(`<!DOCTYPE html> template1 := fmt.Sprintf(`<!DOCTYPE html>
<html> <html>

View File

@ -37,34 +37,34 @@ func (repoDonat *RepoDonat) CreateDonat(
"amount": amount, "amount": amount,
"donat_user": donatUser, "donat_user": donatUser,
} }
_, err := repoDonat.db.Query(ctx, sql.CreateDonat, args) _, err := repoDonat.db.Insert(ctx, sql.CreateDonat, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error(err.Error())
return err return err
} }
return nil return nil
} }
func (repoDonat *RepoDonat) GetDonat( func (repoDonat *RepoDonat) GetDonatByStreamerID(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, streamerID model.StreamerID,
) ([]*model.Donat, error) { ) ([]*model.Donat, error) {
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"widget_id": widgetID, "streamer_id": streamerID,
"paid": true, "paid": true,
"view": false, "view": false,
} }
rows, err := repoDonat.db.Query(ctx, sql.GetDonat, args) rows, err := repoDonat.db.Select(ctx, sql.GetDonatByStreamerID, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
var donats []*model.Donat var donats []*model.Donat
err = pgxscan.ScanAll(&donats, rows) err = pgxscan.ScanAll(&donats, rows)
if err != nil { if err != nil {
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -78,16 +78,16 @@ func (repoDonat *RepoDonat) GetDonatByOrderID(
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"order_id": orderID, "order_id": orderID,
} }
rows, err := repoDonat.db.Query(ctx, sql.GetDonatByOrderID, args) rows, err := repoDonat.db.Select(ctx, sql.GetDonatByOrderID, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
var donats []*model.Donat var donats []*model.Donat
err = pgxscan.ScanAll(&donats, rows) err = pgxscan.ScanAll(&donats, rows)
if err != nil { if err != nil {
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
if len(donats) == 0 { if len(donats) == 0 {
@ -105,9 +105,9 @@ func (repoDonat *RepoDonat) MarkDonatView(
"id": donatID, "id": donatID,
"view": true, "view": true,
} }
_, err := repoDonat.db.Query(ctx, sql.MarkDonatView, args) err := repoDonat.db.Update(ctx, sql.MarkDonatView, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error(err.Error())
return err return err
} }
@ -122,9 +122,9 @@ func (repoDonat *RepoDonat) MarkDonatPaid(
"order_id": orderID, "order_id": orderID,
"paid": true, "paid": true,
} }
_, err := repoDonat.db.Query(ctx, sql.MarkDonatPaid, args) err := repoDonat.db.Update(ctx, sql.MarkDonatPaid, args)
if err != nil { if err != nil {
slog.Error("repoDonat.db.Query: " + err.Error()) slog.Error(err.Error())
return err return err
} }

View File

@ -32,9 +32,9 @@ func (targetRepo *RepoTarget) CreateTarget(
"text": text, "text": text,
} }
_, err := targetRepo.db.Query(ctx, sql.CreateTarget, args) _, err := targetRepo.db.Insert(ctx, sql.CreateTarget, args)
if err != nil { if err != nil {
slog.Error("targetRepo.db.Query", err) slog.Error(err.Error())
return err return err
} }
return nil return nil
@ -47,9 +47,9 @@ func (targetRepo *RepoTarget) GetAllTarget(
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"streamer_id": streamerID, "streamer_id": streamerID,
} }
rows, err := targetRepo.db.Query(ctx, sql.GetAllTarget, args) rows, err := targetRepo.db.Select(ctx, sql.GetAllTarget, args)
if err != nil { if err != nil {
slog.Error("targetRepo.db.Query", err) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -76,9 +76,9 @@ func (targetRepo *RepoTarget) AddAmountToTarget(
"target_id": targetID, "target_id": targetID,
"amount": amount, "amount": amount,
} }
_, err := targetRepo.db.Query(ctx, sql.AddAmountToTarget, args) err := targetRepo.db.Update(ctx, sql.AddAmountToTarget, args)
if err != nil { if err != nil {
slog.Error("targetRepo.db.Query", err) slog.Error(err.Error())
return err return err
} }
return nil return nil

View File

@ -38,26 +38,23 @@ func (widgetRepo *RepoWidget) CreateWidget(
"duration": duration, "duration": duration,
"min_amount": minAmount, "min_amount": minAmount,
} }
_, err := widgetRepo.db.Query(ctx, sql.CreateWidget, args) widgetID, err := widgetRepo.db.Insert(ctx, sql.CreateWidget, args)
if err != nil { if err != nil {
slog.Error("widgetRepo.db.Query: " + err.Error()) slog.Error(err.Error())
return 0, err return 0, err
} }
widgetID := 9
return model.WidgetID(widgetID), nil return model.WidgetID(widgetID), nil
} }
func (widgetRepo *RepoWidget) GetWidget( func (widgetRepo *RepoWidget) GetWidgetByStreamerID(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, streamerID model.StreamerID,
) (*model.Widget, error) { ) ([]*model.Widget, error) {
args := pgx.NamedArgs{ args := pgx.NamedArgs{"streamer_id": streamerID}
"id": widgetID, rows, err := widgetRepo.db.Select(ctx, sql.GetWidgetByStreamerID, args)
}
rows, err := widgetRepo.db.Query(ctx, sql.GetWidget, args)
if err != nil { if err != nil {
slog.Error("widgetRepo.db.Query: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -68,15 +65,28 @@ func (widgetRepo *RepoWidget) GetWidget(
return nil, err return nil, err
} }
if len(widgets) == 0 { return widgets, nil
slog.Error("Widget not found") }
return nil, errors.New("widget not found")
func (widgetRepo *RepoWidget) GetWidgetByID(
ctx context.Context,
widgetID model.WidgetID,
) ([]*model.Widget, error) {
args := pgx.NamedArgs{"id": widgetID}
rows, err := widgetRepo.db.Select(ctx, sql.GetWidgetByID, args)
if err != nil {
slog.Error(err.Error())
return nil, err
} }
widget := widgets[0] var widgets []*model.Widget
widget.NormalizeUrl() err = pgxscan.ScanAll(&widgets, rows)
if err != nil {
slog.Error(err.Error())
return nil, err
}
return widget, nil return widgets, nil
} }
func (widgetRepo *RepoWidget) GetAllWidget( func (widgetRepo *RepoWidget) GetAllWidget(
@ -86,9 +96,9 @@ func (widgetRepo *RepoWidget) GetAllWidget(
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"streamer_id": streamerID, "streamer_id": streamerID,
} }
rows, err := widgetRepo.db.Query(ctx, sql.GetAllWidget, args) rows, err := widgetRepo.db.Select(ctx, sql.GetAllWidget, args)
if err != nil { if err != nil {
slog.Error("widgetRepo.db.Query: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -98,38 +108,10 @@ func (widgetRepo *RepoWidget) GetAllWidget(
slog.Error(err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
if len(widgets) == 0 {
return nil, errors.New("donat not found")
}
return widgets, nil return widgets, nil
} }
func (widgetRepo *RepoWidget) DeleteWidget(
ctx context.Context,
widgetID model.WidgetID,
) error {
panic("implement me")
}
func (widgetRepo *RepoWidget) UpdateDuration(
ctx context.Context,
widgetID model.WidgetID,
duration model.Duration,
) error {
args := pgx.NamedArgs{
"id": widgetID,
"duration": duration,
}
_, err := widgetRepo.db.Query(ctx, sql.UpdateDuration, args)
if err != nil {
slog.Error("widgetRepo.db.Query: " + err.Error())
return err
}
return nil
}
func (widgetRepo *RepoWidget) SetMediaFile( func (widgetRepo *RepoWidget) SetMediaFile(
file model.UploadFile, file model.UploadFile,
filename string, filename string,
@ -138,7 +120,7 @@ func (widgetRepo *RepoWidget) SetMediaFile(
) (model.FileID, error) { ) (model.FileID, error) {
fileData, err := widgetRepo.storage.Upload(file, filename, size, collection) fileData, err := widgetRepo.storage.Upload(file, filename, size, collection)
if err != nil { if err != nil {
slog.Error("repoMedia.storage.Upload: " + err.Error()) slog.Error(err.Error())
return "", err return "", err
} }
@ -150,7 +132,7 @@ func (widgetRepo *RepoWidget) GetMediaFile(
) (model.DownloadFile, error) { ) (model.DownloadFile, error) {
file, err := widgetRepo.storage.Download(fileID) file, err := widgetRepo.storage.Download(fileID)
if err != nil { if err != nil {
slog.Error("repoMedia.storage.Download: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -169,7 +151,7 @@ func (widgetRepo *RepoWidget) UpdateMediaFile(
) error { ) error {
err := widgetRepo.storage.Update(file, fileID, filename, size, collection) err := widgetRepo.storage.Update(file, fileID, filename, size, collection)
if err != nil { if err != nil {
slog.Error("repoMedia.storage.Update: " + err.Error()) slog.Error(err.Error())
return err return err
} }
@ -178,9 +160,9 @@ func (widgetRepo *RepoWidget) UpdateMediaFile(
string(mediaType): model.MediaUrl(fileID), string(mediaType): model.MediaUrl(fileID),
"id": widgetID, "id": widgetID,
} }
_, err = widgetRepo.db.Query(ctx, sql.UpdateMediaUrl(mediaType), args) err = widgetRepo.db.Update(ctx, sql.UpdateMediaUrl(mediaType), args)
if err != nil { if err != nil {
slog.Error("repoMedia.db.Query: " + err.Error()) slog.Error(err.Error())
return err return err
} }
@ -199,9 +181,9 @@ func (widgetRepo *RepoWidget) SetMediaUrl(
string(mediaType): mediaUrl, string(mediaType): mediaUrl,
"id": widgetID, "id": widgetID,
} }
_, err := widgetRepo.db.Query(ctx, sql.UpdateMediaUrl(mediaType), args) err := widgetRepo.db.Update(ctx, sql.UpdateMediaUrl(mediaType), args)
if err != nil { if err != nil {
slog.Error("repoMedia.db.Query: " + err.Error()) slog.Error(err.Error())
return err return err
} }
return nil return nil
@ -216,16 +198,16 @@ func (widgetRepo *RepoWidget) GetMediaUrl(
args := pgx.NamedArgs{ args := pgx.NamedArgs{
"id": widgetID, "id": widgetID,
} }
rows, err := widgetRepo.db.Query(ctx, sql.GetMediaUrl(mediaType), args) rows, err := widgetRepo.db.Select(ctx, sql.GetMediaUrl(mediaType), args)
if err != nil { if err != nil {
slog.Error("repoMedia.db.Query: " + err.Error()) slog.Error(err.Error())
return "", err return "", err
} }
var widgets []*model.Widget var widgets []*model.Widget
err = pgxscan.ScanAll(&widgets, rows) err = pgxscan.ScanAll(&widgets, rows)
if err != nil { if err != nil {
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error()) slog.Error(err.Error())
return "", err return "", err
} }

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/api" "donat-widget/internal/model/api"
"fmt"
"log/slog" "log/slog"
) )
@ -37,10 +36,9 @@ func (donatService *ServiceDonat) CreateDonat(
) (api.CreatePaymentResponse, error) { ) (api.CreatePaymentResponse, error) {
widgets, err := donatService.widgetRepo.GetAllWidget(ctx, streamerID) widgets, err := donatService.widgetRepo.GetAllWidget(ctx, streamerID)
if err != nil { if err != nil {
slog.Error("donatService.widgetRepo.GetAllWidget: ", err) slog.Error(err.Error())
return api.CreatePaymentResponse{}, err return api.CreatePaymentResponse{}, err
} }
fmt.Println(widgets)
var widgetID model.WidgetID var widgetID model.WidgetID
for _, widget := range widgets { for _, widget := range widgets {
@ -50,35 +48,41 @@ func (donatService *ServiceDonat) CreateDonat(
} }
err = donatService.donatRepo.CreateDonat( err = donatService.donatRepo.CreateDonat(
ctx, ctx, widgetID, orderID, targetID, amount, text, donatUser,
widgetID,
orderID,
targetID,
amount,
text,
donatUser,
) )
if err != nil { if err != nil {
slog.Error("donatService.donatRepo.CreateDonat: " + err.Error()) slog.Error(err.Error())
return api.CreatePaymentResponse{}, err return api.CreatePaymentResponse{}, err
} }
createPaymentResponse, err := donatService.paymentClient.CreatePayment(streamerID, amount, orderID) createPaymentResponse, err := donatService.paymentClient.CreatePayment(streamerID, amount, orderID)
if err != nil { if err != nil {
slog.Error("donatService.paymentClient.CreatePayment: " + err.Error()) slog.Error(err.Error())
return api.CreatePaymentResponse{}, err return api.CreatePaymentResponse{}, err
} }
return createPaymentResponse, nil return createPaymentResponse, nil
} }
func (donatService *ServiceDonat) GetDonatByStreamerID(
ctx context.Context,
streamerID model.StreamerID,
) ([]*model.Donat, error) {
donats, err := donatService.donatRepo.GetDonatByStreamerID(ctx, streamerID)
if err != nil {
slog.Error(err.Error())
return nil, err
}
return donats, nil
}
func (donatService *ServiceDonat) GetDonatByOrderID( func (donatService *ServiceDonat) GetDonatByOrderID(
ctx context.Context, ctx context.Context,
orderID model.OrderID, orderID model.OrderID,
) (*model.Donat, error) { ) (*model.Donat, error) {
donat, err := donatService.donatRepo.GetDonatByOrderID(ctx, orderID) donat, err := donatService.donatRepo.GetDonatByOrderID(ctx, orderID)
if err != nil { if err != nil {
slog.Error("donatService.donatRepo.GetDonatByOrderID: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
return donat, nil return donat, nil
@ -93,7 +97,7 @@ func (donatService *ServiceDonat) MarkDonatPaid(
orderID, orderID,
) )
if err != nil { if err != nil {
slog.Error("donatService.donatRepo.MarkDonatView: " + err.Error()) slog.Error(err.Error())
return err return err
} }
return nil return nil

View File

@ -26,7 +26,7 @@ func (targetService *ServiceTarget) CreateTarget(
) error { ) error {
err := targetService.targetRepo.CreateTarget(ctx, streamerID, amount, text) err := targetService.targetRepo.CreateTarget(ctx, streamerID, amount, text)
if err != nil { if err != nil {
slog.Error("targetService.CreateTarget: ", err) slog.Error(err.Error())
return err return err
} }
return nil return nil
@ -38,7 +38,7 @@ func (targetService *ServiceTarget) GetAllTarget(
) ([]*model.Target, error) { ) ([]*model.Target, error) {
targets, err := targetService.targetRepo.GetAllTarget(ctx, streamerID) targets, err := targetService.targetRepo.GetAllTarget(ctx, streamerID)
if err != nil { if err != nil {
slog.Error("targetService.GetAllTarget: ", err) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -52,7 +52,7 @@ func (targetService *ServiceTarget) AddAmountToTarget(
) error { ) error {
err := targetService.targetRepo.AddAmountToTarget(ctx, targetID, amount) err := targetService.targetRepo.AddAmountToTarget(ctx, targetID, amount)
if err != nil { if err != nil {
slog.Error("targetService.AddAmountToTarget: ", err) slog.Error(err.Error())
return err return err
} }
return nil return nil

View File

@ -3,22 +3,20 @@ package widget
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"errors"
"log/slog" "log/slog"
) )
func New( func New(
widgetRepo model.WidgetRepo, widgetRepo model.WidgetRepo,
donatRepo model.DonatRepo,
) *ServiceWidget { ) *ServiceWidget {
return &ServiceWidget{ return &ServiceWidget{
widgetRepo: widgetRepo, widgetRepo: widgetRepo,
donatRepo: donatRepo,
} }
} }
type ServiceWidget struct { type ServiceWidget struct {
widgetRepo model.WidgetRepo widgetRepo model.WidgetRepo
donatRepo model.DonatRepo
} }
func (widgetService *ServiceWidget) CreateWidget( func (widgetService *ServiceWidget) CreateWidget(
@ -36,90 +34,50 @@ func (widgetService *ServiceWidget) CreateWidget(
minAmount, minAmount,
) )
if err != nil { if err != nil {
slog.Error("widgetService.widgetRepo.CreateWidget: " + err.Error()) slog.Error(err.Error())
return 0, err return 0, err
} }
return widgetID, nil return widgetID, nil
} }
func (widgetService *ServiceWidget) DeleteWidget(
ctx context.Context,
widgetID model.WidgetID,
) error {
err := widgetService.widgetRepo.DeleteWidget(ctx, widgetID)
if err != nil {
slog.Error("widgetService.widgetRepo.DeleteWidget: " + err.Error())
return err
}
return nil
}
func (widgetService *ServiceWidget) UpdateDuration(
ctx context.Context,
widgetID model.WidgetID,
duration model.Duration,
) error {
err := widgetService.widgetRepo.UpdateDuration(ctx, widgetID, duration)
if err != nil {
slog.Error("widgetService.widgetRepo.UpdateDuration: " + err.Error())
return err
}
return nil
}
func (widgetService *ServiceWidget) GetWidgetHTML( func (widgetService *ServiceWidget) GetWidgetHTML(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, streamerID model.StreamerID,
) (model.WidgetHTML, error) { ) (model.WidgetHTML, error) {
var widgetHTML model.WidgetHTML
widget, err := widgetService.widgetRepo.GetWidget(ctx, widgetID) widgets, err := widgetService.widgetRepo.GetWidgetByStreamerID(ctx, streamerID)
if err != nil { if err != nil {
slog.Error("widgetService.widgetRepo.GetWidget: " + err.Error()) slog.Error(err.Error())
return widgetHTML, err return "", err
} }
if len(widgets) == 0 {
return "", errors.New("widget not found")
}
widget := widgets[0]
var widgetHTML model.WidgetHTML
if widget.TemplateID == 1 { if widget.TemplateID == 1 {
widgetHTML = model.GetTemplate1( widgetHTML = model.GetTemplate1(
widgetID, streamerID,
widget.BackgroundUrl, widget.BackgroundUrl,
) )
} }
return widgetHTML, nil return widgetHTML, nil
} }
func (widgetService *ServiceWidget) GetWidgetInfo( func (widgetService *ServiceWidget) GetWidgetByID(
ctx context.Context, ctx context.Context,
widgetID model.WidgetID, widgetID model.WidgetID,
) (*model.DonatAndWidget, error) { ) ([]*model.Widget, error) {
widget, err := widgetService.widgetRepo.GetWidget(ctx, widgetID) widget, err := widgetService.widgetRepo.GetWidgetByID(ctx, widgetID)
if err != nil { if err != nil {
slog.Error("widgetService.widgetRepo.GetWidget: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
donats, err := widgetService.donatRepo.GetDonat(ctx, widgetID) return widget, nil
if err != nil {
slog.Error("widgetService.donatRepo.GetDonat: " + err.Error())
return nil, err
}
var donatAndWidget model.DonatAndWidget
if len(donats) == 0 {
donatAndWidget = model.DonatAndWidget{
Display: false,
}
} else {
donatAndWidget = model.DonatAndWidget{
Widget: widget,
Donat: donats[0],
Display: true,
}
}
return &donatAndWidget, nil
} }
func (widgetService *ServiceWidget) SetMediaFile( func (widgetService *ServiceWidget) SetMediaFile(
@ -138,7 +96,7 @@ func (widgetService *ServiceWidget) SetMediaFile(
collection, collection,
) )
if err != nil { if err != nil {
slog.Error("mediaService.mediaRepo.SetMediaFile: " + err.Error()) slog.Error(err.Error())
return err return err
} }
@ -149,7 +107,7 @@ func (widgetService *ServiceWidget) SetMediaFile(
model.MediaUrl(fileID), model.MediaUrl(fileID),
) )
if err != nil { if err != nil {
slog.Error("mediaService.SetMediaUrl: " + err.Error()) slog.Error(err.Error())
return err return err
} }
@ -167,7 +125,7 @@ func (widgetService *ServiceWidget) GetMediaFile(
mediaType, mediaType,
) )
if err != nil { if err != nil {
slog.Error("mediaService.mediaRepo.GetMediaUrl: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
@ -175,48 +133,12 @@ func (widgetService *ServiceWidget) GetMediaFile(
model.FileID(fileID), model.FileID(fileID),
) )
if err != nil { if err != nil {
slog.Error("mediaService.mediaRepo.GetMediaFile: " + err.Error()) slog.Error(err.Error())
return nil, err return nil, err
} }
return file, nil return file, nil
} }
func (widgetService *ServiceWidget) UpdateMediaFile(
ctx context.Context,
widgetID model.WidgetID,
mediaType model.MediaType,
file model.UploadFile,
filename string,
size int64,
collection string,
) error {
fileID, err := widgetService.widgetRepo.GetMediaUrl(
ctx,
widgetID,
mediaType,
)
if err != nil {
slog.Error("mediaService.mediaRepo.GetMediaUrl: " + err.Error())
return err
}
err = widgetService.widgetRepo.UpdateMediaFile(
ctx,
widgetID,
file,
model.FileID(fileID),
filename,
size,
collection,
mediaType,
)
if err != nil {
slog.Error("mediaService.mediaRepo.UpdateMediaFile: " + err.Error())
return err
}
return nil
}
func (widgetService *ServiceWidget) SetMediaUrl( func (widgetService *ServiceWidget) SetMediaUrl(
ctx context.Context, ctx context.Context,
mediaType model.MediaType, mediaType model.MediaType,
@ -230,7 +152,7 @@ func (widgetService *ServiceWidget) SetMediaUrl(
mediaType, mediaType,
) )
if err != nil { if err != nil {
slog.Error("mediaService.mediaRepo.SetMediaUrl: " + err.Error()) slog.Error(err.Error())
return err return err
} }
return nil return nil

15
pkg/logger/logger.go Normal file
View File

@ -0,0 +1,15 @@
package logger
import (
"log/slog"
"os"
)
func New() {
opts := &slog.HandlerOptions{
Level: slog.LevelDebug,
AddSource: true,
}
logger := slog.New(slog.NewJSONHandler(os.Stdout, opts))
slog.SetDefault(logger)
}