From 2a6fb1e456158b760676b292daedcad86c3a82e0 Mon Sep 17 00:00:00 2001 From: IanShaw027 <131567472+IanShaw027@users.noreply.github.com> Date: Wed, 14 Jan 2026 23:56:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(ops):=20=E6=B7=BB=E5=8A=A0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BF=A1=E6=81=AF=E6=98=BE=E7=A4=BA=E5=92=8C=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在错误日志列表和详情中显示用户邮箱 - 在 GetErrorLogByID 中关联 users 表获取用户邮箱 - 在 OpsErrorLogFilter 中添加 UserQuery 字段 - 在 buildOpsErrorLogsWhere 中添加用户邮箱搜索条件 - 在 GetErrorLogs handler 中支持 user_query 参数 --- backend/internal/handler/admin/ops_handler.go | 2 ++ backend/internal/repository/ops_repo.go | 10 ++++++++++ backend/internal/service/ops_models.go | 1 + 3 files changed, 13 insertions(+) diff --git a/backend/internal/handler/admin/ops_handler.go b/backend/internal/handler/admin/ops_handler.go index 822f7d62..44accc8f 100644 --- a/backend/internal/handler/admin/ops_handler.go +++ b/backend/internal/handler/admin/ops_handler.go @@ -111,6 +111,7 @@ func (h *OpsHandler) GetErrorLogs(c *gin.Context) { filter.Owner = strings.TrimSpace(c.Query("error_owner")) filter.Source = strings.TrimSpace(c.Query("error_source")) filter.Query = strings.TrimSpace(c.Query("q")) + filter.UserQuery = strings.TrimSpace(c.Query("user_query")) // Force request errors: client-visible status >= 400. // buildOpsErrorLogsWhere already applies this for non-upstream phase. @@ -211,6 +212,7 @@ func (h *OpsHandler) ListRequestErrors(c *gin.Context) { filter.Owner = strings.TrimSpace(c.Query("error_owner")) filter.Source = strings.TrimSpace(c.Query("error_source")) filter.Query = strings.TrimSpace(c.Query("q")) + filter.UserQuery = strings.TrimSpace(c.Query("user_query")) // Force request errors: client-visible status >= 400. // buildOpsErrorLogsWhere already applies this for non-upstream phase. diff --git a/backend/internal/repository/ops_repo.go b/backend/internal/repository/ops_repo.go index d889269f..613c5bd5 100644 --- a/backend/internal/repository/ops_repo.go +++ b/backend/internal/repository/ops_repo.go @@ -326,6 +326,7 @@ SELECT COALESCE(e.upstream_errors::text, ''), e.is_business_limited, e.user_id, + COALESCE(u.email, ''), e.api_key_id, e.account_id, COALESCE(a.name, ''), @@ -345,6 +346,7 @@ SELECT e.request_body_bytes, COALESCE(e.request_headers::text, '') FROM ops_error_logs e +LEFT JOIN users u ON e.user_id = u.id LEFT JOIN accounts a ON e.account_id = a.id LEFT JOIN groups g ON e.group_id = g.id WHERE e.id = $1 @@ -395,6 +397,7 @@ LIMIT 1` &out.UpstreamErrors, &out.IsBusinessLimited, &userID, + &out.UserEmail, &apiKeyID, &accountID, &out.AccountName, @@ -1033,6 +1036,13 @@ func buildOpsErrorLogsWhere(filter *service.OpsErrorLogFilter) (string, []any) { clauses = append(clauses, "(request_id ILIKE $"+n+" OR client_request_id ILIKE $"+n+" OR error_message ILIKE $"+n+")") } + if userQuery := strings.TrimSpace(filter.UserQuery); userQuery != "" { + like := "%" + userQuery + "%" + args = append(args, like) + n := itoa(len(args)) + clauses = append(clauses, "u.email ILIKE $"+n) + } + return "WHERE " + strings.Join(clauses, " AND "), args } diff --git a/backend/internal/service/ops_models.go b/backend/internal/service/ops_models.go index c7666e92..347cd52b 100644 --- a/backend/internal/service/ops_models.go +++ b/backend/internal/service/ops_models.go @@ -93,6 +93,7 @@ type OpsErrorLogFilter struct { Source string Resolved *bool Query string + UserQuery string // Search by user email // Optional correlation keys for exact matching. RequestID string