1.院后小程序登录接口2.封装短信发送工具类3.小程序登陆时发送短信与验证

This commit is contained in:
youxilong 2024-07-03 17:59:38 +08:00
parent a9238baa3f
commit 17738ada5e
15 changed files with 732 additions and 7 deletions

View File

@ -9,7 +9,7 @@ xinelu:
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/postdischarge/uploadPathLinux配置 /home/postdischarge/uploadPath
profile: D:/postdischarge/uploadPath
profile: E:/postdischarge/uploadPath
# 签约知情书上传
sign-informed-file-url: /signInformed
# 素材库封面上传
@ -223,4 +223,24 @@ wechat-official-account-config:
# 微信公众号事件回调消息加密密钥
official-account-encoding-aes-key: Awcn7nvDU4bcfBwAZmiRbB3lFgXAm2RIg45utdb5Zt3
# 测试模板id
test-template-id: WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc
test-template-id: WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc
# 阿里云参数配置
aliyun-sms:
# AccessKey ID
accessKeyId: LTAIo6vpMk2441nc
# AccessKey Secret
accessKeySecret: JxPKD3Vx404QsZ3SvYSai1wuOlyRtR
# 产品名称:云通信短信API产品,开发者无需替换
product: Dysmsapi
# 产品域名,开发者无需替换
domain: dysmsapi.aliyuncs.com
# 地域ID
regionId: cn-qingdao
# 阿里云登录确认验证模板-短信签名
signName: 新医路
# 阿里云登录确认验证模板-模板CODE
templateCode: SMS_152466667
# 阿里云登录确认验证模板-模板内容
templateContent: 验证码${code},您正在登录,若非本人操作,请勿泄露。

View File

@ -0,0 +1,53 @@
package com.xinelu.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @program: PostDischargePatientManage
* @description: 阿里云参数配置
* @author: yxl
* @create: 2024-07-02 20:48
**/
@Data
@Component
@ConfigurationProperties(prefix = "aliyun-sms")
public class AliYunSmsConfig {
/**
* AccessKey ID
*/
private String accessKeyId;
/**
* AccessKey Secret
*/
private String accessKeySecret;
/**
* 产品名称:云通信短信API产品,开发者无需替换
*/
private String product;
/**
* 产品域名,开发者无需替换
*/
private String domain;
/**
* 地域ID
*/
private String regionId;
/**
* 阿里云登录确认验证模板-模板签名
*/
private String signName;
/**
* 阿里云登录确认验证模板-模板CODE
*/
private String templateCode;
}

View File

@ -368,4 +368,22 @@ public class Constants {
* 常用术语最小层数
*/
public static final Long TERM_MIN_LEVEL = 1L;
/**
* 登录发送短信验证冷却键前缀
*/
public static final String SMS_COOL_DOWN ="SMS_COOL_DOWN_";
/**
* 登录发送短信验证冷却键对应的值
*/
public static final String SMS_COOL_DOWN_VALUE ="COOL_DOWN";
/**
* 登录发送短信验证前缀
*/
public static final String SMS_CODE ="SMS_CODE_";
}

View File

