package com.backendsys.modules.sms.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.backendsys.exception.CustException; import com.backendsys.modules.common.config.redis.utils.RedisUtil; import com.backendsys.modules.common.config.security.utils.HttpRequestUtil; import com.backendsys.modules.sdk.tencentcloud.sms.service.TencentSmsService; import com.backendsys.modules.sms.dao.SmsDao; import com.backendsys.modules.sms.entity.Sms; import com.backendsys.utils.response.ResultEnum; import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse; import com.tencentcloudapi.sms.v20210111.models.SendStatus; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.Map; import java.util.concurrent.TimeUnit; @Slf4j @Service public class SmsServiceImpl implements com.backendsys.modules.sms.service.SmsService { @Autowired private RedisUtil redisUtil; @Autowired private HttpRequestUtil httpRequestUtil; @Autowired private TencentSmsService tencentSmsService; @Autowired private SmsDao smsDao; // [模板] 通用验证码 @Value("${tencent.sms.template-id-of-common}") private String TEMPLATE_ID_COMMON; @Value("${spring.application.name}") private String APPLICATION_NAME; /** * 发送验证码 */ @Override public Map sendValidCode(Sms sms) throws TencentCloudSDKException { String origin = sms.getOrigin(); String phone = sms.getPhone(); Integer phoneAreaCode = sms.getPhone_area_code(); Integer smsExpire = 5; Integer smsCode = RandomUtil.randomInt(100000, 999999); // 生成一个6位的随机整数 (验证码) (5分钟失效) sms.setSms_code(smsCode); // -- 腾讯云短信 ------------------------------------------------ // 模板参数 {1} 验证码, {2} 过期时间(分钟) // 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空 String[] templateParamSet = {String.valueOf(smsCode), String.valueOf(smsExpire)}; // 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号] // 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 String[] phoneNumberSet = {"+" + phoneAreaCode + phone}; SendSmsResponse sendSmsResponse = tencentSmsService.send(TEMPLATE_ID_COMMON, templateParamSet, phoneNumberSet); if (sendSmsResponse != null) { SendStatus[] response = sendSmsResponse.getSendStatusSet(); if (response.length > 0) { // for (int i = 0; i < sendStatuses.length; ++i) { if (response[0] != null && !response[0].getCode().equals("Ok")) { // String sendStatusStr = JSONUtil.toJsonStr(sendStatuses[0]); if (response.length > 1) { throw new CustException("发送失败", ResultEnum.REMOTE_EXCEPTION.getCode(), response[1]); } else { JSONObject sendStatusesObj = JSONUtil.parseObj(response[0]); System.out.println("sendStatusesObj = " + sendStatusesObj); String message = Convert.toStr(sendStatusesObj.get("Message")); System.out.println("message = " + message); throw new CustException(message, ResultEnum.REMOTE_EXCEPTION.getCode(), message); } } } } // ------------------------------------------------------------ // -- 发送成功 -------------------------------------------------- // [Redis] 将 来源+手机号码 为标识,将验证码存入缓存 String originStr = StrUtil.isNotBlank(origin) ? (origin + "-") : ""; String redisKey = APPLICATION_NAME + "-sms-" + originStr + phone; redisUtil.setCacheObject(redisKey, smsCode, smsExpire, TimeUnit.MINUTES); // [插入] 新增短信记录 sms.setIp(httpRequestUtil.getIpAddr()); sms.setUa(httpRequestUtil.getUa()); smsDao.insert(sms); return Map.of("phone", sms.getPhone()); } }