Files
ai-agent/internal/controllers/dashboard/ticket_controller.go
T
mlogclub 62416baabc Refactor API endpoints to use /api/dashboard instead of /api/console
- Updated all relevant API functions in agent.ts, company.ts, customer-contact.ts, customer.ts, dashboard.ts, ticket-config.ts, and ticket.ts to point to the new /api/dashboard paths.
- Ensured that all request methods and payload structures remain unchanged to maintain existing functionality.
2026-04-15 17:12:30 +08:00

502 lines
18 KiB
Go

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"
"github.com/mlogclub/simple/web"
"github.com/mlogclub/simple/web/params"
)
type TicketController struct {
Ctx iris.Context
}
func (c *TicketController) AnyList() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
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"},
).Desc("updated_at").Desc("id")
if keyword, _ := params.Get(c.Ctx, "keyword"); strings.TrimSpace(keyword) != "" {
keyword = "%" + strings.TrimSpace(keyword) + "%"
cnd.Where("ticket_no LIKE ? OR title LIKE ? OR description LIKE ?", keyword, keyword, keyword)
}
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,
}),
Page: aggregate.Paging,
})
}
func (c *TicketController) AnySummary() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
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 {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicketViewList(services.TicketViewService.ListByUser(operator.UserID)))
}
func (c *TicketController) PostSave_view() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
req := request.SaveTicketViewRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
item, err := services.TicketViewService.Save(req, operator)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicketView(item))
}
func (c *TicketController) PostDelete_view() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView)
if err != nil {
return web.JsonError(err)
}
req := request.DeleteTicketViewRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketViewService.Delete(req.ID, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) GetBy(id int64) *web.JsonResult {
if _, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketView); err != nil {
return web.JsonError(err)
}
detail, err := services.TicketService.GetDetail(id)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicketDetail(detail))
}
func (c *TicketController) PostCreate() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketCreate)
if err != nil {
return web.JsonError(err)
}
req := request.CreateTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
item, err := services.TicketService.CreateTicket(req, operator)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicket(item))
}
func (c *TicketController) PostCreate_from_conversation() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketCreate)
if err != nil {
return web.JsonError(err)
}
req := request.CreateTicketFromConversationRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
item, err := services.TicketService.CreateFromConversation(req, operator)
if err != nil {
return web.JsonError(err)
}
return web.JsonData(builders.BuildTicket(item))
}
func (c *TicketController) PostUpdate() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
if err != nil {
return web.JsonError(err)
}
req := request.UpdateTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.UpdateTicket(req, operator); err != nil {
return web.JsonError(err)
}
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 {
return web.JsonError(err)
}
req := request.AssignTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.AssignTicket(req, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostBatch_assign() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketAssign)
if err != nil {
return web.JsonError(err)
}
req := request.BatchAssignTicketRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.BatchAssignTickets(req, operator); err != nil {
return web.JsonError(err)
}
return web.JsonSuccess()
}
func (c *TicketController) PostChange_status() *web.JsonResult {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketChangeStatus)
if err != nil {
return web.JsonError(err)
}
req := request.ChangeTicketStatusRequest{}
if err := params.ReadJSON(c.Ctx, &req); err != nil {
return web.JsonError(err)
}
if err := services.TicketService.ChangeStatus(req, operator); err != nil {
return web.JsonError(err)
}
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 {
operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketUpdate)
if err != nil {
return web.JsonError(err)
}
req := request.AddTicketRelationRequest{}
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)
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})
}