短信渠道的 CRUD 后端代码的完成

plp
YunaiV 5 years ago
parent 86cbf21d6d
commit d8d458a024

@ -1,6 +1,8 @@
package cn.iocoder.dashboard.modules.system.controller.sms; package cn.iocoder.dashboard.modules.system.controller.sms;
import cn.hutool.core.util.URLUtil; import cn.hutool.core.util.URLUtil;
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.annotations.OperateLog;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum; import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
@ -13,6 +15,9 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@Api(tags = "短信回调") @Api(tags = "短信回调")
@RestController @RestController
@ -32,4 +37,13 @@ public class SmsCallbackController {
return "SUCCESS"; // 约定返回 SUCCESS 为成功 return "SUCCESS"; // 约定返回 SUCCESS 为成功
} }
@PostMapping("/sms/aliyun")
@ApiOperation(value = "阿里云短信的回调", notes = "参见 https://help.aliyun.com/document_detail/120998.html 文档")
@OperateLog(enable = false)
public CommonResult<Boolean> receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable {
String text = ServletUtil.getBody(request);
smsService.receiveSmsStatus(SmsChannelEnum.ALIYUN.getCode(), text);
return success(true);
}
} }

@ -2,37 +2,71 @@ package cn.iocoder.dashboard.modules.system.controller.sms;
import cn.iocoder.dashboard.common.pojo.CommonResult; import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelRespVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelUpdateReqVO;
import cn.iocoder.dashboard.modules.system.convert.sms.SysSmsChannelConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success; import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@Api("短信 渠道/签名 API") @Api(tags = "短信渠道")
@RestController @RestController
@RequestMapping("/sms/channel") @RequestMapping("/sms/channel")
public class SmsChannelController { public class SmsChannelController {
@Resource @Resource
private SysSmsChannelService service; private SysSmsChannelService smsChannelService;
@ApiOperation("获取渠道/签名分页") @PostMapping("/create")
@GetMapping("/page") @ApiOperation("创建短信渠道")
public CommonResult<PageResult<SysSmsChannelDO>> getPermissionInfo(@Validated SmsChannelPageReqVO reqVO) { @PreAuthorize("@ss.hasPermission('system:sms-channel:create')")
return success(service.pageSmsChannels(reqVO)); public CommonResult<Long> createSmsChannel(@Valid @RequestBody SysSmsChannelCreateReqVO createReqVO) {
return success(smsChannelService.createSmsChannel(createReqVO));
} }
@ApiOperation("添加消息渠道") @PutMapping("/update")
@PostMapping("/create") @ApiOperation("更新短信渠道")
public CommonResult<Long> add(@Validated @RequestBody SmsChannelCreateReqVO reqVO) { @PreAuthorize("@ss.hasPermission('system:sms-channel:update')")
return success(service.createSmsChannel(reqVO)); public CommonResult<Boolean> updateSmsChannel(@Valid @RequestBody SysSmsChannelUpdateReqVO updateReqVO) {
smsChannelService.updateSmsChannel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除短信渠道")
@ApiImplicitParam(name = "id", value = "编号", required = true)
@PreAuthorize("@ss.hasPermission('system:sms-channel:delete')")
public CommonResult<Boolean> deleteSmsChannel(@RequestParam("id") Long id) {
smsChannelService.deleteSmsChannel(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得短信渠道")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('system:sms-channel:query')")
public CommonResult<SysSmsChannelRespVO> getSmsChannel(@RequestParam("id") Long id) {
SysSmsChannelDO smsChannel = smsChannelService.getSmsChannel(id);
return success(SysSmsChannelConvert.INSTANCE.convert(smsChannel));
}
@GetMapping("/page")
@ApiOperation("获得短信渠道分页")
@PreAuthorize("@ss.hasPermission('system:sms-channel:query')")
public CommonResult<PageResult<SysSmsChannelRespVO>> getSmsChannelPage(@Valid SysSmsChannelPageReqVO pageVO) {
PageResult<SysSmsChannelDO> pageResult = smsChannelService.getSmsChannelPage(pageVO);
return success(SysSmsChannelConvert.INSTANCE.convertPage(pageResult));
} }
} }

@ -1,58 +0,0 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
/**
* ()VO
*
* @author zzf
* @date 2021/1/25 17:01
*/
@Data
@EqualsAndHashCode
public class SmsChannelAllVO implements Serializable {
/**
* id
*/
private Long id;
/**
* ( )
*/
private String code;
/**
* id
*/
private String apiKey;
/**
*
*/
private String apiSecret;
/**
*
*/
private String apiSignatureId;
/**
*
*/
private String signature;
/**
*
*/
private List<SmsTemplateVO> templateList;
public SmsTemplateVO getTemplateByTemplateCode(String tempCode) {
return templateList.stream().filter(s -> s.getCode().equals(tempCode)).findFirst().get();
}
}

@ -0,0 +1,36 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.channel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* Base VO VO 使
* VO Swagger
*/
@Data
public class SysSmsChannelBaseVO {
@ApiModelProperty(value = "短信签名", required = true, example = "芋道源码")
@NotNull(message = "短信签名不能为空")
private String signature;
@ApiModelProperty(value = "任务状态", required = true, example = "1")
@NotNull(message = "任务状态不能为空")
private Integer status;
@ApiModelProperty(value = "备注", example = "好吃!")
private String remark;
@ApiModelProperty(value = "短信 API 的账号", required = true, example = "yudao")
@NotNull(message = "短信 API 的账号不能为空")
private String apiKey;
@ApiModelProperty(value = "短信 API 的秘钥", example = "yuanma")
private String apiSecret;
@ApiModelProperty(value = "短信发送回调 URL", example = "http://www.iocoder.cn")
private String callbackUrl;
}

@ -0,0 +1,21 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.channel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@ApiModel("短信渠道创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SysSmsChannelCreateReqVO extends SysSmsChannelBaseVO {
@ApiModelProperty(value = "渠道编码", required = true, example = "YUN_PIAN", notes = "参见 SmsChannelEnum 枚举类")
@NotNull(message = "渠道编码不能为空")
private String code;
}

@ -0,0 +1,35 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.channel;
import cn.iocoder.dashboard.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("短信渠道分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SysSmsChannelPageReqVO extends PageParam {
@ApiModelProperty(value = "任务状态", example = "1")
private Integer status;
@ApiModelProperty(value = "短信签名", example = "芋道源码", notes = "模糊匹配")
private String signature;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
}

@ -0,0 +1,26 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.channel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("短信渠道 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SysSmsChannelRespVO extends SysSmsChannelBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "渠道编码", required = true, example = "YUN_PIAN", notes = "参见 SmsChannelEnum 枚举类")
private String code;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

@ -0,0 +1,21 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.channel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@ApiModel("短信渠道更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SysSmsChannelUpdateReqVO extends SysSmsChannelBaseVO {
@ApiModelProperty(value = "编号", required = true, example = "1024")
@NotNull(message = "编号不能为空")
private Long id;
}

@ -1,44 +0,0 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.req;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@ApiModel("消息渠道创建 Request VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class SmsChannelCreateReqVO implements Serializable {
@ApiModelProperty("编码(来自枚举类 阿里、华为、七牛等)")
private String code;
@ApiModelProperty("渠道账号id")
private String apiKey;
@ApiModelProperty("渠道账号秘钥")
private String apiSecret;
@ApiModelProperty("优先级(存在多个签名时,选择值最小的,渠道不可用时,按优先级从小到大切换)")
private Integer priority;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("签名值")
private String signature;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("启用状态0正常 1停用")
private Integer status;
}

@ -1,21 +0,0 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.req;
import cn.iocoder.dashboard.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@ApiModel("消息渠道分页 Request VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SmsChannelPageReqVO extends PageParam {
@ApiModelProperty(value = "签名值", example = "源码", notes = "模糊匹配")
private String signature;
}

@ -1,43 +0,0 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.resp;
import cn.iocoder.dashboard.common.pojo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("用户分页 Request VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SmsChannelPageRespVO extends PageParam {
@ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配")
private String username;
@ApiModelProperty(value = "手机号码", example = "yudao", notes = "模糊匹配")
private String mobile;
@ApiModelProperty(value = "展示状态", example = "1", notes = "参见 SysCommonStatusEnum 枚举类")
private Integer status;
@ApiModelProperty(value = "开始时间", example = "2020-10-24")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date beginTime;
@ApiModelProperty(value = "结束时间", example = "2020-10-24")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date endTime;
@ApiModelProperty(value = "部门编号", example = "1024", notes = "同时筛选子部门")
private Long deptId;
}

@ -1,28 +0,0 @@
package cn.iocoder.dashboard.modules.system.convert.sms;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface SmsChannelConvert {
SmsChannelConvert INSTANCE = Mappers.getMapper(SmsChannelConvert.class);
SysSmsChannelDO convert(SmsChannelCreateReqVO bean);
SysSmsChannelDO convert(SysUserUpdateReqVO bean);
List<SmsChannelAllVO> convert(List<SysSmsChannelDO> bean);
List<SmsChannelProperties> convertProperty(List<SmsChannelAllVO> list);
List<SmsChannelProperties> convertList(List<SysSmsChannelDO> list);
}

@ -0,0 +1,36 @@
package cn.iocoder.dashboard.modules.system.convert.sms;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelRespVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* Convert
*
* @author
*/
@Mapper
public interface SysSmsChannelConvert {
SysSmsChannelConvert INSTANCE = Mappers.getMapper(SysSmsChannelConvert.class);
SysSmsChannelDO convert(SysSmsChannelCreateReqVO bean);
SysSmsChannelDO convert(SysSmsChannelUpdateReqVO bean);
SysSmsChannelRespVO convert(SysSmsChannelDO bean);
List<SysSmsChannelRespVO> convertList(List<SysSmsChannelDO> list);
PageResult<SysSmsChannelRespVO> convertPage(PageResult<SysSmsChannelDO> page);
List<SmsChannelProperties> convertList02(List<SysSmsChannelDO> list);
}

@ -1,9 +1,9 @@
package cn.iocoder.dashboard.modules.system.dal.mysql.sms; package cn.iocoder.dashboard.modules.system.dal.mysql.sms;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -13,14 +13,16 @@ import java.util.List;
@Mapper @Mapper
public interface SysSmsChannelMapper extends BaseMapperX<SysSmsChannelDO> { public interface SysSmsChannelMapper extends BaseMapperX<SysSmsChannelDO> {
default PageResult<SysSmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) { default PageResult<SysSmsChannelDO> selectPage(SysSmsChannelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapper<SysSmsChannelDO>() return selectPage(reqVO, new QueryWrapperX<SysSmsChannelDO>()
.like(StrUtil.isNotBlank(reqVO.getSignature()), SysSmsChannelDO::getSignature, reqVO.getSignature())); .likeIfPresent("signature", reqVO.getSignature())
.eqIfPresent("status", reqVO.getStatus())
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc("id"));
} }
default List<SysSmsChannelDO> selectListByStatus(Integer status) { default List<SysSmsChannelDO> selectListByStatus(Integer status) {
return selectList(new LambdaQueryWrapper<SysSmsChannelDO>() return selectList(new LambdaQueryWrapper<SysSmsChannelDO>().eq(SysSmsChannelDO::getStatus, status)
.eq(SysSmsChannelDO::getStatus, status)
.orderByAsc(SysSmsChannelDO::getId)); .orderByAsc(SysSmsChannelDO::getId));
} }

@ -78,19 +78,15 @@ public interface SysErrorCodeConstants {
ErrorCode FILE_UPLOAD_FAILED = new ErrorCode(1002009002, "文件上传失败"); ErrorCode FILE_UPLOAD_FAILED = new ErrorCode(1002009002, "文件上传失败");
ErrorCode FILE_IS_EMPTY= new ErrorCode(1002009003, "文件为空"); ErrorCode FILE_IS_EMPTY= new ErrorCode(1002009003, "文件为空");
// ========== 短信渠道 1002011000 ==========
ErrorCode SMS_CHANNEL_NOT_EXISTS = new ErrorCode(1002011000, "短信渠道不存在");
// ========== 短信模板 1002010000 ========== // ========== 短信模板 1002011000 ==========
ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002010000, "短信模板不存在"); ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002011000, "短信模板不存在");
// ========== 短信发送 1002011000 ========== // ========== 短信发送 1002012000 ==========
ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1002011000, "手机号不存在"); ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1002012000, "手机号不存在");
ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1002011001, "模板参数({})缺失"); ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1002012001, "模板参数({})缺失");
ErrorCode SMS_CHANNEL_NOT_INIT = new ErrorCode(1003001001,
"短信渠道没有初始化, 请调用SmsClientWrapper#initSmsClient()或SmsClientWrapper#addSmsClient");
ErrorCode SMS_CHANNEL_NOT_FOUND = new ErrorCode(1003001002, "没有短信渠道信息, 请初始化sms_channel表数据。");
ErrorCode SMS_SENDER_NOT_FOUND = new ErrorCode(1003001004, "没有找到对应的短信发送对象请检查sms_channel表和sms_template表数据");
ErrorCode INVALID_CHANNEL_CODE = new ErrorCode(1003001005, "非法的短信渠道code请检查sms_channel表的code值是否与SmsChannelEnum中的code值一致。");
ErrorCode PARAM_VALUE_IS_NULL = new ErrorCode(1003001006, "参数【{}】不能为空");
} }

