package user import ( "context" "strings" "github.com/gin-gonic/gin" commonLogic "github.com/perfect-panel/server/internal/logic/common" "github.com/perfect-panel/server/internal/logic/public/user" "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/pkg/authmethod" "github.com/perfect-panel/server/pkg/constant" "github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/xerr" "github.com/pkg/errors" ) // DeleteAccountHandler 注销账号处理器 // 根据当前token删除所有关联设备,然后根据各自设备ID重新新建账号 // 新增:需携带邮箱验证码,验证通过后执行注销 type deleteAccountReq struct { Email string `json:"email" binding:"required,email"` // 用户邮箱 Code string `json:"code" binding:"required"` // 邮箱验证码 } func DeleteAccountHandler(serverCtx *svc.ServiceContext) gin.HandlerFunc { return func(c *gin.Context) { var req deleteAccountReq if err := c.ShouldBindJSON(&req); err != nil { result.ParamErrorResult(c, err) return } // 统一处理邮箱格式:转小写并去空格,与发送验证码逻辑保持一致 req.Email = strings.ToLower(strings.TrimSpace(req.Email)) // 校验邮箱验证码(统一走公共验证码校验器,支持 delete_account/security 场景兼容) if err := verifyEmailCode(c.Request.Context(), serverCtx, req.Email, req.Code); err != nil { result.HttpResult(c, nil, err) return } l := user.NewDeleteAccountLogic(c.Request.Context(), serverCtx) resp, err := l.DeleteAccountAll() result.HttpResult(c, resp, err) } } // verifyEmailCode 校验邮箱验证码 // 1. 统一复用 common checker // 2. 强制 consume=true(最终业务操作做一次性消费) // 3. 兼容历史 security 场景验证码(allow fallback) func verifyEmailCode(ctx context.Context, serverCtx *svc.ServiceContext, email string, code string) error { l := commonLogic.NewCheckVerificationCodeLogic(ctx, serverCtx) resp, err := l.CheckVerificationCodeWithBehavior(&types.CheckVerificationCodeRequest{ Method: authmethod.Email, Account: email, Code: strings.TrimSpace(code), Type: uint8(constant.DeleteAccount), }, commonLogic.VerifyCodeCheckBehavior{ Source: "delete_account", Consume: true, AllowSceneFallback: true, }) if err != nil { return err } if resp == nil || !resp.Status { return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "verification code error or expired") } return nil }