package cn.exrick.xboot.base.controller.common; import cn.exrick.xboot.core.common.annotation.RateLimiter; import cn.exrick.xboot.core.common.constant.CommonConstant; import cn.exrick.xboot.core.common.redis.RedisTemplateHelper; import cn.exrick.xboot.core.common.sms.SmsUtil; import cn.exrick.xboot.core.common.utils.CommonUtil; import cn.exrick.xboot.core.common.utils.CreateVerifyCode; import cn.exrick.xboot.core.common.utils.IpInfoUtil; import cn.exrick.xboot.core.common.utils.ResultUtil; import cn.exrick.xboot.core.common.vo.Result; import cn.exrick.xboot.core.service.SettingService; import cn.exrick.xboot.core.service.UserService; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @author Exrickx */ @Api(tags = "验证码接口") @RequestMapping("/xboot/common/captcha") @RestController @Transactional @Slf4j public class CaptchaController { @Autowired private SmsUtil smsUtil; @Autowired private RedisTemplateHelper redisTemplate; @Autowired private IpInfoUtil ipInfoUtil; @Autowired private UserService userService; @Autowired private SettingService settingService; @RequestMapping(value = "/init", method = RequestMethod.GET) @ApiOperation(value = "初始化验证码") public Result initCaptcha() { String captchaId = IdUtil.simpleUUID(); String code = new CreateVerifyCode().randomStr(4); // 缓存验证码 redisTemplate.set(captchaId, code, 2L, TimeUnit.MINUTES); Map map = new HashMap(); map.put("captchaId",captchaId); map.put("code",code); return ResultUtil.data(map); } @RequestMapping(value = "/draw/{captchaId}", method = RequestMethod.GET) @ApiOperation(value = "根据验证码ID获取图片") public void drawCaptcha(@PathVariable("captchaId") String captchaId, HttpServletResponse response) throws IOException { // 得到验证码 生成指定验证码 String code = redisTemplate.get(captchaId); CreateVerifyCode vCode = new CreateVerifyCode(116, 36, 4, 10, code); response.setContentType("image/png"); vCode.write(response.getOutputStream()); } @RequestMapping(value = "/sendRegistSms/{mobile}", method = RequestMethod.GET) @ApiOperation(value = "发送注册短信验证码") public Result sendRegistSmsCode(@PathVariable String mobile, HttpServletRequest request) { return sendSms(mobile, 2, 0, request); } @RequestMapping(value = "/sendLoginSms/{mobile}", method = RequestMethod.GET) @ApiOperation(value = "发送登录短信验证码") @RateLimiter(name="sendLoginSms", rate = 1, ipLimit = true) public Result sendLoginSmsCode(@PathVariable String mobile, HttpServletRequest request) { return sendSms(mobile, 1, 0, request); } @RequestMapping(value = "/sendResetSms/{mobile}", method = RequestMethod.GET) @ApiOperation(value = "发送重置密码短信验证码") public Result sendResetSmsCode(@PathVariable String mobile, HttpServletRequest request) { return sendSms(mobile, 1, 5, request); } @RequestMapping(value = "/sendEditMobileSms/{mobile}", method = RequestMethod.GET) @ApiOperation(value = "发送修改手机短信验证码") public Result sendEditMobileSmsCode(@PathVariable String mobile, HttpServletRequest request) { if (userService.findByMobile(mobile) != null) { return ResultUtil.error("该手机号已绑定账户"); } return sendSms(mobile, 0, 0, request); } /** * @param mobile 手机号 * @param range 发送范围 0发送给所有手机号 1只发送给注册手机 2只发送给未注册手机 * @param templateType 0通用模版 1注册 2登录 3修改手机 4修改密码 5重置密码 6工作流模版 */ public Result sendSms(String mobile, Integer range, Integer templateType, HttpServletRequest request) { if (range == 1 && userService.findByMobile(mobile) == null) { return ResultUtil.error("手机号未注册"); } else if (range == 2 && userService.findByMobile(mobile) != null) { return ResultUtil.error("手机号已注册"); } // IP限流 1分钟限1个请求 String key = "sendSms:" + ipInfoUtil.getIpAddr(request); String value = redisTemplate.get(key); if (StrUtil.isNotBlank(value)) { return ResultUtil.error("您发送的太频繁啦,请稍后再试"); } // 生成6位数验证码 String code = CommonUtil.getRandomNum(); // 缓存验证码 redisTemplate.set(CommonConstant.PRE_SMS + mobile, code, 5L, TimeUnit.MINUTES); // 发送验证码 smsUtil.sendCode(mobile, code, templateType); // 请求成功 标记限流 redisTemplate.set(key, "sended", 1L, TimeUnit.MINUTES); return ResultUtil.success("发送短信验证码成功"); } }