@ -0,0 +1,236 @@
package com.xinelu.common.enums;
import lombok.Getter;
/**
* 短信发送失败错误码枚举
*/
@Getter
public enum SmsErrorCodeEnum {
/**
* RAM权限不足
*/
RAM_PERMISSION_DENY("isp.RAM_PERMISSION_DENY", "RAM权限不足"),
/**
* 业务停机
*/
OUT_OF_SERVICE("isv.OUT_OF_SERVICE", "业务停机"),
/**
* 未开通云通信产品的阿里云客户
*/
PRODUCT_UN_SUBSCRIPT("isv.PRODUCT_UN_SUBSCRIPT", "未开通云通信产品的阿里云客户"),
/**
* 产品未开通
*/
PRODUCT_UNSUBSCRIBE("isv.PRODUCT_UNSUBSCRIBE", "产品未开通"),
/**
* 账户不存在
*/
ACCOUNT_NOT_EXISTS("isv.ACCOUNT_NOT_EXISTS", "账户不存在"),
/**
* 账户异常
*/
ACCOUNT_ABNORMAL("isv.ACCOUNT_ABNORMAL", "账户异常"),
/**
* 该账号下找不到对应模板
*/
SMS_TEMPLATE_ILLEGAL("isv.SMS_TEMPLATE_ILLEGAL", "该账号下找不到对应模板"),
/**
* 测试模板和签名限制
*/
SMS_TEST_SIGN_TEMPLATE_LIMIT("isv.SMS_TEST_SIGN_TEMPLATE_LIMIT", "测试模板和签名限制"),
/**
* 签名和模板类型不一致
*/
SMS_SIGNATURE_SCENE_ILLEGAL("isv.SMS_SIGNATURE_SCENE_ILLEGAL", "签名和模板类型不一致"),
/**
* 签名禁止使用
*/
SMS_SIGN_ILLEGAL("isv.SMS_SIGN_ILLEGAL", "签名禁止使用"),
/**
* 该账号下找不到对应签名
*/
SMS_SIGNATURE_ILLEGAL("isv.SMS_SIGNATURE_ILLEGAL", "该账号下找不到对应签名"),
/**
* 系统出现错误请重新调用
*/
SYSTEM_ERROR("isp.SYSTEM_ERROR", "系统出现错误,请重新调用"),
/**
* 手机号码格式错误
*/
MOBILE_NUMBER_ILLEGAL("isv.MOBILE_NUMBER_ILLEGAL", "手机号码格式错误"),
/**
* 手机号码数量超过限制最多支持1000条
*/
MOBILE_COUNT_OVER_LIMIT("isv.MOBILE_COUNT_OVER_LIMIT", "手机号码数量超过限制最多支持1000条"),
/**
* 模板变量中存在未赋值变量
*/
TEMPLATE_MISSING_PARAMETERS("isv.TEMPLATE_MISSING_PARAMETERS", "模板变量中存在未赋值变量"),
/**
* 传入的变量内容和实际申请模板时变量所选择的属性类型不配
*/
TEMPLATE_PARAMS_ILLEGAL("isv.TEMPLATE_PARAMS_ILLEGAL", "传入的变量内容和实际申请模板时变量所选择的属性类型不配"),
/**
* 超过单自然日模板申请数量上限
*/
TEMPLATE_COUNT_OVER_LIMIT("isv.TEMPLATE_COUNT_OVER_LIMIT", "超过单自然日模板申请数量上限"),
/**
* 模板字符数量超过限制
*/
TEMPLATE_OVER_LIMIT("isv.TEMPLATE_OVER_LIMIT", "模板字符数量超过限制"),
/**
* 触发云通信流控限制
*/
BUSINESS_LIMIT_CONTROL("isv.BUSINESS_LIMIT_CONTROL", "触发云通信流控限制"),
/**
* 参数格式错误请修改为字符串值
*/
INVALID_JSON_PARAM("isv.INVALID_JSON_PARAM", "参数格式错误,请修改为字符串值"),
/**
* 参数格式不正确
*/
INVALID_PARAMETERS("isv.INVALID_PARAMETERS", "参数格式不正确"),
/**
* 变量中传入疑似违规信息
*/
BLACK_KEY_CONTROL_LIMIT("isv.BLACK_KEY_CONTROL_LIMIT", "变量中传入疑似违规信息"),
/**
* 参数超过长度限制
*/
PARAM_LENGTH_LIMIT("isv.PARAM_LENGTH_LIMIT", "参数超过长度限制"),
/**
* 变量不支持传入URL
*/
PARAM_NOT_SUPPORT_URL("isv.PARAM_NOT_SUPPORT_URL", "变量不支持传入URL"),
/**
* 账户余额不足
*/
AMOUNT_NOT_ENOUGH("isv.AMOUNT_NOT_ENOUGH", "账户余额不足"),
/**
* 关键字拦截
*/
FILTER("FILTER", "关键字拦截"),
/**
* 重复过滤
*/
VALVE_MC("VALVE:M_MC", "重复过滤"),
/**
* 单个号码日或月发送上限流控超限频繁发送超限
*/
MOBILE_SEND_LIMIT("MOBILE_SEND_LIMIT", "单个号码日或月发送上限,流控超限,频繁发送超限"),
/**
* 手机号在黑名单平台或运营商
*/
MOBILE_IN_BLACK("MOBILE_IN_BLACK", "手机号在黑名单(平台或运营商)"),
/**
* 手机终端问题内存满SIM卡满非法设备等
*/
MOBILE_TERMINAL_ERROR("MOBILE_TERMINAL_ERROR", "手机终端问题、内存满、SIM卡满、非法设备等"),
/**
* 未开通国际短信
*/
SP_NOT_BY_INTER_SMS("SP_NOT_BY_INTER_SMS", "未开通国际短信"),
/**
* 用户手机退订此业务产品未开通
*/
USER_REJECT("USER_REJECT", "用户手机退订此业务、产品未开通"),
/**
* 运营商未知错误
*/
SP_UNKNOWN_ERROR("SP_UNKNOWN_ERROR", "运营商未知错误"),
/**
* 用户账户异常携号转网欠费等
*/
MOBILE_ACCOUNT_ABNORMAL("MOBILE_ACCOUNT_ABNORMAL", "用户账户异常、携号转网、欠费等"),
/**
* 消息发送成功
*/
DELIVERED("DELIVERED", "消息发送成功"),
/**
* 内容关键字拦截
*/
CONTENT_KEYWORD("CONTENT_KEYWORD", "内容关键字拦截"),
/**
* 签名黑名单
*/
SIGNATURE_BLACKLIST("SIGNATURE_BLACKLIST", "签名黑名单"),
/**
* 号码不合法
*/
INVALID_NUMBER("INVALID_NUMBER", "号码不合法"),
/**
* 无路由器
*/
NO_ROUTE("NO_ROUTE", "无路由器"),
/**
* 模板内容无退订
*/
CONTENT_ERROR("CONTENT_ERROR", "模板内容无退订"),
/**
* 未知错误
*/
UNKNOWN_ERROR("UNKNOWN_ERROR", "未知错误");
private final String code;
private final String message;
SmsErrorCodeEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getMessage() {
return message;
}
public static SmsErrorCodeEnum getMsgByCode(String code) {
for (SmsErrorCodeEnum errorCode : SmsErrorCodeEnum.values()) {
if (errorCode.code.equals(code)) {
return errorCode;
}
}
return UNKNOWN_ERROR;
}
}

