package server import ( "bytes" "encoding/json" "fmt" "log/slog" "strings" "time" "kra/internal/service" "github.com/gin-gonic/gin" ) func registerEmailRoutes(group *gin.RouterGroup, svc *service.EmailService) { email := group.Group("/email") email.POST("/emailTest", func(c *gin.Context) { if err := svc.Test(c.Request.Context()); err != nil { fail(c, "发送失败:"+err.Error()) return } writeResult(c, codeSuccess, gin.H{}, "发送成功") }) email.POST("/sendEmail", func(c *gin.Context) { var req struct { To string `json:"to"` Subject string `json:"subject"` Body string `json:"body"` } if c.ShouldBindJSON(&req) != nil { fail(c, "参数错误") return } if err := svc.Send(c.Request.Context(), req.To, req.Subject, req.Body); err != nil { fail(c, "发送失败:"+err.Error()) return } writeResult(c, codeSuccess, gin.H{}, "发送成功") }) } func emailErrorAlert(svc *service.EmailService, logger *slog.Logger) gin.HandlerFunc { return func(c *gin.Context) { if strings.Contains(c.Request.URL.Path, "/email/") { c.Next() return } writer := &captureWriter{ResponseWriter: c.Writer} c.Writer = writer started := time.Now() c.Next() failed := c.Writer.Status() >= 400 if !failed { var result struct { Code int `json:"code"` } failed = json.Unmarshal(writer.body.Bytes(), &result) == nil && result.Code != codeSuccess } if !failed { return } username := "Unknown" if claims := currentClaims(c); claims != nil && claims.Username != "" { username = claims.Username } subject := fmt.Sprintf("%s %s 调用 %s 报错", username, c.ClientIP(), c.Request.URL.Path) body := bytes.NewBuffer(nil) fmt.Fprintf(body, "请求方式:%s
请求路径:%s
状态码:%d
耗时:%s
错误响应:
%s
", c.Request.Method, c.Request.URL.Path, c.Writer.Status(), time.Since(started), redactJSON(writer.body.Bytes())) if err := svc.Alert(c.Request.Context(), subject, body.String()); err != nil && logger != nil { logger.Error("send HTTP error email", "error", err) } } }