diff --git a/pkg/api/api.go b/pkg/api/api.go index 62f290c2..b2172827 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -256,7 +256,7 @@ func UserRestAPI() { // Support // v1.POST("/support", ticket.Create) - v1.GET("/support", ticket.GetTitle) + v1.GET("/support", ticket.GetAll) v1.POST("/support/:id", chat.Add) v1.GET("/support/:id", ticket.Get) // diff --git a/pkg/api/core/controller/interface.go b/pkg/api/core/controller/interface.go index db0718fc..504f80c3 100644 --- a/pkg/api/core/controller/interface.go +++ b/pkg/api/core/controller/interface.go @@ -12,6 +12,7 @@ type Chat struct { Err string `json:"error"` CreatedAt time.Time `json:"created_at"` UserID uint `json:"user_id"` + UserName string `json:"user_name"` GroupID uint `json:"group_id"` Admin bool `json:"admin"` Message string `json:"message"` diff --git a/pkg/api/core/controller/v0/admin.go b/pkg/api/core/controller/v0/admin.go index f144300c..3078810a 100644 --- a/pkg/api/core/controller/v0/admin.go +++ b/pkg/api/core/controller/v0/admin.go @@ -24,6 +24,7 @@ func SendChatAdmin(data controller.Chat) { Err: data.Err, CreatedAt: data.CreatedAt, UserID: data.UserID, + UserName: data.UserName, GroupID: data.GroupID, Admin: data.Admin, Message: data.Message, diff --git a/pkg/api/core/interface.go b/pkg/api/core/interface.go index 3cbd8ccf..e4653615 100644 --- a/pkg/api/core/interface.go +++ b/pkg/api/core/interface.go @@ -252,6 +252,8 @@ type Ticket struct { Chat []Chat `json:"chat"` Solved *bool `json:"solved"` Title string `json:"title"` + Group Group `json:"group"` + User User `json:"user"` } type Chat struct { @@ -260,6 +262,7 @@ type Chat struct { UserID uint `json:"user_id"` Admin bool `json:"admin"` Data string `json:"data" gorm:"size:65535"` + User User `json:"user"` } type Token struct { diff --git a/pkg/api/core/support/chat/v0/chat.go b/pkg/api/core/support/chat/v0/chat.go index dc138ab8..b06ff135 100644 --- a/pkg/api/core/support/chat/v0/chat.go +++ b/pkg/api/core/support/chat/v0/chat.go @@ -58,19 +58,19 @@ func Add(c *gin.Context) { return } // 問題解決時はここでエラーを返す - if *resultTicket.Ticket[0].Solved { + if *resultTicket.Tickets[0].Solved { c.JSON(http.StatusInternalServerError, common.Error{Error: "This problem is closed..."}) return } // GroupIDが一致しない場合はここでエラーを返す - if resultTicket.Ticket[0].GroupID != result.Group.ID { + if resultTicket.Tickets[0].GroupID != result.Group.ID { c.JSON(http.StatusInternalServerError, common.Error{Error: "Auth Error: group id failed..."}) return } // Chat DBに登録 resultChat, err := dbChat.Create(&core.Chat{ - TicketID: resultTicket.Ticket[0].ID, + TicketID: resultTicket.Tickets[0].ID, UserID: result.User.ID, Admin: false, Data: input.Data, diff --git a/pkg/api/core/support/interface.go b/pkg/api/core/support/interface.go index 2af97d38..d7a71a58 100644 --- a/pkg/api/core/support/interface.go +++ b/pkg/api/core/support/interface.go @@ -19,23 +19,26 @@ type WebSocketResult struct { UserToken string `json:"user_token"` AccessToken string `json:"access_token"` UserID uint `json:"user_id"` + UserName string `json:"user_name"` GroupID uint `json:"group_id"` Admin bool `json:"admin"` Message string `json:"message"` } type WebSocketChatResponse struct { - CreatedAt time.Time `json:"created_at"` - UserID uint `json:"user_id"` - GroupID uint `json:"group_id"` - Admin bool `json:"admin"` - Message string `json:"message"` + Time string `json:"time"` + UserID uint `json:"user_id"` + UserName string `json:"username"` + GroupID uint `json:"group_id"` + Admin bool `json:"admin"` + Message string `json:"message"` } type WebSocket struct { TicketID uint GroupID uint UserID uint + UserName string Admin bool Socket *websocket.Conn } @@ -49,6 +52,6 @@ type FirstInput struct { } type Result struct { - Ticket []core.Ticket `json:"support_ticket"` - Chat []core.Chat `json:"support_chat"` + Ticket []core.Ticket `json:"ticket"` + Chat []core.Chat `json:"chat"` } diff --git a/pkg/api/core/support/ticket/interface.go b/pkg/api/core/support/ticket/interface.go index 35da2200..67a2911e 100644 --- a/pkg/api/core/support/ticket/interface.go +++ b/pkg/api/core/support/ticket/interface.go @@ -3,7 +3,6 @@ package ticket import ( "github.com/gorilla/websocket" "github.com/homenoc/dsbd-backend/pkg/api/core" - "github.com/jinzhu/gorm" "net/http" ) @@ -16,27 +15,45 @@ const ( //#4 Issue(解決済み) -type AdminAllResult struct { - Ticket []AdminResult `json:"ticket"` +type Ticket struct { + ID uint `json:"id"` + Time string `json:"time"` + GroupID uint `json:"group_id"` + UserID uint `json:"user_id"` + Chat []Chat `json:"chat"` + Solved *bool `json:"solved"` + Title string `json:"title"` + UserName string `json:"username"` } -type AdminResult struct { - gorm.Model - Status bool `json:"status"` - Error string `json:"error"` - GroupID uint `json:"group_id"` - GroupName string `json:"group_name"` - UserID uint `json:"user_id"` - UserName string `json:"user_name"` - ChatIDStart uint `json:"chat_id_start"` - ChatIDEnd uint `json:"chat_id_end"` - Solved *bool `json:"solved"` - Title string `json:"title"` +type Chat struct { + Time string `json:"time"` + TicketID uint `json:"ticket_id"` + UserID uint `json:"user_id"` + UserName string `json:"username"` + Admin bool `json:"admin"` + Data string `json:"data"` +} + +type Result struct { + Ticket Ticket `json:"tickets"` +} + +type ResultAll struct { + Tickets []Ticket `json:"tickets"` +} + +type ResultTicketAll struct { + Tickets []Ticket `json:"tickets"` +} + +type ResultAdminAll struct { + Tickets []core.Ticket `json:"tickets"` } type ResultDatabase struct { - Err error - Ticket []core.Ticket + Err error + Tickets []core.Ticket } var WsUpgrader = websocket.Upgrader{ diff --git a/pkg/api/core/support/ticket/v0/admin.go b/pkg/api/core/support/ticket/v0/admin.go index 88e6cb68..7de0f2b9 100644 --- a/pkg/api/core/support/ticket/v0/admin.go +++ b/pkg/api/core/support/ticket/v0/admin.go @@ -9,13 +9,10 @@ import ( "github.com/homenoc/dsbd-backend/pkg/api/core/common" controllerInterface "github.com/homenoc/dsbd-backend/pkg/api/core/controller" controller "github.com/homenoc/dsbd-backend/pkg/api/core/controller/v0" - "github.com/homenoc/dsbd-backend/pkg/api/core/group" "github.com/homenoc/dsbd-backend/pkg/api/core/support" - "github.com/homenoc/dsbd-backend/pkg/api/core/support/chat" "github.com/homenoc/dsbd-backend/pkg/api/core/support/ticket" "github.com/homenoc/dsbd-backend/pkg/api/core/tool/mail" "github.com/homenoc/dsbd-backend/pkg/api/core/user" - dbGroup "github.com/homenoc/dsbd-backend/pkg/api/store/group/v0" dbChat "github.com/homenoc/dsbd-backend/pkg/api/store/support/chat/v0" dbTicket "github.com/homenoc/dsbd-backend/pkg/api/store/support/ticket/v0" dbUser "github.com/homenoc/dsbd-backend/pkg/api/store/user/v0" @@ -49,7 +46,7 @@ func CreateAdmin(c *gin.Context) { return } - // Ticket DBに登録 + // Tickets DBに登録 ticketResult, err := dbTicket.Create(&core.Ticket{ GroupID: input.GroupID, UserID: 0, @@ -101,7 +98,7 @@ func UpdateAdmin(c *gin.Context) { return } - // Ticket DBからデータを取得 + // Tickets DBからデータを取得 ticketResult := dbTicket.Get(ticket.ID, &core.Ticket{Model: gorm.Model{ID: uint(id)}}) if ticketResult.Err != nil { c.JSON(http.StatusInternalServerError, common.Error{Error: ticketResult.Err.Error()}) @@ -109,7 +106,7 @@ func UpdateAdmin(c *gin.Context) { } // input check - replace, err := updateAdminTicket(input, ticketResult.Ticket[0]) + replace, err := updateAdminTicket(input, ticketResult.Tickets[0]) if err != nil { c.JSON(http.StatusInternalServerError, common.Error{Error: err.Error()}) return @@ -144,15 +141,7 @@ func GetAdmin(c *gin.Context) { c.JSON(http.StatusInternalServerError, common.Error{Error: resultTicket.Err.Error()}) return } - - // Ticket DBからTicket IDのTicketデータを抽出 - // このとき、データはIDの昇順で出力 - resultChat := dbChat.Get(chat.TicketID, &core.Chat{TicketID: resultTicket.Ticket[0].ID}) - if resultChat.Err != nil { - c.JSON(http.StatusInternalServerError, common.Error{Error: resultTicket.Err.Error()}) - return - } - c.JSON(http.StatusOK, support.Result{Ticket: resultTicket.Ticket, Chat: resultChat.Chat}) + c.JSON(http.StatusOK, support.Result{Ticket: resultTicket.Tickets}) } func GetAllAdmin(c *gin.Context) { @@ -163,33 +152,14 @@ func GetAllAdmin(c *gin.Context) { return } - // Ticket DBからGroup IDのTicketデータを抽出 + // Tickets DBからGroup IDのTicketデータを抽出 resultTicket := dbTicket.GetAll() if resultTicket.Err != nil { c.JSON(http.StatusInternalServerError, common.Error{Error: resultTicket.Err.Error()}) return } - var ticketResponse []ticket.AdminResult - - for _, tmp := range resultTicket.Ticket { - //user名検索 - tmpUserResult := dbUser.Get(user.ID, &core.User{Model: gorm.Model{ID: tmp.UserID}}) - //group名検索 - tmpGroupResult := dbGroup.Get(group.ID, &core.Group{Model: gorm.Model{ID: tmp.GroupID}}) - - ticketResponse = append(ticketResponse, ticket.AdminResult{ - Model: tmp.Model, - GroupID: tmp.GroupID, - GroupName: tmpGroupResult.Group[0].Org, - UserID: tmp.UserID, - UserName: tmpUserResult.User[0].Name, - Solved: tmp.Solved, - Title: tmp.Title, - }) - } - - c.JSON(http.StatusOK, ticket.AdminAllResult{Ticket: ticketResponse}) + c.JSON(http.StatusOK, ticket.ResultAdminAll{Tickets: resultTicket.Tickets}) } func GetAdminWebSocket(c *gin.Context) { @@ -231,7 +201,8 @@ func GetAdminWebSocket(c *gin.Context) { support.Clients[&support.WebSocket{ TicketID: uint(id), UserID: resultAdmin.AdminID, - GroupID: ticketResult.Ticket[0].GroupID, + UserName: "HomeNOC", + GroupID: ticketResult.Tickets[0].GroupID, Socket: conn, }] = true @@ -244,14 +215,15 @@ func GetAdminWebSocket(c *gin.Context) { delete(support.Clients, &support.WebSocket{ TicketID: uint(id), UserID: resultAdmin.AdminID, - GroupID: ticketResult.Ticket[0].GroupID, + UserName: "HomeNOC(運営)", + GroupID: ticketResult.Tickets[0].GroupID, Socket: conn, }) break } _, err = dbChat.Create(&core.Chat{ - TicketID: ticketResult.Ticket[0].ID, + TicketID: ticketResult.Tickets[0].ID, UserID: resultAdmin.AdminID, Admin: true, Data: msg.Message, @@ -260,7 +232,8 @@ func GetAdminWebSocket(c *gin.Context) { conn.WriteJSON(&support.WebSocketResult{Err: "db write error"}) } else { msg.UserID = resultAdmin.AdminID - msg.GroupID = ticketResult.Ticket[0].GroupID + msg.GroupID = ticketResult.Tickets[0].GroupID + msg.UserName = "HomeNOC(運営)" msg.Admin = true // Token関連の初期化 msg.AccessToken = "" @@ -271,17 +244,18 @@ func GetAdminWebSocket(c *gin.Context) { CreatedAt: msg.CreatedAt, Admin: msg.Admin, UserID: resultAdmin.AdminID, - GroupID: ticketResult.Ticket[0].GroupID, + UserName: msg.UserName, + GroupID: ticketResult.Tickets[0].GroupID, Message: msg.Message, }) - resultTicket := dbTicket.Get(ticket.ID, &core.Ticket{Model: gorm.Model{ID: ticketResult.Ticket[0].ID}}) + resultTicket := dbTicket.Get(ticket.ID, &core.Ticket{Model: gorm.Model{ID: ticketResult.Tickets[0].ID}}) if resultTicket.Err != nil { log.Println(resultTicket.Err) } - if len(resultTicket.Ticket) != 0 { + if len(resultTicket.Tickets) != 0 { resultUser := dbUser.Get(user.GIDAndLevel, &core.User{ - GroupID: resultTicket.Ticket[0].GroupID, + GroupID: resultTicket.Tickets[0].GroupID, Level: 1, }) if resultUser.Err != nil { @@ -315,11 +289,12 @@ func HandleMessagesAdmin() { return } else if client.GroupID == msg.GroupID { err := client.Socket.WriteJSON(support.WebSocketChatResponse{ - CreatedAt: time.Now(), - UserID: msg.UserID, - GroupID: msg.GroupID, - Admin: msg.Admin, - Message: msg.Message, + Time: time.Now().UTC().Add(9 * time.Hour).Format(timeLayout), + UserID: msg.UserID, + UserName: msg.UserName, + GroupID: msg.GroupID, + Admin: msg.Admin, + Message: msg.Message, }) if err != nil { log.Printf("error: %v", err) diff --git a/pkg/api/core/support/ticket/v0/ticket.go b/pkg/api/core/support/ticket/v0/ticket.go index 4598df16..bffea323 100644 --- a/pkg/api/core/support/ticket/v0/ticket.go +++ b/pkg/api/core/support/ticket/v0/ticket.go @@ -11,7 +11,6 @@ import ( controllerInterface "github.com/homenoc/dsbd-backend/pkg/api/core/controller" controller "github.com/homenoc/dsbd-backend/pkg/api/core/controller/v0" "github.com/homenoc/dsbd-backend/pkg/api/core/support" - "github.com/homenoc/dsbd-backend/pkg/api/core/support/chat" "github.com/homenoc/dsbd-backend/pkg/api/core/support/ticket" "github.com/homenoc/dsbd-backend/pkg/api/core/tool/notification" dbChat "github.com/homenoc/dsbd-backend/pkg/api/store/support/chat/v0" @@ -23,6 +22,8 @@ import ( "time" ) +const timeLayout = "2006-01-02 15:04:05 JST" + func Create(c *gin.Context) { var input support.FirstInput userToken := c.Request.Header.Get("USER_TOKEN") @@ -48,7 +49,7 @@ func Create(c *gin.Context) { return } - // Ticket DBに登録 + // Tickets DBに登録 ticketResult, err := dbTicket.Create(&core.Ticket{ GroupID: result.Group.ID, UserID: result.User.ID, @@ -61,7 +62,7 @@ func Create(c *gin.Context) { } // Chat DBに登録 - chatResult, err := dbChat.Create(&core.Chat{ + _, err = dbChat.Create(&core.Chat{ UserID: result.User.ID, Admin: false, Data: input.Data, @@ -81,7 +82,7 @@ func Create(c *gin.Context) { AddField(slack.Field{Title: "Message", Value: input.Data}) notification.SendSlack(notification.Slack{Attachment: attachment, ID: "main", Status: true}) - c.JSON(http.StatusOK, support.Result{Ticket: []core.Ticket{*ticketResult}, Chat: []core.Chat{*chatResult}}) + c.JSON(http.StatusOK, common.Result{}) } func Get(c *gin.Context) { @@ -109,22 +110,39 @@ func Get(c *gin.Context) { } // GroupIDが一致しない場合はここでエラーを返す - if resultTicket.Ticket[0].GroupID != result.Group.ID { + if resultTicket.Tickets[0].GroupID != result.Group.ID { c.JSON(http.StatusInternalServerError, common.Error{Error: "Auth Error: group id failed..."}) return } - // Ticket DBからTicket IDのTicketデータを抽出 - // このとき、データはIDの昇順で出力 - resultChat := dbChat.Get(chat.TicketID, &core.Chat{TicketID: resultTicket.Ticket[0].ID}) - if resultChat.Err != nil { - c.JSON(http.StatusInternalServerError, common.Error{Error: resultTicket.Err.Error()}) - return + var response ticket.Ticket + + var resultChat []ticket.Chat + for _, tmpChat := range resultTicket.Tickets[0].Chat { + resultChat = append(resultChat, ticket.Chat{ + Time: tmpChat.CreatedAt.Add(9 * time.Hour).Format(timeLayout), + UserID: tmpChat.UserID, + UserName: tmpChat.User.Name, + Admin: tmpChat.Admin, + Data: tmpChat.Data, + }) } - c.JSON(http.StatusOK, support.Result{Ticket: resultTicket.Ticket, Chat: resultChat.Chat}) + + response = ticket.Ticket{ + ID: resultTicket.Tickets[0].ID, + Time: resultTicket.Tickets[0].CreatedAt.Add(9 * time.Hour).Format(timeLayout), + GroupID: resultTicket.Tickets[0].GroupID, + UserID: resultTicket.Tickets[0].UserID, + Solved: resultTicket.Tickets[0].Solved, + Chat: resultChat, + Title: resultTicket.Tickets[0].Title, + UserName: resultTicket.Tickets[0].User.Name, + } + + c.JSON(http.StatusOK, ticket.Result{Ticket: response}) } -func GetTitle(c *gin.Context) { +func GetAll(c *gin.Context) { userToken := c.Request.Header.Get("USER_TOKEN") accessToken := c.Request.Header.Get("ACCESS_TOKEN") @@ -134,16 +152,40 @@ func GetTitle(c *gin.Context) { return } - // Ticket DBからGroup IDのTicketデータを抽出 + // Tickets DBからGroup IDのTicketデータを抽出 resultTicket := dbTicket.Get(ticket.GID, &core.Ticket{GroupID: result.Group.ID}) if resultTicket.Err != nil { c.JSON(http.StatusInternalServerError, common.Error{Error: resultTicket.Err.Error()}) return } - log.Println(resultTicket) + var response []ticket.Ticket + + for _, tmp := range resultTicket.Tickets { + var resultChat []ticket.Chat + for _, tmpChat := range tmp.Chat { + resultChat = append(resultChat, ticket.Chat{ + Time: tmpChat.CreatedAt.Add(9 * time.Hour).Format(timeLayout), + UserID: tmpChat.UserID, + UserName: tmpChat.User.Name, + Admin: tmpChat.Admin, + Data: tmpChat.Data, + }) + } + + response = append(response, ticket.Ticket{ + ID: resultTicket.Tickets[0].ID, + Time: resultTicket.Tickets[0].CreatedAt.Add(9 * time.Hour).Format(timeLayout), + GroupID: tmp.GroupID, + UserID: tmp.UserID, + Solved: tmp.Solved, + Chat: resultChat, + Title: tmp.Title, + UserName: tmp.User.Name, + }) + } - c.JSON(http.StatusOK, support.Result{Ticket: resultTicket.Ticket}) + c.JSON(http.StatusOK, ticket.ResultAll{Tickets: response}) } func GetWebSocket(c *gin.Context) { @@ -182,7 +224,7 @@ func GetWebSocket(c *gin.Context) { return } - if ticketResult.Ticket[0].ID != uint(id) { + if ticketResult.Tickets[0].ID != uint(id) { log.Println("ticketID not match.") } @@ -191,6 +233,7 @@ func GetWebSocket(c *gin.Context) { TicketID: uint(id), Admin: false, UserID: result.User.ID, + UserName: result.User.Name, GroupID: result.Group.ID, Socket: conn, }] = true @@ -205,6 +248,7 @@ func GetWebSocket(c *gin.Context) { TicketID: uint(id), Admin: false, UserID: result.User.ID, + UserName: result.User.Name, GroupID: result.Group.ID, Socket: conn, }) @@ -221,7 +265,7 @@ func GetWebSocket(c *gin.Context) { } _, err = dbChat.Create(&core.Chat{ - TicketID: ticketResult.Ticket[0].ID, + TicketID: ticketResult.Tickets[0].ID, UserID: result.User.ID, Admin: false, Data: msg.Message, @@ -233,6 +277,7 @@ func GetWebSocket(c *gin.Context) { msg.UserID = result.User.ID msg.GroupID = resultGroup.Group.ID msg.Admin = false + msg.UserName = result.User.Name // Token関連の初期化 msg.AccessToken = "" msg.UserToken = "" @@ -241,25 +286,18 @@ func GetWebSocket(c *gin.Context) { controller.SendChatUser(controllerInterface.Chat{ CreatedAt: msg.CreatedAt, UserID: result.User.ID, + UserName: result.User.Name, GroupID: resultGroup.Group.ID, Admin: msg.Admin, Message: msg.Message, }) - userName := "不明" - - for _, tmp := range resultGroup.Group.Users { - if tmp.GroupID == result.User.ID { - userName = tmp.Name - } - } - //Slackに送信 attachment := slack.Attachment{} attachment.AddField(slack.Field{Title: "Title", Value: "Support(新規メッセージ)"}). - AddField(slack.Field{Title: "発行者", Value: strconv.Itoa(int(result.User.ID)) + "-" + userName}). + AddField(slack.Field{Title: "発行者", Value: strconv.Itoa(int(result.User.ID)) + "-" + result.User.Name}). AddField(slack.Field{Title: "Group", Value: strconv.Itoa(int(result.Group.ID)) + "-" + result.Group.Org}). - AddField(slack.Field{Title: "Title", Value: ticketResult.Ticket[0].Title}). + AddField(slack.Field{Title: "Title", Value: ticketResult.Tickets[0].Title}). AddField(slack.Field{Title: "Message", Value: msg.Message}) notification.SendSlack(notification.Slack{Attachment: attachment, ID: "main", Status: true}) @@ -279,11 +317,12 @@ func HandleMessages() { return } else if client.GroupID == msg.GroupID { err := client.Socket.WriteJSON(support.WebSocketChatResponse{ - CreatedAt: time.Now(), - UserID: msg.UserID, - GroupID: msg.GroupID, - Admin: msg.Admin, - Message: msg.Message, + Time: time.Now().UTC().Add(9 * time.Hour).Format(timeLayout), + UserID: msg.UserID, + UserName: msg.UserName, + GroupID: msg.GroupID, + Admin: msg.Admin, + Message: msg.Message, }) if err != nil { log.Printf("error: %v", err) diff --git a/pkg/api/store/support/ticket/v0/ticket.go b/pkg/api/store/support/ticket/v0/ticket.go index b7be9884..8034fb67 100644 --- a/pkg/api/store/support/ticket/v0/ticket.go +++ b/pkg/api/store/support/ticket/v0/ticket.go @@ -68,16 +68,25 @@ func Get(base int, data *core.Ticket) ticket.ResultDatabase { var ticketStruct []core.Ticket if base == ticket.ID { //ID - err = db.First(&ticketStruct, data.ID).Error + err = db.Preload("User"). + Preload("Group"). + Preload("Chat"). + Preload("Chat.User"). + First(&ticketStruct, data.ID).Error } else if base == ticket.GID { //GroupID - err = db.Where("group_id = ?", data.GroupID).Find(&ticketStruct).Error + err = db.Where("group_id = ?", data.GroupID). + Preload("User"). + Preload("Group"). + Preload("Chat"). + Preload("Chat.User"). + Find(&ticketStruct).Error } else if base == ticket.UID { //UserID err = db.Where("user_id = ?", data.UserID).Find(&ticketStruct).Error } else { log.Println("base select error") return ticket.ResultDatabase{Err: fmt.Errorf("(%s)error: base select\n", time.Now())} } - return ticket.ResultDatabase{Ticket: ticketStruct, Err: err} + return ticket.ResultDatabase{Tickets: ticketStruct, Err: err} } func GetAll() ticket.ResultDatabase { @@ -89,6 +98,10 @@ func GetAll() ticket.ResultDatabase { defer db.Close() var tickets []core.Ticket - err = db.Find(&tickets).Error - return ticket.ResultDatabase{Ticket: tickets, Err: err} + err = db.Preload("User"). + Preload("Group"). + Preload("Chat"). + Preload("Chat.User"). + Find(&tickets).Error + return ticket.ResultDatabase{Tickets: tickets, Err: err} }