mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-10 14:56:06 +08:00
refactor: 移除系统中所有短信通知功能
- 删除短信配置平台端 CRUD(实体/参数/结果/DAO/Service/Controller/Convert) - 删除 SmsProviderEnum 枚举 - 删除 sms4j 依赖及配置 - 删除 MerchantUserService 中短信发送/校验逻辑 - 删除 MerchantUserController 中短信相关 API 端点 - 删除 LoginSmsCaptchaService 及 TokenEndpoint 中短信端点 - 删除前端短信配置页面及 API - 清理相关国际化文件及校验消息
This commit is contained in:
@@ -50,13 +50,6 @@
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 短信服务 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-spring-boot-starter</artifactId>
|
||||
<version>3.3.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 支付公共底座 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.daxpay</groupId>
|
||||
|
||||
@@ -12,9 +12,6 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/// # 商户管理
|
||||
///
|
||||
@IgnoreAuth
|
||||
@@ -32,35 +29,6 @@ public class MerchantUserController {
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "发送注册验证码")
|
||||
@PostMapping("/register/send-captcha")
|
||||
public Result<Void> sendRegisterCaptcha(@NotBlank(message = "{validation.field.phone.notBlank}") String phone) {
|
||||
merchantUserService.sendRegisterCaptcha(phone);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "校验注册验证码")
|
||||
@GetMapping("/register/check-captcha")
|
||||
public Result<Void> checkRegisterCaptcha(@NotBlank(message = "{validation.field.phone.notBlank}") String phone,
|
||||
@NotBlank(message = "{validation.field.captcha.notBlank}") String smsCaptcha) {
|
||||
merchantUserService.checkRegisterCaptcha(phone, smsCaptcha);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "发送忘记密码验证码")
|
||||
@PostMapping("/forgot/send-captcha")
|
||||
public Result<String> sendForgotCaptcha(@NotBlank(message = "{validation.field.account.notBlank}") String account,
|
||||
@NotBlank(message = "{validation.field.phone.notBlank}") String phone) {
|
||||
return Res.ok(merchantUserService.sendForgotCaptcha(account, phone));
|
||||
}
|
||||
|
||||
@Operation(summary = "校验忘记密码验证码")
|
||||
@GetMapping("/forgot/check-captcha")
|
||||
public Result<Void> checkForgotCaptcha(@Valid MerchantForgotParam param) {
|
||||
merchantUserService.checkForgotCaptcha(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "修改密码")
|
||||
@PostMapping("/forgot/change-pwd")
|
||||
public Result<Void> forgot(@Validated @RequestBody MerchantForgotParam param) {
|
||||
|
||||
@@ -19,7 +19,4 @@ public class MerchantForgotParam {
|
||||
|
||||
@Schema(description = "用户绑定手机号")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "验证码")
|
||||
private String smsCaptcha;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,6 @@ public class MerchantRegisterParam {
|
||||
@Schema(description = "用户绑定手机号")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "验证码")
|
||||
private String smsCaptcha;
|
||||
|
||||
@NotBlank(message = "{validation.field.account.notBlank}")
|
||||
@Schema(description = "登录账号")
|
||||
private String account;
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
package org.dromara.daxpay.payment.merchant.service.user;
|
||||
|
||||
import org.dromara.daxpay.platform.core.enums.client.ClientEnum;
|
||||
import org.dromara.daxpay.platform.core.exception.DataNotExistException;
|
||||
import org.dromara.daxpay.platform.core.exception.ValidationFailedException;
|
||||
import org.dromara.daxpay.platform.iam.auth.service.PasswordDecryptService;
|
||||
import org.dromara.daxpay.platform.iam.dao.role.RoleManager;
|
||||
import org.dromara.daxpay.platform.iam.dao.user.UserInfoManager;
|
||||
import org.dromara.daxpay.platform.iam.entity.role.Role;
|
||||
import org.dromara.daxpay.platform.iam.entity.user.UserInfo;
|
||||
import org.dromara.daxpay.platform.iam.param.user.UserInfoParam;
|
||||
import org.dromara.daxpay.platform.iam.service.upms.UserRoleService;
|
||||
import org.dromara.daxpay.platform.iam.service.user.UserAdminService;
|
||||
import org.dromara.daxpay.payment.common.context.PaymentContext;
|
||||
import org.dromara.daxpay.platform.core.exception.BizException;
|
||||
import org.dromara.daxpay.platform.core.exception.config.ConfigNotExistException;
|
||||
import org.dromara.daxpay.platform.core.exception.operation.OperationFailException;
|
||||
import org.dromara.daxpay.payment.merchant.convert.info.MerchantInfoConvert;
|
||||
@@ -27,26 +15,21 @@ import org.dromara.daxpay.payment.merchant.param.info.MerchantForgotParam;
|
||||
import org.dromara.daxpay.payment.merchant.param.info.MerchantRegisterParam;
|
||||
import org.dromara.daxpay.payment.merchant.service.appinfo.MchAppInfoService;
|
||||
import org.dromara.daxpay.platform.core.enums.role.RoleCodeEnum;
|
||||
import cn.hutool.core.util.DesensitizedUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.dromara.daxpay.platform.core.code.CommonCode;
|
||||
import org.dromara.daxpay.platform.iam.auth.service.PasswordDecryptService;
|
||||
import org.dromara.daxpay.platform.iam.dao.role.RoleManager;
|
||||
import org.dromara.daxpay.platform.iam.dao.user.UserInfoManager;
|
||||
import org.dromara.daxpay.platform.iam.entity.role.Role;
|
||||
import org.dromara.daxpay.platform.iam.entity.user.UserInfo;
|
||||
import org.dromara.daxpay.platform.iam.param.user.UserInfoParam;
|
||||
import org.dromara.daxpay.platform.iam.service.upms.UserRoleService;
|
||||
import org.dromara.daxpay.platform.iam.service.user.UserAdminService;
|
||||
import org.dromara.daxpay.payment.common.context.PaymentContext;
|
||||
|
||||
/// # 商户用户管理服务
|
||||
///
|
||||
@@ -62,71 +45,20 @@ public class MerchantUserService {
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
// 短信验证码前缀
|
||||
private final static String SMS_CAPTCHA_KEY = "sms:captcha:merchant:forgot:";
|
||||
// 注册短信验证码前缀
|
||||
private final static String SMS_REGISTER_CAPTCHA_KEY = "sms:captcha:merchant:register:";
|
||||
|
||||
private final MerchantInfoManager merchantInfoManager;
|
||||
private final MchAppInfoManager mchAppInfoManager;
|
||||
private final MchAppInfoService mchAppInfoService;
|
||||
private final UserInfoManager userInfoManager;
|
||||
private final MerchantUserManager merchantUserManager;
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
private final ObjectProvider<SmsReadConfig> smsReadConfigProvider;
|
||||
private final UserAdminService userAdminService;
|
||||
private final RoleManager roleManager;
|
||||
private final UserRoleService userRoleService;
|
||||
private final PasswordDecryptService passwordDecryptService;
|
||||
private final PaymentContext apiContext;
|
||||
|
||||
/// 发送注册验证码
|
||||
public void sendRegisterCaptcha(String phone) {
|
||||
// 判断该手机号是否已注册
|
||||
boolean phoneExists = userInfoManager.findByClientCodeAndPhone("mch", phone).isPresent();
|
||||
if (phoneExists) {
|
||||
// 商户: 该手机号已注册
|
||||
throw new ValidationFailedException("error.payment.merchant.phoneRegistered");
|
||||
}
|
||||
|
||||
// 检查手机号发送短信次数是否已经超出次数
|
||||
int smsCaptcha = RandomUtil.randomInt(100000, 999999);
|
||||
// 发送验证码, 有效期五分钟, 写入数据库
|
||||
redisTemplate.opsForValue()
|
||||
.set(SMS_REGISTER_CAPTCHA_KEY + phone, String.valueOf(smsCaptcha), 5, TimeUnit.MINUTES);
|
||||
log.info("手机号: {} 发送验证码: {}", phone, smsCaptcha);
|
||||
|
||||
// 发送前进行初始化
|
||||
SmsFactory.createSmsBlend(getSmsReadConfig(),"def");
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("def");
|
||||
LinkedHashMap<String, String> params = new LinkedHashMap<>();
|
||||
params.put("code", String.valueOf(smsCaptcha));
|
||||
// 发送验证码
|
||||
SmsResponse smsResponse = smsBlend.sendMessage(phone, params);
|
||||
if (!smsResponse.isSuccess()){
|
||||
log.error("发送验证码失败: {}", smsResponse.getData());
|
||||
// 商户: 发送验证码失败
|
||||
throw new OperationFailException(CommonCode.FAIL_CODE, "error.payment.merchant.smsSendFailed");
|
||||
}
|
||||
}
|
||||
|
||||
/// 注册验证码校验
|
||||
public void checkRegisterCaptcha(String phone, String smsCaptcha) {
|
||||
// 查询验证码, 判断是否一致
|
||||
String captcha = redisTemplate.opsForValue()
|
||||
.get(SMS_REGISTER_CAPTCHA_KEY + phone);
|
||||
if (!StrUtil.equals(smsCaptcha, captcha)) {
|
||||
// 商户: 验证码错误或已过期
|
||||
throw new OperationFailException(CommonCode.FAIL_CODE, "error.payment.merchant.smsCodeError");
|
||||
}
|
||||
}
|
||||
|
||||
/// 注册商户
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void register(MerchantRegisterParam param) {
|
||||
// 校验注册验证码
|
||||
this.checkRegisterCaptcha(param.getPhone(), param.getSmsCaptcha());
|
||||
|
||||
var merchant = MerchantInfoConvert.CONVERT.toEntity(param);
|
||||
merchant.setMchNo(this.getMchNo());
|
||||
merchant.setStatus(MerchantStatusEnum.ENABLE.getCode());
|
||||
@@ -141,9 +73,6 @@ public class MerchantUserService {
|
||||
mchApp.setAppId(mchAppInfoService.generateAppId())
|
||||
.setMchNo(merchant.getMchNo());
|
||||
mchAppInfoManager.save(mchApp);
|
||||
|
||||
// 清空验证码
|
||||
redisTemplate.opsForValue().getAndDelete(SMS_REGISTER_CAPTCHA_KEY + param.getPhone());
|
||||
}
|
||||
|
||||
/// 创建商户管理员
|
||||
@@ -176,99 +105,18 @@ public class MerchantUserService {
|
||||
throw new OperationFailException("error.payment.merchant.mchNoGenFailed");
|
||||
}
|
||||
|
||||
/// 获取短信配置
|
||||
private SmsReadConfig getSmsReadConfig() {
|
||||
SmsReadConfig smsReadConfig = smsReadConfigProvider.getIfAvailable();
|
||||
if (smsReadConfig == null) {
|
||||
// 商户: 短信配置不存在,请先完成短信配置
|
||||
throw new ConfigNotExistException("error.payment.merchant.smsConfigNotExist");
|
||||
}
|
||||
return smsReadConfig;
|
||||
}
|
||||
|
||||
/// 发送找后密码验证码
|
||||
public String sendForgotCaptcha(String account, String phone) {
|
||||
// 按服务商+账号查找用户
|
||||
UserInfo userInfo = userInfoManager.findByClientCodeAndAccount("mch", account)
|
||||
// 商户: 账号或手机号未找到
|
||||
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound"));
|
||||
MerchantUser merchantUser = merchantUserManager.findByUserId(userInfo.getId())
|
||||
// 商户: 账号或手机号未找到
|
||||
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound"));
|
||||
if (!merchantInfoManager.existedByMchNo(merchantUser.getMchNo())) {
|
||||
// 商户: 账号或手机号未找到
|
||||
throw new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound");
|
||||
}
|
||||
// 判断密码是否一致
|
||||
if (!Objects.equals(phone, userInfo.getPhone())) {
|
||||
// 商户: 账号或手机号信息不正确
|
||||
throw new OperationFailException(CommonCode.FAIL_CODE, "error.payment.merchant.accountOrPhoneError");
|
||||
}
|
||||
|
||||
// 检查手机号发送短信次数是否已经超出次数
|
||||
|
||||
// 发送验证码, 有效期五分钟
|
||||
int smsCaptcha = RandomUtil.randomInt(100000, 999999);
|
||||
// 发送前进行初始化
|
||||
SmsFactory.createSmsBlend(getSmsReadConfig(),"def");
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend("def");
|
||||
LinkedHashMap<String, String> params = new LinkedHashMap<>();
|
||||
params.put("code", String.valueOf(smsCaptcha));
|
||||
log.info("手机号: {} 发送验证码: {}", phone, smsCaptcha);
|
||||
// 发送验证码
|
||||
SmsResponse smsResponse = smsBlend.sendMessage(phone, params);
|
||||
if (!smsResponse.isSuccess()){
|
||||
log.error("发送验证码失败: {}", smsResponse.getData());
|
||||
// 商户: 发送验证码失败
|
||||
throw new OperationFailException("error.payment.merchant.smsSendFailed");
|
||||
}
|
||||
// 返回脱敏手机号
|
||||
return DesensitizedUtil.mobilePhone(phone);
|
||||
}
|
||||
|
||||
/// 忘记密码验证码校验
|
||||
public void checkForgotCaptcha(MerchantForgotParam param) {
|
||||
// 按服务商+账号查找用户
|
||||
UserInfo userInfo = userInfoManager.findByClientCodeAndAccount("mch", param.getAccount())
|
||||
// 商户: 账号或手机号未找到
|
||||
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound"));
|
||||
MerchantUser merchantUser = merchantUserManager.findByUserId(userInfo.getId())
|
||||
// 商户: 账号或手机号未找到
|
||||
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound"));
|
||||
if (!merchantInfoManager.existedByMchNo(merchantUser.getMchNo())) {
|
||||
// 商户: 账号或手机号未找到
|
||||
throw new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound");
|
||||
}
|
||||
// 判断手机号是否一致
|
||||
if (!Objects.equals(param.getPhone(), userInfo.getPhone())) {
|
||||
// 商户: 账号或手机号信息不正确
|
||||
throw new OperationFailException("error.payment.merchant.accountOrPhoneError");
|
||||
}
|
||||
// 查询验证码, 判断是否一致
|
||||
String phone = userInfo.getPhone();
|
||||
String smsCaptcha = redisTemplate.opsForValue()
|
||||
.get(SMS_CAPTCHA_KEY + phone);
|
||||
if (!StrUtil.equals(param.getSmsCaptcha(), smsCaptcha)) {
|
||||
// 商户: 验证码错误或已过期
|
||||
throw new OperationFailException("error.payment.merchant.smsCodeError");
|
||||
}
|
||||
}
|
||||
|
||||
/// 忘记密码 - 重新设置密码
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void forgot(MerchantForgotParam param) {
|
||||
this.checkForgotCaptcha(param);
|
||||
// 按服务商+账号查找用户
|
||||
UserInfo userInfo = userInfoManager.findByClientCodeAndAccount("mch", param.getAccount())
|
||||
// 商户: 账号或手机号未找到
|
||||
.orElseThrow(() -> new DataNotExistException("error.payment.merchant.accountOrPhoneNotFound"));
|
||||
.orElseThrow(() -> new org.dromara.daxpay.platform.core.exception.DataNotExistException("error.payment.merchant.accountOrPhoneNotFound"));
|
||||
// 解密密码
|
||||
String newPassword = passwordDecryptService.decryptPassword(param.getNewPassword());
|
||||
// 修改密码
|
||||
var passwordHash = BCrypt.hashpw(newPassword, BCrypt.gensalt());
|
||||
userInfo.setPassword(passwordHash);
|
||||
userInfoManager.updateById(userInfo);
|
||||
// 清空验证码
|
||||
redisTemplate.opsForValue().getAndDelete(SMS_CAPTCHA_KEY + param.getPhone());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"aliyun": "Alibaba Cloud",
|
||||
"tencent": "Tencent Cloud"
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
{
|
||||
"phoneRegistered": "Phone number already registered",
|
||||
"smsSendFailed": "Failed to send verification code",
|
||||
"smsCodeError": "Verification code is incorrect or expired",
|
||||
"mchNoGenFailed": "Merchant number generation failed",
|
||||
"smsConfigNotExist": "SMS configuration not found, please configure SMS first",
|
||||
"accountOrPhoneNotFound": "Account or bound phone number not found",
|
||||
"accountOrPhoneError": "Account or phone number information is incorrect",
|
||||
"dataErrorNoMchNo": "Data error, merchant number not found",
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"configNotExist": "SMS configuration not found",
|
||||
"defaultConfigNotExist": "Default SMS configuration not found"
|
||||
}
|
||||
@@ -347,9 +347,6 @@
|
||||
"configName": {
|
||||
"notBlank": "Config name cannot be blank"
|
||||
},
|
||||
"smsProvider": {
|
||||
"notBlank": "SMS provider must not be blank"
|
||||
},
|
||||
"endpoint": {
|
||||
"notBlank": "Endpoint cannot be blank"
|
||||
},
|
||||
@@ -434,8 +431,5 @@
|
||||
"oldPassword": {
|
||||
"notBlank": "Old password cannot be blank"
|
||||
},
|
||||
"smsConfigId": {
|
||||
"notNull": "SMS config ID cannot be blank"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"aliyun": "阿里云",
|
||||
"tencent": "腾讯云"
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
{
|
||||
"phoneRegistered": "该手机号已注册",
|
||||
"smsSendFailed": "发送验证码失败",
|
||||
"smsCodeError": "验证码错误或已过期",
|
||||
"mchNoGenFailed": "商户号生成失败",
|
||||
"smsConfigNotExist": "短信配置不存在,请先完成短信配置",
|
||||
"accountOrPhoneNotFound": "未找到该账号或绑定手机信息",
|
||||
"accountOrPhoneError": "账号或手机号信息不正确",
|
||||
"dataErrorNoMchNo": "数据错误, 未发现商户号",
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"configNotExist": "短信配置不存在",
|
||||
"defaultConfigNotExist": "默认短信配置不存在"
|
||||
}
|
||||
@@ -350,9 +350,6 @@
|
||||
"configName": {
|
||||
"notBlank": "配置名称不能为空"
|
||||
},
|
||||
"smsProvider": {
|
||||
"notBlank": "短信服务商不可为空"
|
||||
},
|
||||
"endpoint": {
|
||||
"notBlank": "服务端点不能为空"
|
||||
},
|
||||
@@ -437,8 +434,5 @@
|
||||
"oldPassword": {
|
||||
"notBlank": "旧密码不能为空"
|
||||
},
|
||||
"smsConfigId": {
|
||||
"notNull": "短信配置ID不能为空"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.dromara.daxpay.platform.core.enums.common;
|
||||
|
||||
import org.dromara.daxpay.platform.core.i18n.I18nSupport;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import java.util.Arrays;
|
||||
|
||||
/// # 短信供应商枚举
|
||||
///
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum SmsProviderEnum implements I18nSupport {
|
||||
|
||||
/// 阿里云
|
||||
ALIYUN("aliyun"),
|
||||
/// 腾讯云
|
||||
TENCENT("tencent");
|
||||
|
||||
/// 编码
|
||||
private final String code;
|
||||
|
||||
/// 翻译 key 前缀
|
||||
@Override
|
||||
public String getI18nPrefix() {
|
||||
return "enum.sms_provider";
|
||||
}
|
||||
public static SmsProviderEnum findByCode(String code) {
|
||||
return Arrays.stream(values())
|
||||
.filter(value -> value.code.equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package org.dromara.daxpay.platform.iam.auth.service;
|
||||
|
||||
import org.dromara.daxpay.platform.core.exception.BizException;
|
||||
import org.dromara.daxpay.platform.iam.code.UserStatusEnum;
|
||||
import org.dromara.daxpay.platform.iam.dao.user.UserInfoManager;
|
||||
import org.dromara.daxpay.platform.iam.entity.user.UserInfo;
|
||||
import org.dromara.daxpay.platform.iam.exception.user.UserInfoNotExistsException;
|
||||
import org.dromara.daxpay.platform.iam.param.auth.LoginSmsCaptchaSendParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.dromara.daxpay.platform.core.code.CommonCode;
|
||||
|
||||
/// # 登录短信验证码服务
|
||||
///
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoginSmsCaptchaService {
|
||||
|
||||
private final UserInfoManager userInfoManager;
|
||||
|
||||
/// 发送登录短信验证码前置校验
|
||||
public void sendSmsCaptcha(LoginSmsCaptchaSendParam param) {
|
||||
UserInfo userInfo = this.findUser(param);
|
||||
if (!Objects.equals(userInfo.getStatus(), UserStatusEnum.NORMAL.getCode())) {
|
||||
// 认证: 用户状态异常
|
||||
throw new BizException(CommonCode.FAIL_CODE, "error.auth.auth.userStatusError");
|
||||
}
|
||||
}
|
||||
|
||||
private UserInfo findUser(LoginSmsCaptchaSendParam param) {
|
||||
if (param.getClientId() != null && !param.getClientId().isBlank()) {
|
||||
return userInfoManager.findByClientCodeAndPhone(param.getClientId(), param.getPhone())
|
||||
.orElseThrow(UserInfoNotExistsException::new);
|
||||
}
|
||||
return userInfoManager.findByPhone(param.getPhone())
|
||||
.orElseThrow(UserInfoNotExistsException::new);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,17 +6,14 @@ import org.dromara.daxpay.platform.core.annotation.NonceVerification;
|
||||
import org.dromara.daxpay.platform.core.rest.Res;
|
||||
import org.dromara.daxpay.platform.core.rest.result.Result;
|
||||
import org.dromara.daxpay.platform.iam.auth.service.LoginContentService;
|
||||
import org.dromara.daxpay.platform.iam.auth.service.LoginSmsCaptchaService;
|
||||
import org.dromara.daxpay.platform.iam.auth.service.SecondCheckService;
|
||||
import org.dromara.daxpay.platform.iam.param.auth.LoginContentParam;
|
||||
import org.dromara.daxpay.platform.iam.param.auth.LoginSmsCaptchaSendParam;
|
||||
import org.dromara.daxpay.platform.iam.result.auth.LoginContentResult;
|
||||
import org.dromara.daxpay.platform.iam.result.auth.SecondCheckResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -34,8 +31,6 @@ public class TokenEndpoint {
|
||||
|
||||
private final LoginContentService loginContentService;
|
||||
|
||||
private final LoginSmsCaptchaService loginSmsCaptchaService;
|
||||
|
||||
private final SecondCheckService secondCheckService;
|
||||
|
||||
private final PlatformConfigProperties platformConfigProperties;
|
||||
@@ -59,13 +54,6 @@ public class TokenEndpoint {
|
||||
return Res.ok(loginContentService.getLoginContent(param == null ? new LoginContentParam() : param));
|
||||
}
|
||||
|
||||
@Operation(summary = "发送登录短信验证码")
|
||||
@PostMapping("/send-sms-captcha")
|
||||
public Result<Void> sendSmsCaptcha(@RequestBody @Valid LoginSmsCaptchaSendParam param) {
|
||||
loginSmsCaptchaService.sendSmsCaptcha(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取二次校验信息")
|
||||
@PostMapping("/second-check")
|
||||
public Result<SecondCheckResult> getSecondCheck(@RequestBody(required = false) LoginContentParam param) {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.dromara.daxpay.platform.iam.param.auth;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 发送登录短信验证码参数
|
||||
///
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "发送登录短信验证码参数")
|
||||
public class LoginSmsCaptchaSendParam {
|
||||
|
||||
@Schema(description = "终端Code")
|
||||
private String clientId;
|
||||
|
||||
@NotBlank(message = "{validation.field.phone.notBlank}")
|
||||
@Schema(description = "手机号")
|
||||
private String phone;
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.controller.config;
|
||||
|
||||
import org.dromara.daxpay.platform.core.rest.Res;
|
||||
import org.dromara.daxpay.platform.core.rest.result.Result;
|
||||
import org.dromara.daxpay.platform.system.param.config.PlatformSmsConfigParam;
|
||||
import org.dromara.daxpay.platform.system.result.config.platform.PlatformSmsConfigResult;
|
||||
import org.dromara.daxpay.platform.system.service.config.PlatformSmsConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/// # 平台短信配置控制器
|
||||
///
|
||||
@Tag(name = "平台短信配置")
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/platform/config/sms")
|
||||
@RequiredArgsConstructor
|
||||
public class PlatformSmsConfigController {
|
||||
private final PlatformSmsConfigService smsConfigService;
|
||||
|
||||
/// 添加短信配置
|
||||
@Operation(summary = "添加短信配置")
|
||||
@PostMapping("/add")
|
||||
public Result<Void> add(@RequestBody @Validated PlatformSmsConfigParam param) {
|
||||
smsConfigService.add(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
/// 更新短信配置
|
||||
@Operation(summary = "更新短信配置")
|
||||
@PostMapping("/update")
|
||||
public Result<Void> update(@RequestBody @Validated PlatformSmsConfigParam param) {
|
||||
smsConfigService.update(param);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
/// 设置短信配置为启用
|
||||
@Operation(summary = "设置短信配置为启用")
|
||||
@PostMapping("/enable")
|
||||
public Result<Void> enable(@NotNull(message = "{validation.field.smsConfigId.notNull}") Long id) {
|
||||
smsConfigService.setupEnable(id);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
/// 取消短信配置启用
|
||||
@Operation(summary = "取消短信配置启用")
|
||||
@PostMapping("/disable")
|
||||
public Result<Void> disable(@NotNull(message = "{validation.field.smsConfigId.notNull}") Long id) {
|
||||
smsConfigService.clearEnable(id);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
/// 删除短信配置
|
||||
@Operation(summary = "删除短信配置")
|
||||
@PostMapping("/delete")
|
||||
public Result<Void> delete(@NotNull(message = "{validation.field.smsConfigId.notNull}") Long id) {
|
||||
smsConfigService.delete(id);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
/// 获取短信配置
|
||||
@Operation(summary = "获取短信配置")
|
||||
@GetMapping("/get")
|
||||
public Result<PlatformSmsConfigResult> findById(@NotNull(message = "{validation.field.smsConfigId.notNull}") Long id) {
|
||||
return Res.ok(smsConfigService.findById(id));
|
||||
}
|
||||
|
||||
/// 获取所有短信配置
|
||||
@Operation(summary = "获取所有短信配置")
|
||||
@GetMapping("/list")
|
||||
public Result<List<PlatformSmsConfigResult>> list() {
|
||||
return Res.ok(smsConfigService.findAll());
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package org.dromara.daxpay.platform.system.convert;
|
||||
|
||||
import org.dromara.daxpay.platform.system.entity.config.platform.PlatformOssConfig;
|
||||
import org.dromara.daxpay.platform.system.entity.config.platform.security.*;
|
||||
import org.dromara.daxpay.platform.system.entity.config.sms.PlatformSmsConfig;
|
||||
import org.dromara.daxpay.platform.system.param.config.*;
|
||||
import org.dromara.daxpay.platform.system.result.config.platform.*;
|
||||
import org.mapstruct.BeanMapping;
|
||||
@@ -17,14 +16,6 @@ import org.mapstruct.factory.Mappers;
|
||||
public interface PlatformConfigConvert {
|
||||
PlatformConfigConvert CONVERT = Mappers.getMapper(PlatformConfigConvert.class);
|
||||
|
||||
// ========== 短信配置转换(保留多记录模式) ==========
|
||||
PlatformSmsConfigResult toResult(PlatformSmsConfig platformSmsConfig);
|
||||
|
||||
PlatformSmsConfig convert(PlatformSmsConfigParam param);
|
||||
|
||||
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
||||
void copy(PlatformSmsConfigParam param, @MappingTarget PlatformSmsConfig entity);
|
||||
|
||||
// ========== OSS配置转换(单配置模式) ==========
|
||||
PlatformOssConfigResult toOssResult(PlatformOssConfig data);
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.dao.config;
|
||||
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.impl.BaseManager;
|
||||
import org.dromara.daxpay.platform.system.entity.config.sms.PlatformSmsConfig;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/// # 平台短信配置
|
||||
///
|
||||
@Repository
|
||||
public class PlatformSmsConfigManager extends BaseManager<PlatformSmsConfigMapper, PlatformSmsConfig> {
|
||||
|
||||
/// 查询默认配置
|
||||
public Optional<PlatformSmsConfig> findDefault() {
|
||||
return this.findByField(PlatformSmsConfig::isEnable, true);
|
||||
}
|
||||
|
||||
/// 清除默认配置
|
||||
public void clearEnable() {
|
||||
this.lambdaUpdate()
|
||||
.set(PlatformSmsConfig::isEnable, false)
|
||||
.setIncrBy(PlatformSmsConfig::getVersion, 1)
|
||||
.update();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.dao.config;
|
||||
|
||||
import org.dromara.daxpay.platform.system.entity.config.sms.PlatformSmsConfig;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/// # 平台短信配置
|
||||
///
|
||||
@Mapper
|
||||
public interface PlatformSmsConfigMapper extends MPJBaseMapper<PlatformSmsConfig> {
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.entity.config.sms;
|
||||
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.base.MpBaseEntity;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.function.ToResult;
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.handler.encrypt.DataEncryptTypeHandler;
|
||||
import org.dromara.daxpay.platform.core.enums.common.SmsProviderEnum;
|
||||
import org.dromara.daxpay.platform.system.convert.PlatformConfigConvert;
|
||||
import org.dromara.daxpay.platform.system.result.config.platform.PlatformSmsConfigResult;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 平台短信配置
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "system_platform_sms_config", autoResultMap = true)
|
||||
public class PlatformSmsConfig extends MpBaseEntity implements ToResult<PlatformSmsConfigResult> {
|
||||
|
||||
/// 配置名称
|
||||
private String configName;
|
||||
|
||||
/// 是否为默认
|
||||
private boolean enable;
|
||||
|
||||
/// 短信供应商
|
||||
/// @see SmsProviderEnum
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String provider;
|
||||
|
||||
/// 短信模板ID
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String templateId;
|
||||
|
||||
/// 短信签名
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String signature;
|
||||
|
||||
/// AccessKey
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS, typeHandler = DataEncryptTypeHandler.class)
|
||||
private String accessKey;
|
||||
|
||||
/// SecretKey
|
||||
@TableField(typeHandler = DataEncryptTypeHandler.class)
|
||||
private String secretKey;
|
||||
|
||||
/// 商户注册模板
|
||||
private String registerId;
|
||||
|
||||
/// 忘记密码模板
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String forgetId;
|
||||
|
||||
/// 验证码模板
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String captchaId;
|
||||
|
||||
/// 通知模板
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String noticeId;
|
||||
|
||||
/// 转换为结果对象
|
||||
@Override
|
||||
public PlatformSmsConfigResult toResult() {
|
||||
return PlatformConfigConvert.CONVERT.toResult(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.param.config;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 平台短信配置参数
|
||||
///
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "平台短信配置参数")
|
||||
public class PlatformSmsConfigParam {
|
||||
|
||||
/// ID
|
||||
@Schema(description = "ID")
|
||||
private Long id;
|
||||
|
||||
/// 配置名称
|
||||
@NotBlank(message = "{validation.field.configName.notBlank}")
|
||||
@Schema(description = "配置名称")
|
||||
private String configName;
|
||||
|
||||
/// 短信服务商
|
||||
@NotBlank(message = "{validation.field.smsProvider.notBlank}")
|
||||
@Schema(description = "短信服务商")
|
||||
private String provider;
|
||||
|
||||
/// 短信签名
|
||||
@Schema(description = "短信签名")
|
||||
private String signature;
|
||||
|
||||
/// AccessKey
|
||||
@Schema(description = "AccessKey")
|
||||
private String accessKey;
|
||||
|
||||
/// SecretKey
|
||||
@Schema(description = "SecretKey")
|
||||
private String secretKey;
|
||||
|
||||
/// 商户注册模板
|
||||
@Schema(description = "商户注册模板")
|
||||
private String registerId;
|
||||
|
||||
/// 忘记密码模板
|
||||
@Schema(description = "忘记密码模板")
|
||||
private String forgetId;
|
||||
|
||||
/// 验证码模板
|
||||
@Schema(description = "验证码模板")
|
||||
private String captchaId;
|
||||
|
||||
/// 通知模板
|
||||
@Schema(description = "通知模板")
|
||||
private String noticeId;
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.result.config.platform;
|
||||
|
||||
import org.dromara.daxpay.platform.common.json.sensitive.SensitiveInfo;
|
||||
import org.dromara.daxpay.platform.core.result.BaseResult;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/// # 平台短信配置
|
||||
///
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "平台短信配置")
|
||||
public class PlatformSmsConfigResult extends BaseResult {
|
||||
|
||||
/// 配置名称
|
||||
@Schema(description = "配置名称")
|
||||
private String configName;
|
||||
|
||||
/// 是否为默认
|
||||
@Schema(description = "是否为默认")
|
||||
private boolean enable;
|
||||
|
||||
/// 短信服务商
|
||||
@Schema(description = "短信服务商")
|
||||
private String provider;
|
||||
|
||||
/// 短信模板ID
|
||||
@Schema(description = "短信模板ID")
|
||||
private String templateId;
|
||||
|
||||
/// 短信签名
|
||||
@Schema(description = "短信签名")
|
||||
private String signature;
|
||||
|
||||
/// AccessKey
|
||||
@SensitiveInfo
|
||||
@Schema(description = "AccessKey")
|
||||
private String accessKey;
|
||||
|
||||
/// SecretKey
|
||||
@SensitiveInfo
|
||||
@Schema(description = "SecretKey")
|
||||
private String secretKey;
|
||||
|
||||
/// 商户注册模板
|
||||
@Schema(description = "商户注册模板")
|
||||
private String registerId;
|
||||
|
||||
/// 忘记密码模板
|
||||
@Schema(description = "忘记密码模板")
|
||||
private String forgetId;
|
||||
|
||||
/// 验证码模板
|
||||
@Schema(description = "验证码模板")
|
||||
private String captchaId;
|
||||
|
||||
/// 通知模板
|
||||
@Schema(description = "通知模板")
|
||||
private String noticeId;
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package org.dromara.daxpay.platform.system.service.config;
|
||||
|
||||
import org.dromara.daxpay.platform.common.mybatisplus.util.MpUtil;
|
||||
import org.dromara.daxpay.platform.system.convert.PlatformConfigConvert;
|
||||
import org.dromara.daxpay.platform.system.dao.config.PlatformSmsConfigManager;
|
||||
import org.dromara.daxpay.platform.system.entity.config.sms.PlatformSmsConfig;
|
||||
import org.dromara.daxpay.platform.core.exception.config.ConfigNotExistException;
|
||||
import org.dromara.daxpay.platform.system.param.config.PlatformSmsConfigParam;
|
||||
import org.dromara.daxpay.platform.system.result.config.platform.PlatformSmsConfigResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/// # 平台短信配置服务
|
||||
///
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PlatformSmsConfigService {
|
||||
private final PlatformSmsConfigManager smsConfigManager;
|
||||
|
||||
/// 添加短信配置
|
||||
public void add(PlatformSmsConfigParam param) {
|
||||
PlatformSmsConfig config = PlatformConfigConvert.CONVERT.convert(param);
|
||||
smsConfigManager.save(config);
|
||||
}
|
||||
|
||||
/// 更新短信配置
|
||||
public void update(PlatformSmsConfigParam param) {
|
||||
var config = smsConfigManager.findById(param.getId())
|
||||
// 系统: 短信配置不存在
|
||||
.orElseThrow(() -> new ConfigNotExistException("error.system.sms.configNotExist"));
|
||||
PlatformConfigConvert.CONVERT.copy(param, config);
|
||||
smsConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/// 设置默认配置
|
||||
public void setupEnable(Long id) {
|
||||
// 先将所有配置设置为非默认
|
||||
smsConfigManager.clearEnable();
|
||||
// 查询
|
||||
var config = smsConfigManager.findById(id)
|
||||
// 系统: 短信配置不存在
|
||||
.orElseThrow(() -> new ConfigNotExistException("error.system.sms.configNotExist"));
|
||||
// 设置当前配置为默认
|
||||
config.setEnable(true);
|
||||
smsConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/// 清除默认配置
|
||||
public void clearEnable(Long id) {
|
||||
// 查询
|
||||
var config = smsConfigManager.findById(id)
|
||||
// 系统: 短信配置不存在
|
||||
.orElseThrow(() -> new ConfigNotExistException("error.system.sms.configNotExist"));
|
||||
// 设置当前配置为默认
|
||||
config.setEnable(false);
|
||||
smsConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/// 删除短信配置
|
||||
public void delete(Long id) {
|
||||
smsConfigManager.deleteById(id);
|
||||
}
|
||||
|
||||
/// 获取短信配置
|
||||
public PlatformSmsConfigResult findById(Long id) {
|
||||
return smsConfigManager.findById(id).map(PlatformSmsConfig::toResult)
|
||||
// 系统: 短信配置不存在
|
||||
.orElseThrow(() -> new ConfigNotExistException("error.system.sms.configNotExist"));
|
||||
}
|
||||
|
||||
/// 获取默认短信配置
|
||||
public PlatformSmsConfig findDefault() {
|
||||
return smsConfigManager.findDefault()
|
||||
// 系统: 默认短信配置不存在
|
||||
.orElseThrow(() -> new ConfigNotExistException("error.system.sms.defaultConfigNotExist"));
|
||||
}
|
||||
|
||||
/// 获取所有短信配置
|
||||
public List<PlatformSmsConfigResult> findAll() {
|
||||
return MpUtil.toListResult(smsConfigManager.findAll());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,6 +50,4 @@ sa-token:
|
||||
easy-trans:
|
||||
#启用平铺模式
|
||||
is-enable-tile: true
|
||||
# 平台配置
|
||||
sms:
|
||||
is-print: false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user