Files
tp/main_dc/yalarba/api_yal/internal/domain/appeal/dto.go
T
valitovgaziz 318075d686 On branch main
modified:   internal/domain/appeal/dto.go
	new file:   internal/domain/appeal/handler.go
	modified:   internal/domain/appeal/router.go
	modified:   internal/domain/appeal/service.go
	modified:   internal/models/appeal.go
	modified:   internal/router/router.go
fix bag with no embeded the Base into appeal
2026-05-21 05:04:34 +05:00

219 lines
8.4 KiB
Go

package appeal
import (
"time"
"api_yal/internal/models"
)
// CreateAppealRequest DTO для создания обращения
type CreateAppealRequest struct {
Type string `json:"type" validate:"required,oneof=complaint suggestion wish question other"`
Title string `json:"title" validate:"required,min=3,max=255"`
Message string `json:"message" validate:"required,min=10"`
Priority string `json:"priority" validate:"omitempty,oneof=low medium high critical"`
ObjectID *uint `json:"object_id,omitempty"`
FeedbackID *uint `json:"feedback_id,omitempty"`
CommentID *uint `json:"comment_id,omitempty"`
ContactName string `json:"contact_name,omitempty"`
ContactEmail string `json:"contact_email,omitempty" validate:"omitempty,email"`
ContactPhone string `json:"contact_phone,omitempty"`
Attachments []string `json:"attachments,omitempty"`
Category string `json:"category,omitempty"`
Labels []string `json:"labels,omitempty"`
CustomData map[string]interface{} `json:"custom_data,omitempty"`
IPAddress string `json:"ip_address,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
}
// UpdateAppealRequest DTO для обновления обращения
type UpdateAppealRequest struct {
Title *string `json:"title,omitempty" validate:"omitempty,min=3,max=255"`
Message *string `json:"message,omitempty" validate:"omitempty,min=10"`
Priority *string `json:"priority,omitempty" validate:"omitempty,oneof=low medium high critical"`
Category *string `json:"category,omitempty"`
Labels []string `json:"labels,omitempty"`
Attachments []string `json:"attachments,omitempty"`
CustomData map[string]interface{} `json:"custom_data,omitempty"`
}
// UpdateStatusRequest DTO для обновления статуса
type UpdateStatusRequest struct {
Status string `json:"status" validate:"required,oneof=new in_progress resolved rejected closed"`
Comment string `json:"comment,omitempty"`
}
// AssignRequest DTO для назначения ответственного
type AssignRequest struct {
AssignedToID *uint `json:"assigned_to_id"`
}
// ResolveRequest DTO для решения обращения
type ResolveRequest struct {
Resolution string `json:"resolution" validate:"required,min=5"`
}
// AppealResponse DTO для ответа
type AppealResponse struct {
ID uint `json:"id"`
Type string `json:"type"`
Status string `json:"status"`
Priority string `json:"priority"`
Title string `json:"title"`
Message string `json:"message"`
AuthorID *uint `json:"author_id,omitempty"`
Author *AuthorInfo `json:"author,omitempty"`
ObjectID *uint `json:"object_id,omitempty"`
Object *ObjectInfo `json:"object,omitempty"`
FeedbackID *uint `json:"feedback_id,omitempty"`
CommentID *uint `json:"comment_id,omitempty"`
ContactName string `json:"contact_name,omitempty"`
ContactEmail string `json:"contact_email,omitempty"`
ContactPhone string `json:"contact_phone,omitempty"`
Attachments []string `json:"attachments,omitempty"`
Category string `json:"category,omitempty"`
Labels []string `json:"labels,omitempty"`
AssignedToID *uint `json:"assigned_to_id,omitempty"`
AssignedTo *AuthorInfo `json:"assigned_to,omitempty"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
ResolvedBy *uint `json:"resolved_by,omitempty"`
Resolution string `json:"resolution,omitempty"`
CustomData map[string]interface{} `json:"custom_data,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// AuthorInfo информация об авторе
type AuthorInfo struct {
ID uint `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
// ObjectInfo информация об объекте
type ObjectInfo struct {
ID uint `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
}
// ListAppealsResponse DTO для списка обращений
type ListAppealsResponse struct {
Data []AppealResponse `json:"data"`
Total int64 `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
TotalPages int `json:"total_pages"`
}
// AppealHistoryResponse DTO для истории
type AppealHistoryResponse struct {
ID uint `json:"id"`
AppealID uint `json:"appeal_id"`
UserID *uint `json:"user_id,omitempty"`
User *AuthorInfo `json:"user,omitempty"`
OldStatus string `json:"old_status"`
NewStatus string `json:"new_status"`
Comment string `json:"comment,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
// ListHistoryResponse DTO для списка истории
type ListHistoryResponse struct {
Data []AppealHistoryResponse `json:"data"`
Total int64 `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
TotalPages int `json:"total_pages"`
}
// AppealStatisticsResponse DTO для статистики
type AppealStatisticsResponse struct {
Total int64 `json:"total"`
ByStatus map[string]int64 `json:"by_status"`
ByType map[string]int64 `json:"by_type"`
ByPriority map[string]int64 `json:"by_priority"`
ByCategory map[string]int64 `json:"by_category,omitempty"`
AvgResolveTime float64 `json:"avg_resolve_time_hours"`
}
// NewAppealResponse создает AppealResponse из модели
func NewAppealResponse(appeal *models.Appeal) AppealResponse {
resp := AppealResponse{
ID: appeal.ID,
Type: string(appeal.Type),
Status: string(appeal.Status),
Priority: string(appeal.Priority),
Title: appeal.Title,
Message: appeal.Message,
AuthorID: appeal.AuthorID,
ObjectID: appeal.ObjectID,
FeedbackID: appeal.FeedbackID,
CommentID: appeal.CommentID,
ContactName: appeal.ContactName,
ContactEmail: appeal.ContactEmail,
ContactPhone: appeal.ContactPhone,
Attachments: appeal.Attachments,
Category: appeal.Category,
Labels: appeal.Labels,
AssignedToID: appeal.AssignedToID,
ResolvedAt: appeal.ResolvedAt,
ResolvedBy: appeal.ResolvedBy,
Resolution: appeal.Resolution,
CustomData: appeal.CustomData,
CreatedAt: appeal.CreatedAt,
UpdatedAt: appeal.UpdatedAt,
}
if appeal.Author != nil {
resp.Author = &AuthorInfo{
ID: appeal.Author.ID,
Email: appeal.Author.Email,
FirstName: appeal.Author.FirstName,
LastName: appeal.Author.LastName,
}
}
if appeal.Object != nil {
resp.Object = &ObjectInfo{
ID: appeal.Object.ID,
Name: appeal.Object.ShortName,
Description: appeal.Object.Description,
}
}
if appeal.AssignedTo != nil {
resp.AssignedTo = &AuthorInfo{
ID: appeal.AssignedTo.ID,
Email: appeal.AssignedTo.Email,
FirstName: appeal.AssignedTo.FirstName,
LastName: appeal.AssignedTo.LastName,
}
}
return resp
}
// NewAppealHistoryResponse создает AppealHistoryResponse из модели
func NewAppealHistoryResponse(history *models.AppealHistory) AppealHistoryResponse {
resp := AppealHistoryResponse{
ID: history.ID,
AppealID: history.AppealID,
UserID: history.UserID,
OldStatus: string(history.OldStatus),
NewStatus: string(history.NewStatus),
Comment: history.Comment,
CreatedAt: history.CreatedAt,
}
if history.User != nil {
resp.User = &AuthorInfo{
ID: history.User.ID,
Email: history.User.Email,
FirstName: history.User.FirstName,
LastName: history.User.LastName,
}
}
return resp
}