@ -18,6 +18,7 @@ public enum SysDictTypeEnum {
SYS_LOGIN_RESULT("sys_login_result"), // 登陆结果 SYS_LOGIN_RESULT("sys_login_result"), // 登陆结果
SYS_CONFIG_TYPE("sys_config_type"), // 参数配置类型 SYS_CONFIG_TYPE("sys_config_type"), // 参数配置类型
SYS_BOOLEAN_STRING("sys_boolean_string"), // Boolean 是否类型 SYS_BOOLEAN_STRING("sys_boolean_string"), // Boolean 是否类型
SYS_SMS_CHANNEL_CODE("sys_sms_channel_code"), // 短信渠道编码
INF_REDIS_TIMEOUT_TYPE("inf_redis_timeout_type"), // Redis 超时类型 INF_REDIS_TIMEOUT_TYPE("inf_redis_timeout_type"), // Redis 超时类型
INF_JOB_STATUS("inf_job_status"), // 定时任务状态的枚举 INF_JOB_STATUS("inf_job_status"), // 定时任务状态的枚举

@ -1,10 +1,15 @@
package cn.iocoder.dashboard.modules.system.service.sms; package cn.iocoder.dashboard.modules.system.service.sms;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
/** /**
* Service * Service
* *
@ -19,19 +24,49 @@ public interface SysSmsChannelService {
void initSmsClients(); void initSmsClients();
/** /**
* *
*
* @param createReqVO
* @return
*/
Long createSmsChannel(@Valid SysSmsChannelCreateReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateSmsChannel(@Valid SysSmsChannelUpdateReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteSmsChannel(Long id);
/**
*
*
* @param id
* @return
*/
SysSmsChannelDO getSmsChannel(Long id);
/**
*
* *
* @param reqVO * @param ids
* @return * @return
*/ */
PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO); List<SysSmsChannelDO> getSmsChannelList(Collection<Long> ids);
/** /**
* *
* *
* @param reqVO * @param pageReqVO
* @return id * @return
*/ */
Long createSmsChannel(SmsChannelCreateReqVO reqVO); PageResult<SysSmsChannelDO> getSmsChannelPage(SysSmsChannelPageReqVO pageReqVO);
} }