View File

@ -1,5 +1,7 @@
package com.xinelu.common.utils.uuid;
import java.security.SecureRandom;
/**
* ID生成器工具类
*
@ -41,4 +43,14 @@ public class IdUtils {
public static String fastSimpleUUID() {
return UUID.fastUUID().toString(true);
}
/**
* SecureRandom生成六位随机数
* @return 六位随机数
*/
public static int generateSixDigitNumber() {
SecureRandom random = new SecureRandom();
// // 100000 (inclusive) to 999999 (inclusive)
return 100000 + random.nextInt(900000);
}
}

View File

@ -69,4 +69,7 @@ public interface ResidentInfoMapper {
* @return 被护理人基本信息
*/
ResidentInfo getResidentInfoByPhoneAndOpenId(@Param("phone") String phone, @Param("openId") String openId);
List<ResidentInfo> getResidentInfoByPhoneAndName(@Param("phone") String phone, @Param("patientName") String patientName);
}

View File

@ -197,4 +197,17 @@
</if>
</where>
</select>
<select id="getResidentInfoByPhoneAndName" resultType="com.xinelu.manage.domain.residentinfo.ResidentInfo">
<include refid="selectResidentInfoVo" />
<where>
del_flag = 0
<if test="phone != null and phone != ''">
and patient_phone = #{phone}
</if>
<if test="patientName != null and patientName != ''">
and patient_name = #{patientName}
</if>
</where>
</select>
</mapper>

