refactor: 移除系统中所有短信通知功能

- 删除短信配置平台端 CRUD(实体/参数/结果/DAO/Service/Controller/Convert)
- 删除 SmsProviderEnum 枚举
- 删除 sms4j 依赖及配置
- 删除 MerchantUserService 中短信发送/校验逻辑
- 删除 MerchantUserController 中短信相关 API 端点
- 删除 LoginSmsCaptchaService 及 TokenEndpoint 中短信端点
- 删除前端短信配置页面及 API
- 清理相关国际化文件及校验消息
This commit is contained in:
DaxPay Dev
2026-06-16 22:22:32 +08:00
parent f96d1091d2
commit 9a5a8da3d6
26 changed files with 11 additions and 761 deletions

View File

@@ -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>

View File

@@ -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) {

View File

@@ -19,7 +19,4 @@ public class MerchantForgotParam {
@Schema(description = "用户绑定手机号")
private String phone;
@Schema(description = "验证码")
private String smsCaptcha;
}

View File

@@ -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;

View File

@@ -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());
}
}

View File

@@ -1,4 +0,0 @@
{
"aliyun": "Alibaba Cloud",
"tencent": "Tencent Cloud"
}

View File

@@ -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",

View File

@@ -1,4 +0,0 @@
{
"configNotExist": "SMS configuration not found",
"defaultConfigNotExist": "Default SMS configuration not found"
}

View File

@@ -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"
}
}
}

View File

@@ -1,4 +0,0 @@
{
"aliyun": "阿里云",
"tencent": "腾讯云"
}

View File

@@ -1,9 +1,5 @@
{
"phoneRegistered": "该手机号已注册",
"smsSendFailed": "发送验证码失败",
"smsCodeError": "验证码错误或已过期",
"mchNoGenFailed": "商户号生成失败",
"smsConfigNotExist": "短信配置不存在,请先完成短信配置",
"accountOrPhoneNotFound": "未找到该账号或绑定手机信息",
"accountOrPhoneError": "账号或手机号信息不正确",
"dataErrorNoMchNo": "数据错误, 未发现商户号",

View File

@@ -1,4 +0,0 @@
{
"configNotExist": "短信配置不存在",
"defaultConfigNotExist": "默认短信配置不存在"
}

View File

@@ -350,9 +350,6 @@
"configName": {
"notBlank": "配置名称不能为空"
},
"smsProvider": {
"notBlank": "短信服务商不可为空"
},
"endpoint": {
"notBlank": "服务端点不能为空"
},
@@ -437,8 +434,5 @@
"oldPassword": {
"notBlank": "旧密码不能为空"
},
"smsConfigId": {
"notNull": "短信配置ID不能为空"
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -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> {
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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());
}
}

View File

@@ -50,6 +50,4 @@ sa-token:
easy-trans:
#启用平铺模式
is-enable-tile: true
# 平台配置
sms:
is-print: false