项目结构调整 x 3

This commit is contained in:
YunaiV
2021-04-28 13:59:28 +08:00
parent f99d48a79b
commit 90e4966420
40 changed files with 451 additions and 477 deletions

View File

@@ -9,6 +9,10 @@ package cn.iocoder.dashboard.framework.apollo.core;
*/
public class ConfigConsts {
/**
* {@link cn.iocoder.dashboard.framework.apollo.internals.ConfigFrameworkDAO} 的实现类
*/
public static final String APOLLO_JDBC_DAO = "apollo.jdbc.dao";
public static final String APOLLO_JDBC_URL = "apollo.jdbc.url";
public static final String APOLLO_JDBC_USERNAME = "apollo.jdbc.username";
public static final String APOLLO_JDBC_PASSWORD = "apollo.jdbc.password";

View File

@@ -1,12 +1,16 @@
package cn.iocoder.dashboard.framework.apollo.internals;
import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;
import cn.iocoder.dashboard.framework.apollo.internals.dto.ConfigRespDTO;
import java.util.Date;
import java.util.List;
/**
* 配置 Framework DAO 接口
*
* 注意,实现类必须提供 (String jdbcUrl, String username, String password) 构造方法
*
* @author 芋道源码
*/
public interface ConfigFrameworkDAO {
@@ -23,6 +27,6 @@ public interface ConfigFrameworkDAO {
*
* @return 配置列表
*/
List<InfConfigDO> selectList();
List<ConfigRespDTO> selectList();
}

View File

@@ -2,9 +2,8 @@ package cn.iocoder.dashboard.framework.apollo.internals;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.dashboard.framework.apollo.core.ConfigConsts;
import cn.iocoder.dashboard.framework.apollo.internals.dto.ConfigRespDTO;
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.dashboard.modules.infra.dal.mysql.config.InfConfigDAOImpl;
import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;
import com.ctrip.framework.apollo.Apollo;
import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
@@ -59,6 +58,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
this.propertiesFactory = ApolloInjector.getInstance(PropertiesFactory.class);
this.m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
// 初始化 DB
cn.iocoder.dashboard.modules.infra.dal.mysql.config
this.configFrameworkDAO = new InfConfigDAOImpl(System.getProperty(ConfigConsts.APOLLO_JDBC_URL),
System.getProperty(ConfigConsts.APOLLO_JDBC_USERNAME), System.getProperty(ConfigConsts.APOLLO_JDBC_PASSWORD));
@@ -84,7 +84,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
@Override
protected void sync() {
// 第一步,尝试获取配置
List<InfConfigDO> configs = this.loadConfigIfUpdate(this.maxUpdateTime);
List<ConfigRespDTO> configs = this.loadConfigIfUpdate(this.maxUpdateTime);
if (CollUtil.isEmpty(configs)) { // 如果没有更新,则返回
return;
}
@@ -94,7 +94,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
this.m_configCache = newProperties;
// 第三步,获取最大的配置时间
assert configs.size() > 0; // 断言,避免告警
this.maxUpdateTime = configs.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime();
this.maxUpdateTime = configs.stream().max(Comparator.comparing(ConfigRespDTO::getUpdateTime)).get().getUpdateTime();
// 第四部,触发配置刷新!重要!!!!
super.fireRepositoryChange(m_namespace, newProperties);
log.info("[sync][缓存配置,数量为:{}]", configs.size());
@@ -120,9 +120,9 @@ public class DBConfigRepository extends AbstractConfigRepository {
return ConfigSourceType.REMOTE;
}
private Properties buildProperties(List<InfConfigDO> configs) {
private Properties buildProperties(List<ConfigRespDTO> configs) {
Properties properties = propertiesFactory.getPropertiesInstance();
configs.stream().filter(BaseDO::getDeleted) // 过滤掉被删除的配置
configs.stream().filter(ConfigRespDTO::getDeleted) // 过滤掉被删除的配置
.forEach(config -> properties.put(config.getKey(), config.getValue()));
return properties;
}
@@ -153,7 +153,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
* @param maxUpdateTime 当前配置的最大更新时间
* @return 配置列表
*/
private List<InfConfigDO> loadConfigIfUpdate(Date maxUpdateTime) {
private List<ConfigRespDTO> loadConfigIfUpdate(Date maxUpdateTime) {
// 第一步,判断是否要更新。
if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
log.info("[loadConfigIfUpdate][首次加载全量配置]");

View File

@@ -0,0 +1,33 @@
package cn.iocoder.dashboard.framework.apollo.internals.dto;
import lombok.Data;
import java.util.Date;
/**
* 配置 Response DTO
*
* @author 芋道源码
*/
@Data
public class ConfigRespDTO {
/**
* 参数键名
*/
private String key;
/**
* 参数键值
*/
private String value;
/**
* 是否删除
*/
private Boolean deleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,33 @@
package cn.iocoder.dashboard.framework.dict.core.dto;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import lombok.Data;
/**
* 字典数据 Response DTO
*
* @author 芋道源码
*/
@Data
public class DictDataRespDTO {
/**
* 字典标签
*/
private String label;
/**
* 字典值
*/
private String value;
/**
* 字典类型
*/
private String dictType;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}

View File

@@ -1,6 +1,6 @@
package cn.iocoder.dashboard.framework.dict.core.service;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO;
import cn.iocoder.dashboard.framework.dict.core.dto.DictDataRespDTO;
import java.util.List;
@@ -13,7 +13,7 @@ public interface DictDataFrameworkService {
* @param value 字典数据值
* @return 字典数据
*/
SysDictDataDO getDictDataFromCache(String type, String value);
DictDataRespDTO getDictDataFromCache(String type, String value);
/**
* 解析获得指定的字典数据,从缓存中
@@ -22,7 +22,7 @@ public interface DictDataFrameworkService {
* @param label 字典数据标签
* @return 字典数据
*/
SysDictDataDO parseDictDataFromCache(String type, String label);
DictDataRespDTO parseDictDataFromCache(String type, String label);
/**
* 获得指定类型的字典数据,从缓存中
@@ -30,6 +30,6 @@ public interface DictDataFrameworkService {
* @param type 字典类型
* @return 字典数据列表
*/
List<SysDictDataDO> listDictDatasFromCache(String type);
List<DictDataRespDTO> listDictDatasFromCache(String type);
}

View File

@@ -1,7 +1,7 @@
package cn.iocoder.dashboard.framework.dict.core.util;
import cn.iocoder.dashboard.framework.dict.core.dto.DictDataRespDTO;
import cn.iocoder.dashboard.framework.dict.core.service.DictDataFrameworkService;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO;
import lombok.extern.slf4j.Slf4j;
/**
@@ -17,11 +17,11 @@ public class DictUtils {
log.info("[init][初始化 DictUtils 成功]");
}
public static SysDictDataDO getDictDataFromCache(String type, String value) {
public static DictDataRespDTO getDictDataFromCache(String type, String value) {
return service.getDictDataFromCache(type, value);
}
public static SysDictDataDO parseDictDataFromCache(String type, String label) {
public static DictDataRespDTO parseDictDataFromCache(String type, String label) {
return service.getDictDataFromCache(type, label);
}

View File

@@ -2,9 +2,9 @@ package cn.iocoder.dashboard.framework.excel.core.convert;
import cn.hutool.core.convert.Convert;
import cn.iocoder.dashboard.framework.dict.core.dto.DictDataRespDTO;
import cn.iocoder.dashboard.framework.dict.core.util.DictUtils;
import cn.iocoder.dashboard.framework.excel.core.annotations.DictFormat;
import cn.iocoder.dashboard.modules.system.dal.dataobject.dict.SysDictDataDO;
import cn.iocoder.dashboard.modules.system.enums.dict.SysDictTypeEnum;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
@@ -14,7 +14,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.extern.slf4j.Slf4j;
/**
* Excel {@link SysDictDataDO} 数据字典转换器
* Excel {@link DictDataRespDTO} 数据字典转换器
*
* @author 芋道源码
*/
@@ -37,7 +37,7 @@ public class DictConvert implements Converter<Object> {
// 使用字典解析
SysDictTypeEnum type = getType(contentProperty);
String label = cellData.getStringValue();
SysDictDataDO dictData = DictUtils.parseDictDataFromCache(type.getValue(), label);
DictDataRespDTO dictData = DictUtils.parseDictDataFromCache(type.getValue(), label);
if (dictData == null) {
log.error("[convertToJavaData][type({}) 解析不掉 label({})]", type, label);
return null;
@@ -58,7 +58,7 @@ public class DictConvert implements Converter<Object> {
// 使用字典格式化
SysDictTypeEnum type = getType(contentProperty);
String value = String.valueOf(object);
SysDictDataDO dictData = DictUtils.getDictDataFromCache(type.getValue(), value);
DictDataRespDTO dictData = DictUtils.getDictDataFromCache(type.getValue(), value);
if (dictData == null) {
log.error("[convertToExcelData][type({}) 转换不了 label({})]", type, value);
return new CellData<>("");

View File

@@ -1,6 +1,5 @@
package cn.iocoder.dashboard.framework.file.config;
import cn.iocoder.dashboard.modules.infra.controller.file.InfFileController;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
@@ -13,7 +12,7 @@ import javax.validation.constraints.NotNull;
public class FileProperties {
/**
* 对应 {@link InfFileController#}
* 对应 InfFileController 的 getFile 方法
*/
@NotNull(message = "基础文件路径不能为空")
private String basePath;

View File

@@ -6,11 +6,11 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.logger.operatelog.core.annotations.OperateLog;
import cn.iocoder.dashboard.framework.logger.operatelog.core.dto.OperateLogCreateReqDTO;
import cn.iocoder.dashboard.framework.logger.operatelog.core.enums.OperateTypeEnum;
import cn.iocoder.dashboard.framework.logger.operatelog.core.service.OperateLogFrameworkService;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO;
import cn.iocoder.dashboard.util.json.JsonUtils;
import cn.iocoder.dashboard.util.servlet.ServletUtils;
import com.google.common.collect.Maps;
@@ -55,13 +55,13 @@ public class OperateLogAspect {
/**
* 用于记录操作内容的上下文
*
* @see SysOperateLogCreateReqVO#getContent()
* @see OperateLogCreateReqDTO#getContent()
*/
private static final ThreadLocal<String> CONTENT = new ThreadLocal<>();
/**
* 用于记录拓展字段的上下文
*
* @see SysOperateLogCreateReqVO#getExts()
* @see OperateLogCreateReqDTO#getExts()
*/
private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
@@ -130,106 +130,106 @@ public class OperateLogAspect {
private void log0(ProceedingJoinPoint joinPoint, OperateLog operateLog, ApiOperation apiOperation,
Date startTime, Object result, Throwable exception) {
SysOperateLogCreateReqVO operateLogVO = new SysOperateLogCreateReqVO();
OperateLogCreateReqDTO operateLogDTO = new OperateLogCreateReqDTO();
// 补全通用字段
operateLogVO.setTraceId(TracerUtils.getTraceId());
operateLogVO.setStartTime(startTime);
operateLogDTO.setTraceId(TracerUtils.getTraceId());
operateLogDTO.setStartTime(startTime);
// 补充用户信息
fillUserFields(operateLogVO);
fillUserFields(operateLogDTO);
// 补全模块信息
fillModuleFields(operateLogVO, joinPoint, operateLog, apiOperation);
fillModuleFields(operateLogDTO, joinPoint, operateLog, apiOperation);
// 补全请求信息
fillRequestFields(operateLogVO);
fillRequestFields(operateLogDTO);
// 补全方法信息
fillMethodFields(operateLogVO, joinPoint, operateLog, startTime, result, exception);
fillMethodFields(operateLogDTO, joinPoint, operateLog, startTime, result, exception);
// 异步记录日志
operateLogFrameworkService.createOperateLogAsync(operateLogVO);
operateLogFrameworkService.createOperateLogAsync(operateLogDTO);
}
private static void fillUserFields(SysOperateLogCreateReqVO operateLogVO) {
operateLogVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
private static void fillUserFields(OperateLogCreateReqDTO operateLogDTO) {
operateLogDTO.setUserId(SecurityFrameworkUtils.getLoginUserId());
}
private static void fillModuleFields(SysOperateLogCreateReqVO operateLogVO,
private static void fillModuleFields(OperateLogCreateReqDTO operateLogDTO,
ProceedingJoinPoint joinPoint, OperateLog operateLog, ApiOperation apiOperation) {
// module 属性
if (operateLog != null) {
operateLogVO.setModule(operateLog.module());
operateLogDTO.setModule(operateLog.module());
}
if (StrUtil.isEmpty(operateLogVO.getModule())) {
if (StrUtil.isEmpty(operateLogDTO.getModule())) {
Api api = getClassAnnotation(joinPoint, Api.class);
if (api != null) {
// 优先读取 @API 的 name 属性
if (StrUtil.isNotEmpty(api.value())) {
operateLogVO.setModule(api.value());
operateLogDTO.setModule(api.value());
}
// 没有的话,读取 @API 的 tags 属性
if (StrUtil.isEmpty(operateLogVO.getModule()) && ArrayUtil.isNotEmpty(api.tags())) {
operateLogVO.setModule(api.tags()[0]);
if (StrUtil.isEmpty(operateLogDTO.getModule()) && ArrayUtil.isNotEmpty(api.tags())) {
operateLogDTO.setModule(api.tags()[0]);
}
}
}
// name 属性
if (operateLog != null) {
operateLogVO.setName(operateLog.name());
operateLogDTO.setName(operateLog.name());
}
if (StrUtil.isEmpty(operateLogVO.getName()) && apiOperation != null) {
operateLogVO.setName(apiOperation.value());
if (StrUtil.isEmpty(operateLogDTO.getName()) && apiOperation != null) {
operateLogDTO.setName(apiOperation.value());
}
// type 属性
if (operateLog != null && ArrayUtil.isNotEmpty(operateLog.type())) {
operateLogVO.setType(operateLog.type()[0].getType());
operateLogDTO.setType(operateLog.type()[0].getType());
}
if (operateLogVO.getType() == null) {
if (operateLogDTO.getType() == null) {
RequestMethod requestMethod = obtainFirstMatchRequestMethod(obtainRequestMethod(joinPoint));
OperateTypeEnum operateLogType = convertOperateLogType(requestMethod);
operateLogVO.setType(operateLogType != null ? operateLogType.getType() : null);
operateLogDTO.setType(operateLogType != null ? operateLogType.getType() : null);
}
// content 和 exts 属性
operateLogVO.setContent(CONTENT.get());
operateLogVO.setExts(EXTS.get());
operateLogDTO.setContent(CONTENT.get());
operateLogDTO.setExts(EXTS.get());
}
private static void fillRequestFields(SysOperateLogCreateReqVO operateLogVO) {
private static void fillRequestFields(OperateLogCreateReqDTO operateLogDTO) {
// 获得 Request 对象
HttpServletRequest request = ServletUtils.getRequest();
if (request == null) {
return;
}
// 补全请求信息
operateLogVO.setRequestMethod(request.getMethod());
operateLogVO.setRequestUrl(request.getRequestURI());
operateLogVO.setUserIp(ServletUtil.getClientIP(request));
operateLogVO.setUserAgent(ServletUtils.getUserAgent(request));
operateLogDTO.setRequestMethod(request.getMethod());
operateLogDTO.setRequestUrl(request.getRequestURI());
operateLogDTO.setUserIp(ServletUtil.getClientIP(request));
operateLogDTO.setUserAgent(ServletUtils.getUserAgent(request));
}
private static void fillMethodFields(SysOperateLogCreateReqVO operateLogVO,
private static void fillMethodFields(OperateLogCreateReqDTO operateLogDTO,
ProceedingJoinPoint joinPoint, OperateLog operateLog,
Date startTime, Object result, Throwable exception) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
operateLogVO.setJavaMethod(methodSignature.toString());
operateLogDTO.setJavaMethod(methodSignature.toString());
if (operateLog == null || operateLog.logArgs()) {
operateLogVO.setJavaMethodArgs(obtainMethodArgs(joinPoint));
operateLogDTO.setJavaMethodArgs(obtainMethodArgs(joinPoint));
}
if (operateLog == null || operateLog.logResultData()) {
operateLogVO.setResultData(obtainResultData(result));
operateLogDTO.setResultData(obtainResultData(result));
}
operateLogVO.setDuration((int) (System.currentTimeMillis() - startTime.getTime()));
operateLogDTO.setDuration((int) (System.currentTimeMillis() - startTime.getTime()));
// (正常)处理 resultCode 和 resultMsg 字段
if (result != null) {
if (result instanceof CommonResult) {
CommonResult<?> commonResult = (CommonResult<?>) result;
operateLogVO.setResultCode(commonResult.getCode());
operateLogVO.setResultMsg(commonResult.getMsg());
operateLogDTO.setResultCode(commonResult.getCode());
operateLogDTO.setResultMsg(commonResult.getMsg());
} else {
operateLogVO.setResultCode(SUCCESS.getCode());
operateLogDTO.setResultCode(SUCCESS.getCode());
}
}
// (异常)处理 resultCode 和 resultMsg 字段
if (exception != null) {
operateLogVO.setResultCode(INTERNAL_SERVER_ERROR.getCode());
operateLogVO.setResultMsg(ExceptionUtil.getRootCauseMessage(exception));
operateLogDTO.setResultCode(INTERNAL_SERVER_ERROR.getCode());
operateLogDTO.setResultMsg(ExceptionUtil.getRootCauseMessage(exception));
}
}

View File

@@ -0,0 +1,84 @@
package cn.iocoder.dashboard.framework.logger.operatelog.core.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.Map;
/**
* 操作日志创建 Request DTO
*/
@Data
public class OperateLogCreateReqDTO {
@ApiModelProperty(value = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab")
@NotEmpty(message = "链路追踪编号不能为空")
private String traceId;
@ApiModelProperty(value = "用户编号", required = true, example = "1024")
@NotNull(message = "用户编号不能为空")
private Long userId;
@ApiModelProperty(value = "操作模块", required = true, example = "订单")
@NotEmpty(message = "操作模块不能为空")
private String module;
@ApiModelProperty(value = "操作名", required = true, example = "创建订单")
@NotEmpty(message = "操作名")
private String name;
@ApiModelProperty(value = "操作分类", required = true, example = "1", notes = "参见 SysOperateLogTypeEnum 枚举类")
@NotNull(message = "操作分类不能为空")
private Integer type;
@ApiModelProperty(value = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。")
private String content;
@ApiModelProperty(value = "拓展字段", example = "{'orderId': 1}")
private Map<String, Object> exts;
@ApiModelProperty(value = "请求方法名", required = true, example = "GET")
@NotEmpty(message = "请求方法名不能为空")
private String requestMethod;
@ApiModelProperty(value = "请求地址", required = true, example = "/xxx/yyy")
@NotEmpty(message = "请求地址不能为空")
private String requestUrl;
@ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1")
@NotEmpty(message = "用户 IP 不能为空")
private String userIp;
@ApiModelProperty(value = "浏览器 UserAgent", required = true, example = "Mozilla/5.0")
@NotEmpty(message = "浏览器 UserAgent 不能为空")
private String userAgent;
@ApiModelProperty(value = "Java 方法名", required = true, example = "cn.iocoder.dashboard.UserController.save(...)")
@NotEmpty(message = "Java 方法名不能为空")
private String javaMethod;
@ApiModelProperty(value = "Java 方法的参数")
private String javaMethodArgs;
@ApiModelProperty(value = "开始时间", required = true)
@NotNull(message = "开始时间不能为空")
private Date startTime;
@ApiModelProperty(value = "执行时长,单位:毫秒", required = true)
@NotNull(message = "执行时长不能为空")
private Integer duration;
@ApiModelProperty(value = "结果码", required = true)
@NotNull(message = "结果码不能为空")
private Integer resultCode;
@ApiModelProperty(value = "结果提示")
private String resultMsg;
@ApiModelProperty(value = "结果数据")
private String resultData;
}

View File

@@ -1,6 +1,6 @@
package cn.iocoder.dashboard.framework.logger.operatelog.core.service;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.operatelog.SysOperateLogCreateReqVO;
import cn.iocoder.dashboard.framework.logger.operatelog.core.dto.OperateLogCreateReqDTO;
import java.util.concurrent.Future;
@@ -12,6 +12,6 @@ public interface OperateLogFrameworkService {
* @param reqVO 操作日志请求
* @return true: 记录成功,false: 记录失败
*/
Future<Boolean> createOperateLogAsync(SysOperateLogCreateReqVO reqVO);
Future<Boolean> createOperateLogAsync(OperateLogCreateReqDTO reqVO);
}

View File

@@ -1,6 +1,5 @@
package cn.iocoder.dashboard.framework.mybatis.core.type;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.util.json.JsonUtils;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.fasterxml.jackson.core.type.TypeReference;
@@ -11,7 +10,7 @@ import java.util.Set;
* 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现
* 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。
*
* 例如说哦,{@link SysUserDO#getPostIds()} 属性
* 例如说哦SysUserDO 的 postIds 属性
*
* @author 芋道源码
*/

View File

@@ -4,9 +4,9 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.framework.security.core.service.SecurityAuthFrameworkService;
import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.dashboard.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService;
import cn.iocoder.dashboard.util.servlet.ServletUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@@ -30,7 +30,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Resource
private SecurityProperties securityProperties;
@Resource
private SysAuthService authService;
private SecurityAuthFrameworkService authService;
@Resource
private GlobalExceptionHandler globalExceptionHandler;

View File

@@ -1,7 +1,5 @@
package cn.iocoder.dashboard.framework.security.core.service;
import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
/**
* Security 框架 Permission Service 接口,定义 security 组件需要的功能
*
@@ -28,7 +26,7 @@ public interface SecurityPermissionFrameworkService {
/**
* 判断是否有角色
*
* 注意,角色使用的是 {@link SysRoleDO#getCode()} 标识
* 注意,角色使用的是 SysRoleDO 的 code 标识
*
* @param role 角色
* @return 是否

View File

@@ -1,224 +0,0 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.dashboard.BaseMockitoUnitTest;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.util.collection.MapUtils;
import cn.iocoder.dashboard.util.date.DateUtils;
import com.aliyuncs.AcsRequest;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.List;
import java.util.function.Function;
import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.SMS_API_PARAM_ERROR;
import static cn.iocoder.dashboard.util.RandomUtils.*;
import static cn.iocoder.dashboard.util.json.JsonUtils.toJsonString;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.when;
/**
* {@link AliyunSmsClient} 的单元测试
*
* @author 芋道源码
*/
public class AliyunSmsClientTest extends BaseMockitoUnitTest {
private final SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey(randomString()) // 随机一个 apiKey避免构建报错
.setApiSecret(randomString()) // 随机一个 apiSecret避免构建报错
.setSignature("芋道源码");
@InjectMocks
private final AliyunSmsClient smsClient = new AliyunSmsClient(properties);
@Mock
private IAcsClient client;
@Test
public void testDoInit() {
// 准备参数
// mock 方法
// 调用
smsClient.doInit();
// 断言
assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "acsClient"));
}
@Test
@SuppressWarnings("unchecked")
public void testDoSendSms() throws ClientException {
// 准备参数
Long sendLogId = randomLongId();
String mobile = randomString();
String apiTemplateId = randomString();
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
// mock 方法
SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> o.setCode("OK"));
when(client.getAcsResponse(argThat((ArgumentMatcher<SendSmsRequest>) acsRequest -> {
assertEquals(mobile, acsRequest.getPhoneNumbers());
assertEquals(properties.getSignature(), acsRequest.getSignName());
assertEquals(apiTemplateId, acsRequest.getTemplateCode());
assertEquals(toJsonString(MapUtils.convertMap(templateParams)), acsRequest.getTemplateParam());
assertEquals(sendLogId.toString(), acsRequest.getOutId());
return true;
}))).thenReturn(response);
// 调用
SmsCommonResult<SmsSendRespDTO> result = smsClient.doSendSms(sendLogId, mobile,
apiTemplateId, templateParams);
// 断言
assertEquals(response.getCode(), result.getApiCode());
assertEquals(response.getMessage(), result.getApiMsg());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
assertEquals(response.getRequestId(), result.getApiRequestId());
// 断言结果
assertEquals(response.getBizId(), result.getData().getSerialNo());
}
@Test
public void testDoTParseSmsReceiveStatus() throws Throwable {
// 准备参数
String text = "[\n" +
" {\n" +
" \"phone_number\" : \"13900000001\",\n" +
" \"send_time\" : \"2017-01-01 11:12:13\",\n" +
" \"report_time\" : \"2017-02-02 22:23:24\",\n" +
" \"success\" : true,\n" +
" \"err_code\" : \"DELIVERED\",\n" +
" \"err_msg\" : \"用户接收成功\",\n" +
" \"sms_size\" : \"1\",\n" +
" \"biz_id\" : \"12345\",\n" +
" \"out_id\" : \"67890\"\n" +
" }\n" +
"]";
// mock 方法
// 调用
List<SmsReceiveRespDTO> statuses = smsClient.doParseSmsReceiveStatus(text);
// 断言
assertEquals(1, statuses.size());
assertTrue(statuses.get(0).getSuccess());
assertEquals("DELIVERED", statuses.get(0).getErrorCode());
assertEquals("用户接收成功", statuses.get(0).getErrorMsg());
assertEquals("13900000001", statuses.get(0).getMobile());
assertEquals(DateUtils.buildTime(2017, 2, 2, 22, 23, 24), statuses.get(0).getReceiveTime());
assertEquals("12345", statuses.get(0).getSerialNo());
assertEquals(67890L, statuses.get(0).getLogId());
}
@Test
public void testDoGetSmsTemplate() throws ClientException {
// 准备参数
String apiTemplateId = randomString();
// mock 方法
QuerySmsTemplateResponse response = randomPojo(QuerySmsTemplateResponse.class, o -> {
o.setCode("OK");
o.setTemplateStatus(1); // 设置模板通过
});
when(client.getAcsResponse(argThat((ArgumentMatcher<QuerySmsTemplateRequest>) acsRequest -> {
assertEquals(apiTemplateId, acsRequest.getTemplateCode());
return true;
}))).thenReturn(response);
// 调用
SmsCommonResult<SmsTemplateRespDTO> result = smsClient.doGetSmsTemplate(apiTemplateId);
// 断言
assertEquals(response.getCode(), result.getApiCode());
assertEquals(response.getMessage(), result.getApiMsg());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
assertEquals(response.getRequestId(), result.getApiRequestId());
// 断言结果
assertEquals(response.getTemplateCode(), result.getData().getId());
assertEquals(response.getTemplateContent(), result.getData().getContent());
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getData().getAuditStatus());
assertEquals(response.getReason(), result.getData().getAuditReason());
}
@Test
public void testConvertSmsTemplateAuditStatus() {
assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
smsClient.convertSmsTemplateAuditStatus(0));
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
smsClient.convertSmsTemplateAuditStatus(1));
assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
smsClient.convertSmsTemplateAuditStatus(2));
assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus(3),
"未知审核状态(3)");
}
@Test
@SuppressWarnings("unchecked")
public void testInvoke_throwable() throws ClientException {
// 准备参数
QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
// mock 方法
ClientException ex = new ClientException("isv.INVALID_PARAMETERS", "参数不正确", randomString());
when(client.getAcsResponse(any(AcsRequest.class))).thenThrow(ex);
// 调用,并断言异常
SmsCommonResult<?> result = smsClient.invoke(request,null);
// 断言
assertEquals(ex.getErrCode(), result.getApiCode());
assertEquals(ex.getErrMsg(), result.getApiMsg());
assertEquals(SMS_API_PARAM_ERROR.getCode(), result.getCode());
assertEquals(SMS_API_PARAM_ERROR.getMsg(), result.getMsg());
assertEquals(ex.getRequestId(), result.getApiRequestId());
}
@Test
public void testInvoke_success() throws ClientException {
// 准备参数
QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
Function<QuerySmsTemplateResponse, SmsTemplateRespDTO> responseConsumer = response -> {
SmsTemplateRespDTO data = new SmsTemplateRespDTO();
data.setId(response.getTemplateCode()).setContent(response.getTemplateContent());
data.setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus()).setAuditReason(response.getReason());
return data;
};
// mock 方法
QuerySmsTemplateResponse response = randomPojo(QuerySmsTemplateResponse.class, o -> {
o.setCode("OK");
o.setTemplateStatus(1); // 设置模板通过
});
when(client.getAcsResponse(any(AcsRequest.class))).thenReturn(response);
// 调用
SmsCommonResult<SmsTemplateRespDTO> result = smsClient.invoke(request, responseConsumer);
// 断言
assertEquals(response.getCode(), result.getApiCode());
assertEquals(response.getMessage(), result.getApiMsg());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
assertEquals(response.getRequestId(), result.getApiRequestId());
// 断言结果
assertEquals(response.getTemplateCode(), result.getData().getId());
assertEquals(response.getTemplateContent(), result.getData().getContent());
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getData().getAuditStatus());
assertEquals(response.getReason(), result.getData().getAuditReason());
}
}

View File

@@ -1,43 +0,0 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
import cn.iocoder.dashboard.BaseMockitoUnitTest;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link AliyunSmsCodeMapping} 的单元测试
*
* @author 芋道源码
*/
public class AliyunSmsCodeMappingTest extends BaseMockitoUnitTest {
@InjectMocks
private AliyunSmsCodeMapping codeMapping;
@Test
public void testApply() {
assertEquals(GlobalErrorCodeConstants.SUCCESS, codeMapping.apply("OK"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_INVALID, codeMapping.apply("MissingAccessKeyId"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_INVALID, codeMapping.apply("isv.ACCOUNT_NOT_EXISTS"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_INVALID, codeMapping.apply("isv.ACCOUNT_ABNORMAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_DAY_LIMIT_CONTROL, codeMapping.apply("isv.DAY_LIMIT_CONTROL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_CONTENT_INVALID, codeMapping.apply("isv.SMS_CONTENT_ILLEGAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SIGN_INVALID, codeMapping.apply("isv.SMS_SIGN_ILLEGAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SIGN_INVALID, codeMapping.apply("isv.SIGN_NAME_ILLEGAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_PERMISSION_DENY, codeMapping.apply("isp.RAM_PERMISSION_DENY"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_MONEY_NOT_ENOUGH, codeMapping.apply("isv.OUT_OF_SERVICE"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_MONEY_NOT_ENOUGH, codeMapping.apply("isv.AMOUNT_NOT_ENOUGH"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_TEMPLATE_INVALID, codeMapping.apply("isv.SMS_TEMPLATE_ILLEGAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SIGN_INVALID, codeMapping.apply("isv.SMS_SIGNATURE_ILLEGAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_API_PARAM_ERROR, codeMapping.apply("isv.INVALID_PARAMETERS"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_API_PARAM_ERROR, codeMapping.apply("isv.INVALID_JSON_PARAM"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_MOBILE_INVALID, codeMapping.apply("isv.MOBILE_NUMBER_ILLEGAL"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_TEMPLATE_PARAM_ERROR, codeMapping.apply("isv.TEMPLATE_MISSING_PARAMETERS"));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_BUSINESS_LIMIT_CONTROL, codeMapping.apply("isv.BUSINESS_LIMIT_CONTROL"));
}
}

View File

@@ -1,202 +0,0 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.dashboard.BaseMockitoUnitTest;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsReceiveRespDTO;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.util.date.DateUtils;
import com.google.common.collect.Lists;
import com.yunpian.sdk.YunpianClient;
import com.yunpian.sdk.api.SmsApi;
import com.yunpian.sdk.api.TplApi;
import com.yunpian.sdk.constant.YunpianConstant;
import com.yunpian.sdk.model.Result;
import com.yunpian.sdk.model.SmsSingleSend;
import com.yunpian.sdk.model.Template;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import static cn.iocoder.dashboard.util.RandomUtils.*;
import static com.yunpian.sdk.constant.Code.OK;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* 对 {@link YunpianSmsClient} 的单元测试
*
* @author 芋道源码
*/
public class YunpianSmsClientTest extends BaseMockitoUnitTest {
private final SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey(randomString()); // 随机一个 apiKey避免构建报错
@InjectMocks
private final YunpianSmsClient smsClient = new YunpianSmsClient(properties);
@Mock
private YunpianClient client;
@Test
public void testDoInit() {
// 准备参数
// mock 方法
// 调用
smsClient.doInit();
// 断言
assertNotEquals(client, ReflectUtil.getFieldValue(smsClient, "client"));
verify(client, times(1)).close();
}
@Test
@SuppressWarnings("unchecked")
public void testDoSendSms() throws Throwable {
// 准备参数
Long sendLogId = randomLongId();
String mobile = randomString();
String apiTemplateId = randomString();
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
// mock sms 方法
SmsApi smsApi = mock(SmsApi.class);
when(client.sms()).thenReturn(smsApi);
// mock tpl_single_send 方法
Map<String, String> request = new HashMap<>();
request.put(YunpianConstant.MOBILE, mobile);
request.put(YunpianConstant.TPL_ID, apiTemplateId);
request.put(YunpianConstant.TPL_VALUE, "#code#=1234&#op#=login");
request.put(YunpianConstant.UID, String.valueOf(sendLogId));
request.put(YunpianConstant.CALLBACK_URL, properties.getCallbackUrl());
Result<SmsSingleSend> responseResult = randomPojo(Result.class, SmsSingleSend.class,
o -> o.setCode(OK)); // API 发送成功的 code
when(smsApi.tpl_single_send(eq(request))).thenReturn(responseResult);
// 调用
SmsCommonResult<SmsSendRespDTO> result = smsClient.doSendSms(sendLogId, mobile,
apiTemplateId, templateParams);
// 断言
assertEquals(String.valueOf(responseResult.getCode()), result.getApiCode());
assertEquals(responseResult.getMsg() + " => " + responseResult.getDetail(), result.getApiMsg());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
assertNull(result.getApiRequestId());
// 断言结果
assertEquals(String.valueOf(responseResult.getData().getSid()), result.getData().getSerialNo());
}
@Test
public void testDoParseSmsReceiveStatus() throws Throwable {
// 准备参数
String text = "[{\"sid\":9527,\"uid\":1024,\"user_receive_time\":\"2014-03-17 22:55:21\",\"error_msg\":\"\",\"mobile\":\"15205201314\",\"report_status\":\"SUCCESS\"}]";
// mock 方法
// 调用
// 断言
// 调用
List<SmsReceiveRespDTO> statuses = smsClient.doParseSmsReceiveStatus(text);
// 断言
assertEquals(1, statuses.size());
assertTrue(statuses.get(0).getSuccess());
assertEquals("", statuses.get(0).getErrorCode());
assertNull(statuses.get(0).getErrorMsg());
assertEquals("15205201314", statuses.get(0).getMobile());
assertEquals(DateUtils.buildTime(2014, 3, 17, 22, 55, 21), statuses.get(0).getReceiveTime());
assertEquals("9527", statuses.get(0).getSerialNo());
assertEquals(1024L, statuses.get(0).getLogId());
}
@Test
@SuppressWarnings("unchecked")
public void testDoGetSmsTemplate() throws Throwable {
// 准备参数
String apiTemplateId = randomString();
// mock tpl 方法
TplApi tplApi = mock(TplApi.class);
when(client.tpl()).thenReturn(tplApi);
// mock get 方法
Map<String, String> request = new HashMap<>();
request.put(YunpianConstant.APIKEY, properties.getApiKey());
request.put(YunpianConstant.TPL_ID, apiTemplateId);
Result<List<Template>> responseResult = randomPojo(Result.class, List.class, o -> {
o.setCode(OK); // API 发送成功的 code
o.setData(randomPojoList(Template.class, t -> t.setCheck_status("SUCCESS")));
});
when(tplApi.get(eq(request))).thenReturn(responseResult);
// 调用
SmsCommonResult<SmsTemplateRespDTO> result = smsClient.doGetSmsTemplate(apiTemplateId);
// 断言
assertEquals(String.valueOf(responseResult.getCode()), result.getApiCode());
assertEquals(responseResult.getMsg() + " => " + responseResult.getDetail(), result.getApiMsg());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
assertNull(result.getApiRequestId());
// 断言结果
Template template = responseResult.getData().get(0);
assertEquals(template.getTpl_id().toString(), result.getData().getId());
assertEquals(template.getTpl_content(), result.getData().getContent());
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getData().getAuditStatus());
assertEquals(template.getReason(), result.getData().getAuditReason());
}
@Test
public void testConvertSmsTemplateAuditStatus() {
assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
smsClient.convertSmsTemplateAuditStatus("CHECKING"));
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
smsClient.convertSmsTemplateAuditStatus("SUCCESS"));
assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
smsClient.convertSmsTemplateAuditStatus("FAIL"));
assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus("test"),
"未知审核状态(test)");
}
@Test
public void testInvoke_throwable() {
// 准备参数
Supplier<Result<Object>> requestConsumer =
() -> new Result<>().setThrowable(new NullPointerException());
// mock 方法
// 调用,并断言异常
assertThrows(NullPointerException.class,
() -> smsClient.invoke(requestConsumer, null));
}
@Test
@SuppressWarnings("unchecked")
public void testInvoke_success() throws Throwable {
// 准备参数
Result<SmsSingleSend> responseResult = randomPojo(Result.class, SmsSingleSend.class, o -> o.setCode(OK));
Supplier<Result<SmsSingleSend>> requestConsumer = () -> responseResult;
Function<SmsSingleSend, SmsSendRespDTO> responseConsumer =
smsSingleSend -> new SmsSendRespDTO().setSerialNo(String.valueOf(responseResult.getData().getSid()));
// mock 方法
// 调用
SmsCommonResult<SmsSendRespDTO> result = smsClient.invoke(requestConsumer, responseConsumer);
// 断言
assertEquals(String.valueOf(responseResult.getCode()), result.getApiCode());
assertEquals(responseResult.getMsg() + " => " + responseResult.getDetail(), result.getApiMsg());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getCode(), result.getCode());
assertEquals(GlobalErrorCodeConstants.SUCCESS.getMsg(), result.getMsg());
assertNull(result.getApiRequestId());
assertEquals(String.valueOf(responseResult.getData().getSid()), result.getData().getSerialNo());
}
}

View File

@@ -1,43 +0,0 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
import cn.iocoder.dashboard.BaseMockitoUnitTest;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import static com.yunpian.sdk.constant.Code.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link YunpianSmsCodeMapping} 的单元测试
*
* @author 芋道源码
*/
class YunpianSmsCodeMappingTest extends BaseMockitoUnitTest {
@InjectMocks
private YunpianSmsCodeMapping codeMapping;
@Test
public void testApply() {
assertEquals(GlobalErrorCodeConstants.SUCCESS, codeMapping.apply(String.valueOf(OK)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_API_PARAM_ERROR, codeMapping.apply(String.valueOf(ARGUMENT_MISSING)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_TEMPLATE_PARAM_ERROR, codeMapping.apply(String.valueOf(BAD_ARGUMENT_FORMAT)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_MONEY_NOT_ENOUGH, codeMapping.apply(String.valueOf(MONEY_NOT_ENOUGH)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_TEMPLATE_INVALID, codeMapping.apply(String.valueOf(TPL_NOT_FOUND)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_TEMPLATE_INVALID, codeMapping.apply(String.valueOf(TPL_NOT_VALID)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_BUSINESS_LIMIT_CONTROL, codeMapping.apply(String.valueOf(DUP_IN_SHORT_TIME)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_BUSINESS_LIMIT_CONTROL, codeMapping.apply(String.valueOf(TOO_MANY_TIME_IN_5)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_BUSINESS_LIMIT_CONTROL, codeMapping.apply(String.valueOf(DAY_LIMIT_PER_MOBILE)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SEND_BUSINESS_LIMIT_CONTROL, codeMapping.apply(String.valueOf(HOUR_LIMIT_PER_MOBILE)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_MOBILE_BLACK, codeMapping.apply(String.valueOf(BLACK_PHONE_FILTER)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SIGN_INVALID, codeMapping.apply(String.valueOf(SIGN_NOT_MATCH)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SIGN_INVALID, codeMapping.apply(String.valueOf(SIGN_NOT_VALID)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_SIGN_INVALID, codeMapping.apply(String.valueOf(BAD_SIGN_FORMAT)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_INVALID, codeMapping.apply(String.valueOf(BAD_API_KEY)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_PERMISSION_DENY, codeMapping.apply(String.valueOf(API_NOT_ALLOWED)));
assertEquals(SmsFrameworkErrorCodeConstants.SMS_IP_DENY, codeMapping.apply(String.valueOf(IP_NOT_ALLOWED)));
}
}

View File

@@ -0,0 +1,39 @@
package cn.iocoder.dashboard.modules.system.enums.dict;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 字典类型的类型枚举
*/
@Getter
@AllArgsConstructor
public enum SysDictTypeEnum {
USER_TYPE("user_type"), // 用户类型
SYS_USER_SEX("sys_user_sex"), // 用户性别
SYS_COMMON_STATUS("sys_common_status"), // 系统状态
SYS_OPERATE_TYPE("sys_operate_type"), // 操作类型
SYS_LOGIN_RESULT("sys_login_result"), // 登陆结果
SYS_CONFIG_TYPE("sys_config_type"), // 参数配置类型
SYS_BOOLEAN_STRING("sys_boolean_string"), // Boolean 是否类型
SYS_SMS_CHANNEL_CODE("sys_sms_channel_code"), // 短信渠道编码
SYS_SMS_TEMPLATE_TYPE("sys_sms_template_type"), // 短信模板类型
SYS_SMS_SEND_STATUS("sys_sms_send_status"), // 短信发送状态
SYS_SMS_RECEIVE_STATUS("sys_sms_receive_status"), // 短信接收状态
SYS_ERROR_CODE_TYPE("inf_error_code_type"), // 错误码的类型枚举
INF_REDIS_TIMEOUT_TYPE("inf_redis_timeout_type"), // Redis 超时类型
INF_JOB_STATUS("inf_job_status"), // 定时任务状态的枚举
INF_JOB_LOG_STATUS("inf_job_log_status"), // 定时任务日志状态的枚举
INF_API_ERROR_LOG_PROCESS_STATUS("inf_api_error_log_process_status"), // API 错误日志的处理状态的枚举
;
/**
* 值
*/
private final String value;
}

View File

@@ -3,7 +3,6 @@ package cn.iocoder.dashboard.util;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import uk.co.jemos.podam.api.PodamFactory;
import uk.co.jemos.podam.api.PodamFactoryImpl;
@@ -71,11 +70,6 @@ public class RandomUtils {
return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
}
@SafeVarargs
public static SysUserDO randomUserDO(Consumer<SysUserDO>... consumers) {
return randomPojo(SysUserDO.class, consumers);
}
@SafeVarargs
public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
T pojo = PODAM_FACTORY.manufacturePojo(clazz);