Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,22 @@ public static class CaptchaSms {
* 模板 ID
*/
private String templateId;

/**
* 供应商渠道
*
* @see top.continew.admin.system.model.resp.SmsConfigResp#supplier
*/
private String supplier;

/**
* 验证码字段模版键名
*/
private String codeKey = "code";

/**
* 失效时间字段模版键名
*/
private String timeKey = "expirationInMinutes";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package top.continew.admin.system.config.sms;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.dromara.sms4j.provider.config.BaseConfig;
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
import org.dromara.sms4j.provider.factory.ProviderFactoryHolder;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import top.continew.admin.system.model.resp.SmsConfigResp;

/**
* 短信配置工具类
*
* @author Top2Hub
* @since 2025/04/21 14:00
*/

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class SmsConfigUtil {

private static final TypeReference<Map<String, Object>> CONFIG_MAP_TYPE = new TypeReference<Map<String, Object>>() {};
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

/**
* 将本地配置对象转换为 BaseConfig
*
* @param smsConfig 本地配置对象
* @return SMS4j 配置基类
*/
public static BaseConfig from(SmsConfigResp smsConfig) {
if (Objects.isNull(smsConfig))
return null;

String supplierName = smsConfig.getSupplier();
BaseProviderFactory<?, ?> providerFactory = ProviderFactoryHolder.requireForSupplier(supplierName);
if (Objects.isNull(providerFactory))
return null;

Map<String, Object> configInfo = new HashMap<>();
configInfo.put("configId", smsConfig.getId().toString());
configInfo.put("accessKeyId", smsConfig.getAccessKey());
configInfo.put("accessKeySecret", smsConfig.getSecretKey());
configInfo.put("signature", smsConfig.getSignature());
configInfo.put("templateId", smsConfig.getTemplateId());
if (Objects.nonNull(smsConfig.getWeight()))
configInfo.put("weight", smsConfig.getWeight());
if (Objects.nonNull(smsConfig.getRetryInterval()))
configInfo.put("retryInterval", smsConfig.getRetryInterval());
if (Objects.nonNull(smsConfig.getMaxRetries()))
configInfo.put("maxRetries", smsConfig.getMaxRetries());

if (Objects.nonNull(smsConfig.getSupplierConfig())) {
Map<String, Object> supplierInfo = OBJECT_MAPPER.convertValue(smsConfig
.getSupplierConfig(), CONFIG_MAP_TYPE);
configInfo.putAll(supplierInfo);
}

BaseConfig config = (BaseConfig)OBJECT_MAPPER.convertValue(configInfo, providerFactory.getConfigClass());
return config;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;

import org.dromara.sms4j.core.datainterface.SmsReadConfig;
import org.dromara.sms4j.provider.config.BaseConfig;
import org.springframework.stereotype.Component;

import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.system.model.query.SmsConfigQuery;
import top.continew.admin.system.model.resp.SmsConfigResp;
Expand Down Expand Up @@ -48,7 +50,7 @@ public BaseConfig getSupplierConfig(String configId) {
if (DisEnableStatusEnum.DISABLE.equals(smsConfig.getStatus())) {
return null;
}
return smsConfig.getSupplier().toBaseConfig(smsConfig);
return SmsConfigUtil.from(smsConfig);
}

@Override
Expand All @@ -59,6 +61,6 @@ public List<BaseConfig> getSupplierConfigList() {
if (CollUtil.isEmpty(list)) {
return List.of();
}
return list.stream().map(smsConfig -> smsConfig.getSupplier().toBaseConfig(smsConfig)).toList();
return list.stream().map(smsConfig -> SmsConfigUtil.from(smsConfig)).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
* @author luoqiz
* @author Charles7c
* @since 2025/03/15 22:15
*
* @deprecated 使用数据字典`sms_supplier_type`动态维护
*/
@Deprecated
@Getter
@RequiredArgsConstructor
public enum SmsSupplierEnum implements BaseEnum<String> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import lombok.Data;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.model.entity.BaseDO;
import top.continew.admin.system.enums.SmsSupplierEnum;
import top.continew.starter.security.crypto.annotation.FieldEncrypt;

import java.io.Serial;
Expand All @@ -47,7 +46,7 @@ public class SmsConfigDO extends BaseDO {
/**
* 厂商
*/
private SmsSupplierEnum supplier;
private String supplier;

/**
* Access Key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.system.enums.SmsSupplierEnum;
import top.continew.starter.data.core.annotation.Query;
import top.continew.starter.data.core.enums.QueryType;

Expand Down Expand Up @@ -52,7 +51,7 @@ public class SmsConfigQuery implements Serializable {
*/
@Schema(description = "厂商", example = "cloopen")
@Query
private SmsSupplierEnum supplier;
private String supplier;

/**
* Access Key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

import org.hibernate.validator.constraints.Length;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.system.enums.SmsSupplierEnum;

import java.io.Serial;
import java.io.Serializable;
Expand Down Expand Up @@ -56,7 +55,7 @@ public class SmsConfigReq implements Serializable {
*/
@Schema(description = "厂商", example = "cloopen")
@NotNull(message = "厂商无效")
private SmsSupplierEnum supplier;
private String supplier;

/**
* Access Key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.continew.admin.common.config.excel.DictExcelProperty;
import top.continew.admin.common.config.excel.ExcelDictConverter;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.common.model.resp.BaseDetailResp;
import top.continew.admin.system.enums.SmsSupplierEnum;
import top.continew.starter.file.excel.converter.ExcelBaseEnumConverter;
import top.continew.starter.security.mask.annotation.JsonMask;

Expand Down Expand Up @@ -52,10 +53,14 @@ public class SmsConfigResp extends BaseDetailResp {

/**
* 厂商
* 对齐 sms4j 短信服务商常量类
*
* @see org.dromara.sms4j.comm.constant.SupplierConstant
*/
@Schema(description = "厂商", example = "cloopen")
@ExcelProperty(value = "厂商")
private SmsSupplierEnum supplier;
@ExcelProperty(value = "厂商", converter = ExcelDictConverter.class)
@DictExcelProperty("sms_supplier_type")
private String supplier;

/**
* Access Key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

package top.continew.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;

import org.dromara.sms4j.core.factory.SmsFactory;
import org.dromara.sms4j.provider.config.BaseConfig;
import org.springframework.stereotype.Service;
import top.continew.admin.system.enums.SmsSupplierEnum;

import top.continew.admin.system.config.sms.SmsConfigUtil;
import top.continew.admin.system.mapper.SmsConfigMapper;
import top.continew.admin.system.model.entity.SmsConfigDO;
import top.continew.admin.system.model.query.SmsConfigQuery;
Expand All @@ -31,6 +32,7 @@
import top.continew.starter.extension.crud.service.BaseServiceImpl;

import java.util.List;
import java.util.Objects;

/**
* 短信配置业务实现
Expand Down Expand Up @@ -69,9 +71,11 @@ public void afterDelete(List<Long> ids) {
* @param entity 配置信息
*/
private void load(SmsConfigDO entity) {
SmsSupplierEnum supplier = entity.getSupplier();
BaseConfig config = supplier.toBaseConfig(BeanUtil.toBean(entity, SmsConfigResp.class));
SmsFactory.createSmsBlend(config);
SmsConfigResp smsConfig = this.get(entity.getId());

BaseConfig config = SmsConfigUtil.from(smsConfig);
if (Objects.nonNull(config))
SmsFactory.createSmsBlend(config);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import lombok.RequiredArgsConstructor;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.comm.constant.SupplierConstant;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.annotation.Validated;
Expand Down Expand Up @@ -204,12 +203,16 @@ public R getSmsCaptcha(@NotBlank(message = "手机号不能为空") @Mobile Stri
String captcha = RandomUtil.randomNumbers(captchaSms.getLength());
// 发送验证码
Long expirationInMinutes = captchaSms.getExpirationInMinutes();
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.CLOOPEN);

SmsBlend smsBlend = SmsFactory.getBySupplier(captchaSms.getSupplier());

Map<String, String> messageMap = MapUtil.newHashMap(2, true);
messageMap.put("captcha", captcha);
messageMap.put("expirationInMinutes", String.valueOf(expirationInMinutes));
messageMap.put(captchaSms.getCodeKey(), captcha);
messageMap.put(captchaSms.getTimeKey(), String.valueOf(expirationInMinutes));

SmsResponse smsResponse = smsBlend.sendMessage(phone, captchaSms
.getTemplateId(), (LinkedHashMap<String, String>)messageMap);

CheckUtils.throwIf(!smsResponse.isSuccess(), "验证码发送失败");
// 保存验证码
String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + phone;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ databaseChangeLog:
file: db/changelog/mysql/plugin/plugin_open.sql
- include:
file: db/changelog/mysql/plugin/plugin_generator.sql
- include:
file: db/changelog/mysql/sms_dict_data.sql
# PostgreSQL
# - include:
# file: db/changelog/postgresql/main_table.sql
Expand All @@ -23,4 +25,6 @@ databaseChangeLog:
# - include:
# file: db/changelog/postgresql/plugin/plugin_open.sql
# - include:
# file: db/changelog/postgresql/plugin/plugin_generator.sql
# file: db/changelog/postgresql/plugin/plugin_generator.sql
# - include:
# file: db/changelog/postgresql/sms_dict_data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- liquibase formatted sql

-- changeset TopHub:2
-- comment 新增 短信厂商 字典

-- 新增 短信厂商 字典数据
INSERT INTO `sys_dict`
(`id`, `name`, `code`, `description`, `is_system`, `create_user`, `create_time`)
VALUES
(4, '短信厂商', 'sms_supplier_type', NULL, b'1', 1, NOW());

-- 新增 短信厂商 字典项
INSERT INTO `sys_dict_item`
(`id`, `label`, `value`, `color`, `sort`, `description`, `status`, `dict_id`, `create_user`, `create_time`)
VALUES
(8, '阿里云', 'alibaba', 'primary', 1, NULL, 1, 4, 1, NOW()),
(9, '容联云', 'cloopen', 'success', 2, NULL, 1, 4, 1, NOW()),
(10, '天翼云', 'ctyun', 'warning', 3, NULL, 1, 4, 1, NOW()),
(11, '亿美软通', 'emay', 'primary', 4, NULL, 1, 4, 1, NOW()),
(12, '华为', 'huawei', 'success', 5, NULL, 1, 4, 1, NOW()),
(13, '京东', 'jdcloud', 'warning', 6, NULL, 1, 4, 1, NOW()),
(14, '网易', 'netease', 'primary', 7, NULL, 1, 4, 1, NOW()),
(15, '腾讯', 'tencent', 'success', 8, NULL, 1, 4, 1, NOW()),
(16, '合一', 'unisms', 'warning', 9, NULL, 1, 4, 1, NOW()),
(17, '云片', 'yunpian', 'primary', 10, NULL, 1, 4, 1, NOW()),
(18, '助通', 'zhutong', 'success', 11, NULL, 1, 4, 1, NOW()),
(19, '联麓', 'lianlu', 'warning', 12, NULL, 1, 4, 1, NOW()),
(20, '鼎众', 'dingzhong', 'primary', 13, NULL, 1, 4, 1, NOW()),
(21, '七牛云', 'qiniu', 'success', 14, NULL, 1, 4, 1, NOW()),
(22, '创蓝', 'chuanglan', 'warning', 15, NULL, 1, 4, 1, NOW()),
(23, '极光', 'jiguang', 'primary', 16, NULL, 1, 4, 1, NOW()),
(24, '布丁云V2', 'buding_v2', 'success', 17, NULL, 1, 4, 1, NOW()),
(25, '中国移动 云MAS', 'mas', 'warning', 18, NULL, 1, 4, 1, NOW()),
(26, '百度云', 'baidu', 'primary', 19, NULL, 1, 4, 1, NOW()),
(27, '螺丝帽', 'luosimao', 'success', 20, NULL, 1, 4, 1, NOW()),
(28, 'SUBMAIL短信', 'mysubmail', 'success', 21, NULL, 1, 4, 1, NOW()),
(29, '单米科技短信', 'danmi', 'success', 22, NULL, 1, 4, 1, NOW()),
(30, '联通一信通', 'yixintong', 'success', 23, NULL, 1, 4, 1, NOW());
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- liquibase formatted sql

-- changeset TopHub:2
-- comment 新增 短信厂商 字典

-- 新增 短信厂商 字典数据
INSERT INTO "sys_dict"
("id", "name", "code", "description", "is_system", "create_user", "create_time")
VALUES
(4, '短信厂商', 'sms_supplier_type', NULL, true, 1, NOW());

-- 新增 短信厂商 字典项
INSERT INTO "sys_dict_item"
("id", "label", "value", "color", "sort", "description", "status", "dict_id", "create_user", "create_time")
VALUES
(8, '阿里云', 'alibaba', 'primary', 1, NULL, 1, 4, 1, NOW()),
(9, '容联云', 'cloopen', 'success', 2, NULL, 1, 4, 1, NOW()),
(10, '天翼云', 'ctyun', 'warning', 3, NULL, 1, 4, 1, NOW()),
(11, '亿美软通', 'emay', 'primary', 4, NULL, 1, 4, 1, NOW()),
(12, '华为', 'huawei', 'success', 5, NULL, 1, 4, 1, NOW()),
(13, '京东', 'jdcloud', 'warning', 6, NULL, 1, 4, 1, NOW()),
(14, '网易', 'netease', 'primary', 7, NULL, 1, 4, 1, NOW()),
(15, '腾讯', 'tencent', 'success', 8, NULL, 1, 4, 1, NOW()),
(16, '合一', 'unisms', 'warning', 9, NULL, 1, 4, 1, NOW()),
(17, '云片', 'yunpian', 'primary', 10, NULL, 1, 4, 1, NOW()),
(18, '助通', 'zhutong', 'success', 11, NULL, 1, 4, 1, NOW()),
(19, '联麓', 'lianlu', 'warning', 12, NULL, 1, 4, 1, NOW()),
(20, '鼎众', 'dingzhong', 'primary', 13, NULL, 1, 4, 1, NOW()),
(21, '七牛云', 'qiniu', 'success', 14, NULL, 1, 4, 1, NOW()),
(22, '创蓝', 'chuanglan', 'warning', 15, NULL, 1, 4, 1, NOW()),
(23, '极光', 'jiguang', 'primary', 16, NULL, 1, 4, 1, NOW()),
(24, '布丁云V2', 'buding_v2', 'success', 17, NULL, 1, 4, 1, NOW()),
(25, '中国移动 云MAS', 'mas', 'warning', 18, NULL, 1, 4, 1, NOW()),
(26, '百度云', 'baidu', 'primary', 19, NULL, 1, 4, 1, NOW()),
(27, '螺丝帽', 'luosimao', 'success', 20, NULL, 1, 4, 1, NOW()),
(28, 'SUBMAIL短信', 'mysubmail', 'success', 21, NULL, 1, 4, 1, NOW()),
(29, '单米科技短信', 'danmi', 'success', 22, NULL, 1, 4, 1, NOW()),
(30, '联通一信通', 'yixintong', 'success', 23, NULL, 1, 4, 1, NOW());
Loading