dev
This commit is contained in:
parent
b94abfe75b
commit
13a80221ed
40
.github/workflows/CI-CD.yml
vendored
40
.github/workflows/CI-CD.yml
vendored
@ -22,23 +22,23 @@ jobs:
|
|||||||
dockerhub-st.ru/donat-widget:latest
|
dockerhub-st.ru/donat-widget:latest
|
||||||
dockerhub-st.ru/donat-widget:${{ github.sha }}
|
dockerhub-st.ru/donat-widget:${{ github.sha }}
|
||||||
|
|
||||||
# deploy:
|
deploy:
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# steps:
|
steps:
|
||||||
# - name: Checkout code
|
- name: Checkout code
|
||||||
# uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
#
|
|
||||||
# - name: Install kubectl
|
- name: Install kubectl
|
||||||
# uses: azure/setup-kubectl@v1
|
uses: azure/setup-kubectl@v1
|
||||||
# with:
|
with:
|
||||||
# version: 'v1.21.0'
|
version: 'v1.21.0'
|
||||||
#
|
|
||||||
# - name: Configure kube-config
|
- name: Configure kube-config
|
||||||
# run: |
|
run: |
|
||||||
# mkdir -p $HOME/.kube
|
mkdir -p $HOME/.kube
|
||||||
# echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config
|
echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config
|
||||||
# export KUBECONFIG=$HOME/.kube/config
|
export KUBECONFIG=$HOME/.kube/config
|
||||||
#
|
|
||||||
# - name: Update deployment
|
- name: Update deployment
|
||||||
# run: |
|
run: |
|
||||||
# kubectl restart rollout deployment donat-user-deployment
|
kubectl restart rollout deployment donat-user-deployment
|
24
cmd/main.go
24
cmd/main.go
@ -4,29 +4,21 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"donat-widget/internal/app/http"
|
"donat-widget/internal/app/http"
|
||||||
"donat-widget/internal/config"
|
"donat-widget/internal/config"
|
||||||
|
DonatRepo "donat-widget/internal/repository/donat"
|
||||||
|
DonatService "donat-widget/internal/service/donat"
|
||||||
)
|
)
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"donat-widget/infrastructure/pg"
|
"donat-widget/infrastructure/pg"
|
||||||
"donat-widget/infrastructure/weed"
|
"donat-widget/infrastructure/weed"
|
||||||
|
PaymentClient "donat-widget/pkg/api/payment"
|
||||||
)
|
)
|
||||||
|
|
||||||
import (
|
import (
|
||||||
WidgetRepo "donat-widget/internal/repository/widget"
|
WidgetRepo "donat-widget/internal/repository/widget"
|
||||||
DonatRepo "donat-widget/internal/repository/widget/donat"
|
|
||||||
MediaRepo "donat-widget/internal/repository/widget/media"
|
|
||||||
WidgetService "donat-widget/internal/service/widget"
|
WidgetService "donat-widget/internal/service/widget"
|
||||||
DonatService "donat-widget/internal/service/widget/donat"
|
|
||||||
MediaService "donat-widget/internal/service/widget/media"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @title Widget service
|
|
||||||
// @version 1.0
|
|
||||||
// @description Описание.
|
|
||||||
|
|
||||||
// @host localhost:8002
|
|
||||||
// @BasePath /api/widget
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfg := config.Init()
|
cfg := config.Init()
|
||||||
|
|
||||||
@ -34,20 +26,20 @@ func main() {
|
|||||||
db := pg.NewPgPool(context.Background(), cfg.Db.Username, cfg.Db.Password, cfg.Db.Host, cfg.Db.Port, cfg.Db.DBName)
|
db := pg.NewPgPool(context.Background(), cfg.Db.Username, cfg.Db.Password, cfg.Db.Host, cfg.Db.Port, cfg.Db.DBName)
|
||||||
storage := weed.NewWeed(cfg.Storage.Filer, cfg.Storage.Master)
|
storage := weed.NewWeed(cfg.Storage.Filer, cfg.Storage.Master)
|
||||||
|
|
||||||
|
// CLIENTS
|
||||||
|
paymentClient := PaymentClient.New(cfg.PaymentService.Host, cfg.PaymentService.Port)
|
||||||
|
|
||||||
// REPOSITORIES
|
// REPOSITORIES
|
||||||
widgetRepo := WidgetRepo.New(db)
|
widgetRepo := WidgetRepo.New(db, storage)
|
||||||
mediaRepo := MediaRepo.New(db, storage)
|
|
||||||
donatRepo := DonatRepo.New(db)
|
donatRepo := DonatRepo.New(db)
|
||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
widgetService := WidgetService.New(widgetRepo, donatRepo)
|
widgetService := WidgetService.New(widgetRepo, donatRepo)
|
||||||
mediaService := MediaService.New(mediaRepo)
|
donatService := DonatService.New(donatRepo, widgetRepo, paymentClient)
|
||||||
donatService := DonatService.New(donatRepo)
|
|
||||||
|
|
||||||
http.NewApp(
|
http.NewApp(
|
||||||
db,
|
db,
|
||||||
widgetService,
|
widgetService,
|
||||||
mediaService,
|
|
||||||
donatService,
|
donatService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
3
go.mod
3
go.mod
@ -5,8 +5,10 @@ go 1.23.0
|
|||||||
require (
|
require (
|
||||||
github.com/georgysavva/scany/v2 v2.1.3
|
github.com/georgysavva/scany/v2 v2.1.3
|
||||||
github.com/go-playground/validator/v10 v10.22.0
|
github.com/go-playground/validator/v10 v10.22.0
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
github.com/jackc/pgx/v5 v5.6.0
|
github.com/jackc/pgx/v5 v5.6.0
|
||||||
github.com/labstack/echo/v4 v4.12.0
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
|
github.com/linxGnu/goseaweedfs v0.1.6
|
||||||
github.com/swaggo/echo-swagger v1.4.1
|
github.com/swaggo/echo-swagger v1.4.1
|
||||||
github.com/swaggo/swag v1.16.3
|
github.com/swaggo/swag v1.16.3
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
@ -29,7 +31,6 @@ require (
|
|||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/labstack/gommon v0.4.2 // indirect
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/linxGnu/goseaweedfs v0.1.6 // indirect
|
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -30,6 +30,8 @@ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4
|
|||||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||||
|
95
internal/api/http/handlers/donat/donat.go
Normal file
95
internal/api/http/handlers/donat/donat.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package donat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"donat-widget/internal/model"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateDonat(donatService model.DonatService) echo.HandlerFunc {
|
||||||
|
type Body struct {
|
||||||
|
StreamerID model.StreamerID `json:"streamerID"`
|
||||||
|
TargetID model.TargetID `json:"targetID"`
|
||||||
|
Amount model.DonatAmount `json:"amount"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
DonatUser string `json:"donatUser"`
|
||||||
|
}
|
||||||
|
return func(request echo.Context) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
var body Body
|
||||||
|
if err := request.Bind(&body); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
if err := request.Validate(&body); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
orderID := model.OrderID(uuid.New().String())
|
||||||
|
|
||||||
|
err := donatService.CreateDonat(
|
||||||
|
ctx,
|
||||||
|
body.StreamerID,
|
||||||
|
orderID,
|
||||||
|
body.Amount,
|
||||||
|
body.Text,
|
||||||
|
body.DonatUser,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return request.JSON(500, "Set donat error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return request.String(200, "Set donat success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarkDonatPaid(donatService model.DonatService) echo.HandlerFunc {
|
||||||
|
type Body struct {
|
||||||
|
OrderID model.OrderID `json:"orderID"`
|
||||||
|
}
|
||||||
|
return func(request echo.Context) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
var body Body
|
||||||
|
if err := request.Bind(&body); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
if err := request.Validate(&body); err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err := donatService.MarkDonatPaid(ctx, body.OrderID)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("donatService.MarkDonatPaid error: " + err.Error())
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return request.String(200, "Donat paid success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarkDonatView(donatService model.DonatService) echo.HandlerFunc {
|
||||||
|
return func(request echo.Context) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
donatID, err := strconv.Atoi(request.Param("donatID"))
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(400, "Path parameter 'donatID' is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = donatService.MarkDonatView(
|
||||||
|
ctx,
|
||||||
|
model.DonatID(donatID),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(500, "Delete donat error")
|
||||||
|
}
|
||||||
|
slog.Info("Delete donat success")
|
||||||
|
return request.String(200, "donat view success")
|
||||||
|
}
|
||||||
|
}
|
1
internal/api/http/handlers/target/target.go
Normal file
1
internal/api/http/handlers/target/target.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package target
|
@ -1,76 +0,0 @@
|
|||||||
package donat
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"donat-widget/internal/model"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"log/slog"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetDonat
|
|
||||||
//
|
|
||||||
// @Description Set donat
|
|
||||||
// @Tags Donat
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param RegisterData body SetDonatRequest true "Set donat"
|
|
||||||
// @Router /api/widget/donat/set [post]
|
|
||||||
func SetDonat(donatService model.DonatService) echo.HandlerFunc {
|
|
||||||
return func(request echo.Context) error {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
var donatData SetDonatRequest
|
|
||||||
if err := request.Bind(&donatData); err != nil {
|
|
||||||
slog.Error(err.Error())
|
|
||||||
return echo.NewHTTPError(400, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err := request.Validate(&donatData)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(err.Error())
|
|
||||||
return echo.NewHTTPError(400, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = donatService.SetDonat(
|
|
||||||
ctx,
|
|
||||||
donatData.WidgetID,
|
|
||||||
donatData.Text,
|
|
||||||
donatData.Amount,
|
|
||||||
donatData.DonatUser,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return request.JSON(500, "Set donat error")
|
|
||||||
}
|
|
||||||
slog.Info("donat set success")
|
|
||||||
return request.String(200, "Set donat success")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteDonat
|
|
||||||
//
|
|
||||||
// @Description Delete donat
|
|
||||||
// @Tags Donat
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Router /api/widget/donat/delete/{donatID} [post]
|
|
||||||
func DeleteDonat(donatService model.DonatService) echo.HandlerFunc {
|
|
||||||
return func(request echo.Context) error {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
donatID, err := strconv.Atoi(request.Param("donatID"))
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(400, "Path parameter 'donatID' is invalid")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = donatService.DeleteDonat(
|
|
||||||
ctx,
|
|
||||||
model.DonatID(donatID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(500, "Delete donat error")
|
|
||||||
}
|
|
||||||
slog.Info("Delete donat success")
|
|
||||||
return request.String(200, "Delete donat success")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package donat
|
|
||||||
|
|
||||||
import "donat-widget/internal/model"
|
|
||||||
|
|
||||||
type SetDonatRequest struct {
|
|
||||||
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
|
|
||||||
Text string `json:"text" validate:"required"`
|
|
||||||
Amount model.DonatAmount `json:"amount" validate:"required"`
|
|
||||||
DonatUser string `json:"donatUser" validate:"required"`
|
|
||||||
}
|
|
@ -1,165 +0,0 @@
|
|||||||
package media
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"donat-widget/internal/model"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"log/slog"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetMediaFile
|
|
||||||
//
|
|
||||||
// @Description Upload media
|
|
||||||
// @Tags Media
|
|
||||||
// @Accept mpfd
|
|
||||||
// @Produce json
|
|
||||||
// @Param file formData file true "File to upload"
|
|
||||||
// @Param widgetId path int true "Widget ID"
|
|
||||||
// @Router /api/widget/media/{mediaType}/upload [post]
|
|
||||||
func SetMediaFile(service model.MediaService) 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 = service.SetMediaFile(
|
|
||||||
ctx,
|
|
||||||
model.MediaType(mediaType),
|
|
||||||
model.WidgetID(widgetID),
|
|
||||||
&src,
|
|
||||||
file.Filename,
|
|
||||||
file.Size,
|
|
||||||
"",
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(500, "File upload is failed")
|
|
||||||
}
|
|
||||||
slog.Info("set " + mediaType + " file successfully")
|
|
||||||
return request.String(200, "File successfully uploaded")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMediaFile
|
|
||||||
//
|
|
||||||
// @Description Get media
|
|
||||||
// @Produce application/octet-stream
|
|
||||||
// @Success 200 {array} byte
|
|
||||||
// @Param widgetId path int true "Widget ID"
|
|
||||||
// @Param mediaType path string true "'background' or 'image' or 'audio'"
|
|
||||||
// @Router /api/widget/media/{mediaType}/get/{widgetID} [post]
|
|
||||||
func GetMediaFile(service model.MediaService) echo.HandlerFunc {
|
|
||||||
return func(request echo.Context) error {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
mediaType := request.Param("mediaType")
|
|
||||||
if mediaType != "background" && mediaType != "image" && mediaType != "audio" {
|
|
||||||
return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid")
|
|
||||||
}
|
|
||||||
widgetID, err := strconv.Atoi(request.Param("widgetID"))
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(400, "Path parameter 'widgetID' is invalid")
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := service.GetMediaFile(
|
|
||||||
ctx,
|
|
||||||
model.WidgetID(widgetID),
|
|
||||||
model.MediaType(mediaType),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(500, "Get File is failed")
|
|
||||||
}
|
|
||||||
slog.Info("get " + mediaType + " file successfully")
|
|
||||||
return request.Blob(200, "application/octet-stream", file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateMediaFile(service model.MediaService) 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 = service.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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMediaUrl
|
|
||||||
//
|
|
||||||
// @Description Set media URL
|
|
||||||
// @Param mediaType path string true "'background' or 'image' or 'audio'"
|
|
||||||
// @Router /api/widget/media/{mediaType}/set [post]
|
|
||||||
func SetMediaUrl(service model.MediaService) echo.HandlerFunc {
|
|
||||||
return func(request echo.Context) error {
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
var backgroundData SetRequest
|
|
||||||
if err := request.Bind(&backgroundData); err != nil {
|
|
||||||
return echo.NewHTTPError(400, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaType := request.Param("mediaType")
|
|
||||||
|
|
||||||
err := request.Validate(&backgroundData)
|
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
return echo.NewHTTPError(400, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = service.SetMediaUrl(
|
|
||||||
ctx,
|
|
||||||
model.MediaType(mediaType),
|
|
||||||
backgroundData.WidgetID,
|
|
||||||
backgroundData.MediaUrl,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(500, "Set MediaUrl is failed")
|
|
||||||
}
|
|
||||||
slog.Info("Set media url successfully")
|
|
||||||
return request.String(200, "Media URL successfully set")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package media
|
|
||||||
|
|
||||||
import "donat-widget/internal/model"
|
|
||||||
|
|
||||||
type SetRequest struct {
|
|
||||||
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
|
|
||||||
MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"`
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package widget
|
|
||||||
|
|
||||||
import "donat-widget/internal/model"
|
|
||||||
|
|
||||||
type CreateWidgetRequest struct {
|
|
||||||
StreamerID model.StreamerID `json:"streamerID" validate:"required"`
|
|
||||||
TemplateID model.TemplateID `json:"templateID" validate:"required"`
|
|
||||||
}
|
|
||||||
type CreateWidgetResponse struct {
|
|
||||||
WidgetID model.WidgetID `json:"widgetID"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetWidgetInfoResponse struct {
|
|
||||||
AudioUrl model.MediaUrl `json:"audioUrl"`
|
|
||||||
ImageUrl model.MediaUrl `json:"imageUrl"`
|
|
||||||
Text string `json:"text"`
|
|
||||||
Amount model.DonatAmount `json:"amount"`
|
|
||||||
DonatUser string `json:"donatUser"`
|
|
||||||
Display model.Display `json:"display"`
|
|
||||||
Duration model.Duration `json:"duration"`
|
|
||||||
DonatID model.DonatID `json:"donatID"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateDurationRequest struct {
|
|
||||||
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
|
|
||||||
Duration model.Duration `json:"duration" validate:"required"`
|
|
||||||
}
|
|
@ -8,53 +8,42 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateWidget
|
|
||||||
//
|
|
||||||
// @Description Create widget
|
|
||||||
// @Tags Widget
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param RegisterData body CreateWidgetRequest true "Create widget"
|
|
||||||
// @Success 200 {object} CreateWidgetResponse
|
|
||||||
// @Router /api/widget/create [post]
|
|
||||||
func CreateWidget(widgetService model.WidgetService) echo.HandlerFunc {
|
func CreateWidget(widgetService model.WidgetService) echo.HandlerFunc {
|
||||||
return func(request echo.Context) error {
|
type Body struct {
|
||||||
ctx := context.Background()
|
StreamerID model.StreamerID `json:"streamerID" validate:"required"`
|
||||||
|
TemplateID model.TemplateID `json:"templateID" validate:"required"`
|
||||||
var widgetData CreateWidgetRequest
|
|
||||||
if err := request.Bind(&widgetData); err != nil {
|
|
||||||
return echo.NewHTTPError(400, err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := request.Validate(&widgetData)
|
type Response struct {
|
||||||
if err != nil {
|
WidgetID model.WidgetID `json:"widgetID"`
|
||||||
|
}
|
||||||
|
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())
|
return echo.NewHTTPError(400, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
widgetID, err := widgetService.CreateWidget(
|
widgetID, err := widgetService.CreateWidget(
|
||||||
ctx,
|
ctx,
|
||||||
widgetData.StreamerID,
|
body.StreamerID,
|
||||||
widgetData.TemplateID,
|
body.TemplateID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return request.JSON(422, "Create widget error")
|
return request.JSON(422, "Create widget error")
|
||||||
}
|
}
|
||||||
|
|
||||||
response := CreateWidgetResponse{
|
response := Response{
|
||||||
WidgetID: widgetID,
|
WidgetID: widgetID,
|
||||||
}
|
}
|
||||||
slog.Info("Widget created")
|
|
||||||
return request.JSON(200, response)
|
return request.JSON(200, response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWidgetHTML @Description Get widget
|
|
||||||
//
|
|
||||||
// @Tags Widget
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200
|
|
||||||
// @Router /api/widget/html/{widgetID} [get]
|
|
||||||
func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc {
|
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()
|
||||||
@ -76,15 +65,17 @@ func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWidgetInfo
|
|
||||||
//
|
|
||||||
// @Description Widget Info
|
|
||||||
// @Tags Widget
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param widgetID path int true "Widget ID"
|
|
||||||
// @Router /api/widget/info/{widgetID} [get]
|
|
||||||
func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
|
func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
|
||||||
|
type Response struct {
|
||||||
|
AudioUrl model.MediaUrl `json:"audioUrl"`
|
||||||
|
ImageUrl model.MediaUrl `json:"imageUrl"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
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()
|
||||||
|
|
||||||
@ -99,14 +90,13 @@ func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !donatAndWidget.Display {
|
if !donatAndWidget.Display {
|
||||||
response := GetWidgetInfoResponse{
|
response := Response{
|
||||||
Display: donatAndWidget.Display,
|
Display: donatAndWidget.Display,
|
||||||
}
|
}
|
||||||
slog.Info("Get widget info successfully")
|
|
||||||
return request.JSON(200, response)
|
return request.JSON(200, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
response := GetWidgetInfoResponse{
|
response := Response{
|
||||||
AudioUrl: donatAndWidget.Widget.AudioUrl,
|
AudioUrl: donatAndWidget.Widget.AudioUrl,
|
||||||
ImageUrl: donatAndWidget.Widget.ImageUrl,
|
ImageUrl: donatAndWidget.Widget.ImageUrl,
|
||||||
Text: donatAndWidget.Donat.Text,
|
Text: donatAndWidget.Donat.Text,
|
||||||
@ -116,44 +106,171 @@ func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
|
|||||||
Amount: donatAndWidget.Donat.Amount,
|
Amount: donatAndWidget.Donat.Amount,
|
||||||
DonatID: donatAndWidget.Donat.ID,
|
DonatID: donatAndWidget.Donat.ID,
|
||||||
}
|
}
|
||||||
slog.Info("Get widget info successfully")
|
|
||||||
return request.JSON(200, response)
|
return request.JSON(200, response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateDuration
|
|
||||||
//
|
|
||||||
// @Description UpdateDuration
|
|
||||||
// @Tags Widget
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param UpdateData body UpdateDurationRequest true "UpdateDuration"
|
|
||||||
// @Success 200
|
|
||||||
// @Router /api/widget/duration/update [post]
|
|
||||||
func UpdateDuration(widgetService model.WidgetService) echo.HandlerFunc {
|
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 {
|
return func(request echo.Context) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
var body Body
|
||||||
var widgetData UpdateDurationRequest
|
if err := request.Bind(&body); err != nil {
|
||||||
if err := request.Bind(&widgetData); err != nil {
|
return echo.NewHTTPError(400, err.Error())
|
||||||
|
}
|
||||||
|
if err := request.Validate(&body); err != nil {
|
||||||
return echo.NewHTTPError(400, err.Error())
|
return echo.NewHTTPError(400, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
err := request.Validate(&widgetData)
|
err := widgetService.UpdateDuration(
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(400, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = widgetService.UpdateDuration(
|
|
||||||
ctx,
|
ctx,
|
||||||
widgetData.WidgetID,
|
body.WidgetID,
|
||||||
widgetData.Duration,
|
body.Duration,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return request.JSON(422, "Update duration error")
|
return request.JSON(422, "Update duration error")
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Info("Duration updated")
|
|
||||||
return request.JSON(200, "Update duration successfully")
|
return request.JSON(200, "Update duration successfully")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetMediaFile(service model.MediaService) 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 = service.SetMediaFile(
|
||||||
|
ctx,
|
||||||
|
model.MediaType(mediaType),
|
||||||
|
model.WidgetID(widgetID),
|
||||||
|
&src,
|
||||||
|
file.Filename,
|
||||||
|
file.Size,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(500, "File upload is failed")
|
||||||
|
}
|
||||||
|
slog.Info("set " + mediaType + " file successfully")
|
||||||
|
return request.String(200, "File successfully uploaded")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMediaFile(service model.MediaService) echo.HandlerFunc {
|
||||||
|
return func(request echo.Context) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
mediaType := request.Param("mediaType")
|
||||||
|
if mediaType != "background" && mediaType != "image" && mediaType != "audio" {
|
||||||
|
return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid")
|
||||||
|
}
|
||||||
|
widgetID, err := strconv.Atoi(request.Param("widgetID"))
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(400, "Path parameter 'widgetID' is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := service.GetMediaFile(
|
||||||
|
ctx,
|
||||||
|
model.WidgetID(widgetID),
|
||||||
|
model.MediaType(mediaType),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(500, "Get File is failed")
|
||||||
|
}
|
||||||
|
slog.Info("get " + mediaType + " file successfully")
|
||||||
|
return request.Blob(200, "application/octet-stream", file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateMediaFile(service model.MediaService) 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 = service.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(service model.MediaService) echo.HandlerFunc {
|
||||||
|
type Body struct {
|
||||||
|
WidgetID model.WidgetID `json:"widgetID" validate:"required"`
|
||||||
|
MediaUrl model.MediaUrl `json:"mediaUrl" 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())
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaType := request.Param("mediaType")
|
||||||
|
|
||||||
|
err := service.SetMediaUrl(
|
||||||
|
ctx,
|
||||||
|
model.MediaType(mediaType),
|
||||||
|
body.WidgetID,
|
||||||
|
body.MediaUrl,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(500, "Set MediaUrl is failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return request.String(200, "Media URL successfully set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
. "donat-widget/internal/api/http/handlers/donat"
|
||||||
"donat-widget/internal/model/sql"
|
"donat-widget/internal/model/sql"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/swaggo/echo-swagger"
|
"github.com/swaggo/echo-swagger"
|
||||||
@ -15,8 +16,6 @@ import (
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
. "donat-widget/internal/api/http/handlers/widget"
|
. "donat-widget/internal/api/http/handlers/widget"
|
||||||
. "donat-widget/internal/api/http/handlers/widget/donat"
|
|
||||||
. "donat-widget/internal/api/http/handlers/widget/media"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var PREFIX = "/api/widget"
|
var PREFIX = "/api/widget"
|
||||||
@ -24,7 +23,6 @@ var PREFIX = "/api/widget"
|
|||||||
func NewApp(
|
func NewApp(
|
||||||
db model.Db,
|
db model.Db,
|
||||||
widgetService model.WidgetService,
|
widgetService model.WidgetService,
|
||||||
mediaService model.MediaService,
|
|
||||||
donatService model.DonatService,
|
donatService model.DonatService,
|
||||||
) {
|
) {
|
||||||
server := echo.New()
|
server := echo.New()
|
||||||
@ -35,7 +33,6 @@ func NewApp(
|
|||||||
server.GET(PREFIX+"/table/drop", DropTale(db))
|
server.GET(PREFIX+"/table/drop", DropTale(db))
|
||||||
|
|
||||||
IncludeWidgetHandlers(server, widgetService)
|
IncludeWidgetHandlers(server, widgetService)
|
||||||
IncludeMediaHandlers(server, mediaService)
|
|
||||||
IncludeDonatHandlers(server, donatService)
|
IncludeDonatHandlers(server, donatService)
|
||||||
|
|
||||||
server.Logger.Fatal(server.Start(":8002"))
|
server.Logger.Fatal(server.Start(":8002"))
|
||||||
@ -45,23 +42,18 @@ func IncludeDonatHandlers(
|
|||||||
server *echo.Echo,
|
server *echo.Echo,
|
||||||
donatService model.DonatService,
|
donatService model.DonatService,
|
||||||
) {
|
) {
|
||||||
server.POST(PREFIX+"/donat/set", SetDonat(donatService))
|
server.POST(PREFIX+"/donat/create", CreateDonat(donatService))
|
||||||
server.DELETE(PREFIX+"/donat/delete/:donatID", DeleteDonat(donatService))
|
server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService))
|
||||||
}
|
server.POST(PREFIX+"/donat/paid/:donatID", MarkDonatPaid(donatService))
|
||||||
|
|
||||||
func IncludeMediaHandlers(
|
|
||||||
server *echo.Echo,
|
|
||||||
mediaService model.MediaService,
|
|
||||||
) {
|
|
||||||
server.POST(PREFIX+"/media/:mediaType/upload", SetMediaFile(mediaService))
|
|
||||||
server.POST(PREFIX+"/media/:mediaType/set", SetMediaUrl(mediaService))
|
|
||||||
server.GET(PREFIX+"/media/:mediaType/get/:widgetID", GetMediaFile(mediaService))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func IncludeWidgetHandlers(
|
func IncludeWidgetHandlers(
|
||||||
server *echo.Echo,
|
server *echo.Echo,
|
||||||
widgetService model.WidgetService,
|
widgetService model.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.POST(PREFIX+"/create", CreateWidget(widgetService))
|
||||||
server.PATCH(PREFIX+"/duration/update", UpdateDuration(widgetService))
|
server.PATCH(PREFIX+"/duration/update", UpdateDuration(widgetService))
|
||||||
server.GET(PREFIX+"/html/:widgetID", GetWidgetHTML(widgetService))
|
server.GET(PREFIX+"/html/:widgetID", GetWidgetHTML(widgetService))
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Db Database `yaml:"db"`
|
Db Database `yaml:"db"`
|
||||||
Storage Storage `yaml:"storage"`
|
Storage Storage `yaml:"storage"`
|
||||||
|
PaymentService PaymentService `yaml:"paymentService"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
@ -23,6 +24,11 @@ type Storage struct {
|
|||||||
Master string `yaml:"master"`
|
Master string `yaml:"master"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PaymentService struct {
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port string `yaml:"port"`
|
||||||
|
}
|
||||||
|
|
||||||
func Init() *Config {
|
func Init() *Config {
|
||||||
data, err := os.ReadFile("internal/config/config.yaml")
|
data, err := os.ReadFile("internal/config/config.yaml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -11,3 +11,7 @@ server:
|
|||||||
storage:
|
storage:
|
||||||
filer: "http://92.63.193.151:8111"
|
filer: "http://92.63.193.151:8111"
|
||||||
master: "http://92.63.193.151:9333"
|
master: "http://92.63.193.151:9333"
|
||||||
|
|
||||||
|
paymentService:
|
||||||
|
host: "payment-service"
|
||||||
|
port: "8003"
|
12
internal/model/api/tinkoff.go
Normal file
12
internal/model/api/tinkoff.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
type CreatePaymentResponse struct {
|
||||||
|
Amount int `json:"Amount"`
|
||||||
|
ErrorCode string `json:"ErrorCode"`
|
||||||
|
OrderId string `json:"OrderId"`
|
||||||
|
PaymentId string `json:"PaymentId"`
|
||||||
|
PaymentURL string `json:"PaymentURL"`
|
||||||
|
Status string `json:"Status"`
|
||||||
|
Success bool `json:"Success"`
|
||||||
|
TerminalKey string `json:"TerminalKey"`
|
||||||
|
}
|
@ -2,6 +2,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"donat-widget/internal/model/api"
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5/pgconn"
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
@ -13,6 +14,10 @@ type WidgetService interface {
|
|||||||
UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error
|
UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error
|
||||||
GetWidgetInfo(ctx context.Context, widgetID WidgetID) (*DonatAndWidget, error)
|
GetWidgetInfo(ctx context.Context, widgetID WidgetID) (*DonatAndWidget, error)
|
||||||
GetWidgetHTML(ctx context.Context, widgetID WidgetID) (WidgetHTML, error)
|
GetWidgetHTML(ctx context.Context, widgetID WidgetID) (WidgetHTML, 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
|
||||||
|
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 {
|
||||||
@ -20,16 +25,7 @@ type WidgetRepo interface {
|
|||||||
DeleteWidget(ctx context.Context, widgetID WidgetID) error
|
DeleteWidget(ctx context.Context, widgetID WidgetID) error
|
||||||
UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error
|
UpdateDuration(ctx context.Context, widgetID WidgetID, duration Duration) error
|
||||||
GetWidget(ctx context.Context, widgetID WidgetID) (*Widget, error)
|
GetWidget(ctx context.Context, widgetID WidgetID) (*Widget, error)
|
||||||
}
|
GetAllWidget(ctx context.Context, streamerID StreamerID) ([]*Widget, error)
|
||||||
|
|
||||||
type MediaService interface {
|
|
||||||
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
|
|
||||||
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 MediaRepo interface {
|
|
||||||
SetMediaFile(file UploadFile, filename string, size int64, collection string) (FileID, 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)
|
||||||
@ -38,14 +34,16 @@ type MediaRepo interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DonatService interface {
|
type DonatService interface {
|
||||||
SetDonat(ctx context.Context, widgetID WidgetID, text string, amount DonatAmount, donatUser string) error
|
CreateDonat(ctx context.Context, streamerID StreamerID, orderID OrderID, amount DonatAmount, text string, donatUser string) error
|
||||||
DeleteDonat(ctx context.Context, DonatID DonatID) error
|
MarkDonatPaid(ctx context.Context, orderID OrderID) error
|
||||||
|
MarkDonatView(ctx context.Context, DonatID DonatID) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type DonatRepo interface {
|
type DonatRepo interface {
|
||||||
SetDonat(ctx context.Context, widgetID WidgetID, text string, amount DonatAmount, donatUser string) error
|
CreateDonat(ctx context.Context, widgetID WidgetID, orderID OrderID, amount DonatAmount, text string, donatUser string) error
|
||||||
GetDonat(ctx context.Context, widgetID WidgetID) ([]*Donat, error)
|
GetDonat(ctx context.Context, widgetID WidgetID) ([]*Donat, error)
|
||||||
DeleteDonat(ctx context.Context, donatID DonatID) error
|
MarkDonatPaid(ctx context.Context, orderID OrderID) error
|
||||||
|
MarkDonatView(ctx context.Context, DonatID DonatID) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Error interface {
|
type Error interface {
|
||||||
@ -58,6 +56,9 @@ type Storage interface {
|
|||||||
Update(file UploadFile, fileID FileID, filename string, size int64, collection string) error
|
Update(file UploadFile, fileID FileID, filename string, size int64, collection string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PaymentClient interface {
|
||||||
|
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)
|
Exec(ctx context.Context, query string, args ...interface{}) (pgconn.CommandTag, error)
|
||||||
Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error)
|
Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error)
|
||||||
|
@ -7,15 +7,51 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Widget struct {
|
type Widget struct {
|
||||||
ID WidgetID
|
ID WidgetID `db:"id"`
|
||||||
StreamerID StreamerID
|
StreamerID StreamerID `db:"streamer_id"`
|
||||||
TemplateID TemplateID
|
TemplateID TemplateID `db:"template_id"`
|
||||||
BackgroundUrl MediaUrl
|
|
||||||
ImageUrl MediaUrl
|
BackgroundUrl MediaUrl `db:"background_url"`
|
||||||
AudioUrl MediaUrl
|
ImageUrl MediaUrl `db:"image_url"`
|
||||||
Duration Duration
|
AudioUrl MediaUrl `db:"audio_url"`
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
MinAmount DonatAmount `db:"min_amount"`
|
||||||
|
Duration Duration `db:"duration"`
|
||||||
|
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Donat struct {
|
||||||
|
ID DonatID `db:"id"`
|
||||||
|
WidgetID WidgetID `db:"widget_id"`
|
||||||
|
|
||||||
|
Text string `db:"text"`
|
||||||
|
DonatUser string `db:"donat_user"`
|
||||||
|
Amount DonatAmount `db:"amount"`
|
||||||
|
|
||||||
|
Paid bool `db:"paid"`
|
||||||
|
View bool `db:"view"`
|
||||||
|
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Target struct {
|
||||||
|
ID TargetID `db:"id"`
|
||||||
|
|
||||||
|
Text string `db:"text"`
|
||||||
|
Collected DonatAmount `db:"collected"`
|
||||||
|
Amount DonatAmount `db:"amount"`
|
||||||
|
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DonatAndWidget struct {
|
||||||
|
Widget *Widget
|
||||||
|
Donat *Donat
|
||||||
|
Display Display
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Widget) GetMediaUrl(mediaType MediaType) MediaUrl {
|
func (widget *Widget) GetMediaUrl(mediaType MediaType) MediaUrl {
|
||||||
@ -45,19 +81,3 @@ func (widget *Widget) NormalizeUrl() {
|
|||||||
widget.AudioUrl = MediaUrl(selfDomain + "/audio/get/" + strWidgetID)
|
widget.AudioUrl = MediaUrl(selfDomain + "/audio/get/" + strWidgetID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Donat struct {
|
|
||||||
ID DonatID
|
|
||||||
WidgetID WidgetID
|
|
||||||
Text string
|
|
||||||
DonatUser string
|
|
||||||
Amount DonatAmount
|
|
||||||
CreatedAt time.Time
|
|
||||||
UpdatedAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type DonatAndWidget struct {
|
|
||||||
Widget *Widget
|
|
||||||
Donat *Donat
|
|
||||||
Display Display
|
|
||||||
}
|
|
||||||
|
@ -5,10 +5,14 @@ CREATE TABLE IF NOT EXISTS widgets (
|
|||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
streamer_id INTEGER NOT NULL,
|
streamer_id INTEGER NOT NULL,
|
||||||
template_id INTEGER NOT NULL,
|
template_id INTEGER NOT NULL,
|
||||||
|
|
||||||
background_url TEXT DEFAULT '',
|
background_url TEXT DEFAULT '',
|
||||||
image_url TEXT DEFAULT '',
|
image_url TEXT DEFAULT '',
|
||||||
audio_url TEXT DEFAULT '',
|
audio_url TEXT DEFAULT '',
|
||||||
duration INTEGER DEFAULT 30,
|
|
||||||
|
duration INTEGER NOT NULL,
|
||||||
|
min_amount INTEGER NOT NUll,
|
||||||
|
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
@ -16,14 +20,30 @@ CREATE TABLE IF NOT EXISTS widgets (
|
|||||||
CREATE TABLE IF NOT EXISTS donats (
|
CREATE TABLE IF NOT EXISTS donats (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
widget_id INTEGER NOT NULL,
|
widget_id INTEGER NOT NULL,
|
||||||
text TEXT DEFAULT '',
|
order_id TEXT NOT NULL,
|
||||||
amount TEXT DEFAULT '',
|
|
||||||
donat_user TEXT DEFAULT '',
|
text TEXT NOT NULL,
|
||||||
|
amount INTEGER NOT NULL,
|
||||||
|
donat_user TEXT NOT NULL,
|
||||||
|
|
||||||
|
paid BOOLEAN DEFAULT FALSE,
|
||||||
|
view BOOLEAN DEFAULT FALSE,
|
||||||
|
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION update_updated_at()
|
CREATE TABLE IF NOT EXISTS targets (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
amount INTEGER NOT NULL,
|
||||||
|
collected INTEGER NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION update_updated_at()
|
||||||
RETURNS TRIGGER AS $$
|
RETURNS TRIGGER AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
NEW.updated_at = NOW();
|
NEW.updated_at = NOW();
|
||||||
@ -40,9 +60,15 @@ CREATE TRIGGER update_updated_at_trigger
|
|||||||
BEFORE UPDATE ON donats
|
BEFORE UPDATE ON donats
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
EXECUTE PROCEDURE update_updated_at();
|
EXECUTE PROCEDURE update_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER update_updated_at_trigger
|
||||||
|
BEFORE UPDATE ON targets
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE update_updated_at();
|
||||||
`
|
`
|
||||||
|
|
||||||
var DropTableQuery = `
|
var DropTableQuery = `
|
||||||
DROP TABLE IF EXISTS widgets;
|
DROP TABLE IF EXISTS widgets;
|
||||||
DROP TABLE IF EXISTS donats;
|
DROP TABLE IF EXISTS donats;
|
||||||
|
DROP TABLE IF EXISTS targets;
|
||||||
`
|
`
|
||||||
|
@ -5,27 +5,21 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var CreateWidgetQuery = `
|
var CreateWidget = `
|
||||||
INSERT INTO widgets (streamer_id, template_id)
|
INSERT INTO widgets (streamer_id, template_id)
|
||||||
VALUES (@streamer_id, @template_id);
|
VALUES (@streamer_id, @template_id);
|
||||||
`
|
`
|
||||||
|
var UpdateDuration = `
|
||||||
var SetDonatQuery = `
|
|
||||||
INSERT INTO donats (widget_id, text, amount, donat_user)
|
|
||||||
VALUES (@widget_id, @text, @amount, @donat_user);
|
|
||||||
`
|
|
||||||
|
|
||||||
var DeleteDonatQuery = `
|
|
||||||
DELETE FROM donats WHERE id = (@id);
|
|
||||||
`
|
|
||||||
|
|
||||||
var UpdateDurationQuery = `
|
|
||||||
UPDATE widgets
|
UPDATE widgets
|
||||||
SET duration = (@duration)
|
SET duration = (@duration)
|
||||||
WHERE id = (@id)
|
WHERE id = (@id)
|
||||||
`
|
`
|
||||||
|
var GetWidget = `
|
||||||
|
SELECT * FROM widgets
|
||||||
|
WHERE id = (@id);
|
||||||
|
`
|
||||||
|
|
||||||
func UpdateMediaUrlQuery(mediaType model.MediaType) string {
|
func UpdateMediaUrl(mediaType model.MediaType) string {
|
||||||
query := fmt.Sprintf(`
|
query := fmt.Sprintf(`
|
||||||
UPDATE widgets
|
UPDATE widgets
|
||||||
SET %s = (@%s)
|
SET %s = (@%s)
|
||||||
@ -34,13 +28,9 @@ func UpdateMediaUrlQuery(mediaType model.MediaType) string {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
var GetDonatQuery = `
|
var GetAllWidget = `
|
||||||
SELECT * FROM donats WHERE widget_id = (@widget_id);
|
|
||||||
`
|
|
||||||
|
|
||||||
var GetWidgetQuery = `
|
|
||||||
SELECT * FROM widgets
|
SELECT * FROM widgets
|
||||||
WHERE id = (@id);
|
WHERE streamer_id = (@streamer_id);
|
||||||
`
|
`
|
||||||
|
|
||||||
func GetMediaUrl(mediaType model.MediaType) string {
|
func GetMediaUrl(mediaType model.MediaType) string {
|
||||||
@ -51,3 +41,22 @@ func GetMediaUrl(mediaType model.MediaType) string {
|
|||||||
`, mediaType)
|
`, mediaType)
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var CreateDonat = `
|
||||||
|
INSERT INTO donats (widget_id, text, amount, donat_user, order_id)
|
||||||
|
VALUES (@widget_id, @text, @amount, @donat_user, @order_id);
|
||||||
|
`
|
||||||
|
var MarkDonatView = `
|
||||||
|
UPDATE donats
|
||||||
|
SET view = (@view)
|
||||||
|
WHERE id = (@id);
|
||||||
|
`
|
||||||
|
var MarkDonatPaid = `
|
||||||
|
UPDATE donats
|
||||||
|
SET paid = (@paid)
|
||||||
|
WHERE order_id = (@order_id);
|
||||||
|
`
|
||||||
|
var GetDonat = `
|
||||||
|
SELECT * FROM donats
|
||||||
|
WHERE widget_id = (@widget_id) AND paid = (@paid) AND view = (@view);
|
||||||
|
`
|
||||||
|
@ -23,5 +23,9 @@ type UploadFile *multipart.File
|
|||||||
type DownloadFile []byte
|
type DownloadFile []byte
|
||||||
type FileID string
|
type FileID string
|
||||||
|
|
||||||
type DonatAmount string
|
type DonatAmount int
|
||||||
type DonatID int
|
type DonatID int
|
||||||
|
type OrderID string
|
||||||
|
|
||||||
|
type TargetID int
|
||||||
|
type Collected int
|
||||||
|
@ -19,20 +19,22 @@ type RepoDonat struct {
|
|||||||
db model.Db
|
db model.Db
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repoDonat *RepoDonat) SetDonat(
|
func (repoDonat *RepoDonat) CreateDonat(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
widgetID model.WidgetID,
|
widgetID model.WidgetID,
|
||||||
text string,
|
orderID model.OrderID,
|
||||||
amount model.DonatAmount,
|
amount model.DonatAmount,
|
||||||
|
text string,
|
||||||
donatUser string,
|
donatUser string,
|
||||||
) error {
|
) error {
|
||||||
args := model.QueryArgs{
|
args := model.QueryArgs{
|
||||||
"widget_id": widgetID,
|
"widget_id": widgetID,
|
||||||
|
"order_id": orderID,
|
||||||
"text": text,
|
"text": text,
|
||||||
"amount": amount,
|
"amount": amount,
|
||||||
"donat_user": donatUser,
|
"donat_user": donatUser,
|
||||||
}
|
}
|
||||||
_, err := repoDonat.db.Query(ctx, sql.SetDonatQuery, args)
|
_, err := repoDonat.db.Query(ctx, sql.CreateDonat, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("repoDonat.db.Query: " + err.Error())
|
slog.Error("repoDonat.db.Query: " + err.Error())
|
||||||
return err
|
return err
|
||||||
@ -47,8 +49,10 @@ func (repoDonat *RepoDonat) GetDonat(
|
|||||||
) ([]*model.Donat, error) {
|
) ([]*model.Donat, error) {
|
||||||
args := pgx.NamedArgs{
|
args := pgx.NamedArgs{
|
||||||
"widget_id": widgetID,
|
"widget_id": widgetID,
|
||||||
|
"paid": true,
|
||||||
|
"view": false,
|
||||||
}
|
}
|
||||||
rows, err := repoDonat.db.Query(ctx, sql.GetDonatQuery, args)
|
rows, err := repoDonat.db.Query(ctx, sql.GetDonat, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("repoDonat.db.Query: " + err.Error())
|
slog.Error("repoDonat.db.Query: " + err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -64,14 +68,32 @@ func (repoDonat *RepoDonat) GetDonat(
|
|||||||
return donats, nil
|
return donats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repoDonat *RepoDonat) DeleteDonat(
|
func (repoDonat *RepoDonat) MarkDonatView(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
donatID model.DonatID,
|
donatID model.DonatID,
|
||||||
) error {
|
) error {
|
||||||
args := pgx.NamedArgs{
|
args := pgx.NamedArgs{
|
||||||
"id": donatID,
|
"id": donatID,
|
||||||
|
"view": true,
|
||||||
}
|
}
|
||||||
_, err := repoDonat.db.Query(ctx, sql.DeleteDonatQuery, args)
|
_, err := repoDonat.db.Query(ctx, sql.MarkDonatView, args)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoDonat.db.Query: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repoDonat *RepoDonat) MarkDonatPaid(
|
||||||
|
ctx context.Context,
|
||||||
|
orderID model.OrderID,
|
||||||
|
) error {
|
||||||
|
args := pgx.NamedArgs{
|
||||||
|
"order_id": orderID,
|
||||||
|
"paid": true,
|
||||||
|
}
|
||||||
|
_, err := repoDonat.db.Query(ctx, sql.MarkDonatPaid, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("repoDonat.db.Query: " + err.Error())
|
slog.Error("repoDonat.db.Query: " + err.Error())
|
||||||
return err
|
return err
|
1
internal/repository/target/target.go
Normal file
1
internal/repository/target/target.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package target
|
@ -1,135 +0,0 @@
|
|||||||
package media
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"donat-widget/internal/model"
|
|
||||||
"donat-widget/internal/model/sql"
|
|
||||||
"errors"
|
|
||||||
"github.com/georgysavva/scany/v2/pgxscan"
|
|
||||||
"log/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func New(
|
|
||||||
db model.Db,
|
|
||||||
storage model.Storage,
|
|
||||||
) *RepoMedia {
|
|
||||||
return &RepoMedia{
|
|
||||||
db: db,
|
|
||||||
storage: storage,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type RepoMedia struct {
|
|
||||||
db model.Db
|
|
||||||
storage model.Storage
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repoMedia *RepoMedia) SetMediaFile(
|
|
||||||
file model.UploadFile,
|
|
||||||
filename string,
|
|
||||||
size int64,
|
|
||||||
collection string,
|
|
||||||
) (model.FileID, error) {
|
|
||||||
fileData, err := repoMedia.storage.Upload(file, filename, size, collection)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.storage.Upload: " + err.Error())
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return model.FileID(fileData.FileID), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repoMedia *RepoMedia) GetMediaFile(
|
|
||||||
fileID model.FileID,
|
|
||||||
) (model.DownloadFile, error) {
|
|
||||||
file, err := repoMedia.storage.Download(fileID)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.storage.Download: " + err.Error())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return file, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repoMedia *RepoMedia) UpdateMediaFile(
|
|
||||||
ctx context.Context,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
file model.UploadFile,
|
|
||||||
fileID model.FileID,
|
|
||||||
filename string,
|
|
||||||
size int64,
|
|
||||||
collection string,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
) error {
|
|
||||||
err := repoMedia.storage.Update(file, fileID, filename, size, collection)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.storage.Update: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaType = mediaType + "_url"
|
|
||||||
args := model.QueryArgs{
|
|
||||||
string(mediaType): model.MediaUrl(fileID),
|
|
||||||
"id": widgetID,
|
|
||||||
}
|
|
||||||
_, err = repoMedia.db.Query(ctx, sql.UpdateMediaUrlQuery(mediaType), args)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.db.Query: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repoMedia *RepoMedia) SetMediaUrl(
|
|
||||||
ctx context.Context,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
mediaUrl model.MediaUrl,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
) error {
|
|
||||||
mediaType = mediaType + "_url"
|
|
||||||
|
|
||||||
args := model.QueryArgs{
|
|
||||||
string(mediaType): mediaUrl,
|
|
||||||
"id": widgetID,
|
|
||||||
}
|
|
||||||
_, err := repoMedia.db.Query(ctx, sql.UpdateMediaUrlQuery(mediaType), args)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.db.Query: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (repoMedia *RepoMedia) GetMediaUrl(
|
|
||||||
ctx context.Context,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
) (model.MediaUrl, error) {
|
|
||||||
mediaType = mediaType + "_url"
|
|
||||||
args := model.QueryArgs{
|
|
||||||
"id": widgetID,
|
|
||||||
}
|
|
||||||
rows, err := repoMedia.db.Query(ctx, sql.GetMediaUrl(mediaType), args)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.db.Query: " + err.Error())
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var widgets []*model.Widget
|
|
||||||
err = pgxscan.ScanAll(&widgets, rows)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error())
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(widgets) == 0 {
|
|
||||||
slog.Error("Widget does not exist")
|
|
||||||
return "", errors.New("widget does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
widget := widgets[0]
|
|
||||||
mediaUrl := widget.GetMediaUrl(mediaType)
|
|
||||||
|
|
||||||
return mediaUrl, nil
|
|
||||||
}
|
|
@ -9,14 +9,19 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(db model.Db) *RepoWidget {
|
func New(
|
||||||
|
db model.Db,
|
||||||
|
storage model.Storage,
|
||||||
|
) *RepoWidget {
|
||||||
return &RepoWidget{
|
return &RepoWidget{
|
||||||
db: db,
|
db: db,
|
||||||
|
storage: storage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type RepoWidget struct {
|
type RepoWidget struct {
|
||||||
db model.Db
|
db model.Db
|
||||||
|
storage model.Storage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widgetRepo *RepoWidget) CreateWidget(
|
func (widgetRepo *RepoWidget) CreateWidget(
|
||||||
@ -28,7 +33,7 @@ func (widgetRepo *RepoWidget) CreateWidget(
|
|||||||
"streamer_id": streamerID,
|
"streamer_id": streamerID,
|
||||||
"template_id": templateID,
|
"template_id": templateID,
|
||||||
}
|
}
|
||||||
_, err := widgetRepo.db.Query(ctx, sql.CreateWidgetQuery, args)
|
_, err := widgetRepo.db.Query(ctx, sql.CreateWidget, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("widgetRepo.db.Query: " + err.Error())
|
slog.Error("widgetRepo.db.Query: " + err.Error())
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -45,7 +50,7 @@ func (widgetRepo *RepoWidget) GetWidget(
|
|||||||
args := model.QueryArgs{
|
args := model.QueryArgs{
|
||||||
"id": widgetID,
|
"id": widgetID,
|
||||||
}
|
}
|
||||||
rows, err := widgetRepo.db.Query(ctx, sql.GetWidgetQuery, 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("widgetRepo.db.Query: " + err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -69,6 +74,29 @@ func (widgetRepo *RepoWidget) GetWidget(
|
|||||||
return widget, nil
|
return widget, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (widgetRepo *RepoWidget) GetAllWidget(
|
||||||
|
ctx context.Context,
|
||||||
|
streamerID model.StreamerID,
|
||||||
|
) ([]*model.Widget, error) {
|
||||||
|
args := model.QueryArgs{
|
||||||
|
"streamerID": streamerID,
|
||||||
|
}
|
||||||
|
rows, err := widgetRepo.db.Query(ctx, sql.GetAllWidget, args)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("widgetRepo.db.Query: " + err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var widgets []*model.Widget
|
||||||
|
err = pgxscan.ScanAll(&widgets, rows)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return widgets, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (widgetRepo *RepoWidget) DeleteWidget(
|
func (widgetRepo *RepoWidget) DeleteWidget(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
widgetID model.WidgetID,
|
widgetID model.WidgetID,
|
||||||
@ -85,7 +113,7 @@ func (widgetRepo *RepoWidget) UpdateDuration(
|
|||||||
"id": widgetID,
|
"id": widgetID,
|
||||||
"duration": duration,
|
"duration": duration,
|
||||||
}
|
}
|
||||||
_, err := widgetRepo.db.Query(ctx, sql.UpdateDurationQuery, args)
|
_, err := widgetRepo.db.Query(ctx, sql.UpdateDuration, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("widgetRepo.db.Query: " + err.Error())
|
slog.Error("widgetRepo.db.Query: " + err.Error())
|
||||||
return err
|
return err
|
||||||
@ -93,3 +121,113 @@ func (widgetRepo *RepoWidget) UpdateDuration(
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (widgetRepo *RepoWidget) SetMediaFile(
|
||||||
|
file model.UploadFile,
|
||||||
|
filename string,
|
||||||
|
size int64,
|
||||||
|
collection string,
|
||||||
|
) (model.FileID, error) {
|
||||||
|
fileData, err := widgetRepo.storage.Upload(file, filename, size, collection)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.storage.Upload: " + err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.FileID(fileData.FileID), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (widgetRepo *RepoWidget) GetMediaFile(
|
||||||
|
fileID model.FileID,
|
||||||
|
) (model.DownloadFile, error) {
|
||||||
|
file, err := widgetRepo.storage.Download(fileID)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.storage.Download: " + err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (widgetRepo *RepoWidget) UpdateMediaFile(
|
||||||
|
ctx context.Context,
|
||||||
|
widgetID model.WidgetID,
|
||||||
|
file model.UploadFile,
|
||||||
|
fileID model.FileID,
|
||||||
|
filename string,
|
||||||
|
size int64,
|
||||||
|
collection string,
|
||||||
|
mediaType model.MediaType,
|
||||||
|
) error {
|
||||||
|
err := widgetRepo.storage.Update(file, fileID, filename, size, collection)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.storage.Update: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaType = mediaType + "_url"
|
||||||
|
args := model.QueryArgs{
|
||||||
|
string(mediaType): model.MediaUrl(fileID),
|
||||||
|
"id": widgetID,
|
||||||
|
}
|
||||||
|
_, err = widgetRepo.db.Query(ctx, sql.UpdateMediaUrl(mediaType), args)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.db.Query: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (widgetRepo *RepoWidget) SetMediaUrl(
|
||||||
|
ctx context.Context,
|
||||||
|
widgetID model.WidgetID,
|
||||||
|
mediaUrl model.MediaUrl,
|
||||||
|
mediaType model.MediaType,
|
||||||
|
) error {
|
||||||
|
mediaType = mediaType + "_url"
|
||||||
|
|
||||||
|
args := model.QueryArgs{
|
||||||
|
string(mediaType): mediaUrl,
|
||||||
|
"id": widgetID,
|
||||||
|
}
|
||||||
|
_, err := widgetRepo.db.Query(ctx, sql.UpdateMediaUrl(mediaType), args)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.db.Query: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (widgetRepo *RepoWidget) GetMediaUrl(
|
||||||
|
ctx context.Context,
|
||||||
|
widgetID model.WidgetID,
|
||||||
|
mediaType model.MediaType,
|
||||||
|
) (model.MediaUrl, error) {
|
||||||
|
mediaType = mediaType + "_url"
|
||||||
|
args := model.QueryArgs{
|
||||||
|
"id": widgetID,
|
||||||
|
}
|
||||||
|
rows, err := widgetRepo.db.Query(ctx, sql.GetMediaUrl(mediaType), args)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.db.Query: " + err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var widgets []*model.Widget
|
||||||
|
err = pgxscan.ScanAll(&widgets, rows)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("repoMedia.pgxscan.ScanAll: " + err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(widgets) == 0 {
|
||||||
|
slog.Error("Widget does not exist")
|
||||||
|
return "", errors.New("widget does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
widget := widgets[0]
|
||||||
|
mediaUrl := widget.GetMediaUrl(mediaType)
|
||||||
|
|
||||||
|
return mediaUrl, nil
|
||||||
|
}
|
||||||
|
92
internal/service/donat/donat.go
Normal file
92
internal/service/donat/donat.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package donat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"donat-widget/internal/model"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceDonat struct {
|
||||||
|
donatRepo model.DonatRepo
|
||||||
|
widgetRepo model.WidgetRepo
|
||||||
|
paymentClient model.PaymentClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(
|
||||||
|
donatRepo model.DonatRepo,
|
||||||
|
widgetRepo model.WidgetRepo,
|
||||||
|
paymentClient model.PaymentClient,
|
||||||
|
) *ServiceDonat {
|
||||||
|
return &ServiceDonat{
|
||||||
|
donatRepo: donatRepo,
|
||||||
|
widgetRepo: widgetRepo,
|
||||||
|
paymentClient: paymentClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (donatService *ServiceDonat) CreateDonat(
|
||||||
|
ctx context.Context,
|
||||||
|
streamerID model.StreamerID,
|
||||||
|
orderID model.OrderID,
|
||||||
|
amount model.DonatAmount,
|
||||||
|
text string,
|
||||||
|
donatUser string,
|
||||||
|
) error {
|
||||||
|
widgets, err := donatService.widgetRepo.GetAllWidget(ctx, streamerID)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("donatService.widgetRepo.GetAllWidget: ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var widgetID model.WidgetID
|
||||||
|
for _, widget := range widgets {
|
||||||
|
if widget.MinAmount <= amount {
|
||||||
|
widgetID = widget.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = donatService.donatRepo.CreateDonat(
|
||||||
|
ctx,
|
||||||
|
widgetID,
|
||||||
|
orderID,
|
||||||
|
amount,
|
||||||
|
text,
|
||||||
|
donatUser,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("donatService.donatRepo.SetDonat: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (donatService *ServiceDonat) MarkDonatPaid(
|
||||||
|
ctx context.Context,
|
||||||
|
orderID model.OrderID,
|
||||||
|
) error {
|
||||||
|
err := donatService.donatRepo.MarkDonatPaid(
|
||||||
|
ctx,
|
||||||
|
orderID,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("donatService.donatRepo.MarkDonatView: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (donatService *ServiceDonat) MarkDonatView(
|
||||||
|
ctx context.Context,
|
||||||
|
donatID model.DonatID,
|
||||||
|
) error {
|
||||||
|
err := donatService.donatRepo.MarkDonatView(
|
||||||
|
ctx,
|
||||||
|
donatID,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("donatService.donatRepo.MarkDonatView: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
1
internal/service/target/target.go
Normal file
1
internal/service/target/target.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package target
|
@ -1,55 +0,0 @@
|
|||||||
package donat
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"donat-widget/internal/model"
|
|
||||||
"log/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ServiceDonat struct {
|
|
||||||
donatRepo model.DonatRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(
|
|
||||||
donatRepo model.DonatRepo,
|
|
||||||
) *ServiceDonat {
|
|
||||||
return &ServiceDonat{
|
|
||||||
donatRepo: donatRepo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (donatService *ServiceDonat) SetDonat(
|
|
||||||
ctx context.Context,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
text string,
|
|
||||||
amount model.DonatAmount,
|
|
||||||
donatUser string,
|
|
||||||
) error {
|
|
||||||
err := donatService.donatRepo.SetDonat(
|
|
||||||
ctx,
|
|
||||||
widgetID,
|
|
||||||
text,
|
|
||||||
amount,
|
|
||||||
donatUser,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("donatService.donatRepo.SetDonat: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (donatService *ServiceDonat) DeleteDonat(
|
|
||||||
ctx context.Context,
|
|
||||||
donatID model.DonatID,
|
|
||||||
) error {
|
|
||||||
err := donatService.donatRepo.DeleteDonat(
|
|
||||||
ctx,
|
|
||||||
donatID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("donatService.donatRepo.DeleteDonat: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
package media
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"donat-widget/internal/model"
|
|
||||||
"log/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func New(mediaRepo model.MediaRepo) *ServiceMedia {
|
|
||||||
return &ServiceMedia{
|
|
||||||
mediaRepo: mediaRepo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceMedia struct {
|
|
||||||
mediaRepo model.MediaRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mediaService *ServiceMedia) SetMediaFile(
|
|
||||||
ctx context.Context,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
file model.UploadFile,
|
|
||||||
filename string,
|
|
||||||
size int64,
|
|
||||||
collection string,
|
|
||||||
) error {
|
|
||||||
fileID, err := mediaService.mediaRepo.SetMediaFile(
|
|
||||||
file,
|
|
||||||
filename,
|
|
||||||
size,
|
|
||||||
collection,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("mediaService.mediaRepo.SetMediaFile: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mediaService.SetMediaUrl(
|
|
||||||
ctx,
|
|
||||||
mediaType,
|
|
||||||
widgetID,
|
|
||||||
model.MediaUrl(fileID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("mediaService.SetMediaUrl: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mediaService *ServiceMedia) GetMediaFile(
|
|
||||||
ctx context.Context,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
) (model.DownloadFile, error) {
|
|
||||||
fileID, err := mediaService.mediaRepo.GetMediaUrl(
|
|
||||||
ctx,
|
|
||||||
widgetID,
|
|
||||||
mediaType,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("mediaService.mediaRepo.GetMediaUrl: " + err.Error())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := mediaService.mediaRepo.GetMediaFile(
|
|
||||||
model.FileID(fileID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("mediaService.mediaRepo.GetMediaFile: " + err.Error())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return file, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mediaService *ServiceMedia) UpdateMediaFile(
|
|
||||||
ctx context.Context,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
file model.UploadFile,
|
|
||||||
filename string,
|
|
||||||
size int64,
|
|
||||||
collection string,
|
|
||||||
) error {
|
|
||||||
fileID, err := mediaService.mediaRepo.GetMediaUrl(
|
|
||||||
ctx,
|
|
||||||
widgetID,
|
|
||||||
mediaType,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("mediaService.mediaRepo.GetMediaUrl: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mediaService.mediaRepo.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 (mediaService *ServiceMedia) SetMediaUrl(
|
|
||||||
ctx context.Context,
|
|
||||||
mediaType model.MediaType,
|
|
||||||
widgetID model.WidgetID,
|
|
||||||
mediaUrl model.MediaUrl,
|
|
||||||
) error {
|
|
||||||
err := mediaService.mediaRepo.SetMediaUrl(
|
|
||||||
ctx,
|
|
||||||
widgetID,
|
|
||||||
mediaUrl,
|
|
||||||
mediaType,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("mediaService.mediaRepo.SetMediaUrl: " + err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -113,3 +113,117 @@ func (widgetService *ServiceWidget) GetWidgetInfo(
|
|||||||
|
|
||||||
return &donatAndWidget, nil
|
return &donatAndWidget, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (widgetService *ServiceWidget) SetMediaFile(
|
||||||
|
ctx context.Context,
|
||||||
|
mediaType model.MediaType,
|
||||||
|
widgetID model.WidgetID,
|
||||||
|
file model.UploadFile,
|
||||||
|
filename string,
|
||||||
|
size int64,
|
||||||
|
collection string,
|
||||||
|
) error {
|
||||||
|
fileID, err := widgetService.widgetRepo.SetMediaFile(
|
||||||
|
file,
|
||||||
|
filename,
|
||||||
|
size,
|
||||||
|
collection,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("mediaService.mediaRepo.SetMediaFile: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = widgetService.SetMediaUrl(
|
||||||
|
ctx,
|
||||||
|
mediaType,
|
||||||
|
widgetID,
|
||||||
|
model.MediaUrl(fileID),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("mediaService.SetMediaUrl: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (widgetService *ServiceWidget) GetMediaFile(
|
||||||
|
ctx context.Context,
|
||||||
|
widgetID model.WidgetID,
|
||||||
|
mediaType model.MediaType,
|
||||||
|
) (model.DownloadFile, error) {
|
||||||
|
fileID, err := widgetService.widgetRepo.GetMediaUrl(
|
||||||
|
ctx,
|
||||||
|
widgetID,
|
||||||
|
mediaType,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("mediaService.mediaRepo.GetMediaUrl: " + err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := widgetService.widgetRepo.GetMediaFile(
|
||||||
|
model.FileID(fileID),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("mediaService.mediaRepo.GetMediaFile: " + err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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(
|
||||||
|
ctx context.Context,
|
||||||
|
mediaType model.MediaType,
|
||||||
|
widgetID model.WidgetID,
|
||||||
|
mediaUrl model.MediaUrl,
|
||||||
|
) error {
|
||||||
|
err := widgetService.widgetRepo.SetMediaUrl(
|
||||||
|
ctx,
|
||||||
|
widgetID,
|
||||||
|
mediaUrl,
|
||||||
|
mediaType,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("mediaService.mediaRepo.SetMediaUrl: " + err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
71
pkg/api/payment/tinkoff.go
Normal file
71
pkg/api/payment/tinkoff.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package payment
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"donat-widget/internal/model"
|
||||||
|
"donat-widget/internal/model/api"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(host, port string) *ClientPayment {
|
||||||
|
return &ClientPayment{
|
||||||
|
client: &http.Client{},
|
||||||
|
baseURL: "http://" + host + ":" + port + "/api/payment",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientPayment struct {
|
||||||
|
client *http.Client
|
||||||
|
baseURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClientPayment) CreatePayment(
|
||||||
|
streamerID model.StreamerID,
|
||||||
|
amount model.DonatAmount,
|
||||||
|
orderID model.OrderID,
|
||||||
|
) (api.CreatePaymentResponse, error) {
|
||||||
|
requestBody := map[string]any{
|
||||||
|
"sellerID": streamerID,
|
||||||
|
"amount": amount,
|
||||||
|
"orderID": orderID,
|
||||||
|
}
|
||||||
|
response, err := c.post("/buyer/pay", requestBody)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("c.post /buyer/pay", err)
|
||||||
|
return api.CreatePaymentResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var createPaymentResponse api.CreatePaymentResponse
|
||||||
|
if err = json.Unmarshal(response, &createPaymentResponse); err != nil {
|
||||||
|
slog.Error("json.Unmarshal", err)
|
||||||
|
return api.CreatePaymentResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPaymentResponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClientPayment) post(path string, body map[string]any) ([]byte, error) {
|
||||||
|
bytesBody, _ := json.Marshal(body)
|
||||||
|
|
||||||
|
resp, err := c.client.Post(c.baseURL+path, "application/json", bytes.NewReader(bytesBody))
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("c.client.Post: " + err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("tinkoff: post failed: " + resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("io.ReadAll: " + err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user