1
zj
9 hours ago d615fc515fc52d6ed970c11d59a017e48de4be32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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 "滁州炬亿科技";
    }
}