support sms login

This commit is contained in:
Timi
2026-08-21 18:13:58 +08:00
parent aff056712e
commit 1b8936f197
12 changed files with 175 additions and 158 deletions
@@ -1,30 +1,30 @@
//package com.imyeyu.api.modules.common.service;
//
//import com.e2ins.ms.notify.entity.Notify;
//import com.e2ins.ms.notify.entity.NotifyDetail;
//
///**
// *
// *
// * @author 夜雨
// * @since 2026-05-14 12:12
// */
//public interface SmsService {
//
// /**
// * 创建短信验证码通知
// *
// * @param detail 通知
// * @return 通知详情 ID
// */
// String captchaCreate(Notify detail);
//
// /**
// * 校验短信验证码
// *
// * @param detailId 通知详情 ID
// * @param captcha 请求验证码
// * @return 通知详情
// */
// NotifyDetail captchaVerify(String detailId, String captcha);
//}
package com.imyeyu.api.modules.common.service;
import com.imyeyu.api.modules.common.entity.Notify;
import com.imyeyu.api.modules.common.entity.NotifyDetail;
/**
*
*
* @author 夜雨
* @since 2026-05-14 12:12
*/
public interface SmsService {
/**
* 创建短信验证码通知
*
* @param detail 通知
* @return 通知详情 ID
*/
String captchaCreate(Notify detail);
/**
* 校验短信验证码
*
* @param detailId 通知详情 ID
* @param captcha 请求验证码
* @return 通知详情
*/
NotifyDetail captchaVerify(String detailId, String captcha);
}
@@ -1,6 +1,5 @@
package com.imyeyu.api.modules.common.service.implement;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imyeyu.api.modules.common.config.NotifyQueueConfig;
import com.imyeyu.api.modules.common.entity.NotifyDetail;
@@ -11,9 +10,9 @@ import com.imyeyu.api.modules.common.service.SmsQueueService;
import com.imyeyu.api.modules.common.util.QCloudSmsProxy;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.utils.Regex;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import com.imyeyu.utils.Regex;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -56,12 +55,7 @@ public class SmsQueueServiceImplement extends AbstractQueueService<SmsQueue, Not
@Override
protected void doSend(SmsQueue queue) {
try {
String[] args = new String[0];
if (queue.getArgs() != null && !queue.getArgs().isBlank()) {
JsonNode argsNode = jackson.readTree(queue.getArgs());
TimiException.requiredTrue(argsNode != null && argsNode.isArray(), "短信参数必须是数组");
args = jackson.treeToValue(argsNode, String[].class);
}
String[] args = jackson.treeToValue(queue.getArgs(), String[].class);
SendSmsResponse response = smsProxy.send(queue.getSendTo(), queue.getTemplateId(), args);
TimiException.required(response, "未找到短信响应");
SendStatus[] statusSet = response.getSendStatusSet();
@@ -1,82 +1,82 @@
//package com.imyeyu.api.modules.common.service.implement;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.node.ArrayNode;
//import com.imyeyu.api.modules.common.config.NotifyQueueConfig;
//import com.imyeyu.api.modules.common.entity.Notify;
//import com.imyeyu.api.modules.common.entity.NotifyDetail;
//import com.imyeyu.api.modules.common.service.NotifyDetailService;
//import com.imyeyu.api.modules.common.service.NotifyService;
//import com.imyeyu.api.modules.common.service.SmsService;
//import com.imyeyu.java.bean.timi.TimiException;
//import com.imyeyu.utils.Regex;
//import com.imyeyu.utils.Text;
//import com.imyeyu.utils.Time;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Service;
//
//import java.util.List;
//
///**
// *
// *
// * @author 夜雨
// * @since 2026-05-14 12:12
// */
//@Slf4j
//@Service
//@RequiredArgsConstructor
//public class SmsServiceImplement implements SmsService {
//
// @Value("${spring.profiles.active}")
// private String env;
//
// private final NotifyQueueConfig config;
// private final ObjectMapper jackson;
//
// private final NotifyService notifyService;
// private final NotifyDetailService notifyDetailService;
//
// @Override
// public String captchaCreate(Notify notify) {
// NotifyQueueConfig.Sms.Captcha captchaConf = config.getSms().getCaptcha();
// TimiException.required(notify.getAppId(), "not found appId");
//
// NotifyDetail detail = notify.getDetailList().getFirst();
//
// TimiException.requiredTrue(Regex.isMatch(Regex.MOBILE_PHONE, detail.getSendTo()), "invalid mobilePhone", "captcha.sms.invalid_mobile_phone");
//
// String code = Text.randomString("0123456789", 6);
// if (!env.equalsIgnoreCase("prod")) {
// code = "123456";
// }
// detail.setMsgType(NotifyDetail.MsgType.SMS);
// detail.setTemplateId(captchaConf.getTemplateId());
// detail.setArgs(jackson.valueToTree(List.of(code, captchaConf.getTtlMinute())));
//
// notifyService.create(notify);
// return notifyDetailService.listByNotifyId(notify.getId()).getFirst().getId();
// }
//
// @Override
// public NotifyDetail captchaVerify(String detailId, String captcha) {
// AppConfig.Sms.Captcha captchaConf = config.getSms().getCaptcha();
//
// NotifyDetail detail = notifyDetailService.get(detailId);
// if (Time.M * captchaConf.getTtlMinute() < Time.now() - detail.getSendAt()) {
// throw new AppException(ResultCode.ARG_EXPIRED).msgKey("captcha.expired");
// }
// if (detail.getArgs() instanceof ArrayNode array) {
// String dbCaptcha = array.get(captchaConf.getArgIndex()).asText();
// if (!dbCaptcha.equalsIgnoreCase(captcha)) {
// throw new AppException(ResultCode.RESULT_BAD).msgKey("captcha.invalid");
// }
// } else {
// throw new AppException(ResultCode.ERROR, "not array args");
// }
// detail.setNotify(notifyService.get(detail.getNotifyId()));
// return detail;
// }
//}
package com.imyeyu.api.modules.common.service.implement;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.imyeyu.api.modules.common.config.NotifyQueueConfig;
import com.imyeyu.api.modules.common.entity.Notify;
import com.imyeyu.api.modules.common.entity.NotifyDetail;
import com.imyeyu.api.modules.common.service.NotifyDetailService;
import com.imyeyu.api.modules.common.service.NotifyService;
import com.imyeyu.api.modules.common.service.SmsService;
import com.imyeyu.java.bean.timi.TimiCode;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.utils.Regex;
import com.imyeyu.utils.Text;
import com.imyeyu.utils.Time;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*
*
* @author 夜雨
* @since 2026-05-14 12:12
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SmsServiceImplement implements SmsService {
@Value("${spring.profiles.active}")
private String env;
private final NotifyQueueConfig config;
private final ObjectMapper jackson;
private final NotifyService notifyService;
private final NotifyDetailService notifyDetailService;
@Override
public String captchaCreate(Notify notify) {
NotifyQueueConfig.Sms.Captcha captchaConf = config.getSms().getCaptcha();
NotifyDetail detail = notify.getDetailList().getFirst();
TimiException.requiredTrue(Regex.isMatch(Regex.MOBILE_PHONE, detail.getSendTo()), "invalid mobilePhone");
String code = Text.randomString("0123456789", 6);
if (!env.equalsIgnoreCase("prod")) {
code = "123456";
}
detail.setMsgType(NotifyDetail.MsgType.SMS);
detail.setTemplateId(captchaConf.getTemplateId());
detail.setArgs(jackson.valueToTree(List.of(code, captchaConf.getTtlMinute())));
notifyService.create(notify);
return notifyDetailService.listByNotifyId(notify.getId()).getFirst().getId();
}
@Override
public NotifyDetail captchaVerify(String detailId, String captcha) {
NotifyQueueConfig.Sms.Captcha captchaConf = config.getSms().getCaptcha();
NotifyDetail detail = notifyDetailService.get(detailId);
if (Time.M * captchaConf.getTtlMinute() < Time.now() - detail.getSendAt()) {
throw new TimiException(TimiCode.ARG_EXPIRED, "验证码过期");
}
if (detail.getArgs() instanceof ArrayNode array) {
String dbCaptcha = array.get(captchaConf.getArgIndex()).asText();
if (!dbCaptcha.equalsIgnoreCase(captcha)) {
throw new TimiException(TimiCode.RESULT_BAD, "验证码错误");
}
} else {
throw new TimiException(TimiCode.ERROR, "not array args");
}
detail.setNotify(notifyService.get(detail.getNotifyId()));
return detail;
}
}