View File

@ -39,5 +39,12 @@
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
</dependency>
<!--阿里云发送短信-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alicloud-sms</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies>
</project>

View File

@ -1,5 +1,12 @@
package com.xinelu.mobile.controller;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.utils.uuid.IdUtils;
import com.xinelu.mobile.dto.smssend.SmsInfoDTO;
import com.xinelu.mobile.utils.SmsSendUtils;
import com.xinelu.mobile.utils.WeChatAppletUtils;
import com.xinelu.mobile.utils.WeChatOfficialAccountUtils;
import com.xinelu.mobile.vo.wechatofficialaccountcallback.PatientVO;
@ -22,6 +29,10 @@ public class MobileTestController {
private WeChatAppletUtils weChatAppletUtils;
@Resource
private WeChatOfficialAccountUtils weChatOfficialAccountUtils;
@Resource
private SmsSendUtils smsSendUtils;
@Resource
private AliYunSmsConfig aliYunSmsConfig;
/**
* 测试获取微信小程序accessToken
@ -54,4 +65,25 @@ public class MobileTestController {
public void sendAppletTemplate(PatientVO patientVO) {
weChatOfficialAccountUtils.sendAppletTemplateMessage(patientVO);
}
/**
*发送短信验证
*/
@GetMapping("/sendSms")
public AjaxResult sendAppletTemplate(String phoneNum) throws ClientException {
SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
smsInfoDTO.setPhoneNumbers(phoneNum);
smsInfoDTO.setSignName(aliYunSmsConfig.getSignName());
smsInfoDTO.setTemplateCode(aliYunSmsConfig.getTemplateCode());
// 生成六位数验证码
String code = String.valueOf(IdUtils.generateSixDigitNumber());
JSONObject obj = new JSONObject();
obj.put("code", code);
smsInfoDTO.setTemplateParam(obj);
Boolean b = smsSendUtils.sendSms(smsInfoDTO);
if (!b) {
return AjaxResult.error("短信发送失败");
}
return AjaxResult.success("短信发送成功");
}
}

View File

@ -4,12 +4,11 @@ import com.xinelu.common.core.controller.BaseController;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.page.TableDataInfo;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO;
import com.xinelu.mobile.dto.verifysmscode.VerifySmsCodeDTO;
import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@ -80,4 +79,40 @@ public class AppletPersonCenterController extends BaseController {
return AjaxResult.success(appletPersonCenterService.getHealthRecordInfoById(id));
}
@ApiOperation("院后微信小程序登录接口")
@GetMapping("/appletLoginV1")
public AjaxResult appletLoginV1(@RequestParam("loginCode") String loginCode) {
if (StringUtils.isBlank(loginCode)) {
return AjaxResult.error("登录凭证编码不能为空!");
}
return appletPersonCenterService.appletLoginV1(loginCode);
}
@ApiOperation("小程序登录发送短信验证码")
@GetMapping("/sendSms")
public AjaxResult sendSms(String phoneNum) {
if (StringUtils.isBlank(phoneNum)) {
return AjaxResult.error("手机号码不能为空!");
}
return appletPersonCenterService.sendSms(phoneNum);
}
@ApiOperation("小程序登录验证短信验证码")
@PostMapping("/verifySmsCode")
public AjaxResult verifySmsCode(@RequestBody VerifySmsCodeDTO verifySmsCodeDTO) {
if (StringUtils.isBlank(verifySmsCodeDTO.getOpenId())) {
return AjaxResult.error("微信小程序openid不能为空!");
}
if (StringUtils.isBlank(verifySmsCodeDTO.getPhoneNum())) {
return AjaxResult.error("手机号不能为空!");
}
if (StringUtils.isBlank(verifySmsCodeDTO.getPatientName())) {
return AjaxResult.error("姓名不能为空");
}
if (StringUtils.isBlank(verifySmsCodeDTO.getSmsCode())) {
return AjaxResult.error("短信验证码不能为空!");
}
return appletPersonCenterService.verifySmsCode(verifySmsCodeDTO);
}
}

