瀏覽代碼

add send captcha

张延森 5 年之前
父節點
當前提交
9cb0124623

+ 134
- 0
src/main/java/com/huiju/estateagents/common/SMSUtils.java 查看文件

1
+package com.huiju.estateagents.common;
2
+
3
+import com.huiju.estateagents.config.SMSProperties;
4
+import lombok.Data;
5
+import lombok.extern.slf4j.Slf4j;
6
+import org.springframework.beans.factory.annotation.Autowired;
7
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
8
+import org.springframework.context.annotation.Configuration;
9
+import org.springframework.http.*;
10
+import org.springframework.web.client.RestTemplate;
11
+
12
+import java.time.LocalDateTime;
13
+import java.util.*;
14
+
15
+@Slf4j
16
+@Configuration
17
+@EnableConfigurationProperties(SMSProperties.class)
18
+public class SMSUtils {
19
+    // 短信服务配置
20
+    SMSProperties smsProperties;
21
+
22
+    Map<String, Phone> allPhones;
23
+
24
+    @Autowired
25
+    public SMSUtils(SMSProperties properties) {
26
+        smsProperties = properties;
27
+        allPhones = new HashMap<>();
28
+    }
29
+
30
+    /**
31
+     * 发送验证码到 tel
32
+     * @param tel
33
+     * @return
34
+     */
35
+    public boolean sendCaptcha(String tel) {
36
+        Phone phone = allPhones.get(tel);
37
+        if (null == phone) {
38
+            phone = new Phone();
39
+            phone.setTel(tel);
40
+        }
41
+
42
+        phone.setCaptcha(genCaptcha(smsProperties.getCaptcha().getSize()));
43
+        phone.setExpire(LocalDateTime.now().plusSeconds(smsProperties.getCaptcha().getExpire()));
44
+        allPhones.put(tel, phone);
45
+
46
+        log.info("发送手机 {} 验证码 {}", tel, phone.getCaptcha());
47
+
48
+        String[] params = { phone.getCaptcha(), smsProperties.getCaptcha().getSign() };
49
+        return sendMessage(smsProperties.getCaptcha().getCode(), tel, params);
50
+    }
51
+
52
+    /**
53
+     * 校验验证码
54
+     * @param tel
55
+     * @param smsCaptcha
56
+     * @return
57
+     */
58
+    public boolean checkCaptcha(String tel, String smsCaptcha) {
59
+        Phone phone = allPhones.get(tel);
60
+        if (null == phone) {
61
+            log.error("手机号 {} 的验证码未找到", tel);
62
+            return false;
63
+        }
64
+
65
+        if (null == smsCaptcha || !smsCaptcha.equals(phone.getCaptcha())) {
66
+            log.error("手机号 {} 校验验证码出错, 正确: {}, 错误: {}", tel, phone.getCaptcha(), smsCaptcha);
67
+            return false;
68
+        }
69
+
70
+        LocalDateTime now = LocalDateTime.now();
71
+        if (now.isAfter(phone.getExpire())) {
72
+            log.error("手机号 {} 的验证码已过期", tel);
73
+            return false;
74
+        }
75
+
76
+        // 如果验证成功, 则从缓存中删除
77
+        allPhones.remove(tel);
78
+        return true;
79
+    }
80
+
81
+    public boolean sendVisitor(String tel, String name) {
82
+        log.info("发送手机 {} 客户名称 {}", tel, name);
83
+
84
+        String[] params = { name };
85
+        return sendMessage(smsProperties.getVisitor().getCode(), tel, params);
86
+    }
87
+
88
+    private String genCaptcha(int length) {
89
+        List<String> nums = new ArrayList<>();
90
+        for (int i = 0; i < length; i ++) {
91
+            int rand = (new Random()).nextInt(10);
92
+            nums.add(String.valueOf(rand));
93
+        }
94
+        return String.join("", nums);
95
+    }
96
+
97
+    private boolean sendMessage(String code, String tel, String[] params) {
98
+        // 发送内容
99
+        SMSProperties.Template message = new SMSProperties.Template();
100
+        message.setCode(code);
101
+        message.setTel(tel);
102
+        message.setParams(params);
103
+
104
+        // 构造 request
105
+        HttpHeaders headers = new HttpHeaders();
106
+        headers.setContentType(MediaType.parseMediaType(smsProperties.getContentType()));
107
+//        String body = JSONObject.toJSONString(message);
108
+        HttpMethod method = HttpMethod.resolve(smsProperties.getMethod());
109
+        HttpEntity requestEntity = new HttpEntity(message, headers);
110
+
111
+        RestTemplate template = new RestTemplate();
112
+        HttpEntity<String> response = template.exchange(
113
+                smsProperties.getUrl(),
114
+                method,
115
+                requestEntity,
116
+                String.class,
117
+                new Object()
118
+        );
119
+
120
+        if (((ResponseEntity<String>) response).getStatusCodeValue() != HttpStatus.OK.value()) {
121
+            log.error("请求发送短信验证码失败: {}", response.toString());
122
+            return false;
123
+        }
124
+
125
+        return true;
126
+    }
127
+
128
+    @Data
129
+    public static class Phone {
130
+        String tel;
131
+        String captcha;
132
+        LocalDateTime expire;
133
+    }
134
+}

