diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsCallbackController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsCallbackController.java index d81ecfa4b..30d75bca5 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsCallbackController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsCallbackController.java @@ -1,6 +1,8 @@ package cn.iocoder.dashboard.modules.system.controller.sms; 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.sms.core.enums.SmsChannelEnum; 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 javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +import static cn.iocoder.dashboard.common.pojo.CommonResult.success; @Api(tags = "短信回调") @RestController @@ -32,4 +37,13 @@ public class SmsCallbackController { return "SUCCESS"; // 约定返回 SUCCESS 为成功 } + @PostMapping("/sms/aliyun") + @ApiOperation(value = "阿里云短信的回调", notes = "参见 https://help.aliyun.com/document_detail/120998.html 文档") + @OperateLog(enable = false) + public CommonResult receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable { + String text = ServletUtil.getBody(request); + smsService.receiveSmsStatus(SmsChannelEnum.ALIYUN.getCode(), text); + return success(true); + } + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java index 3d6ccc575..359f17f0b 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java @@ -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.PageResult; -import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; -import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; +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.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.service.sms.SysSmsChannelService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; 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 javax.annotation.Resource; +import javax.validation.Valid; import static cn.iocoder.dashboard.common.pojo.CommonResult.success; -@Api("短信 渠道/签名 API") +@Api(tags = "短信渠道") @RestController @RequestMapping("/sms/channel") public class SmsChannelController { @Resource - private SysSmsChannelService service; + private SysSmsChannelService smsChannelService; - @ApiOperation("获取渠道/签名分页") - @GetMapping("/page") - public CommonResult> getPermissionInfo(@Validated SmsChannelPageReqVO reqVO) { - return success(service.pageSmsChannels(reqVO)); + @PostMapping("/create") + @ApiOperation("创建短信渠道") + @PreAuthorize("@ss.hasPermission('system:sms-channel:create')") + public CommonResult createSmsChannel(@Valid @RequestBody SysSmsChannelCreateReqVO createReqVO) { + return success(smsChannelService.createSmsChannel(createReqVO)); } - @ApiOperation("添加消息渠道") - @PostMapping("/create") - public CommonResult add(@Validated @RequestBody SmsChannelCreateReqVO reqVO) { - return success(service.createSmsChannel(reqVO)); + @PutMapping("/update") + @ApiOperation("更新短信渠道") + @PreAuthorize("@ss.hasPermission('system:sms-channel:update')") + public CommonResult 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 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 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> getSmsChannelPage(@Valid SysSmsChannelPageReqVO pageVO) { + PageResult pageResult = smsChannelService.getSmsChannelPage(pageVO); + return success(SysSmsChannelConvert.INSTANCE.convertPage(pageResult)); } } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/SmsChannelAllVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/SmsChannelAllVO.java deleted file mode 100644 index 042cddaa2..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/SmsChannelAllVO.java +++ /dev/null @@ -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 templateList; - - public SmsTemplateVO getTemplateByTemplateCode(String tempCode) { - return templateList.stream().filter(s -> s.getCode().equals(tempCode)).findFirst().get(); - } - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelBaseVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelBaseVO.java new file mode 100644 index 000000000..141033082 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelBaseVO.java @@ -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; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelCreateReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelCreateReqVO.java new file mode 100644 index 000000000..a21cbb71d --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelCreateReqVO.java @@ -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; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelPageReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelPageReqVO.java new file mode 100644 index 000000000..523a6c375 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelPageReqVO.java @@ -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; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelRespVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelRespVO.java new file mode 100644 index 000000000..20770689a --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelRespVO.java @@ -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; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelUpdateReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelUpdateReqVO.java new file mode 100644 index 000000000..66ab79412 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/channel/SysSmsChannelUpdateReqVO.java @@ -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; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelCreateReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelCreateReqVO.java deleted file mode 100644 index b38f7c832..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelCreateReqVO.java +++ /dev/null @@ -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; - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelPageReqVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelPageReqVO.java deleted file mode 100644 index 9b941edf3..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelPageReqVO.java +++ /dev/null @@ -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; - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/resp/SmsChannelPageRespVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/resp/SmsChannelPageRespVO.java deleted file mode 100644 index 2ad1ce357..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/resp/SmsChannelPageRespVO.java +++ /dev/null @@ -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; - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java b/src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java deleted file mode 100644 index c8a0f7591..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java +++ /dev/null @@ -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 convert(List bean); - - List convertProperty(List list); - - List convertList(List list); - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SysSmsChannelConvert.java b/src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SysSmsChannelConvert.java new file mode 100644 index 000000000..11b036a86 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SysSmsChannelConvert.java @@ -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 convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/sms/SysSmsChannelMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/sms/SysSmsChannelMapper.java index e6371e9c9..10155a1b4 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/sms/SysSmsChannelMapper.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/sms/SysSmsChannelMapper.java @@ -1,9 +1,9 @@ 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.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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; @@ -13,14 +13,16 @@ import java.util.List; @Mapper public interface SysSmsChannelMapper extends BaseMapperX { - default PageResult selectChannelPage(SmsChannelPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapper() - .like(StrUtil.isNotBlank(reqVO.getSignature()), SysSmsChannelDO::getSignature, reqVO.getSignature())); + default PageResult selectPage(SysSmsChannelPageReqVO reqVO) { + return selectPage(reqVO, new QueryWrapperX() + .likeIfPresent("signature", reqVO.getSignature()) + .eqIfPresent("status", reqVO.getStatus()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); } default List selectListByStatus(Integer status) { - return selectList(new LambdaQueryWrapper() - .eq(SysSmsChannelDO::getStatus, status) + return selectList(new LambdaQueryWrapper().eq(SysSmsChannelDO::getStatus, status) .orderByAsc(SysSmsChannelDO::getId)); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java index 87271a655..6fbd295b4 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java @@ -78,19 +78,15 @@ public interface SysErrorCodeConstants { ErrorCode FILE_UPLOAD_FAILED = new ErrorCode(1002009002, "文件上传失败"); ErrorCode FILE_IS_EMPTY= new ErrorCode(1002009003, "文件为空"); + // ========== 短信渠道 1002011000 ========== + ErrorCode SMS_CHANNEL_NOT_EXISTS = new ErrorCode(1002011000, "短信渠道不存在"); - // ========== 短信模板 1002010000 ========== - ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002010000, "短信模板不存在"); + // ========== 短信模板 1002011000 ========== + ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002011000, "短信模板不存在"); - // ========== 短信发送 1002011000 ========== - ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1002011000, "手机号不存在"); - ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1002011001, "模板参数({})缺失"); + // ========== 短信发送 1002012000 ========== + ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1002012000, "手机号不存在"); + 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, "参数【{}】不能为空"); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java index c31b3ae5f..705662126 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/dict/SysDictTypeEnum.java @@ -18,6 +18,7 @@ public enum SysDictTypeEnum { 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"), // 短信渠道编码 INF_REDIS_TIMEOUT_TYPE("inf_redis_timeout_type"), // Redis 超时类型 INF_JOB_STATUS("inf_job_status"), // 定时任务状态的枚举 diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java index 142812b3c..6864bf6f6 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java @@ -1,10 +1,15 @@ package cn.iocoder.dashboard.modules.system.service.sms; 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.req.SmsChannelPageReqVO; +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 javax.validation.Valid; +import java.util.Collection; +import java.util.List; + /** * 短信渠道Service接口 * @@ -19,19 +24,49 @@ public interface SysSmsChannelService { void initSmsClients(); /** - * 分页查询短信渠道信息 + * 创建短信渠道 * - * @param reqVO 参数对象 - * @return 短信渠道分页对象 + * @param createReqVO 创建信息 + * @return 编号 */ - PageResult pageSmsChannels(SmsChannelPageReqVO reqVO); + Long createSmsChannel(@Valid SysSmsChannelCreateReqVO createReqVO); /** - * 创建新的渠道信息 + * 更新短信渠道 * - * @param reqVO 参数对象 - * @return 渠道id + * @param updateReqVO 更新信息 */ - Long createSmsChannel(SmsChannelCreateReqVO reqVO); + void updateSmsChannel(@Valid SysSmsChannelUpdateReqVO updateReqVO); + + /** + * 删除短信渠道 + * + * @param id 编号 + */ + void deleteSmsChannel(Long id); + + /** + * 获得短信渠道 + * + * @param id 编号 + * @return 短信渠道 + */ + SysSmsChannelDO getSmsChannel(Long id); + + /** + * 获得短信渠道列表 + * + * @param ids 编号 + * @return 短信渠道列表 + */ + List getSmsChannelList(Collection ids); + + /** + * 获得短信渠道分页 + * + * @param pageReqVO 分页查询 + * @return 短信渠道分页 + */ + PageResult getSmsChannelPage(SysSmsChannelPageReqVO pageReqVO); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java index a34d511bb..70c176c76 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java @@ -4,9 +4,10 @@ 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.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.req.SmsChannelPageReqVO; -import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert; +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.convert.sms.SysSmsChannelConvert; 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.SysSmsChannelService; @@ -14,8 +15,12 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; +import java.util.Collection; 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实现类 * @@ -29,46 +34,65 @@ public class SysSmsChannelServiceImpl implements SysSmsChannelService { private SmsClientFactory smsClientFactory; @Resource - private SysSmsChannelMapper channelMapper; + private SysSmsChannelMapper smsChannelMapper; @Override @PostConstruct public void initSmsClients() { // 查询有效渠道信息 - List channelDOList = channelMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); + List channelDOList = smsChannelMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); // 创建渠道 Client - List propertiesList = SmsChannelConvert.INSTANCE.convertList(channelDOList); + List propertiesList = SysSmsChannelConvert.INSTANCE.convertList02(channelDOList); propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties)); } // TODO 芋艿:刷新缓存 @Override - public PageResult pageSmsChannels(SmsChannelPageReqVO reqVO) { - return channelMapper.selectChannelPage(reqVO); + public Long createSmsChannel(SysSmsChannelCreateReqVO createReqVO) { + // 插入 + SysSmsChannelDO smsChannel = SysSmsChannelConvert.INSTANCE.convert(createReqVO); + smsChannelMapper.insert(smsChannel); + // 返回 + return smsChannel.getId(); } @Override - public Long createSmsChannel(SmsChannelCreateReqVO reqVO) { - SysSmsChannelDO channelDO = SmsChannelConvert.INSTANCE.convert(reqVO); - channelMapper.insert(channelDO); - return channelDO.getId(); + 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 getSmsChannelList(Collection ids) { + return smsChannelMapper.selectBatchIds(ids); + } + + @Override + public PageResult getSmsChannelPage(SysSmsChannelPageReqVO pageReqVO) { + return smsChannelMapper.selectPage(pageReqVO); } -// @Override -// public List listSmsChannelAllEnabledInfo() { -// List channelDOList = channelMapper.selectListByStatus(); -// if (ObjectUtil.isNull(channelDOList)) { -// return null; -// } -// List channelAllVOList = SmsChannelConvert.INSTANCE.convert(channelDOList); -// channelAllVOList.forEach(smsChannelDO -> { -// List templateDOList = templateMapper.selectListByChannelId(smsChannelDO.getId()); -// if (ObjectUtil.isNull(templateDOList)) { -// templateDOList = new ArrayList<>(); -// } -// smsChannelDO.setTemplateList(SmsTemplateConvert.INSTANCE.convert(templateDOList)); -// }); -// return channelAllVOList; -// } } diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java index 373665546..48a80056e 100644 --- a/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/dept/SysDeptServiceTest.java @@ -270,4 +270,5 @@ class SysDeptServiceTest extends BaseDbUnitTest { }; return randomPojo(SysDeptDO.class, ArrayUtils.append(consumer, consumers)); } + } diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelServiceTest.java new file mode 100644 index 000000000..60eae778b --- /dev/null +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelServiceTest.java @@ -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 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... consumers) { + Consumer consumer = (o) -> { + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 + }; + return randomPojo(SysSmsChannelDO.class, ArrayUtils.append(consumer, consumers)); + } + +} diff --git a/src/test/resources/sql/clean.sql b/src/test/resources/sql/clean.sql index c2d1d63d8..ae95d824e 100644 --- a/src/test/resources/sql/clean.sql +++ b/src/test/resources/sql/clean.sql @@ -19,3 +19,4 @@ DELETE FROM "sys_post"; DELETE FROM "sys_login_log"; DELETE FROM "sys_operate_log"; DELETE FROM "sys_user"; +DELETE FROM "sys_sms_channel"; diff --git a/src/test/resources/sql/create_tables.sql b/src/test/resources/sql/create_tables.sql index 23bf9c07b..6ef2d705d 100644 --- a/src/test/resources/sql/create_tables.sql +++ b/src/test/resources/sql/create_tables.sql @@ -47,8 +47,7 @@ CREATE TABLE IF NOT EXISTS "inf_job" ( PRIMARY KEY ("id") ) COMMENT='定时任务表'; -DROP TABLE IF EXISTS "inf_job_log"; -CREATE TABLE "inf_job_log" ( +CREATE TABLE IF NOT EXISTS "inf_job_log" ( "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '日志编号', "job_id" bigint(20) 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`) ) 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, "code" varchar(64) NOT NULL, "name" varchar(50) NOT NULL, @@ -208,7 +206,6 @@ CREATE TABLE IF NOT EXISTS "sys_post" PRIMARY KEY ("id") ) COMMENT '岗位信息表'; - CREATE TABLE IF NOT EXISTS "sys_notice" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "title" varchar(50) NOT NULL COMMENT '公告标题', @@ -223,7 +220,6 @@ CREATE TABLE IF NOT EXISTS "sys_notice" ( PRIMARY KEY("id") ) COMMENT '通知公告表'; - CREATE TABLE IF NOT EXISTS `sys_login_log` ( `id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, `log_type` bigint(4) NOT NULL, @@ -240,7 +236,6 @@ CREATE TABLE IF NOT EXISTS `sys_login_log` ( PRIMARY KEY (`id`) ) COMMENT ='系统访问记录'; - CREATE TABLE IF NOT EXISTS `sys_operate_log` ( `id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, `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, primary key ("id") ) 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 '短信渠道';