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
@@ -2,12 +2,10 @@ package dashboard
import (
"strings"
"time"
"cs-agent/internal/builders"
"cs-agent/internal/pkg/constants"
"cs-agent/internal/pkg/dto/request"
"cs-agent/internal/pkg/enums"
"cs-agent/internal/services"
"github.com/kataras/iris/v12"
@@ -26,13 +24,11 @@ func (c *TicketController) AnyList() *web.JsonResult {
}
cnd := params.NewPagedSqlCnd(c.Ctx,
params.QueryFilter{ParamName: "status"},
params.QueryFilter{ParamName: "priority"},
params.QueryFilter{ParamName: "severity"},
params.QueryFilter{ParamName: "currentTeamId"},
params.QueryFilter{ParamName: "currentAssigneeId"},
params.QueryFilter{ParamName: "customerId"},
params.QueryFilter{ParamName: "conversationId"},
params.QueryFilter{ParamName: "source"},
params.QueryFilter{ParamName: "channel"},
).Desc("updated_at").Desc("id")
if keyword, _ := params.Get(c.Ctx, "keyword"); strings.TrimSpace(keyword) != "" {
keyword = "%" + strings.TrimSpace(keyword) + "%"
@@ -41,47 +37,21 @@ func (c *TicketController) AnyList() *web.JsonResult {
if tagID, _ := params.GetInt64(c.Ctx, "tagId"); tagID > 0 {
cnd.Where("id IN (SELECT ticket_id FROM t_ticket_tag WHERE tag_id = ?)", tagID)
}
if watching, _ := params.Get(c.Ctx, "watching"); watching == "1" || strings.EqualFold(watching, "true") {
cnd.Where("id IN (SELECT ticket_id FROM t_ticket_watcher WHERE user_id = ?)", operator.UserID)
}
if collaborating, _ := params.Get(c.Ctx, "collaborating"); collaborating == "1" || strings.EqualFold(collaborating, "true") {
cnd.Where("id IN (SELECT ticket_id FROM t_ticket_collaborator WHERE user_id = ?)", operator.UserID)
}
if collaboration, _ := params.Get(c.Ctx, "collaboration"); collaboration == "1" || strings.EqualFold(collaboration, "true") {
cnd.Where(
"(id IN (SELECT ticket_id FROM t_ticket_collaborator WHERE user_id = ?) OR id IN (SELECT ticket_id FROM t_ticket_mention WHERE mentioned_user_id = ?))",
operator.UserID,
operator.UserID,
)
}
if mentioned, _ := params.Get(c.Ctx, "mentioned"); mentioned == "1" || strings.EqualFold(mentioned, "true") {
cnd.Where("id IN (SELECT ticket_id FROM t_ticket_mention WHERE mentioned_user_id = ?)", operator.UserID)
}
if mine, _ := params.Get(c.Ctx, "mine"); mine == "1" || strings.EqualFold(mine, "true") {
cnd.Eq("current_assignee_id", operator.UserID)
}
if unassigned, _ := params.Get(c.Ctx, "unassigned"); unassigned == "1" || strings.EqualFold(unassigned, "true") {
cnd.Eq("current_assignee_id", 0)
}
if overdue, _ := params.Get(c.Ctx, "overdue"); overdue == "1" || strings.EqualFold(overdue, "true") {
cnd.In("status", []string{"new", "open", "pending_customer", "pending_internal"})
cnd.Where("resolve_deadline_at IS NOT NULL")
cnd.Where("resolve_deadline_at < ?", time.Now())
}
aggregate, err := services.TicketService.FindPageAggregateByCnd(cnd, operator.UserID)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(&web.PageResult{
Results: builders.BuildTicketListWithContext(aggregate.List, &builders.TicketBuildContext{
TagsByTicketID: aggregate.TagsByTicketID,
Priorities: aggregate.Priorities,
ResolutionCodes: aggregate.ResolutionCodes,
Users: aggregate.Users,
Teams: aggregate.Teams,
Customers: aggregate.Customers,
SLAByTicketID: aggregate.SLAByTicketID,
WatchedTicketIDs: aggregate.WatchedTicketIDs,
TagsByTicketID: aggregate.TagsByTicketID,
Users: aggregate.Users,
Customers: aggregate.Customers,
}),
Page: aggregate.Paging,
})
@@ -95,44 +65,6 @@ func (c *TicketController) AnySummary() *web.JsonResult {
return web.JsonData(builders.BuildTicketSummary(services.TicketService.GetSummary(operator)))
}
func (c *TicketController) AnyRisk_overview() *web.JsonResult {
if _, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView); err != nil {
return web.JsonError(err)
}
teamID, _ := params.GetInt64(c.Ctx, "currentTeamId")
riskWindowMins, _ := params.GetInt(c.Ctx, "riskWindowMins")
return web.JsonData(builders.BuildTicketRiskOverview(services.TicketService.GetRiskOverview(teamID, riskWindowMins)))
}
func (c *TicketController) AnyRisk_list() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
riskType, _ := params.Get(c.Ctx, "riskType")
teamID, _ := params.GetInt64(c.Ctx, "currentTeamId")
riskWindowMins, _ := params.GetInt(c.Ctx, "riskWindowMins")
page, _ := params.GetInt(c.Ctx, "page")
limit, _ := params.GetInt(c.Ctx, "limit")
aggregate, err := services.TicketService.GetRiskPageAggregate(riskType, teamID, riskWindowMins, page, limit, operator.UserID)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(&web.PageResult{
Results: builders.BuildTicketListWithContext(aggregate.List, &builders.TicketBuildContext{
TagsByTicketID: aggregate.TagsByTicketID,
Priorities: aggregate.Priorities,
ResolutionCodes: aggregate.ResolutionCodes,
Users: aggregate.Users,
Teams: aggregate.Teams,
Customers: aggregate.Customers,
SLAByTicketID: aggregate.SLAByTicketID,
WatchedTicketIDs: aggregate.WatchedTicketIDs,
}),
Page: aggregate.Paging,
})
}
func (c *TicketController) AnyView_list() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
@@ -230,21 +162,6 @@ func (c *TicketController) PostUpdate() *web.JsonResult {
return web.JsonSuccess()
}
func (c *TicketController) PostLink_customer() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
if err != nil {
return web.JsonError(err)
}
req := request.LinkTicketCustomerRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.LinkTicketCustomer(req.TicketID, req.CustomerID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostAssign() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketAssign)
if err != nil {
@@ -290,212 +207,18 @@ func (c *TicketController) PostChange_status() *web.JsonResult {
return web.JsonSuccess()
}
func (c *TicketController) PostBatch_change_status() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketChangeStatus)
if err != nil {
return web.JsonError(err)
}
req := request.BatchChangeTicketStatusRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.BatchChangeStatus(req, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostReply() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketReply)
if err != nil {
return web.JsonError(err)
}
req := request.ReplyTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
item, err := services.TicketService.ReplyTicket(req, operator)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicketComment(item))
}
func (c *TicketController) PostInternal_note() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketReply)
if err != nil {
return web.JsonError(err)
}
req := request.InternalNoteRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
item, err := services.TicketService.AddInternalNote(req, operator)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicketComment(item))
}
func (c *TicketController) PostClose() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketClose)
if err != nil {
return web.JsonError(err)
}
req := request.CloseTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.CloseTicket(req, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostReopen() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketReopen)
if err != nil {
return web.JsonError(err)
}
req := request.ReopenTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.ReopenTicket(req, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostWatch() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
req := request.WatchTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.WatchTicket(req.TicketID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostUnwatch() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
req := request.WatchTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.UnwatchTicket(req.TicketID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostBatch_watch() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
req := request.BatchWatchTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.BatchWatchTickets(req, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostAdd_relation() *web.JsonResult {
func (c *TicketController) PostAdd_progress() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
if err != nil {
return web.JsonError(err)
}
req := request.AddTicketRelationRequest{}
req := request.CreateTicketProgressRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
relatedTicketID := req.RelatedTicketID
if relatedTicketID <= 0 && strings.TrimSpace(req.RelatedTicketNo) != "" {
if relatedTicket := services.TicketService.Take("ticket_no = ?", strings.TrimSpace(req.RelatedTicketNo)); relatedTicket != nil {
relatedTicketID = relatedTicket.ID
}
}
if err := services.TicketRelationService.AddRelation(req.TicketID, relatedTicketID, enums.TicketRelationType(strings.TrimSpace(req.RelationType)), operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostDelete_relation() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
item, err := services.TicketService.AddProgress(req, operator)
if err != nil {
return web.JsonError(err)
}
req := request.DeleteTicketRelationRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketRelationService.DeleteRelation(req.TicketID, req.RelationID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostAdd_collaborator() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
if err != nil {
return web.JsonError(err)
}
req := request.AddTicketCollaboratorRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.AddCollaborator(req.TicketID, req.UserID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostDelete_collaborator() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
if err != nil {
return web.JsonError(err)
}
req := request.DeleteTicketCollaboratorRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.RemoveCollaborator(req.TicketID, req.CollaboratorID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) AnyComment_list() *web.JsonResult {
if _, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView); err != nil {
return web.JsonError(err)
}
ticketID, _ := params.GetInt64(c.Ctx, "ticketId")
if ticketID <= 0 {
return web.JsonData(&web.PageResult{Results: []any{}, Page: params.GetPaging(c.Ctx)})
}
cnd := params.NewPagedSqlCnd(c.Ctx, params.QueryFilter{ParamName: "ticketId"}).Asc("id")
results, paging := services.TicketCommentService.FindPageByCnd(cnd)
return web.JsonData(&web.PageResult{Results: builders.BuildTicketCommentList(results), Page: paging})
}
func (c *TicketController) AnyEvent_list() *web.JsonResult {
if _, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView); err != nil {
return web.JsonError(err)
}
cnd := params.NewPagedSqlCnd(c.Ctx, params.QueryFilter{ParamName: "ticketId"}).Desc("id")
list, paging := services.TicketEventLogService.FindPageByCnd(cnd)
return web.JsonData(&web.PageResult{Results: builders.BuildTicketEventLogList(list), Page: paging})
return web.JsonData(builders.BuildTicketProgress(item))
}