package com.nq.service.impl; import com.nq.common.ServerResponse; import com.nq.dao.SiteSmsLogMapper; import com.nq.dao.UserMapper; import com.nq.pojo.SiteInfo; import com.nq.pojo.SiteSmsLog; import com.nq.pojo.User; import com.nq.service.ISiteInfoService; import com.nq.service.ISmsService; import com.nq.utils.DateTimeUtil; import com.nq.utils.PhoneUtil; import com.nq.utils.PropertiesUtil; import com.nq.utils.redis.RedisShardedPoolUtils; import com.nq.utils.captcha.CaptchaUtil; import com.nq.utils.sms.SmsBaoClient; import com.nq.utils.sms.SmsConstants; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @Service("iSmsService") public class SmsServiceImpl implements ISmsService { private static final Logger log = LoggerFactory.getLogger(SmsServiceImpl.class); @Autowired SiteSmsLogMapper siteSmsLogMapper; @Autowired UserMapper userMapper; @Autowired ISiteInfoService iSiteInfoService; @Override public ServerResponse sendRegSms(String phoneNum, String captchaCode, String captchaToken, HttpServletRequest request) { if (!SmsConstants.isVerifyEnabled()) { return ServerResponse.createBySuccess(); } if (StringUtils.isBlank(phoneNum)) { return ServerResponse.createByErrorMsg("发送失败,手机号不能为空"); } if (!PhoneUtil.isValidChinaMobile(phoneNum)) { return ServerResponse.createByErrorMsg("请输入正确的手机号码"); } if (!verifyCaptcha(request, captchaCode, captchaToken)) { return ServerResponse.createByErrorMsg("图形验证码错误"); } String phone = PhoneUtil.normalizeChinaMobile(phoneNum); User exist = userMapper.findByPhone(phone); if (exist != null) { return ServerResponse.createByErrorMsg("该手机号已注册"); } String lockKey = SmsConstants.SMS_SEND_LOCK_PREFIX + phone; if (StringUtils.isNotBlank(RedisShardedPoolUtils.get(lockKey))) { return ServerResponse.createByErrorMsg("请60秒后再试"); } String yzmCode = RandomStringUtils.randomNumeric(4); String signName = resolveSignName(); String content = "【" + signName + "】您的验证码是" + yzmCode + "。如非本人操作,请忽略本短信"; boolean sent = SmsBaoClient.send(phone, content); if (!sent) { return ServerResponse.createByErrorMsg("短信发送失败,请稍后重试"); } String codeKey = SmsConstants.SMS_CODE_PREFIX + phone; RedisShardedPoolUtils.setEx(codeKey, yzmCode, SmsConstants.SMS_CODE_TTL_SECONDS); RedisShardedPoolUtils.setEx(lockKey, "1", SmsConstants.SMS_SEND_INTERVAL_SECONDS); SiteSmsLog siteSmsLog = new SiteSmsLog(); siteSmsLog.setSmsPhone(phone); siteSmsLog.setSmsTitle("注册验证码"); siteSmsLog.setSmsCnt(yzmCode); siteSmsLog.setSmsTemplate("smsbao-reg"); siteSmsLog.setSmsStatus(Integer.valueOf(0)); siteSmsLog.setAddTime(DateTimeUtil.getCurrentDate()); siteSmsLogMapper.insert(siteSmsLog); log.info("注册短信发送成功 phone={}", phone); return ServerResponse.createBySuccessMsg("发送成功"); } @Override public ServerResponse sendAliyunSMS(String phoneNum, String aliTemplate) { return ServerResponse.createByErrorMsg("请先完成图形验证码校验"); } private boolean verifyCaptcha(HttpServletRequest request, String captchaCode, String captchaToken) { if (StringUtils.isBlank(captchaCode)) { return false; } if (StringUtils.isNotBlank(captchaToken)) { boolean ok = CaptchaUtil.verifyAndRemove(captchaToken.trim(), captchaCode); if (!ok) { log.warn("图形验证码校验失败(Redis) token={}", captchaToken); } return ok; } if (request == null) { return false; } HttpSession session = request.getSession(); String original = (String) session.getAttribute("KAPTCHA_SESSION_KEY"); session.removeAttribute("KAPTCHA_SESSION_KEY"); return StringUtils.isNotEmpty(original) && captchaCode.trim().equalsIgnoreCase(original.trim()); } private String resolveSignName() { String configured = PropertiesUtil.getProperty("smsbao.sign.name"); if (StringUtils.isNotBlank(configured)) { return configured.trim(); } try { ServerResponse resp = iSiteInfoService.get(); if (resp.isSuccess() && resp.getData() != null) { SiteInfo siteInfo = (SiteInfo) resp.getData(); if (StringUtils.isNotBlank(siteInfo.getSiteName())) { return siteInfo.getSiteName().trim(); } } } catch (Exception e) { log.warn("读取站点名称失败,使用默认短信签名", e); } return "滁州炬亿科技"; } }