View File

@ -0,0 +1,34 @@
package com.xinelu.mobile.dto.smssend;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
/**
* @program: PostDischargePatientManage
* @description: 短信发送参数DTO
* @author: yxl
* @create: 2024-07-02 21:05
**/
@Data
public class SmsInfoDTO {
/**
* :短信签名
*/
private String signName;
/**
* 待发送手机号多个用逗号隔开
*/
private String phoneNumbers;
/**
* 短信模板Code
*/
private String templateCode;
/**
* 模板中的变量替换JSON串
*/
private JSONObject templateParam;
}

View File

@ -0,0 +1,27 @@
package com.xinelu.mobile.dto.verifysmscode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @program: PostDischargePatientManage
* @description: 验证短信验证码DTO
* @author: yxl
* @create: 2024-07-03 14:58
**/
@Data
public class VerifySmsCodeDTO {
@ApiModelProperty(value = "微信小程序openid")
private String openId;
@ApiModelProperty(value = "手机号")
private String phoneNum;
@ApiModelProperty(value = "姓名")
private String patientName;
@ApiModelProperty(value = "短信验证码")
private String smsCode;
}

View File

@ -3,6 +3,7 @@ package com.xinelu.mobile.service.appletpersoncenter;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordInfoDTO;
import com.xinelu.mobile.dto.verifysmscode.VerifySmsCodeDTO;
import java.util.List;
@ -48,4 +49,25 @@ public interface AppletPersonCenterService {
*/
HealthRecordInfoDTO getHealthRecordInfoById(Long id);
/**
* 院后微信小程序登录接口
* @param loginCode 登录凭证
* @return 微信小程序用户登录信息
*/
AjaxResult appletLoginV1(String loginCode);
/**
* 小程序登录发送验证码
* @param phoneNum 手机号码
* @return 发送短信验证码信息
*/
AjaxResult sendSms(String phoneNum);
/**
* 小程序登录验证短信验证码
* @param verifySmsCodeDTO 验证短信验证码DTO
* @return 验证短信验证码信息
*/
AjaxResult verifySmsCode(VerifySmsCodeDTO verifySmsCodeDTO);
}

View File

