短信发送器-【验证码发送统一接口处理】

书接上文,需要做一个通用的验证码发送,发送操作还是以上篇文章为主,这里主要是对验证码发送进行一个重构
https://blog.csdn.net/MinisterOL/article/details/136750920

  1. 通过统一的验证码接口请求进入系统
  2. 在业务实现中,遍历 实现了 CaptchaHandler接口的组件信息

在这里插入图片描述
ApiCaptchaBizServiceImpl.java

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.extra.spring.SpringUtil;
import com..captcha.common.handler.CaptchaHandler;
import com..captcha.service.biz.ApiCaptchaBizService;
import com..captcha.model.req.SendCaptchaReq;
import com.ruoyi.common.exception.GlobalException;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * ApiCaptchaBizServiceImpl
 *
 * @author SERVER-ZJ
 * @since 2023/10/25 8:30
 */
@Service
public class ApiCaptchaBizServiceImpl implements ApiCaptchaBizService {

    @Override
    public void captcha(SendCaptchaReq req) {
        if (!Validator.isMobile(req.getMobile())) {
            throw new GlobalException("手机号格式错误");
        }
        Map<String, CaptchaHandler> captchaHandlerBeansByNameMap
                = SpringUtil.getBeansOfType(CaptchaHandler.class);
        if (CollectionUtil.isEmpty(captchaHandlerBeansByNameMap)) {
            throw new GlobalException("业务不存在!");
        }

        CaptchaHandler currentCaptchaHandler;
        CaptchaHandler targetCaptchaHandler = null;
        for (Map.Entry<String, CaptchaHandler> captchaHandlerBeansByNameMapEntry
                : captchaHandlerBeansByNameMap.entrySet()) {
            currentCaptchaHandler = captchaHandlerBeansByNameMapEntry.getValue();
            if (req.getTypeCode().equals(currentCaptchaHandler.getCode())) {
                targetCaptchaHandler = currentCaptchaHandler;
            }
        }
        if (targetCaptchaHandler == null) {
            throw new GlobalException("业务不存在!");
        }
        targetCaptchaHandler.send(req.getMobile());
    }
}

CaptchaHandler.java

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com..captcha.common.cont.CaptchaConst;
import com..captcha.common.manager.CaptchaManager;
import com..captcha.model.extend.Captcha;
import com..sms.SmsSender;
import com..sms.common.cont.PlatformEnum;
import com..sms.model.base.BaseSendParam;
import com.ruoyi.common.exception.GlobalException;

import java.util.Date;

/**
 * CaptchaHandler
 *
 * @author SERVER
 * @since 2024/3/28 11:37
 */
public interface CaptchaHandler {

    /**
     * 获取验证码管理器
     *
     * @return 验证码管理器
     */
    default CaptchaManager getCaptchaManager() {
        Object captchaManager = SpringUtil.getBean("CaptchaManager");
        if (ObjectUtil.isNull(captchaManager) ||
                !(captchaManager instanceof CaptchaManager)) {
            throw new GlobalException("验证码管理器暂未注册");
        }
        return (CaptchaManager) captchaManager;
    }

    /**
     * 对应处理编码
     *
     * @return 验证模块编码
     */
    default String getCode() {
        return "";
    }

    /**
     * 发送
     */
    default void send(String mobile) {

        this.beforeSend(mobile);
        // 2、查看缓存中是否有对应的手机号验证码缓存
        Captcha captcha
                = this.getCaptchaManager().getCaptcha(this.getCode(), mobile);
        // 3、判断是不是超过60s
        if (captcha != null) {
            long captchaSendingIntervalSecond = DateUtil.between(new Date(), captcha.getCreateTime(), DateUnit.SECOND);
            if (captchaSendingIntervalSecond < CaptchaConst.CAPTCHA_SENDING_INTERVAL_LIMIT_SECOND) {
                throw new GlobalException("验证码已发送,请 " + (CaptchaConst.CAPTCHA_SENDING_INTERVAL_LIMIT_SECOND - captchaSendingIntervalSecond) + "s 后再试");
            }
        }
        // 4、重新生成验证码
        captcha = this.getCaptchaManager().createCaptcha(this.getCode(), mobile);
        // 5、发送短信
        SmsSender.send(PlatformEnum.ALI_DA_YU, mobile, this.createCaptchaSmsBody(captcha));
    }

    /**
     * 短信发送前置处理
     *
     * @param mobile 手机号
     */
    void beforeSend(String mobile);

    /**
     * 根据验证码创建短信body
     *
     * @param captcha 验证码
     * @return 发送短信体
     */
    BaseSendParam createCaptchaSmsBody(Captcha captcha);

    /**
     * 校验验证码
     *
     * @param mobile      手机号
     * @param captchaCode 校验验证码
     */
    default void verify(String mobile, String captchaCode) {
        Captcha captcha = this.getCaptchaManager().getCaptcha(this.getCode(), mobile);
        if (captcha == null || !captcha.getMobile().equals(mobile)) {
            throw new GlobalException("验证码无效!");
        }
        if (!captcha.getCaptcha().equals(captchaCode)) {
            throw new GlobalException("验证码错误!");
        }
    }
}

实现举例:
RegisterCaptchaHandler.class

import com..captcha.common.handler.CaptchaHandler;
import com..captcha.model.extend.Captcha;
import com..recruit.api.account.common.checker.AccountChecker;
import com..recruit.api.common.common.sms.model.CaptchaTemplateParam;
import com..sms.common.template.AliDaYuTemplate;
import com..sms.model.base.BaseSendParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * AccountCaptchaHandler
 *
 * @author SERVER
 * @since 2024/3/28 13:27
 */
@Component
public class AccountRegisterCaptchaHandler implements CaptchaHandler {


    @Autowired
    private AccountChecker accountChecker;

    @Override
    public String getCode() {
        return "accountRegister";
    }


    @Override
    public void beforeSend(String mobile) {
        accountChecker.checkRegisterMobile(mobile);
    }

    @Override
    public BaseSendParam createCaptchaSmsBody(Captcha captcha) {
        AliDaYuTemplate template = new AliDaYuTemplate("XXXX科技", "SMS_14238XXXXX");
        return template.createSmsBody(new CaptchaTemplateParam(captcha.getCaptcha()));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值