+ 35
- 0
src/main/java/com/huiju/estateagents/config/SMSProperties.java 查看文件

1
+package com.huiju.estateagents.config;
2
+
3
+
4
+import lombok.Data;
5
+import org.springframework.boot.context.properties.ConfigurationProperties;
6
+
7
+@Data
8
+@ConfigurationProperties(prefix = "sms")
9
+public class SMSProperties {
10
+    String url;
11
+    String method;
12
+    String contentType;
13
+    Captcha captcha;
14
+    Visitor visitor;
15
+
16
+    @Data
17
+    public static class Template {
18
+        String code;
19
+        String tel;
20
+        String[] params;
21
+    }
22
+
23
+    @Data
24
+    public static class Captcha {
25
+        String code;
26
+        Integer expire;
27
+        Integer size;
28
+        String sign;
29
+    }
30
+
31
+    @Data
32
+    public static class Visitor {
33
+        String code;
34
+    }
35
+}

+ 14
- 0
src/main/java/com/huiju/estateagents/controller/CommonController.java 查看文件

4
 import com.huiju.estateagents.base.ResponseBean;
4
 import com.huiju.estateagents.base.ResponseBean;
5
 import com.huiju.estateagents.common.AliOSSUtils;
5
 import com.huiju.estateagents.common.AliOSSUtils;
6
 import com.huiju.estateagents.common.CommConstant;
6
 import com.huiju.estateagents.common.CommConstant;
7
+import com.huiju.estateagents.common.SMSUtils;
7
 import com.huiju.estateagents.common.StringUtils;
8
 import com.huiju.estateagents.common.StringUtils;
8
 import org.apache.ibatis.annotations.Mapper;
9
 import org.apache.ibatis.annotations.Mapper;
10
+import org.springframework.beans.factory.annotation.Autowired;
9
 import org.springframework.web.bind.annotation.*;
11
 import org.springframework.web.bind.annotation.*;
10
 import org.springframework.web.multipart.MultipartFile;
12
 import org.springframework.web.multipart.MultipartFile;
11
 
13
 
18
 @RestController
20
 @RestController
19
 @RequestMapping("/api")
21
 @RequestMapping("/api")
20
 public class CommonController {
22
 public class CommonController {
23
+    @Autowired
24
+    SMSUtils smsUtils;
21
 
25
 
22
     /**
26
     /**
23
      * 图片上传
27
      * 图片上传
60
         return result;
64
         return result;
61
     }
65
     }
62
 
66
 
67
+    @PostMapping("{plat}/captcha")
68
+    public ResponseBean sendCaptcha(@RequestParam String tel) {
69
+        boolean success = smsUtils.sendCaptcha(tel);
70
+        if (success) {
71
+            return ResponseBean.success("发送验证码成功");
72
+        } else {
73
+            return ResponseBean.error("验证码发送失败, 请重试", ResponseBean.ERROR_UNAVAILABLE);
74
+        }
75
+    }
76
+
63
     @GetMapping("/wx/awesome/dict/{typeFor}")
77
     @GetMapping("/wx/awesome/dict/{typeFor}")
64
     public ResponseBean dicts(@PathVariable String typeFor) {
78
     public ResponseBean dicts(@PathVariable String typeFor) {
65
 
79