diff --git a/internal/builders/ticket_builder.go b/internal/builders/ticket_builder.go index cbc0f66..a76bf41 100644 --- a/internal/builders/ticket_builder.go +++ b/internal/builders/ticket_builder.go @@ -101,6 +101,10 @@ func BuildTicketProgressWithContext(item *models.TicketProgress, ctx *TicketDeta return ret } +func BuildTicketProgressList(list []models.TicketProgress) []response.TicketProgressResponse { + return BuildTicketProgressListWithContext(list, nil) +} + func BuildTicketProgressListWithContext(list []models.TicketProgress, ctx *TicketDetailBuildContext) []response.TicketProgressResponse { if len(list) == 0 { return nil diff --git a/internal/controllers/dashboard/ticket_controller.go b/internal/controllers/dashboard/ticket_controller.go index d3ce904..bb17cf1 100644 --- a/internal/controllers/dashboard/ticket_controller.go +++ b/internal/controllers/dashboard/ticket_controller.go @@ -9,6 +9,7 @@ import ( "cs-agent/internal/services" "github.com/kataras/iris/v12" + "github.com/mlogclub/simple/sqls" "github.com/mlogclub/simple/web" "github.com/mlogclub/simple/web/params" ) @@ -213,6 +214,29 @@ func (c *TicketController) PostChange_status() *web.JsonResult { } func (c *TicketController) PostAdd_progress() *web.JsonResult { + return c.createProgress() +} + +func (c *TicketController) AnyProgress_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.JsonErrorMsg("工单不存在") + } + if services.TicketService.Get(ticketID) == nil { + return web.JsonErrorMsg("工单不存在") + } + progresses := services.TicketProgressService.Find(sqls.NewCnd().Eq("ticket_id", ticketID).Asc("id")) + return web.JsonData(builders.BuildTicketProgressList(progresses)) +} + +func (c *TicketController) PostProgress_create() *web.JsonResult { + return c.createProgress() +} + +func (c *TicketController) createProgress() *web.JsonResult { operator, err := services.AuthService.RequirePermission(c.Ctx, constants.PermissionTicketProgress) if err != nil { return web.JsonError(err) diff --git a/internal/pkg/constants/auth.go b/internal/pkg/constants/auth.go index 453d67f..f46f61d 100644 --- a/internal/pkg/constants/auth.go +++ b/internal/pkg/constants/auth.go @@ -345,7 +345,7 @@ var RolePermissions = map[string][]Permission{ PermissionRoleView, PermissionPermissionView, PermissionConversationView, - PermissionTicketView, PermissionTicketCreate, PermissionTicketProgress, + PermissionTicketView, PermissionTicketCreate, PermissionTicketAssign, PermissionTicketChangeStatus, PermissionTicketProgress, PermissionNotificationView, PermissionNotificationUpdate, PermissionQuickReplyView, PermissionTagView, diff --git a/internal/services/event_handlers/notification_event_handler.go b/internal/services/event_handlers/notification_event_handler.go index 243434e..1f3ee31 100644 --- a/internal/services/event_handlers/notification_event_handler.go +++ b/internal/services/event_handlers/notification_event_handler.go @@ -45,7 +45,7 @@ func handleTicketAssignedInAppNotification(ctx context.Context, event events.Tic NotificationType: "ticket_assigned", BizType: "ticket", BizID: ticket.ID, - ActionURL: fmt.Sprintf("/dashboard/tickets/%d", ticket.ID), + ActionURL: fmt.Sprintf("/dashboard/tickets?ticketId=%d", ticket.ID), }) if err != nil { slog.Error("create ticket assigned in-app notification failed", "error", err, "ticketId", event.TicketID, "toUserId", event.ToUserID) diff --git a/internal/services/event_handlers/notification_event_handler_test.go b/internal/services/event_handlers/notification_event_handler_test.go index fbdf9d8..0bfbd28 100644 --- a/internal/services/event_handlers/notification_event_handler_test.go +++ b/internal/services/event_handlers/notification_event_handler_test.go @@ -52,7 +52,7 @@ func TestTicketAssignedInAppNotification(t *testing.T) { if got.NotificationType != "ticket_assigned" || got.BizType != "ticket" || got.BizID != ticket.ID { t.Fatalf("unexpected notification: %+v", got) } - if got.ActionURL != "/dashboard/tickets/1" { + if got.ActionURL != "/dashboard/tickets?ticketId=1" { t.Fatalf("unexpected action url: %q", got.ActionURL) } } diff --git a/web/app/dashboard/tickets/page.tsx b/web/app/dashboard/tickets/page.tsx index 84a42ff..573c010 100644 --- a/web/app/dashboard/tickets/page.tsx +++ b/web/app/dashboard/tickets/page.tsx @@ -1,6 +1,7 @@ "use client" import { PlusIcon, RefreshCcwIcon, SearchXIcon } from "lucide-react" +import { useSearchParams } from "next/navigation" import { useCallback, useEffect, useMemo, useRef, useState } from "react" import { toast } from "sonner" @@ -103,6 +104,7 @@ function assigneeLabel(ticket: TicketItem) { } export default function TicketsPage() { + const searchParams = useSearchParams() const [tickets, setTickets] = useState([]) const [summary, setSummary] = useState(emptySummary) const [quickView, setQuickView] = useState("all") @@ -191,6 +193,14 @@ export default function TicketsPage() { void loadData() }, [loadData]) + useEffect(() => { + const ticketId = Number(searchParams.get("ticketId")) + if (ticketId > 0) { + setSelectedTicketId(ticketId) + setDetailOpen(true) + } + }, [searchParams]) + useEffect(() => { let active = true Promise.all([fetchAgentProfilesAll(), fetchTagsAll()]) diff --git a/web/lib/api/ticket.ts b/web/lib/api/ticket.ts index 63c3edd..e99ba10 100644 --- a/web/lib/api/ticket.ts +++ b/web/lib/api/ticket.ts @@ -211,7 +211,7 @@ export function createTicketProgress(payload: { ticketId: number content: string }) { - return request("/api/dashboard/ticket/add_progress", { + return request("/api/dashboard/ticket/progress/create", { method: "POST", body: JSON.stringify(payload), })