From c259b0f34c27b59e290821324135216c359648b1 Mon Sep 17 00:00:00 2001 From: mm Date: Mon, 21 Oct 2024 10:31:25 +0500 Subject: [PATCH] dev --- internal/api/http/handlers/donat/donat.go | 15 ++-- internal/api/http/handlers/widget/widget.go | 24 ++++--- internal/app/http/app.go | 14 ++-- internal/config/config.yaml | 10 +-- internal/model/interfaces.go | 16 +++-- internal/model/sql/model.go | 6 +- internal/model/sql/query.go | 23 ++++-- internal/model/widget-templates.go | 2 +- internal/repository/donat/donat.go | 4 +- internal/repository/target/target.go | 80 +++++++++++++++++++++ internal/repository/widget/widget.go | 19 +++-- internal/service/donat/donat.go | 19 +++-- internal/service/target/target.go | 18 +++++ internal/service/widget/widget.go | 10 ++- 14 files changed, 209 insertions(+), 51 deletions(-) diff --git a/internal/api/http/handlers/donat/donat.go b/internal/api/http/handlers/donat/donat.go index 5077ca2..750fa0c 100644 --- a/internal/api/http/handlers/donat/donat.go +++ b/internal/api/http/handlers/donat/donat.go @@ -11,7 +11,7 @@ import ( ) func CreateDonat(donatService model.DonatService) echo.HandlerFunc { - type Body struct { + type CreateDonatBody struct { StreamerID model.StreamerID `json:"streamerID"` TargetID model.TargetID `json:"targetID"` Amount model.DonatAmount `json:"amount"` @@ -20,7 +20,7 @@ func CreateDonat(donatService model.DonatService) echo.HandlerFunc { } return func(request echo.Context) error { ctx := context.Background() - var body Body + var body CreateDonatBody if err := request.Bind(&body); err != nil { slog.Error(err.Error()) return echo.NewHTTPError(400, err.Error()) @@ -32,29 +32,30 @@ func CreateDonat(donatService model.DonatService) echo.HandlerFunc { orderID := model.OrderID(uuid.New().String()) - err := donatService.CreateDonat( + order, err := donatService.CreateDonat( ctx, body.StreamerID, orderID, + body.TargetID, body.Amount, body.Text, body.DonatUser, ) if err != nil { - return request.JSON(500, "Set donat error") + return request.JSON(500, "Create donat error") } - return request.String(200, "Set donat success") + return request.JSON(http.StatusCreated, order) } } func MarkDonatPaid(donatService model.DonatService) echo.HandlerFunc { - type Body struct { + type MarkDonatPaidBody struct { OrderID model.OrderID `json:"orderID"` } return func(request echo.Context) error { ctx := context.Background() - var body Body + var body MarkDonatPaidBody if err := request.Bind(&body); err != nil { slog.Error(err.Error()) return echo.NewHTTPError(400, err.Error()) diff --git a/internal/api/http/handlers/widget/widget.go b/internal/api/http/handlers/widget/widget.go index 4869abb..a5255a4 100644 --- a/internal/api/http/handlers/widget/widget.go +++ b/internal/api/http/handlers/widget/widget.go @@ -10,8 +10,10 @@ import ( func CreateWidget(widgetService model.WidgetService) echo.HandlerFunc { type Body struct { - StreamerID model.StreamerID `json:"streamerID" validate:"required"` - TemplateID model.TemplateID `json:"templateID" validate:"required"` + StreamerID model.StreamerID `json:"streamerID"` + TemplateID model.TemplateID `json:"templateID"` + MinAmount model.DonatAmount `json:"minAmount"` + Duration model.Duration `json:"duration"` } type Response struct { @@ -31,6 +33,8 @@ func CreateWidget(widgetService model.WidgetService) echo.HandlerFunc { ctx, body.StreamerID, body.TemplateID, + body.Duration, + body.MinAmount, ) if err != nil { return request.JSON(422, "Create widget error") @@ -140,7 +144,7 @@ func UpdateDuration(widgetService model.WidgetService) echo.HandlerFunc { } } -func SetMediaFile(service model.MediaService) echo.HandlerFunc { +func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { return func(request echo.Context) error { ctx := context.Background() @@ -161,7 +165,7 @@ func SetMediaFile(service model.MediaService) echo.HandlerFunc { return echo.NewHTTPError(500, "File is invalid") } - err = service.SetMediaFile( + err = widgetService.SetMediaFile( ctx, model.MediaType(mediaType), model.WidgetID(widgetID), @@ -178,7 +182,7 @@ func SetMediaFile(service model.MediaService) echo.HandlerFunc { } } -func GetMediaFile(service model.MediaService) echo.HandlerFunc { +func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { return func(request echo.Context) error { ctx := context.Background() @@ -191,7 +195,7 @@ func GetMediaFile(service model.MediaService) echo.HandlerFunc { return echo.NewHTTPError(400, "Path parameter 'widgetID' is invalid") } - file, err := service.GetMediaFile( + file, err := widgetService.GetMediaFile( ctx, model.WidgetID(widgetID), model.MediaType(mediaType), @@ -204,7 +208,7 @@ func GetMediaFile(service model.MediaService) echo.HandlerFunc { } } -func UpdateMediaFile(service model.MediaService) echo.HandlerFunc { +func UpdateMediaFile(widgetService model.WidgetService) echo.HandlerFunc { return func(request echo.Context) error { ctx := context.Background() @@ -225,7 +229,7 @@ func UpdateMediaFile(service model.MediaService) echo.HandlerFunc { return echo.NewHTTPError(500, "File is invalid") } - err = service.UpdateMediaFile( + err = widgetService.UpdateMediaFile( ctx, model.WidgetID(widgetID), model.MediaType(mediaType), @@ -243,7 +247,7 @@ func UpdateMediaFile(service model.MediaService) echo.HandlerFunc { } } -func SetMediaUrl(service model.MediaService) echo.HandlerFunc { +func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc { type Body struct { WidgetID model.WidgetID `json:"widgetID" validate:"required"` MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"` @@ -261,7 +265,7 @@ func SetMediaUrl(service model.MediaService) echo.HandlerFunc { mediaType := request.Param("mediaType") - err := service.SetMediaUrl( + err := widgetService.SetMediaUrl( ctx, model.MediaType(mediaType), body.WidgetID, diff --git a/internal/app/http/app.go b/internal/app/http/app.go index a2b6a7d..6d99600 100644 --- a/internal/app/http/app.go +++ b/internal/app/http/app.go @@ -2,7 +2,7 @@ package http import ( "context" - . "donat-widget/internal/api/http/handlers/donat" + "donat-widget/internal/model/sql" "github.com/labstack/echo/v4" "github.com/swaggo/echo-swagger" @@ -15,6 +15,7 @@ import ( ) import ( + . "donat-widget/internal/api/http/handlers/donat" . "donat-widget/internal/api/http/handlers/widget" ) @@ -44,20 +45,23 @@ func IncludeDonatHandlers( ) { server.POST(PREFIX+"/donat/create", CreateDonat(donatService)) server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService)) - server.POST(PREFIX+"/donat/paid/:donatID", MarkDonatPaid(donatService)) + server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService)) } func IncludeWidgetHandlers( server *echo.Echo, widgetService model.WidgetService, ) { + server.POST(PREFIX+"/create", CreateWidget(widgetService)) + server.GET(PREFIX+"/html/:widgetID", GetWidgetHTML(widgetService)) + server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService)) + server.POST(PREFIX+"/media/:mediaType/upload", SetMediaFile(widgetService)) server.POST(PREFIX+"/media/:mediaType/set", SetMediaUrl(widgetService)) server.GET(PREFIX+"/media/:mediaType/get/:widgetID", GetMediaFile(widgetService)) - server.POST(PREFIX+"/create", CreateWidget(widgetService)) + server.PATCH(PREFIX+"/duration/update", UpdateDuration(widgetService)) - server.GET(PREFIX+"/html/:widgetID", GetWidgetHTML(widgetService)) - server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService)) + } func CreateTale(db model.Db) echo.HandlerFunc { diff --git a/internal/config/config.yaml b/internal/config/config.yaml index 3f6a2f6..400aa58 100644 --- a/internal/config/config.yaml +++ b/internal/config/config.yaml @@ -1,9 +1,9 @@ db: port: "5432" - host: "80.87.195.79" - password: "test" - username: "test" - dbname: "test" + host: "db" + password: "postgres" + username: "postgres" + dbname: "postgres" server: port: "8002" @@ -13,5 +13,5 @@ storage: master: "http://92.63.193.151:9333" paymentService: - host: "payment-service" + host: "92.118.114.148" port: "8003" \ No newline at end of file diff --git a/internal/model/interfaces.go b/internal/model/interfaces.go index 6281bea..e082536 100644 --- a/internal/model/interfaces.go +++ b/internal/model/interfaces.go @@ -9,7 +9,7 @@ import ( ) type WidgetService interface { - CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID) (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 GetWidgetInfo(ctx context.Context, widgetID WidgetID) (*DonatAndWidget, error) @@ -21,7 +21,7 @@ type WidgetService interface { } type WidgetRepo interface { - CreateWidget(ctx context.Context, streamerID StreamerID, templateId TemplateID) (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 GetWidget(ctx context.Context, widgetID WidgetID) (*Widget, error) @@ -34,18 +34,26 @@ type WidgetRepo interface { } type DonatService interface { - CreateDonat(ctx context.Context, streamerID StreamerID, orderID OrderID, amount DonatAmount, text string, donatUser string) error + CreateDonat(ctx context.Context, streamerID StreamerID, orderID OrderID, targetID TargetID, amount DonatAmount, text string, donatUser string) (api.CreatePaymentResponse, error) MarkDonatPaid(ctx context.Context, orderID OrderID) error MarkDonatView(ctx context.Context, DonatID DonatID) error } type DonatRepo interface { - CreateDonat(ctx context.Context, widgetID WidgetID, orderID OrderID, 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) MarkDonatPaid(ctx context.Context, orderID OrderID) error MarkDonatView(ctx context.Context, DonatID DonatID) error } +type TargetService interface { + CreateTarget() +} + +type TargetRepo interface { + CreateTarget() +} + type Error interface { Error() string } diff --git a/internal/model/sql/model.go b/internal/model/sql/model.go index 0860556..378d86d 100644 --- a/internal/model/sql/model.go +++ b/internal/model/sql/model.go @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS donats ( id SERIAL PRIMARY KEY, widget_id INTEGER NOT NULL, order_id TEXT NOT NULL, + target_id INTEGER NOT NULL, text TEXT NOT NULL, amount INTEGER NOT NULL, @@ -35,9 +36,12 @@ CREATE TABLE IF NOT EXISTS donats ( CREATE TABLE IF NOT EXISTS targets ( id SERIAL PRIMARY KEY, + streamer_id INTEGER NOT NULL, + text TEXT NOT NULL, amount INTEGER NOT NULL, - collected INTEGER NOT NULL, + collected INTEGER DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ); diff --git a/internal/model/sql/query.go b/internal/model/sql/query.go index 4cd843e..5610408 100644 --- a/internal/model/sql/query.go +++ b/internal/model/sql/query.go @@ -6,8 +6,8 @@ import ( ) var CreateWidget = ` -INSERT INTO widgets (streamer_id, template_id) -VALUES (@streamer_id, @template_id); +INSERT INTO widgets (streamer_id, template_id, duration, min_amount) +VALUES (@streamer_id, @template_id, @duration, @min_amount); ` var UpdateDuration = ` UPDATE widgets @@ -43,8 +43,8 @@ func GetMediaUrl(mediaType model.MediaType) string { } var CreateDonat = ` -INSERT INTO donats (widget_id, text, amount, donat_user, order_id) -VALUES (@widget_id, @text, @amount, @donat_user, @order_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); ` var MarkDonatView = ` UPDATE donats @@ -60,3 +60,18 @@ var GetDonat = ` SELECT * FROM donats WHERE widget_id = (@widget_id) AND paid = (@paid) AND view = (@view); ` + +var CreateTarget = ` +INSERT INTO targets (streamer_id, text, amount) +VALUES (@streamer_id, @text, @amount); +` + +var GetAllTarget = ` +SELECT * FROM targets +WHERE streamer_id = (@streamer_id); +` +var AddAmountToTarget = ` +UPDATE targets +SET amount = amount + (@amount) +WHERE id = (@target_id); +` diff --git a/internal/model/widget-templates.go b/internal/model/widget-templates.go index 2ba6e76..621d70a 100644 --- a/internal/model/widget-templates.go +++ b/internal/model/widget-templates.go @@ -81,7 +81,7 @@ async function endDonat(donatID) { while (contentDiv.firstChild) { contentDiv.removeChild(contentDiv.firstChild); } - let response = await fetch(baseUrl + '/donat/delete/' + String(donatID), {method: 'DELETE'}); + let response = await fetch(baseUrl + '/donat/view/' + String(donatID), {method: 'POST'}); } let audio; diff --git a/internal/repository/donat/donat.go b/internal/repository/donat/donat.go index f056db5..16b4001 100644 --- a/internal/repository/donat/donat.go +++ b/internal/repository/donat/donat.go @@ -23,13 +23,15 @@ func (repoDonat *RepoDonat) CreateDonat( ctx context.Context, widgetID model.WidgetID, orderID model.OrderID, + targetID model.TargetID, amount model.DonatAmount, text string, donatUser string, ) error { - args := model.QueryArgs{ + args := pgx.NamedArgs{ "widget_id": widgetID, "order_id": orderID, + "target_id": targetID, "text": text, "amount": amount, "donat_user": donatUser, diff --git a/internal/repository/target/target.go b/internal/repository/target/target.go index ec6c15d..8d3141c 100644 --- a/internal/repository/target/target.go +++ b/internal/repository/target/target.go @@ -1 +1,81 @@ package target + +import ( + "context" + "donat-widget/internal/model" + "donat-widget/internal/model/sql" + "github.com/georgysavva/scany/v2/pgxscan" + "github.com/jackc/pgx/v5" + "log/slog" +) + +func New(db model.Db) *RepoTarget { + return &RepoTarget{ + db: db, + } +} + +type RepoTarget struct { + db model.Db +} + +func (targetRepo *RepoTarget) CreateTarget( + ctx context.Context, + streamerID model.StreamerID, + amount model.DonatAmount, + text string, +) error { + args := pgx.NamedArgs{ + "streamer_id": streamerID, + "amount": amount, + "text": text, + } + + _, err := targetRepo.db.Query(ctx, sql.CreateTarget, args) + if err != nil { + slog.Error("targetRepo.db.Query", err) + return err + } + return nil +} + +func (targetRepo *RepoTarget) GetAllTarget( + ctx context.Context, + streamerID model.StreamerID, +) ([]*model.Target, error) { + args := pgx.NamedArgs{ + "streamer_id": streamerID, + } + rows, err := targetRepo.db.Query(ctx, sql.GetAllTarget, args) + if err != nil { + slog.Error("targetRepo.db.Query", err) + return nil, err + } + + var targets []*model.Target + err = pgxscan.ScanAll(&targets, rows) + if err != nil { + slog.Error("targetRepo.db.Query", err) + return nil, err + } + + return targets, nil + +} + +func (targetRepo *RepoTarget) AddAmountToTarget( + ctx context.Context, + targetID model.TargetID, + amount model.DonatAmount, +) error { + args := pgx.NamedArgs{ + "target_id": targetID, + "amount": amount, + } + _, err := targetRepo.db.Query(ctx, sql.AddAmountToTarget, args) + if err != nil { + slog.Error("targetRepo.db.Query", err) + return err + } + return nil +} diff --git a/internal/repository/widget/widget.go b/internal/repository/widget/widget.go index 79f3ad9..f4b2cd3 100644 --- a/internal/repository/widget/widget.go +++ b/internal/repository/widget/widget.go @@ -6,6 +6,7 @@ import ( "donat-widget/internal/model/sql" "errors" "github.com/georgysavva/scany/v2/pgxscan" + "github.com/jackc/pgx/v5" "log/slog" ) @@ -28,10 +29,14 @@ func (widgetRepo *RepoWidget) CreateWidget( ctx context.Context, streamerID model.StreamerID, templateID model.TemplateID, + duration model.Duration, + minAmount model.DonatAmount, ) (model.WidgetID, error) { - args := model.QueryArgs{ + args := pgx.NamedArgs{ "streamer_id": streamerID, "template_id": templateID, + "duration": duration, + "min_amount": minAmount, } _, err := widgetRepo.db.Query(ctx, sql.CreateWidget, args) if err != nil { @@ -47,7 +52,7 @@ func (widgetRepo *RepoWidget) GetWidget( ctx context.Context, widgetID model.WidgetID, ) (*model.Widget, error) { - args := model.QueryArgs{ + args := pgx.NamedArgs{ "id": widgetID, } rows, err := widgetRepo.db.Query(ctx, sql.GetWidget, args) @@ -78,7 +83,7 @@ func (widgetRepo *RepoWidget) GetAllWidget( ctx context.Context, streamerID model.StreamerID, ) ([]*model.Widget, error) { - args := model.QueryArgs{ + args := pgx.NamedArgs{ "streamerID": streamerID, } rows, err := widgetRepo.db.Query(ctx, sql.GetAllWidget, args) @@ -109,7 +114,7 @@ func (widgetRepo *RepoWidget) UpdateDuration( widgetID model.WidgetID, duration model.Duration, ) error { - args := model.QueryArgs{ + args := pgx.NamedArgs{ "id": widgetID, "duration": duration, } @@ -166,7 +171,7 @@ func (widgetRepo *RepoWidget) UpdateMediaFile( } mediaType = mediaType + "_url" - args := model.QueryArgs{ + args := pgx.NamedArgs{ string(mediaType): model.MediaUrl(fileID), "id": widgetID, } @@ -187,7 +192,7 @@ func (widgetRepo *RepoWidget) SetMediaUrl( ) error { mediaType = mediaType + "_url" - args := model.QueryArgs{ + args := pgx.NamedArgs{ string(mediaType): mediaUrl, "id": widgetID, } @@ -205,7 +210,7 @@ func (widgetRepo *RepoWidget) GetMediaUrl( mediaType model.MediaType, ) (model.MediaUrl, error) { mediaType = mediaType + "_url" - args := model.QueryArgs{ + args := pgx.NamedArgs{ "id": widgetID, } rows, err := widgetRepo.db.Query(ctx, sql.GetMediaUrl(mediaType), args) diff --git a/internal/service/donat/donat.go b/internal/service/donat/donat.go index b69ee6e..f5bec89 100644 --- a/internal/service/donat/donat.go +++ b/internal/service/donat/donat.go @@ -3,6 +3,7 @@ package donat import ( "context" "donat-widget/internal/model" + "donat-widget/internal/model/api" "log/slog" ) @@ -28,14 +29,15 @@ func (donatService *ServiceDonat) CreateDonat( ctx context.Context, streamerID model.StreamerID, orderID model.OrderID, + targetID model.TargetID, amount model.DonatAmount, text string, donatUser string, -) error { +) (api.CreatePaymentResponse, error) { widgets, err := donatService.widgetRepo.GetAllWidget(ctx, streamerID) if err != nil { slog.Error("donatService.widgetRepo.GetAllWidget: ", err) - return err + return api.CreatePaymentResponse{}, err } var widgetID model.WidgetID @@ -49,16 +51,23 @@ func (donatService *ServiceDonat) CreateDonat( ctx, widgetID, orderID, + targetID, amount, text, donatUser, ) if err != nil { - slog.Error("donatService.donatRepo.SetDonat: " + err.Error()) - return err + slog.Error("donatService.donatRepo.CreateDonat: " + err.Error()) + return api.CreatePaymentResponse{}, err } - return nil + createPaymentResponse, err := donatService.paymentClient.CreatePayment(streamerID, amount, orderID) + if err != nil { + slog.Error("donatService.paymentClient.CreatePayment: " + err.Error()) + return api.CreatePaymentResponse{}, err + } + + return createPaymentResponse, nil } func (donatService *ServiceDonat) MarkDonatPaid( diff --git a/internal/service/target/target.go b/internal/service/target/target.go index ec6c15d..ca51ae0 100644 --- a/internal/service/target/target.go +++ b/internal/service/target/target.go @@ -1 +1,19 @@ package target + +import "donat-widget/internal/model" + +type ServiceDonat struct { + targetRepo model.TargerRep +} + +func New( + donatRepo model.DonatRepo, + widgetRepo model.WidgetRepo, + paymentClient model.PaymentClient, +) *ServiceDonat { + return &ServiceDonat{ + donatRepo: donatRepo, + widgetRepo: widgetRepo, + paymentClient: paymentClient, + } +} diff --git a/internal/service/widget/widget.go b/internal/service/widget/widget.go index d836d27..da13ddc 100644 --- a/internal/service/widget/widget.go +++ b/internal/service/widget/widget.go @@ -25,8 +25,16 @@ func (widgetService *ServiceWidget) CreateWidget( ctx context.Context, streamerID model.StreamerID, templateID model.TemplateID, + duration model.Duration, + minAmount model.DonatAmount, ) (model.WidgetID, error) { - widgetID, err := widgetService.widgetRepo.CreateWidget(ctx, streamerID, templateID) + widgetID, err := widgetService.widgetRepo.CreateWidget( + ctx, + streamerID, + templateID, + duration, + minAmount, + ) if err != nil { slog.Error("widgetService.widgetRepo.CreateWidget: " + err.Error()) return 0, err