@ -1,26 +1,36 @@
package com.xinelu.mobile.service.appletpersoncenter.Impl;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.config.WeChatAppletChatConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.utils.uuid.IdUtils;
import com.xinelu.manage.domain.residentinfo.ResidentInfo;
import com.xinelu.manage.mapper.residentinfo.ResidentInfoMapper;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordDTO;
import com.xinelu.mobile.dto.appletpersoncenter.HealthRecordInfoDTO;
import com.xinelu.mobile.dto.smssend.SmsInfoDTO;
import com.xinelu.mobile.dto.verifysmscode.VerifySmsCodeDTO;
import com.xinelu.mobile.mapper.appletpersoncenter.AppletPersonCenterMapper;
import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService;
import com.xinelu.mobile.utils.SmsSendUtils;
import com.xinelu.mobile.utils.WeChatAppletUtils;
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletPhoneVO;
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* @Description 院后小程序个人中心业务层实现类
@ -37,12 +47,17 @@ public class AppletPersonCenterServiceImpl implements AppletPersonCenterService
@Resource
private WeChatAppletChatConfig weChatAppletChatConfig;
@Resource
private RedisTemplate<String, Object> redisTemplate;
private RedisTemplate<String, String> redisTemplate;
@Resource
private ResidentInfoMapper residentInfoMapper;
@Resource
private AppletPersonCenterMapper appletPersonCenterMapper;
@Resource
private SmsSendUtils smsSendUtils;
@Resource
private AliYunSmsConfig aliYunSmsConfig;
/**
* 院后微信小程序一键登录接口
*
@ -156,4 +171,116 @@ public class AppletPersonCenterServiceImpl implements AppletPersonCenterService
}
return healthRecordInfoDTO;
}
/**
* 院后微信小程序登录接口
*
* @param loginCode 登录凭证
* @return 微信小程序用户登录信息
*/
@Override
public AjaxResult appletLoginV1(String loginCode) {
//根据code获取用户的微信unionId以及openId等信息
PostDischargeAppletVO appletLoginInfo = weChatAppletUtils.getPostDischargeAppletLogin(weChatAppletChatConfig.getAppletId(), weChatAppletChatConfig.getSecret(), loginCode, weChatAppletChatConfig.getGrantType());
if (Objects.isNull(appletLoginInfo)) {
return AjaxResult.error("获取院后微信小程序用户信息失败");
}
if (Objects.nonNull(appletLoginInfo.getErrcode()) && appletLoginInfo.getErrcode() != Constants.SUCCESS_CODE) {
return AjaxResult.error("获取院后微信小程序用户信息失败,失败信息为:" + appletLoginInfo.getErrmsg());
}
String openId = StringUtils.isBlank(appletLoginInfo.getOpenid()) ? "" : appletLoginInfo.getOpenid();
ResidentInfo residentInfo = residentInfoMapper.getResidentInfoByPhoneAndOpenId(null, openId);
if (ObjectUtils.isEmpty(residentInfo)) {
return AjaxResult.success("未注册", openId);
}
return AjaxResult.success("已注册", residentInfo);
}
/**
* 小程序登录发送验证码
*
* @param phoneNum 手机号码
* @return 发送短信验证码信息
*/
@Override
public AjaxResult sendSms(String phoneNum) {
try {
String coolDownKey = Constants.SMS_COOL_DOWN + phoneNum;
String cacheKey = Constants.SMS_CODE + phoneNum;
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
// 检查是否处于冷却期
if (valueOperations.get(coolDownKey) != null) {
return AjaxResult.error("请等待60秒后再尝试发送验证码");
}
// 生成并发送新的验证码
SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
smsInfoDTO.setPhoneNumbers(phoneNum);
smsInfoDTO.setSignName(aliYunSmsConfig.getSignName());
smsInfoDTO.setTemplateCode(aliYunSmsConfig.getTemplateCode());
String code = String.valueOf(IdUtils.generateSixDigitNumber());
JSONObject obj = new JSONObject();
obj.put("code", code);
smsInfoDTO.setTemplateParam(obj);
Boolean b = smsSendUtils.sendSms(smsInfoDTO);
if (!b) {
log.error("短信发送失败,手机号:{}", phoneNum);
return AjaxResult.error("短信发送失败");
}
// 更新验证码和冷却键
valueOperations.set(cacheKey, code, 5, TimeUnit.MINUTES);
valueOperations.set(coolDownKey, Constants.SMS_COOL_DOWN_VALUE, 60, TimeUnit.SECONDS);
log.info("手机号为{}的验证码已经生成", phoneNum);
return AjaxResult.success("短信发送成功");
} catch (ClientException e) {
log.error("短信发送失败,手机号:{},错误原因:{}", phoneNum, e.getMessage(), e);
return AjaxResult.error("短信发送失败");
}
}
/**
* 小程序登录验证短信验证码
*
* @param verifySmsCodeDTO 验证短信验证码DTO
* @return 验证短信验证码信息
*/
@Override
public AjaxResult verifySmsCode(VerifySmsCodeDTO verifySmsCodeDTO) {
try {
String openId = verifySmsCodeDTO.getOpenId();
String smsCode = verifySmsCodeDTO.getSmsCode();
String cacheKey = Constants.SMS_CODE + verifySmsCodeDTO.getPhoneNum();
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
String storedCode = valueOperations.get(cacheKey);
if (storedCode == null) {
log.info("验证码已过期,手机号:{}", verifySmsCodeDTO.getPhoneNum());
return AjaxResult.error("验证码已过期,请重新获取!");
}
if (!storedCode.equals(smsCode)) {
log.info("验证码验证失败,手机号:{},输入的验证码:{},获取的验证码:{}", verifySmsCodeDTO.getPhoneNum(), smsCode, storedCode);
return AjaxResult.error("验证码错误,请重新输入!");
}
log.info("验证码验证成功,手机号:{}", verifySmsCodeDTO.getPhoneNum());
List<ResidentInfo> residentInfos = residentInfoMapper.getResidentInfoByPhoneAndName(verifySmsCodeDTO.getPhoneNum(), verifySmsCodeDTO.getPatientName());
if (residentInfos == null || residentInfos.isEmpty()) {
return AjaxResult.error("您的用户信息尚未录入系统,无法执行注册操作!");
} else if (residentInfos.size() > 1) {
// 存在姓名和手机号重复的情况
return AjaxResult.error("您的信息存在重复记录,请联系管理员进行操作!");
}
ResidentInfo residentInfo = residentInfos.get(0);
residentInfo.setOpenId(openId);
residentInfoMapper.updateResidentInfo(residentInfo);
return AjaxResult.success("注册成功!", residentInfo);
} catch (Exception e) {
log.error("验证验证码时发生异常,手机号:{},异常信息:{}", verifySmsCodeDTO.getPhoneNum(), e.getMessage(), e);
return AjaxResult.error("短信验证码验证失败!");
}
}
}