@ -4,9 +4,10 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory; import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert; import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelUpdateReqVO;
import cn.iocoder.dashboard.modules.system.convert.sms.SysSmsChannelConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsChannelMapper; import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsChannelMapper;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
@ -14,8 +15,12 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection;
import java.util.List; import java.util.List;
import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
/** /**
* Service * Service
* *
@ -29,46 +34,65 @@ public class SysSmsChannelServiceImpl implements SysSmsChannelService {
private SmsClientFactory smsClientFactory; private SmsClientFactory smsClientFactory;
@Resource @Resource
private SysSmsChannelMapper channelMapper; private SysSmsChannelMapper smsChannelMapper;
@Override @Override
@PostConstruct @PostConstruct
public void initSmsClients() { public void initSmsClients() {
// 查询有效渠道信息 // 查询有效渠道信息
List<SysSmsChannelDO> channelDOList = channelMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); List<SysSmsChannelDO> channelDOList = smsChannelMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 创建渠道 Client // 创建渠道 Client
List<SmsChannelProperties> propertiesList = SmsChannelConvert.INSTANCE.convertList(channelDOList); List<SmsChannelProperties> propertiesList = SysSmsChannelConvert.INSTANCE.convertList02(channelDOList);
propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties)); propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties));
} }
// TODO 芋艿:刷新缓存 // TODO 芋艿:刷新缓存
@Override @Override
public PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO) { public Long createSmsChannel(SysSmsChannelCreateReqVO createReqVO) {
return channelMapper.selectChannelPage(reqVO); // 插入
SysSmsChannelDO smsChannel = SysSmsChannelConvert.INSTANCE.convert(createReqVO);
smsChannelMapper.insert(smsChannel);
// 返回
return smsChannel.getId();
}
@Override
public void updateSmsChannel(SysSmsChannelUpdateReqVO updateReqVO) {
// 校验存在
this.validateSmsChannelExists(updateReqVO.getId());
// 更新
SysSmsChannelDO updateObj = SysSmsChannelConvert.INSTANCE.convert(updateReqVO);
smsChannelMapper.updateById(updateObj);
}
@Override
public void deleteSmsChannel(Long id) {
// 校验存在
this.validateSmsChannelExists(id);
// 更新
smsChannelMapper.deleteById(id);
}
private void validateSmsChannelExists(Long id) {
if (smsChannelMapper.selectById(id) == null) {
throw exception(SMS_CHANNEL_NOT_EXISTS);
}
}
@Override
public SysSmsChannelDO getSmsChannel(Long id) {
return smsChannelMapper.selectById(id);
}
@Override
public List<SysSmsChannelDO> getSmsChannelList(Collection<Long> ids) {
return smsChannelMapper.selectBatchIds(ids);
} }
@Override @Override
public Long createSmsChannel(SmsChannelCreateReqVO reqVO) { public PageResult<SysSmsChannelDO> getSmsChannelPage(SysSmsChannelPageReqVO pageReqVO) {
SysSmsChannelDO channelDO = SmsChannelConvert.INSTANCE.convert(reqVO); return smsChannelMapper.selectPage(pageReqVO);
channelMapper.insert(channelDO);
return channelDO.getId();
} }
// @Override
// public List<SmsChannelAllVO> listSmsChannelAllEnabledInfo() {
// List<SysSmsChannelDO> channelDOList = channelMapper.selectListByStatus();
// if (ObjectUtil.isNull(channelDOList)) {
// return null;
// }
// List<SmsChannelAllVO> channelAllVOList = SmsChannelConvert.INSTANCE.convert(channelDOList);
// channelAllVOList.forEach(smsChannelDO -> {
// List<SysSmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(smsChannelDO.getId());
// if (ObjectUtil.isNull(templateDOList)) {
// templateDOList = new ArrayList<>();
// }
// smsChannelDO.setTemplateList(SmsTemplateConvert.INSTANCE.convert(templateDOList));
// });
// return channelAllVOList;
// }
} }

@ -270,4 +270,5 @@ class SysDeptServiceTest extends BaseDbUnitTest {
}; };
return randomPojo(SysDeptDO.class, ArrayUtils.append(consumer, consumers)); return randomPojo(SysDeptDO.class, ArrayUtils.append(consumer, consumers));
} }
} }

@ -0,0 +1,149 @@
package cn.iocoder.dashboard.modules.system.service.sms;
import cn.iocoder.dashboard.BaseDbUnitTest;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.channel.SysSmsChannelUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsChannelMapper;
import cn.iocoder.dashboard.modules.system.service.sms.impl.SysSmsChannelServiceImpl;
import cn.iocoder.dashboard.util.collection.ArrayUtils;
import cn.iocoder.dashboard.util.object.ObjectUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import java.util.function.Consumer;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
import static cn.iocoder.dashboard.util.RandomUtils.*;
import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link SysSmsChannelServiceImpl}
*
* @author
*/
@Import(SysSmsChannelServiceImpl.class)
public class SysSmsChannelServiceTest extends BaseDbUnitTest {
@Resource
private SysSmsChannelServiceImpl smsChannelService;
@MockBean
private SmsClientFactory smsClientFactory;
@Resource
private SysSmsChannelMapper smsChannelMapper;
@Test
public void testCreateSmsChannel_success() {
// 准备参数
SysSmsChannelCreateReqVO reqVO = randomPojo(SysSmsChannelCreateReqVO.class, o -> o.setStatus(randomCommonStatus()));
// 调用
Long smsChannelId = smsChannelService.createSmsChannel(reqVO);
// 断言
assertNotNull(smsChannelId);
// 校验记录的属性是否正确
SysSmsChannelDO smsChannel = smsChannelMapper.selectById(smsChannelId);
assertPojoEquals(reqVO, smsChannel);
}
@Test
public void testUpdateSmsChannel_success() {
// mock 数据
SysSmsChannelDO dbSmsChannel = randomSmsChannelDO();
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
// 准备参数
SysSmsChannelUpdateReqVO reqVO = randomPojo(SysSmsChannelUpdateReqVO.class, o -> {
o.setId(dbSmsChannel.getId()); // 设置更新的 ID
o.setStatus(randomCommonStatus());
});
// 调用
smsChannelService.updateSmsChannel(reqVO);
// 校验是否更新正确
SysSmsChannelDO smsChannel = smsChannelMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, smsChannel);
}
@Test
public void testUpdateSmsChannel_notExists() {
// 准备参数
SysSmsChannelUpdateReqVO reqVO = randomPojo(SysSmsChannelUpdateReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> smsChannelService.updateSmsChannel(reqVO), SMS_CHANNEL_NOT_EXISTS);
}
@Test
public void testDeleteSmsChannel_success() {
// mock 数据
SysSmsChannelDO dbSmsChannel = randomSmsChannelDO();
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbSmsChannel.getId();
// 调用
smsChannelService.deleteSmsChannel(id);
// 校验数据不存在了
assertNull(smsChannelMapper.selectById(id));
}
@Test
public void testDeleteSmsChannel_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> smsChannelService.deleteSmsChannel(id), SMS_CHANNEL_NOT_EXISTS);
}
@Test
public void testGetSmsChannelPage() {
// mock 数据
SysSmsChannelDO dbSmsChannel = randomPojo(SysSmsChannelDO.class, o -> { // 等会查询到
o.setSignature("芋道源码");
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
o.setCreateTime(buildTime(2020, 12, 12));
});
smsChannelMapper.insert(dbSmsChannel);
// 测试 signature 不匹配
smsChannelMapper.insert(ObjectUtils.clone(dbSmsChannel, o -> o.setSignature("源码")));
// 测试 status 不匹配
smsChannelMapper.insert(ObjectUtils.clone(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
// 测试 createTime 不匹配
smsChannelMapper.insert(ObjectUtils.clone(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11))));
// 准备参数
SysSmsChannelPageReqVO reqVO = new SysSmsChannelPageReqVO();
reqVO.setSignature("芋道");
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
reqVO.setBeginCreateTime(buildTime(2020, 12, 1));
reqVO.setEndCreateTime(buildTime(2020, 12, 24));
// 调用
PageResult<SysSmsChannelDO> pageResult = smsChannelService.getSmsChannelPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbSmsChannel, pageResult.getList().get(0));
}
@SafeVarargs
private static SysSmsChannelDO randomSmsChannelDO(Consumer<SysSmsChannelDO>... consumers) {
Consumer<SysSmsChannelDO> consumer = (o) -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
};
return randomPojo(SysSmsChannelDO.class, ArrayUtils.append(consumer, consumers));
}
}

