refactor(ticket): contract backend ticket core

This commit is contained in:
mlogclub
2026-05-02 18:49:10 +08:00
parent b687804363
commit fce0b5709d
43 changed files with 1103 additions and 5615 deletions
@@ -1,37 +0,0 @@
package request
import "cs-agent/internal/pkg/enums"
type CreateTicketResolutionCodeRequest struct {
Name string `json:"name"`
Code string `json:"code"`
SortNo int `json:"sortNo"`
Status enums.Status `json:"status"`
Remark string `json:"remark"`
}
type UpdateTicketResolutionCodeRequest struct {
ID int64 `json:"id"`
CreateTicketResolutionCodeRequest
}
type DeleteTicketResolutionCodeRequest struct {
ID int64 `json:"id"`
}
type CreateTicketPriorityConfigRequest struct {
Name string `json:"name"`
FirstResponseMinutes int `json:"firstResponseMinutes"`
ResolutionMinutes int `json:"resolutionMinutes"`
Status enums.Status `json:"status"`
Remark string `json:"remark"`
}
type UpdateTicketPriorityConfigRequest struct {
ID int64 `json:"id"`
CreateTicketPriorityConfigRequest
}
type DeleteTicketPriorityConfigRequest struct {
ID int64 `json:"id"`
}
+22 -111
View File
@@ -1,143 +1,54 @@
package request
type CreateTicketRequest struct {
Title string `json:"title"`
Description string `json:"description"`
Source string `json:"source"`
Channel string `json:"channel"`
CustomerID int64 `json:"customerId"`
ConversationID int64 `json:"conversationId"`
TagIDs []int64 `json:"tagIds"`
Type string `json:"type"`
Priority int64 `json:"priority"`
Severity int `json:"severity"`
CurrentTeamID int64 `json:"currentTeamId"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
DueAt string `json:"dueAt"`
CustomFields map[string]any `json:"customFields"`
Title string `json:"title"`
Description string `json:"description"`
Source string `json:"source"`
Channel string `json:"channel"`
CustomerID int64 `json:"customerId"`
ConversationID int64 `json:"conversationId"`
TagIDs []int64 `json:"tagIds"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
}
type CreateTicketFromConversationRequest struct {
ConversationID int64 `json:"conversationId"`
Title string `json:"title"`
Description string `json:"description"`
TagIDs []int64 `json:"tagIds"`
Priority int64 `json:"priority"`
Severity int `json:"severity"`
CurrentTeamID int64 `json:"currentTeamId"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
SyncToConversation bool `json:"syncToConversation"`
CustomFields map[string]any `json:"customFields"`
ConversationID int64 `json:"conversationId"`
Title string `json:"title"`
Description string `json:"description"`
TagIDs []int64 `json:"tagIds"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
}
type UpdateTicketRequest struct {
TicketID int64 `json:"ticketId"`
Title string `json:"title"`
Description string `json:"description"`
TagIDs []int64 `json:"tagIds"`
Type string `json:"type"`
Priority int64 `json:"priority"`
Severity int `json:"severity"`
CurrentTeamID int64 `json:"currentTeamId"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
DueAt string `json:"dueAt"`
CustomFields map[string]any `json:"customFields"`
TicketID int64 `json:"ticketId"`
Title string `json:"title"`
Description string `json:"description"`
TagIDs []int64 `json:"tagIds"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
}
type AssignTicketRequest struct {
TicketID int64 `json:"ticketId"`
ToUserID int64 `json:"toUserId"`
ToTeamID int64 `json:"toTeamId"`
Reason string `json:"reason"`
}
type ChangeTicketStatusRequest struct {
TicketID int64 `json:"ticketId"`
Status string `json:"status"`
PendingReason string `json:"pendingReason"`
CloseReason string `json:"closeReason"`
ResolutionCode string `json:"resolutionCode"`
ResolutionSummary string `json:"resolutionSummary"`
Reason string `json:"reason"`
}
type ReplyTicketRequest struct {
TicketID int64 `json:"ticketId"`
ContentType string `json:"contentType"`
Content string `json:"content"`
Payload string `json:"payload"`
}
type InternalNoteRequest struct {
TicketID int64 `json:"ticketId"`
ContentType string `json:"contentType"`
Content string `json:"content"`
Payload string `json:"payload"`
}
type CloseTicketRequest struct {
TicketID int64 `json:"ticketId"`
CloseReason string `json:"closeReason"`
}
type ReopenTicketRequest struct {
TicketID int64 `json:"ticketId"`
Reason string `json:"reason"`
Status string `json:"status"`
}
type WatchTicketRequest struct {
TicketID int64 `json:"ticketId"`
type CreateTicketProgressRequest struct {
TicketID int64 `json:"ticketId"`
Content string `json:"content"`
}
type BatchAssignTicketRequest struct {
TicketIDs []int64 `json:"ticketIds"`
ToUserID int64 `json:"toUserId"`
ToTeamID int64 `json:"toTeamId"`
Reason string `json:"reason"`
}
type BatchChangeTicketStatusRequest struct {
TicketIDs []int64 `json:"ticketIds"`
Status string `json:"status"`
PendingReason string `json:"pendingReason"`
CloseReason string `json:"closeReason"`
ResolutionCode string `json:"resolutionCode"`
ResolutionSummary string `json:"resolutionSummary"`
Reason string `json:"reason"`
}
type BatchWatchTicketRequest struct {
TicketIDs []int64 `json:"ticketIds"`
Watched bool `json:"watched"`
}
type AddTicketRelationRequest struct {
TicketID int64 `json:"ticketId"`
RelatedTicketID int64 `json:"relatedTicketId"`
RelatedTicketNo string `json:"relatedTicketNo"`
RelationType string `json:"relationType"`
}
type DeleteTicketRelationRequest struct {
TicketID int64 `json:"ticketId"`
RelationID int64 `json:"relationId"`
}
type AddTicketCollaboratorRequest struct {
TicketID int64 `json:"ticketId"`
UserID int64 `json:"userId"`
}
type DeleteTicketCollaboratorRequest struct {
TicketID int64 `json:"ticketId"`
CollaboratorID int64 `json:"collaboratorId"`
}
type LinkTicketCustomerRequest struct {
TicketID int64 `json:"ticketId"`
CustomerID int64 `json:"customerId"`
}
type SaveTicketViewRequest struct {
ID int64 `json:"id"`
Name string `json:"name"`
@@ -1,22 +0,0 @@
package response
import "cs-agent/internal/pkg/enums"
type TicketResolutionCodeResponse struct {
ID int64 `json:"id"`
Name string `json:"name"`
Code string `json:"code"`
SortNo int `json:"sortNo"`
Status enums.Status `json:"status"`
Remark string `json:"remark"`
}
type TicketPriorityConfigResponse struct {
ID int64 `json:"id"`
Name string `json:"name"`
SortNo int `json:"sortNo"`
FirstResponseMinutes int `json:"firstResponseMinutes"`
ResolutionMinutes int `json:"resolutionMinutes"`
Status enums.Status `json:"status"`
Remark string `json:"remark"`
}
+34 -130
View File
@@ -2,145 +2,49 @@ package response
import "cs-agent/internal/pkg/enums"
type TicketSLAResponse struct {
SLAType enums.TicketSLAType `json:"slaType"`
TargetMinutes int `json:"targetMinutes"`
Status enums.TicketSLAStatus `json:"status"`
StartedAt string `json:"startedAt,omitempty"`
PausedAt string `json:"pausedAt,omitempty"`
StoppedAt string `json:"stoppedAt,omitempty"`
BreachedAt string `json:"breachedAt,omitempty"`
ElapsedMin int `json:"elapsedMin"`
}
type TicketWatcherResponse struct {
ID int64 `json:"id"`
UserID int64 `json:"userId"`
UserName string `json:"userName,omitempty"`
}
type TicketCommentResponse struct {
ID int64 `json:"id"`
TicketID int64 `json:"ticketId"`
CommentType enums.TicketCommentType `json:"commentType"`
AuthorType enums.IMSenderType `json:"authorType"`
AuthorID int64 `json:"authorId"`
AuthorName string `json:"authorName,omitempty"`
ContentType string `json:"contentType"`
Content string `json:"content"`
Payload string `json:"payload,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
}
type TicketEventLogResponse struct {
ID int64 `json:"id"`
TicketID int64 `json:"ticketId"`
EventType enums.TicketEventType `json:"eventType"`
OperatorType enums.IMSenderType `json:"operatorType"`
OperatorID int64 `json:"operatorId"`
OperatorName string `json:"operatorName,omitempty"`
OldValue string `json:"oldValue,omitempty"`
NewValue string `json:"newValue,omitempty"`
Content string `json:"content,omitempty"`
Payload string `json:"payload,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
type TicketProgressResponse struct {
ID int64 `json:"id"`
TicketID int64 `json:"ticketId"`
Content string `json:"content"`
AuthorID int64 `json:"authorId"`
AuthorName string `json:"authorName,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
}
type TicketResponse struct {
ID int64 `json:"id"`
TicketNo string `json:"ticketNo"`
Title string `json:"title"`
Description string `json:"description"`
Source enums.TicketSource `json:"source"`
Channel string `json:"channel"`
CustomerID int64 `json:"customerId"`
ConversationID int64 `json:"conversationId"`
Tags []TagResponse `json:"tags,omitempty"`
Type string `json:"type"`
Priority int64 `json:"priority"`
PriorityName string `json:"priorityName,omitempty"`
Severity enums.TicketSeverity `json:"severity"`
Status enums.TicketStatus `json:"status"`
CurrentTeamID int64 `json:"currentTeamId"`
CurrentTeamName string `json:"currentTeamName,omitempty"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
CurrentAssigneeName string `json:"currentAssigneeName,omitempty"`
WatchedByMe bool `json:"watchedByMe"`
PendingReason string `json:"pendingReason,omitempty"`
CloseReason string `json:"closeReason,omitempty"`
ResolutionCode string `json:"resolutionCode,omitempty"`
ResolutionCodeName string `json:"resolutionCodeName,omitempty"`
ResolutionSummary string `json:"resolutionSummary,omitempty"`
FirstResponseAt string `json:"firstResponseAt,omitempty"`
ResolvedAt string `json:"resolvedAt,omitempty"`
ClosedAt string `json:"closedAt,omitempty"`
DueAt string `json:"dueAt,omitempty"`
NextReplyDeadlineAt string `json:"nextReplyDeadlineAt,omitempty"`
ResolveDeadlineAt string `json:"resolveDeadlineAt,omitempty"`
ReopenedCount int `json:"reopenedCount"`
CreatedAt string `json:"createdAt,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
Customer *CustomerResponse `json:"customer,omitempty"`
SLA []TicketSLAResponse `json:"sla,omitempty"`
ID int64 `json:"id"`
TicketNo string `json:"ticketNo"`
Title string `json:"title"`
Description string `json:"description"`
Source enums.TicketSource `json:"source"`
Channel string `json:"channel"`
CustomerID int64 `json:"customerId"`
ConversationID int64 `json:"conversationId"`
Tags []TagResponse `json:"tags,omitempty"`
Status enums.TicketStatus `json:"status"`
CurrentAssigneeID int64 `json:"currentAssigneeId"`
CurrentAssigneeName string `json:"currentAssigneeName,omitempty"`
CreatedBy int64 `json:"createdBy"`
CreatedByName string `json:"createdByName,omitempty"`
HandledAt string `json:"handledAt,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
Customer *CustomerResponse `json:"customer,omitempty"`
}
type TicketDetailResponse struct {
Ticket TicketResponse `json:"ticket"`
Watchers []TicketWatcherResponse `json:"watchers,omitempty"`
Collaborators []TicketCollaboratorResponse `json:"collaborators,omitempty"`
Comments []TicketCommentResponse `json:"comments,omitempty"`
Events []TicketEventLogResponse `json:"events,omitempty"`
RelatedTickets []TicketRelationResponse `json:"relatedTickets,omitempty"`
Ticket TicketResponse `json:"ticket"`
Progresses []TicketProgressResponse `json:"progresses,omitempty"`
}
type TicketSummaryResponse struct {
All int64 `json:"all"`
Mine int64 `json:"mine"`
Watching int64 `json:"watching"`
Collaboration int64 `json:"collaboration"`
Participating int64 `json:"participating"`
Mentioned int64 `json:"mentioned"`
Unassigned int64 `json:"unassigned"`
PendingCustomer int64 `json:"pendingCustomer"`
PendingInternal int64 `json:"pendingInternal"`
Overdue int64 `json:"overdue"`
}
type TicketRiskReasonResponse struct {
Code string `json:"code"`
Title string `json:"title"`
Description string `json:"description"`
Count int64 `json:"count"`
}
type TicketRiskOverviewResponse struct {
Overdue int64 `json:"overdue"`
HighRisk int64 `json:"highRisk"`
Unassigned int64 `json:"unassigned"`
PendingInternal int64 `json:"pendingInternal"`
PendingCustomer int64 `json:"pendingCustomer"`
RiskWindowMins int `json:"riskWindowMins"`
Reasons []TicketRiskReasonResponse `json:"reasons,omitempty"`
}
type TicketRelationResponse struct {
ID int64 `json:"id"`
TicketID int64 `json:"ticketId"`
RelatedTicketID int64 `json:"relatedTicketId"`
RelationType enums.TicketRelationType `json:"relationType"`
RelatedTicketNo string `json:"relatedTicketNo,omitempty"`
RelatedTicketTitle string `json:"relatedTicketTitle,omitempty"`
RelatedTicketStatus enums.TicketStatus `json:"relatedTicketStatus,omitempty"`
CurrentTeamName string `json:"currentTeamName,omitempty"`
CurrentAssigneeName string `json:"currentAssigneeName,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
}
type TicketCollaboratorResponse struct {
ID int64 `json:"id"`
UserID int64 `json:"userId"`
UserName string `json:"userName,omitempty"`
TeamName string `json:"teamName,omitempty"`
All int64 `json:"all"`
Pending int64 `json:"pending"`
InProgress int64 `json:"inProgress"`
Done int64 `json:"done"`
Unassigned int64 `json:"unassigned"`
Mine int64 `json:"mine"`
Stale int64 `json:"stale"`
}
type TicketViewResponse struct {
+9 -110
View File
@@ -3,33 +3,21 @@ package enums
type TicketStatus string
const (
TicketStatusNew TicketStatus = "new"
TicketStatusOpen TicketStatus = "open"
TicketStatusPendingCustomer TicketStatus = "pending_customer"
TicketStatusPendingInternal TicketStatus = "pending_internal"
TicketStatusResolved TicketStatus = "resolved"
TicketStatusClosed TicketStatus = "closed"
TicketStatusCancelled TicketStatus = "cancelled"
TicketStatusPending TicketStatus = "pending"
TicketStatusInProgress TicketStatus = "in_progress"
TicketStatusDone TicketStatus = "done"
)
var TicketStatusValues = []TicketStatus{
TicketStatusNew,
TicketStatusOpen,
TicketStatusPendingCustomer,
TicketStatusPendingInternal,
TicketStatusResolved,
TicketStatusClosed,
TicketStatusCancelled,
TicketStatusPending,
TicketStatusInProgress,
TicketStatusDone,
}
var ticketStatusLabelMap = map[TicketStatus]string{
TicketStatusNew: "新建",
TicketStatusOpen: "处理中",
TicketStatusPendingCustomer: "待客户反馈",
TicketStatusPendingInternal: "待内部处理",
TicketStatusResolved: "已解决",
TicketStatusClosed: "已关闭",
TicketStatusCancelled: "已取消",
TicketStatusPending: "待处理",
TicketStatusInProgress: "处理中",
TicketStatusDone: "已处理",
}
func GetTicketStatusLabel(status TicketStatus) string {
@@ -45,55 +33,16 @@ func IsValidTicketStatus(status string) bool {
return false
}
type TicketSeverity int
const (
TicketSeverityMinor TicketSeverity = 1
TicketSeverityMajor TicketSeverity = 2
TicketSeverityCritical TicketSeverity = 3
)
var TicketSeverityValues = []TicketSeverity{
TicketSeverityMinor,
TicketSeverityMajor,
TicketSeverityCritical,
}
var ticketSeverityLabelMap = map[TicketSeverity]string{
TicketSeverityMinor: "轻微",
TicketSeverityMajor: "严重",
TicketSeverityCritical: "致命",
}
func GetTicketSeverityLabel(severity TicketSeverity) string {
return ticketSeverityLabelMap[severity]
}
func IsValidTicketSeverity(severity int) bool {
for _, item := range TicketSeverityValues {
if int(item) == severity {
return true
}
}
return false
}
type TicketSource string
const (
TicketSourceManual TicketSource = "manual"
TicketSourceConversation TicketSource = "conversation"
TicketSourcePortal TicketSource = "portal"
TicketSourceAPI TicketSource = "api"
TicketSourceRule TicketSource = "rule"
)
var TicketSourceValues = []TicketSource{
TicketSourceManual,
TicketSourceConversation,
TicketSourcePortal,
TicketSourceAPI,
TicketSourceRule,
}
func IsValidTicketSource(source string) bool {
@@ -104,53 +53,3 @@ func IsValidTicketSource(source string) bool {
}
return false
}
type TicketCommentType string
const (
TicketCommentTypePublicReply TicketCommentType = "public_reply"
TicketCommentTypeInternalNote TicketCommentType = "internal_note"
TicketCommentTypeSystemLog TicketCommentType = "system_log"
)
type TicketEventType string
const (
TicketEventTypeCreated TicketEventType = "created"
TicketEventTypeUpdated TicketEventType = "updated"
TicketEventTypeAssigned TicketEventType = "assigned"
TicketEventTypeTransferred TicketEventType = "transferred"
TicketEventTypeStatusChanged TicketEventType = "status_changed"
TicketEventTypeReplied TicketEventType = "replied"
TicketEventTypeInternalNoted TicketEventType = "internal_noted"
TicketEventTypeClosed TicketEventType = "closed"
TicketEventTypeReopened TicketEventType = "reopened"
TicketEventTypeSLABreached TicketEventType = "sla_breached"
TicketEventTypeLinkedConversation TicketEventType = "linked_conversation"
TicketEventTypeMentioned TicketEventType = "mentioned"
)
type TicketSLAType string
const (
TicketSLATypeFirstResponse TicketSLAType = "first_response"
TicketSLATypeResolution TicketSLAType = "resolution"
)
type TicketSLAStatus string
const (
TicketSLAStatusRunning TicketSLAStatus = "running"
TicketSLAStatusPaused TicketSLAStatus = "paused"
TicketSLAStatusCompleted TicketSLAStatus = "completed"
TicketSLAStatusBreached TicketSLAStatus = "breached"
)
type TicketRelationType string
const (
TicketRelationTypeDuplicate TicketRelationType = "duplicate"
TicketRelationTypeRelated TicketRelationType = "related"
TicketRelationTypeParent TicketRelationType = "parent"
TicketRelationTypeChild TicketRelationType = "child"
)