Files
tyapi-server/internal/infrastructure/http/handlers/captcha_handler.go
2026-02-27 14:49:29 +08:00

93 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"tyapi-server/internal/config"
"tyapi-server/internal/infrastructure/external/captcha"
"tyapi-server/internal/shared/interfaces"
)
// CaptchaHandler 验证码滑块HTTP 处理器
type CaptchaHandler struct {
captchaService *captcha.CaptchaService
response interfaces.ResponseBuilder
config *config.Config
logger *zap.Logger
}
// NewCaptchaHandler 创建验证码处理器
func NewCaptchaHandler(
captchaService *captcha.CaptchaService,
response interfaces.ResponseBuilder,
cfg *config.Config,
logger *zap.Logger,
) *CaptchaHandler {
return &CaptchaHandler{
captchaService: captchaService,
response: response,
config: cfg,
logger: logger,
}
}
// EncryptedSceneIdReq 获取加密场景 ID 的请求(可选参数)
type EncryptedSceneIdReq struct {
ExpireSeconds *int `form:"expire_seconds" json:"expire_seconds"` // 有效期秒数186400默认 3600
}
// GetEncryptedSceneId 获取加密场景 ID供前端加密模式初始化阿里云验证码
// @Summary 获取验证码加密场景ID
// @Description 用于加密模式下发 EncryptedSceneId前端用此初始化滑块验证码
// @Tags 验证码
// @Accept json
// @Produce json
// @Param body body EncryptedSceneIdReq false "可选expire_seconds 有效期(1-86400)默认3600"
// @Success 200 {object} map[string]interface{} "encryptedSceneId"
// @Failure 400 {object} map[string]interface{} "配置未启用或参数错误"
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
// @Router /api/v1/captcha/encryptedSceneId [post]
func (h *CaptchaHandler) GetEncryptedSceneId(c *gin.Context) {
expireSec := 3600
if c.Request.ContentLength > 0 {
var req EncryptedSceneIdReq
if err := c.ShouldBindJSON(&req); err == nil && req.ExpireSeconds != nil {
expireSec = *req.ExpireSeconds
}
}
if expireSec <= 0 || expireSec > 86400 {
h.response.BadRequest(c, "expire_seconds 必须在 186400 之间")
return
}
encrypted, err := h.captchaService.GetEncryptedSceneId(expireSec)
if err != nil {
if err == captcha.ErrCaptchaEncryptMissing || err == captcha.ErrCaptchaConfig {
h.logger.Warn("验证码加密场景ID生成失败", zap.Error(err))
h.response.BadRequest(c, "验证码加密模式未配置或配置错误")
return
}
h.logger.Error("验证码加密场景ID生成失败", zap.Error(err))
h.response.InternalError(c, "生成失败,请稍后重试")
return
}
h.response.Success(c, map[string]string{"encryptedSceneId": encrypted}, "ok")
}
// GetConfig 获取验证码前端配置是否启用、场景ID等便于前端决定是否展示滑块
// @Summary 获取验证码配置
// @Description 返回是否启用滑块、场景ID非加密模式用
// @Tags 验证码
// @Produce json
// @Success 200 {object} map[string]interface{} "captchaEnabled, sceneId"
// @Router /api/v1/captcha/config [get]
func (h *CaptchaHandler) GetConfig(c *gin.Context) {
data := map[string]interface{}{
"captchaEnabled": h.config.SMS.CaptchaEnabled,
"sceneId": h.config.SMS.SceneID,
}
h.response.Success(c, data, "ok")
}