View File

@ -0,0 +1,86 @@
package com.xinelu.mobile.utils;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.xinelu.common.config.AliYunSmsConfig;
import com.xinelu.common.enums.SmsErrorCodeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.mobile.dto.smssend.SmsInfoDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @program: PostDischargePatientManage
* @description: 短信发送工具类
* @author: yxl
* @create: 2024-07-02 20:50
**/
@Component
@Slf4j
public class SmsSendUtils {
private static final String SUCCESS = "OK";
@Resource
private AliYunSmsConfig aliyunSmsConfig;
/**
* 发送短信
*/
public Boolean sendSms(SmsInfoDTO smsInfoDTO) throws ClientException, ServiceException {
try {
// 短信发送参数非空性判断
if (ObjectUtils.isEmpty(smsInfoDTO)) {
throw new ServiceException("短信发送参数不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getPhoneNumbers())) {
throw new ServiceException("待发送手机号不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getSignName())) {
throw new ServiceException("短信签名不能为空!");
}
if (StringUtils.isBlank(smsInfoDTO.getTemplateCode())) {
throw new ServiceException("短信模板Code不能为空!");
}
// 设置系统的默认连接超时时间和读取超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
// 初始化acsClient暂不支持region化
IClientProfile profile = DefaultProfile.getProfile(aliyunSmsConfig.getRegionId(), aliyunSmsConfig.getAccessKeyId(), aliyunSmsConfig.getAccessKeySecret());
DefaultProfile.addEndpoint(aliyunSmsConfig.getRegionId(), aliyunSmsConfig.getProduct(), aliyunSmsConfig.getDomain());
IAcsClient acsClient = new DefaultAcsClient(profile);
// 组装请求对象
SendSmsRequest request = new SendSmsRequest();
request.setPhoneNumbers(smsInfoDTO.getPhoneNumbers());
request.setSignName(smsInfoDTO.getSignName());
request.setTemplateCode(smsInfoDTO.getTemplateCode());
request.setTemplateParam(smsInfoDTO.getTemplateParam().toJSONString());
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
// 判断响应的结果
if (!SUCCESS.equals(sendSmsResponse.getCode())) {
SmsErrorCodeEnum errorCode = SmsErrorCodeEnum.getMsgByCode(sendSmsResponse.getCode());
log.error("短信发送失败,错误码:{},错误信息:{}", sendSmsResponse.getCode(), errorCode.getMessage());
return false;
}
log.info("短信发送成功code{}", sendSmsResponse.getCode());
return true;
} catch (ClientException e) {
log.error("发送短信出现异常,异常信息:{}", e.getMessage());
throw e;
}
}
}