heruvym/internal/controllers/tickets/tickets.go

401 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}