added controllers fiber, need only sse methods

This commit is contained in:
Pavel 2024-09-30 15:49:03 +03:00
parent ba9da92197
commit e3f08cac07
16 changed files with 1243 additions and 72 deletions

@ -1,52 +0,0 @@
package app
import (
"github.com/gofiber/contrib/fiberzap"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/recover"
"go.uber.org/zap"
"heruvym/dal/mongo"
"heruvym/internal/utils/middleware"
"heruvym/service"
)
type AccountHTTP struct {
fiber *fiber.App
}
func NewAccountHTTP(dal *mongo.DAL, logger *zap.Logger) *AccountHTTP {
srv := fiber.New(fiber.Config{
AppName: "Heryvum Account",
ErrorHandler: fiber.DefaultErrorHandler,
})
srv.Use(
recover.New(recover.Config{EnableStackTrace: true}),
fiberzap.New(fiberzap.Config{Logger: logger}),
middleware.Jwt,
cors.New(cors.ConfigDefault),
)
return &AccountHTTP{fiber: srv}
}
// StartTLS - запускает http сервер
func (srv *AccountHTTP) StartTLS(address, certFile, keyFile string) error {
return srv.fiber.ListenTLS(address, certFile, keyFile)
}
func (srv *AccountHTTP) Start(address string) error {
return srv.fiber.Listen(address)
}
func (srv *AccountHTTP) Register(routes ...service.Route) {
for _, route := range routes {
srv.fiber.Add(route.Method, route.Path, route.Handler).Name(route.Name)
}
}
// Stop - останавливает http сервер
func (srv *AccountHTTP) Stop() error {
return srv.fiber.Shutdown()
}

