From c8155e2d3348b0053585fc11d6df16f7b98d2f95 Mon Sep 17 00:00:00 2001 From: "Logan.Li" Date: Mon, 26 Oct 2026 19:14:35 +0800 Subject: [PATCH] fix(ticket): implicit executor for default-flow tickets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - list is_executor and ExecuteTicket both required an execute-step approval record; tickets created without a workflow (default flow) had none, so the execute button never appeared and the API returned 403 for everyone - admin/dba are now implicit executors (approved status only, consistent in both list enrichment and execution check) - status labels: pending/reviewing/approved were all shown as 审核中; now 待初审/审批中/待执行 so the ready-to-execute state is visible - verified end-to-end on test backend: create -> quick review dialog with comment -> impact-summary execute confirm -> success, detail page stage steps reach 完成 with execute result visible --- backend/internal/handler/ticket.go | 14 ++++++++++++-- frontend/src/features/ticket/constants.ts | 6 +++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/backend/internal/handler/ticket.go b/backend/internal/handler/ticket.go index bf4717b..ea69aa2 100644 --- a/backend/internal/handler/ticket.go +++ b/backend/internal/handler/ticket.go @@ -143,6 +143,10 @@ func ListTickets(c *gin.Context) { model.DB.Model(&model.TicketApproval{}).Where("ticket_id = ? AND step_type = 'execute'", t.ID).Count(&execCount) var isExec, isAppr int64 model.DB.Model(&model.TicketApproval{}).Where("ticket_id = ? AND step_type = 'execute' AND approver_id = ?", t.ID, userID).Count(&isExec) + // 无执行步配置的工单(默认流程):approved 状态下 admin/dba 为隐式执行人 + if isExec == 0 && execCount == 0 && (role == "admin" || role == "dba") && t.Status != nil && *t.Status == "approved" { + isExec = 1 + } // Only count PENDING approvals (action IS NULL) — already-approved records should not show approve button model.DB.Model(&model.TicketApproval{}).Where("ticket_id = ? AND step_type != 'execute' AND step_type != 'submit' AND approver_id = ? AND action IS NULL", t.ID, userID).Count(&isAppr) result = append(result, TicketWithMeta{ @@ -569,8 +573,14 @@ func ExecuteTicket(c *gin.Context) { Where("ticket_id = ? AND step_type = 'execute' AND (approver_id = ? OR approver_id IS NULL)", id, userID). Count(&executorCheck) if executorCheck == 0 { - resp.Forbidden(c, "你不是此工单的执行人") - return + // 无执行步配置的工单(默认流程):admin/dba 为隐式执行人(与列表 is_executor 判定一致) + var execStepCount int64 + model.DB.Model(&model.TicketApproval{}).Where("ticket_id = ? AND step_type = 'execute'", id).Count(&execStepCount) + _, _, role := middleware.GetCurrentUser(c) + if execStepCount > 0 || (role != "admin" && role != "dba") { + resp.Forbidden(c, "你不是此工单的执行人") + return + } } var pendingExec model.TicketApproval diff --git a/frontend/src/features/ticket/constants.ts b/frontend/src/features/ticket/constants.ts index 0576cba..533f747 100644 --- a/frontend/src/features/ticket/constants.ts +++ b/frontend/src/features/ticket/constants.ts @@ -5,9 +5,9 @@ /** 展示用状态映射 — 按用户要求简化 */ export const displayStatusMap: Record = { - pending: '审核中', - reviewing: '审核中', - approved: '审核中', + pending: '待初审', + reviewing: '审批中', + approved: '待执行', rejected: '已拒绝', executing: '执行中', success: '完成',