package developer import ( "fmt" "math/rand" "time" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "verification-platform-backend/internal/service" "verification-platform-backend/pkg/response" "github.com/gin-gonic/gin" ) func SetupEmailRoutes(r *gin.RouterGroup) { r.GET("/applications/:id/email-config", handleGetEmailConfig) r.PUT("/applications/:id/email-config", handleUpdateEmailConfig) r.POST("/applications/:id/email-config/test", handleTestEmailConfig) r.GET("/applications/:id/email-templates", handleGetEmailTemplates) r.GET("/applications/:id/email-templates/:template_id", handleGetEmailTemplate) r.POST("/applications/:id/email-templates", handleCreateEmailTemplate) r.PUT("/applications/:id/email-templates/:template_id", handleUpdateEmailTemplate) r.DELETE("/applications/:id/email-templates/:template_id", handleDeleteEmailTemplate) r.POST("/applications/:id/send-verify-code", handleSendVerifyCode) } func handleGetEmailConfig(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var permission model.PackagePermission hasPermission := checkEmailPermission(userID.(uint), &permission) if !hasPermission { response.Error(c, 403, "您的套餐不支持邮件功能") return } var smtpConfig model.AppSMTPConfig database.DB.Where("application_id = ?", app.ID).First(&smtpConfig) result := gin.H{ "enable_email_verify": app.EnableEmailVerify, "require_email_verify": app.RequireEmailVerify, "enable_password_reset": app.EnablePasswordReset, "permission": gin.H{ "allow_email": permission.AllowEmail, }, } if smtpConfig.ID > 0 { result["smtp_config"] = gin.H{ "id": smtpConfig.ID, "host": smtpConfig.Host, "port": smtpConfig.Port, "user": smtpConfig.User, "from_name": smtpConfig.FromName, "from_email": smtpConfig.FromEmail, "use_ssl": smtpConfig.UseSSL, "status": smtpConfig.Status, } } else { result["smtp_config"] = nil } response.Success(c, result) } func handleUpdateEmailConfig(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var permission model.PackagePermission hasPermission := checkEmailPermission(userID.(uint), &permission) if !hasPermission { response.Error(c, 403, "您的套餐不支持邮件功能") return } var req struct { EnableEmailVerify bool `json:"enable_email_verify"` RequireEmailVerify bool `json:"require_email_verify"` EnablePasswordReset bool `json:"enable_password_reset"` SMTPConfig *struct { Host string `json:"host"` Port int `json:"port"` User string `json:"user"` Password string `json:"password"` FromName string `json:"from_name"` FromEmail string `json:"from_email"` UseSSL bool `json:"use_ssl"` } `json:"smtp_config"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } updates := map[string]interface{}{ "enable_email_verify": req.EnableEmailVerify, "require_email_verify": req.RequireEmailVerify, "enable_password_reset": req.EnablePasswordReset, } if err := database.DB.Model(&app).Updates(updates).Error; err != nil { response.Error(c, 500, "更新失败") return } if req.SMTPConfig != nil { var smtpConfig model.AppSMTPConfig database.DB.Where("application_id = ?", app.ID).First(&smtpConfig) smtpConfig.ApplicationID = app.ID smtpConfig.Host = req.SMTPConfig.Host smtpConfig.Port = req.SMTPConfig.Port smtpConfig.User = req.SMTPConfig.User if req.SMTPConfig.Password != "" { smtpConfig.Password = req.SMTPConfig.Password } smtpConfig.FromName = req.SMTPConfig.FromName smtpConfig.FromEmail = req.SMTPConfig.FromEmail smtpConfig.UseSSL = req.SMTPConfig.UseSSL if smtpConfig.ID > 0 { database.DB.Save(&smtpConfig) } else { database.DB.Create(&smtpConfig) } } response.Success(c, gin.H{ "message": "更新成功", }) } func handleTestEmailConfig(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var req struct { Email string `json:"email" binding:"required,email"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "请输入有效的邮箱地址") return } var smtpConfig model.AppSMTPConfig if err := database.DB.Where("application_id = ?", app.ID).First(&smtpConfig).Error; err != nil { response.Error(c, 400, "请先配置SMTP") return } emailService := service.NewEmailService() config := service.EmailConfig{ Host: smtpConfig.Host, Port: smtpConfig.Port, User: smtpConfig.User, Password: smtpConfig.Password, FromName: smtpConfig.FromName, FromEmail: smtpConfig.FromEmail, UseSSL: smtpConfig.UseSSL, } if err := emailService.SendTestEmail(config, req.Email, app.Name); err != nil { response.Error(c, 500, fmt.Sprintf("发送失败: %v", err)) return } response.Success(c, gin.H{ "message": "测试邮件已发送", }) } func handleGetEmailTemplates(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var permission model.PackagePermission hasPermission := checkEmailPermission(userID.(uint), &permission) if !hasPermission { response.Error(c, 403, "您的套餐不支持邮箱验证功能") return } var templates []model.EmailTemplate database.DB.Where("application_id = ?", app.ID).Order("created_at DESC").Find(&templates) response.Success(c, templates) } func handleGetEmailTemplate(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") templateID := c.Param("template_id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var template model.EmailTemplate if err := database.DB.Where("id = ? AND application_id = ?", templateID, app.ID).First(&template).Error; err != nil { response.Error(c, 404, "模板不存在") return } response.Success(c, template) } func handleCreateEmailTemplate(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var permission model.PackagePermission hasPermission := checkEmailPermission(userID.(uint), &permission) if !hasPermission { response.Error(c, 403, "您的套餐不支持邮件功能") return } var req struct { Type string `json:"type" binding:"required"` Name string `json:"name" binding:"required"` Subject string `json:"subject" binding:"required"` Content string `json:"content" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } template := model.EmailTemplate{ ApplicationID: app.ID, Type: req.Type, Name: req.Name, Subject: req.Subject, Content: req.Content, Status: "active", } if err := database.DB.Create(&template).Error; err != nil { response.Error(c, 500, "创建失败") return } response.Success(c, template) } func handleUpdateEmailTemplate(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") templateID := c.Param("template_id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var permission model.PackagePermission hasPermission := checkEmailPermission(userID.(uint), &permission) if !hasPermission { response.Error(c, 403, "您的套餐不支持邮件功能") return } var template model.EmailTemplate if err := database.DB.Where("id = ? AND application_id = ?", templateID, app.ID).First(&template).Error; err != nil { response.Error(c, 404, "模板不存在") return } var req struct { Type string `json:"type"` Name string `json:"name"` Subject string `json:"subject"` Content string `json:"content"` Status string `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } updates := map[string]interface{}{} if req.Type != "" { updates["type"] = req.Type } if req.Name != "" { updates["name"] = req.Name } if req.Subject != "" { updates["subject"] = req.Subject } if req.Content != "" { updates["content"] = req.Content } if req.Status != "" { updates["status"] = req.Status } if err := database.DB.Model(&template).Updates(updates).Error; err != nil { response.Error(c, 500, "更新失败") return } response.Success(c, template) } func handleDeleteEmailTemplate(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") templateID := c.Param("template_id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var permission model.PackagePermission hasPermission := checkEmailPermission(userID.(uint), &permission) if !hasPermission { response.Error(c, 403, "您的套餐不支持邮件功能") return } if err := database.DB.Where("id = ? AND application_id = ?", templateID, app.ID).Delete(&model.EmailTemplate{}).Error; err != nil { response.Error(c, 500, "删除失败") return } response.Success(c, gin.H{ "message": "删除成功", }) } func handleSendVerifyCode(c *gin.Context) { userID, _ := c.Get("user_id") appID := c.Param("id") var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", appID, userID).First(&app).Error; err != nil { response.Error(c, 404, "应用不存在") return } var req struct { Email string `json:"email" binding:"required,email"` Purpose string `json:"purpose"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "请输入有效的邮箱地址") return } if req.Purpose == "" { req.Purpose = "register" } var smtpConfig model.AppSMTPConfig if err := database.DB.Where("application_id = ?", app.ID).First(&smtpConfig).Error; err != nil { response.Error(c, 400, "请先配置SMTP") return } var template model.EmailTemplate database.DB.Where("application_id = ? AND type = ? AND status = ?", app.ID, req.Purpose, "active"). Order("is_default DESC").First(&template) code := generateVerifyCode() expireAt := time.Now().Add(15 * time.Minute) verifyCode := model.EmailVerifyCode{ ApplicationID: app.ID, Email: req.Email, Code: code, Purpose: req.Purpose, ExpiresAt: expireAt, } database.DB.Create(&verifyCode) emailService := service.NewEmailService() config := service.EmailConfig{ Host: smtpConfig.Host, Port: smtpConfig.Port, User: smtpConfig.User, Password: smtpConfig.Password, FromName: smtpConfig.FromName, FromEmail: smtpConfig.FromEmail, UseSSL: smtpConfig.UseSSL, } subject := fmt.Sprintf("验证码 - %s", app.Name) content := fmt.Sprintf(`

邮箱验证

您的验证码是:%s

验证码有效期为15分钟,请尽快使用。


此邮件由 %s 系统自动发送,请勿回复。

`, code, app.Name) if template.ID > 0 { subject = template.Subject content = template.Content } if err := emailService.SendEmail(config, req.Email, subject, content); err != nil { response.Error(c, 500, fmt.Sprintf("发送失败: %v", err)) return } response.Success(c, gin.H{ "message": "验证码已发送", }) } func checkEmailPermission(userID uint, permission *model.PackagePermission) bool { var userPackage model.UserPackage if err := database.DB.Where("user_id = ? AND status = ?", userID, "active"). Preload("Package").First(&userPackage).Error; err != nil { return false } if userPackage.ExpiredAt != nil && userPackage.ExpiredAt.Before(time.Now()) { return false } if err := database.DB.Where("package_id = ?", userPackage.PackageID).First(permission).Error; err != nil { return false } return permission.AllowEmail } func generateVerifyCode() string { r := rand.New(rand.NewSource(time.Now().UnixNano())) return fmt.Sprintf("%06d", r.Intn(1000000)) }