@ -4,7 +4,7 @@ import (
"context"
"errors"
"fmt"
"heruvym/model"
"heruvym/internal/model"
"time"
"github.com/rs/xid"
@ -249,7 +249,7 @@ func (d *DAL) CreateTicket(
ctx context.Context,
userID,
sessionID,
origin,
origin,
title, message string,
files []string,
) (string, error) {
@ -265,7 +265,7 @@ func (d *DAL) CreateTicket(
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Rate: -1,
Origin: origin,
Origin: origin,
TopMessage: model.Message{
ID: xid.New().String(),
UserID: userID,

@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/suite"
"github.com/themakers/hlog"
"go.uber.org/zap"
"heruvym/model"
"heruvym/internal/model"
"testing"
)

23
go.mod

@ -35,8 +35,8 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fatih/color v1.10.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-playground/assert/v2 v2.2.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
@ -44,9 +44,9 @@ require (
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.5 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/gofuzz v1.0.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/renameio v0.1.0 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/hpcloud/tail v1.0.0 // indirect
@ -56,7 +56,7 @@ require (
github.com/kisielk/gotool v1.0.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.1.2 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kr/pty v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.3 // indirect
@ -75,7 +75,7 @@ require (
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/rogpeppe/go-internal v1.3.0 // indirect
github.com/rogpeppe/go-internal v1.6.1 // indirect
github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
@ -95,7 +95,7 @@ require (
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect
@ -103,15 +103,16 @@ require (
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.6.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/errgo.v2 v2.1.0 // indirect
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/telebot.v3 v3.3.8 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/tools v0.0.1-2019.2.3 // indirect
honnef.co/go/tools v0.0.1-2020.1.4 // indirect
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240804072029-436a9f848461 // indirect
)

731
go.sum

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
package errors
type ErrorClose struct {
Err error
}
type ErrorMarshal struct {
Err error
}
type ErrorWrite struct {
Err error
}

@ -0,0 +1,42 @@
package other
import (
"github.com/gofiber/fiber/v2"
"heruvym/internal/repository/mongo"
"heruvym/internal/utils/jwt_adapter"
)
type Deps struct {
Dal *mongo.DAL
}
type OtherController struct {
dal *mongo.DAL
}
func NewOtherController(deps Deps) *OtherController {
return &OtherController{
dal: deps.Dal,
}
}
type ReqScreenshot struct {
TicketID string `json:"ticket"`
Lang string `json:"lang"`
}
func (o *OtherController) RequestScreenshot(ctx *fiber.Ctx) error {
var request ReqScreenshot
sess := jwt_adapter.Get(ctx.Context())
_, err := o.dal.PutSCRequest(
ctx.Context(),
sess.Id,
sess.Id,
request.TicketID,
)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
}
return ctx.SendStatus(fiber.StatusOK)
}

@ -0,0 +1,14 @@
package other
import "github.com/gofiber/fiber/v2"
func (o *OtherController) Register(router fiber.Router) {
router.Post("/requestScreenshot", o.RequestScreenshot)
router.Post("/sendFiles", o.PutFile)
router.Post("/sendSC", o.PutSC)
}
func (o *OtherController) Name() string {
return ""
}

@ -0,0 +1,22 @@
package tickets
import "github.com/gofiber/fiber/v2"
func (t *TicketController) Register(router fiber.Router) {
router.Post("/create", t.CreateTicket)
router.Get("/subscribe", t.GetList) // sse
router.Get("/ticket", t.Subscribe) // sse
router.Post("/send", t.PutMessage)
router.Post("/getTickets", t.GetTickets)
router.Post("/getMessages", t.GetMessages)
router.Post("/pick", t.Pick)
router.Post("/delegate", t.Delegate)
router.Post("/vote", t.Vote)
router.Post("/close", t.CloseTicket)
router.Post("/shown", t.SetShown)
}
func (t *TicketController) Name() string {
return ""
}

@ -0,0 +1,400 @@
package tickets
import (
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/themakers/hlog"
"go.uber.org/zap"
"gopkg.in/telebot.v3"
tb "gopkg.in/tucnak/telebot.v2"
our_errors "heruvym/internal/controllers/errors"
"heruvym/internal/model"
"heruvym/internal/repository/mongo"
"heruvym/internal/utils/jwt_adapter"
"heruvym/internal/utils/middleware"
)
type Deps struct {
Dal *mongo.DAL
Notifier *telebot.Bot
TgChatID int64
HLogger hlog.Logger
ZapLogger *zap.Logger
}
type TicketController struct {
dal *mongo.DAL
notifier *telebot.Bot
tgChatID int64
hLogger hlog.Logger
zapLogger *zap.Logger
}
func NewTicketController(deps Deps) *TicketController {
return &TicketController{
dal: deps.Dal,
notifier: deps.Notifier,
tgChatID: deps.TgChatID,
hLogger: deps.HLogger,
zapLogger: deps.ZapLogger,
}
}
type CreateTicketReq struct {
Title string `json:"Title"`
Message string `json:"Message"`
}
type CreateTicketResp struct {
Ticket string `json:"Ticket"`
Sess string `json:"sess"`
}
func (t *TicketController) CreateTicket(ctx *fiber.Ctx) error {
var (
err error
request CreateTicketReq
)
err = ctx.BodyParser(&request)
if err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
if request.Title == "" {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "title is required"})
}
if request.Message == "" {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "message is required"})
}
session := jwt_adapter.Get(ctx.Context())
if session == nil {
return ctx.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "unauthorized"})
}
var (
ticketID string
tickets []model.Ticket
role = jwt_adapter.GetRole(ctx.Context())
)
if role == "" {
tickets, _, err = t.dal.GetTickets4Sess(ctx.Context(), session.Id)
}
if err != nil || len(tickets) == 0 {
ticketID, err = t.dal.CreateTicket(
ctx.Context(),
session.Id,
session.Id,
ctx.Get("Origin"),
request.Title,
request.Message,
[]string{},
)
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
if _, err := t.dal.PutMessage(ctx.Context(),
request.Message,
session.Id,
session.Id,
ticketID,
[]string{},
); err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
domain := ctx.Context().Value(middleware.HostKey).(string)
if domain == "" {
t.zapLogger.Error("domain is nil err")
}
go func() {
if session.Id != "" && role != "admin" {
if err == nil && t.notifier != nil {
var userLink, supportLink string
if session.StandardClaims.Issuer != "" {
if domain[0] == 's' {
userLink = fmt.Sprintf("https://sadmin.pena/users/%s", session.Id)
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID)
} else {
userLink = fmt.Sprintf("https://admin.pena/users/%s", session.Id)
supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID)
}
} else {
if domain[0] == 's' {
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID)
} else {
supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID)
}
userLink = "незарегистрированного пользователя"
}
message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s",
userLink, domain, supportLink)
if _, err := t.notifier.Send(tb.ChatID(t.tgChatID), message); err != nil {
fmt.Println("CAN NOT NOTIFY", err)
}
return
}
}
}()
} else {
ticketID = tickets[0].ID
}
response, err := json.Marshal(CreateTicketResp{Ticket: ticketID, Sess: session.Id})
if err != nil {
t.hLogger.Emit(our_errors.ErrorClose{
Err: err,
})
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return ctx.Status(fiber.StatusOK).JSON(response)
}
type ReqPutMessage struct {
Message string `json:"message"`
TicketID string `json:"ticket"`
Files []string `json:"files"`
Lang string `json:"lang"`
}
func (t *TicketController) PutMessage(ctx *fiber.Ctx) error {
var request ReqPutMessage
err := ctx.BodyParser(&request)
if err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
sess := jwt_adapter.Get(ctx.Context())
request.Files = []string{}
domain := ctx.Context().Value(middleware.HostKey).(string)
if domain == "" {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "domain is nil"})
}
message, err := t.dal.PutMessage(
ctx.Context(),
request.Message,
sess.Id,
sess.Id,
request.TicketID,
[]string{},
)
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
role := jwt_adapter.GetRole(ctx.Context())
go func() {
if sess.Id != "" && role != "admin" {
if err == nil && t.notifier != nil {
var userLink, supportLink string
if sess.StandardClaims.Issuer != "" {
if domain[0] == 's' {
userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id)
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID)
} else {
userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id)
supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID)
}
} else {
if domain[0] == 's' {
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID)
} else {
supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID)
}
userLink = "незарегистрированного пользователя"
}
message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ссылка на чат - %s",
userLink, domain, supportLink)
if _, err := t.notifier.Send(tb.ChatID(t.tgChatID), message); err != nil {
t.zapLogger.Error("CAN NOT NOTIFY", zap.Error(err))
}
return
}
}
}()
if err := t.dal.UpdateTopMessage(ctx.Context(), request.TicketID, message); err != nil {
fmt.Println("PUTMES01", err, request.TicketID, message)
//return errors.New("can not update ticket"), http.StatusInternalServerError
}
return ctx.SendStatus(fiber.StatusOK)
}
type GetTicketsReq struct {
Amount int64 `json:"amt"`
Page int64 `json:"page"`
Search string `json:"srch"`
Status string `json:"status"`
}
type GetTicketsResp struct {
Data []model.Ticket `json:"data"`
Count int64 `json:"count"`
}
func (t *TicketController) GetTickets(ctx *fiber.Ctx) error {
var request GetTicketsReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
role := jwt_adapter.GetRole(ctx.Context())
if role == "admin" {
result, count, err := t.dal.GetTicketPage(ctx.Context(),
request.Status,
request.Search,
request.Amount,
request.Page,
)
if err != nil {
return ctx.Status(fiber.StatusNoContent).JSON(fiber.Map{"error": "No Content"})
}
return ctx.Status(fiber.StatusOK).JSON(GetTicketsResp{
Data: *result,
Count: count,
})
} else {
sess := jwt_adapter.Get(ctx.Context())
result, count, err := t.dal.YieldUserTickets(ctx.Context(), sess.Id, request.Amount, request.Page*request.Amount)
if err != nil {
return ctx.Status(fiber.StatusNoContent).JSON(fiber.Map{"error": "No Content"})
}
return ctx.Status(fiber.StatusOK).JSON(GetTicketsResp{
Data: result,
Count: count,
})
}
}
type GetMessagesReq struct {
Amount int64 `json:"amt"`
Page int64 `json:"page"`
Search string `json:"srch"`
TicketID string `json:"ticket"`
}
func (t *TicketController) GetMessages(ctx *fiber.Ctx) error {
var request GetMessagesReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
result, err := t.dal.GetMessagesPage(ctx.Context(),
request.Search,
request.TicketID,
request.Amount,
request.Page,
)
if err != nil {
return ctx.Status(fiber.StatusNoContent).JSON(fiber.Map{"error": "No Content"})
}
return ctx.Status(fiber.StatusOK).JSON(result)
}
type PickReq struct {
TicketID string `json:"ticket"`
}
func (t *TicketController) Pick(ctx *fiber.Ctx) error {
var request PickReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
sess := jwt_adapter.Get(ctx.Context())
if err := t.dal.SetAnswerer(ctx.Context(), request.TicketID, sess.Id); err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return ctx.SendStatus(fiber.StatusOK)
}
type DelegateReq struct {
TicketID string `json:"ticket"`
AnswererID string `json:"answerer"`
}
func (t *TicketController) Delegate(ctx *fiber.Ctx) error {
var request DelegateReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
if err := t.dal.SetAnswerer(ctx.Context(), request.TicketID, request.AnswererID); err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return ctx.SendStatus(fiber.StatusOK)
}
type VoteReq struct {
TicketID string `json:"ticket"`
Rate int `json:"rate"`
}
func (t *TicketController) Vote(ctx *fiber.Ctx) error {
var request VoteReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
if err := t.dal.SetRate(ctx.Context(), request.TicketID, request.Rate); err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return ctx.SendStatus(fiber.StatusOK)
}
type CloseTicketReq struct {
TicketID string `json:"ticket"`
}
type CloseTicketResp struct {
TicketID string `json:"ticket"`
}
func (t *TicketController) CloseTicket(ctx *fiber.Ctx) error {
var request CloseTicketReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
if err := t.dal.SetTicketStatus(ctx.Context(), request.TicketID, model.StateClose); err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
if _, err := t.dal.PutMessage(ctx.Context(), "close", "close", "close", request.TicketID, []string{}); err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return ctx.Status(fiber.StatusOK).JSON(CloseTicketResp{
TicketID: request.TicketID,
})
}
type ShownReq struct {
ID string `json:"id"`
}
func (t *TicketController) SetShown(ctx *fiber.Ctx) error {
var request ShownReq
if err := ctx.BodyParser(&request); err != nil {
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
err := t.dal.SetShown(ctx.Context(), request.ID, "me")
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return ctx.SendStatus(fiber.StatusOK)
}

@ -4,7 +4,7 @@ import (
"context"
"errors"
"fmt"
"heruvym/model"
"heruvym/internal/model"
"time"
"github.com/rs/xid"

@ -5,7 +5,7 @@ import (
"github.com/stretchr/testify/suite"
"github.com/themakers/hlog"
"go.uber.org/zap"
"heruvym/model"
"heruvym/internal/model"
"testing"
)

@ -8,7 +8,7 @@ import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"heruvym/model"
"heruvym/internal/model"
)
const (

@ -10,9 +10,9 @@ import (
"github.com/go-redis/redis/v8"
"heruvym/dal/minio"
"heruvym/dal/mongo"
"heruvym/internal/model"
"heruvym/internal/utils/jwt_adapter"
"heruvym/internal/utils/middleware"
"heruvym/model"
"heruvym/tools"
"heruvym/utils"
"io"

@ -8,8 +8,8 @@ import (
"errors"
"fmt"
"github.com/skeris/appInit"
"heruvym/internal/model"
"heruvym/internal/utils/jwt_adapter"
"heruvym/model"
"io"
"io/ioutil"
"mime/multipart"