@ -19,3 +19,4 @@ DELETE FROM "sys_post";
DELETE FROM "sys_login_log"; DELETE FROM "sys_login_log";
DELETE FROM "sys_operate_log"; DELETE FROM "sys_operate_log";
DELETE FROM "sys_user"; DELETE FROM "sys_user";
DELETE FROM "sys_sms_channel";

@ -47,8 +47,7 @@ CREATE TABLE IF NOT EXISTS "inf_job" (
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT='定时任务表'; ) COMMENT='定时任务表';
DROP TABLE IF EXISTS "inf_job_log"; CREATE TABLE IF NOT EXISTS "inf_job_log" (
CREATE TABLE "inf_job_log" (
"id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号', "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号',
"job_id" bigint(20) NOT NULL COMMENT '任务编号', "job_id" bigint(20) NOT NULL COMMENT '任务编号',
"handler_name" varchar(64) NOT NULL COMMENT '处理器的名字', "handler_name" varchar(64) NOT NULL COMMENT '处理器的名字',
@ -192,8 +191,7 @@ CREATE TABLE IF NOT EXISTS `sys_user_session` (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) COMMENT '用户在线 Session'; ) COMMENT '用户在线 Session';
CREATE TABLE IF NOT EXISTS "sys_post" CREATE TABLE IF NOT EXISTS "sys_post" (
(
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"code" varchar(64) NOT NULL, "code" varchar(64) NOT NULL,
"name" varchar(50) NOT NULL, "name" varchar(50) NOT NULL,
@ -208,7 +206,6 @@ CREATE TABLE IF NOT EXISTS "sys_post"
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT '岗位信息表'; ) COMMENT '岗位信息表';
CREATE TABLE IF NOT EXISTS "sys_notice" ( CREATE TABLE IF NOT EXISTS "sys_notice" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"title" varchar(50) NOT NULL COMMENT '公告标题', "title" varchar(50) NOT NULL COMMENT '公告标题',
@ -223,7 +220,6 @@ CREATE TABLE IF NOT EXISTS "sys_notice" (
PRIMARY KEY("id") PRIMARY KEY("id")
) COMMENT '通知公告表'; ) COMMENT '通知公告表';
CREATE TABLE IF NOT EXISTS `sys_login_log` ( CREATE TABLE IF NOT EXISTS `sys_login_log` (
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, `id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`log_type` bigint(4) NOT NULL, `log_type` bigint(4) NOT NULL,
@ -240,7 +236,6 @@ CREATE TABLE IF NOT EXISTS `sys_login_log` (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) COMMENT ='系统访问记录'; ) COMMENT ='系统访问记录';
CREATE TABLE IF NOT EXISTS `sys_operate_log` ( CREATE TABLE IF NOT EXISTS `sys_operate_log` (
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, `id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`trace_id` varchar(64) NOT NULL DEFAULT '', `trace_id` varchar(64) NOT NULL DEFAULT '',
@ -346,3 +341,20 @@ CREATE TABLE IF NOT EXISTS "inf_api_error_log" (
"deleted" bit not null default false, "deleted" bit not null default false,
primary key ("id") primary key ("id")
) COMMENT '系统异常日志'; ) COMMENT '系统异常日志';
CREATE TABLE IF NOT EXISTS "sys_sms_channel" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"signature" varchar(10) NOT NULL,
"code" varchar(63) NOT NULL,
"status" tinyint NOT NULL,
"remark" varchar(255) DEFAULT NULL,
"api_key" varchar(63) NOT NULL,
"api_secret" varchar(63) DEFAULT NULL,
"callback_url" varchar(255) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '短信渠道';

Loading…
Cancel
Save