org.projectlombok
lombok
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsSign/ListSmsSignBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsSign/ListSmsSignBO.java
new file mode 100644
index 000000000..bc3a3db8d
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsSign/ListSmsSignBO.java
@@ -0,0 +1,53 @@
+package cn.iocoder.mall.system.biz.bo.smsSign;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * sms page
+ *
+ * @author Sin
+ * @time 2019/5/19 4:23 PM
+ */
+@Data
+@Accessors(chain = true)
+public class ListSmsSignBO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 短信平台
+ */
+ private Integer platform;
+ /**
+ * 签名名称
+ */
+ private String sign;
+ /**
+ * 审核状态
+ *
+ * - 1、审核中
+ * - 2、审核成功
+ * - 3、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+ /**
+ * 更新时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTime;
+ /**
+ * 创建时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsSign/SmsSignBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsSign/SmsSignBO.java
new file mode 100644
index 000000000..e14e3f38e
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsSign/SmsSignBO.java
@@ -0,0 +1,40 @@
+package cn.iocoder.mall.system.biz.bo.smsSign;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 短信签名
+ *
+ * @author Sin
+ * @time 2019/5/16 6:30 PM
+ */
+@Data
+@Accessors(chain = true)
+public class SmsSignBO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 签名id 这个是第三方的
+ */
+ private Integer signId;
+ /**
+ * 签名名称
+ */
+ private String sign;
+ /**
+ * 审核状态
+ *
+ * - 1、审核中
+ * - 2、审核成功
+ * - 3、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsTemplate/ListSmsTemplateBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsTemplate/ListSmsTemplateBO.java
new file mode 100644
index 000000000..0cbf83d58
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsTemplate/ListSmsTemplateBO.java
@@ -0,0 +1,103 @@
+package cn.iocoder.mall.system.biz.bo.smsTemplate;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * sms page
+ *
+ * @author Sin
+ * @time 2019/5/19 4:23 PM
+ */
+@Data
+@Accessors(chain = true)
+public class ListSmsTemplateBO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 模板编号 (第三方的)
+ */
+ private Integer smsSignId;
+ /**
+ * 短信签名 id
+ */
+ private String platform;
+ /**
+ * 短信模板 Code
+ */
+ private String templateCode;
+ /**
+ * 短信模板
+ */
+ private String template;
+ /**
+ * 短信类型
+ */
+ private Integer smsType;
+ /**
+ * 审核状态
+ *
+ * 1、审核中
+ * 2、审核成功
+ * 3、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+ /**
+ * 更新时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date updateTime;
+ /**
+ * 创建时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+ ///
+ /// 关联字段
+
+ /**
+ * 签名信息
+ */
+ private Sign sign;
+
+
+ @Data
+ @Accessors(chain = true)
+ public static class Sign {
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 签名id 这个是第三方的
+ */
+ private String platformId;
+ /**
+ * 签名名称
+ */
+ private String sign;
+ /**
+ * 审核状态
+ *
+ * - 1、审核中
+ * - 2、审核成功
+ * - 3、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsTemplate/SmsTemplateBO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsTemplate/SmsTemplateBO.java
new file mode 100644
index 000000000..d19aab797
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/bo/smsTemplate/SmsTemplateBO.java
@@ -0,0 +1,44 @@
+package cn.iocoder.mall.system.biz.bo.smsTemplate;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 短信 template
+ *
+ * @author Sin
+ * @time 2019/5/16 7:41 PM
+ */
+@Data
+@Accessors(chain = true)
+public class SmsTemplateBO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 模板编号 (第三方的)
+ */
+ private Integer smsSignId;
+ /**
+ * 短信签名 id
+ */
+ private String platformId;
+ /**
+ * 短信模板
+ */
+ private String template;
+ /**
+ * 审核状态
+ *
+ * 1、审核中
+ * 2、审核成功
+ * 3、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java
new file mode 100644
index 000000000..02a1cb837
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsSignConvert.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.system.biz.convert;
+
+import cn.iocoder.mall.system.biz.bo.smsSign.ListSmsSignBO;
+import cn.iocoder.mall.system.biz.bo.smsSign.SmsSignBO;
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsSignDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 短信 签名
+ *
+ * @author Sin
+ * @time 2019/5/16 6:31 PM
+ */
+@Mapper
+public interface SmsSignConvert {
+
+ SmsSignConvert INSTANCE = Mappers.getMapper(SmsSignConvert.class);
+
+ @Mappings({})
+ SmsSignBO convert(SmsSignDO smsSignDO);
+
+ @Mappings({})
+ List convert(List smsSignDOList);
+
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsTemplateConvert.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsTemplateConvert.java
new file mode 100644
index 000000000..586fcc389
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/convert/SmsTemplateConvert.java
@@ -0,0 +1,32 @@
+package cn.iocoder.mall.system.biz.convert;
+
+import cn.iocoder.mall.system.biz.bo.smsTemplate.ListSmsTemplateBO;
+import cn.iocoder.mall.system.biz.bo.smsTemplate.SmsTemplateBO;
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsSignDO;
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsTemplateDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 短信 template
+ *
+ * @author Sin
+ * @time 2019/5/16 7:43 PM
+ */
+@Mapper
+public interface SmsTemplateConvert {
+
+ SmsTemplateConvert INSTANCE = Mappers.getMapper(SmsTemplateConvert.class);
+
+ @Mappings({})
+ SmsTemplateBO convert(SmsTemplateDO smsTemplateDO);
+
+ @Mappings({})
+ List convert(List smsTemplateDOList);
+
+ @Mappings({})
+ List convertTemplateSign(List smsSignDOList);
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsSendMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsSendMapper.java
new file mode 100644
index 000000000..88475fab0
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsSendMapper.java
@@ -0,0 +1,15 @@
+package cn.iocoder.mall.system.biz.dao.sms;
+
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsSendLogDO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 短信
+ *
+ * @author Sin
+ * @time 2019/5/16 6:18 PM
+ */
+@Repository
+public interface SmsSendMapper extends BaseMapper {
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsSignMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsSignMapper.java
new file mode 100644
index 000000000..e3f8ac542
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsSignMapper.java
@@ -0,0 +1,15 @@
+package cn.iocoder.mall.system.biz.dao.sms;
+
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsSignDO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 短信
+ *
+ * @author Sin
+ * @time 2019/5/16 6:18 PM
+ */
+@Repository
+public interface SmsSignMapper extends BaseMapper {
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsTemplateMapper.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsTemplateMapper.java
new file mode 100644
index 000000000..04770f2ff
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dao/sms/SmsTemplateMapper.java
@@ -0,0 +1,15 @@
+package cn.iocoder.mall.system.biz.dao.sms;
+
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsTemplateDO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 短信 template
+ *
+ * @author Sin
+ * @time 2019/5/16 6:18 PM
+ */
+@Repository
+public interface SmsTemplateMapper extends BaseMapper {
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsSendLogDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsSendLogDO.java
new file mode 100644
index 000000000..0a376d11c
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsSendLogDO.java
@@ -0,0 +1,37 @@
+package cn.iocoder.mall.system.biz.dataobject.sms;
+
+import cn.iocoder.common.framework.dataobject.BaseDO;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 短信 client log
+ *
+ * @author Sin
+ * @time 2019/5/25 12:36 PM
+ */
+@Data
+@Accessors(chain = true)
+public class SmsSendLogDO extends BaseDO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 短信模板
+ */
+ private Integer templateId;
+ /**
+ * 短信
+ */
+ private String template;
+ /**
+ * 参数
+ */
+ private String params;
+ /**
+ * 发送信息
+ */
+ private String message;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsSignDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsSignDO.java
new file mode 100644
index 000000000..e5fe58225
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsSignDO.java
@@ -0,0 +1,48 @@
+package cn.iocoder.mall.system.biz.dataobject.sms;
+
+import cn.iocoder.common.framework.dataobject.DeletableDO;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 短信签名
+ *
+ * 签名是短信发送前缀 如:【阿里云】、【小红书】
+ *
+ * @author Sin
+ * @time 2019/5/16 12:28 PM
+ */
+@Data
+@Accessors(chain = true)
+@TableName("sms_sign")
+public class SmsSignDO extends DeletableDO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 签名名称
+ */
+ private String sign;
+ /**
+ * 平台
+ *
+ * 1、云片
+ * 2、阿里云
+ */
+ private Integer platform;
+ /**
+ * 审核状态
+ *
+ * - 1、审核中
+ * - 2、审核成功
+ * - 10、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsTemplateDO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsTemplateDO.java
new file mode 100644
index 000000000..1dc760ebf
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dataobject/sms/SmsTemplateDO.java
@@ -0,0 +1,59 @@
+package cn.iocoder.mall.system.biz.dataobject.sms;
+
+import cn.iocoder.common.framework.dataobject.DeletableDO;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 短信 模板
+ *
+ * @author Sin
+ * @time 2019/5/16 12:31 PM
+ */
+@Data
+@Accessors(chain = true)
+@TableName("sms_template")
+public class SmsTemplateDO extends DeletableDO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 模板编号 (第三方的)
+ */
+ private Integer smsSignId;
+ /**
+ * 模板 code(第三方平台 code)
+ */
+ private String templateCode;
+ /**
+ * 短信签名 id
+ */
+ private Integer platform;
+ /**
+ * 短信模板
+ */
+ private String template;
+ /**
+ * 短信类型
+ *
+ * - 验证码类
+ * - 通知类
+ * - 营销类
+ */
+ private Integer smsType;
+ /**
+ * 审核状态
+ *
+ * 1、审核中
+ * 2、审核成功
+ * 10、审核失败
+ */
+ private Integer applyStatus;
+ /**
+ * 审核信息
+ */
+ private String applyMessage;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/AddSignDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/AddSignDTO.java
new file mode 100644
index 000000000..01fc7bfcb
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/AddSignDTO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.mall.system.biz.dto.smsSign;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 添加 sign
+ *
+ * author: sin
+ * time: 2020/4/20 11:10 上午
+ */
+@Data
+@Accessors(chain = true)
+public class AddSignDTO implements Serializable {
+
+ private String sign;
+
+ private Integer platform;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/ListSmsSignDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/ListSmsSignDTO.java
new file mode 100644
index 000000000..518fcdb13
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/ListSmsSignDTO.java
@@ -0,0 +1,28 @@
+package cn.iocoder.mall.system.biz.dto.smsSign;
+
+import cn.iocoder.common.framework.vo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * page 短信模板 query
+ *
+ * @author Sin
+ * @time 2019/5/19 4:32 PM
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel("短信服务查询")
+public class ListSmsSignDTO extends PageParam {
+
+ @ApiModelProperty("编号")
+ private Integer id;
+
+ @ApiModelProperty("签名")
+ private String sign;
+
+ @ApiModelProperty("申请状态")
+ private Integer applyStatus;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/UpdateSignDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/UpdateSignDTO.java
new file mode 100644
index 000000000..8e45514f4
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsSign/UpdateSignDTO.java
@@ -0,0 +1,24 @@
+package cn.iocoder.mall.system.biz.dto.smsSign;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 更新签名
+ *
+ * author: sin
+ * time: 2020/4/20 11:05 上午
+ */
+@Data
+@Accessors(chain = true)
+public class UpdateSignDTO implements Serializable {
+
+ private Integer id;
+
+ private String sign;
+
+ private Integer platform;
+
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsTemplate/ListSmsTemplateDTO.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsTemplate/ListSmsTemplateDTO.java
new file mode 100644
index 000000000..86eaecb50
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/dto/smsTemplate/ListSmsTemplateDTO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.mall.system.biz.dto.smsTemplate;
+
+import cn.iocoder.common.framework.vo.PageParam;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * page 短信模板 query
+ *
+ * @author Sin
+ * @time 2019/5/19 4:32 PM
+ */
+@Data
+@Accessors(chain = true)
+public class ListSmsTemplateDTO extends PageParam {
+
+ @NotNull
+ private String id;
+
+ @NotNull
+ private Integer smsSignId;
+
+ @NotNull
+ private String template;
+
+ @NotNull
+ private String applyStatus;
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/AdminErrorCodeEnum.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/AdminErrorCodeEnum.java
new file mode 100644
index 000000000..db625e84a
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/AdminErrorCodeEnum.java
@@ -0,0 +1,85 @@
+package cn.iocoder.mall.system.biz.enums;
+
+/**
+ * 错误码枚举类
+ *
+ * 管理员系统,使用 1-002-000-000 段
+ */
+public enum AdminErrorCodeEnum {
+
+ // ========== OAUTH2 模块 ==========
+ OAUTH2_UNKNOWN(1002001000, "未知错误"), // 预留
+// OAUTH2_INVALID_GRANT_BAD_CREDENTIALS(1001001001, "密码不正确"), // 暂时没用到
+// OAUTH2_INVALID_GRANT_USERNAME_NOT_FOUND(1001001002, "账号不存在"), // 暂时没用到
+// OAUTH2_INVALID_GRANT(1001001010, ""), // 预留
+ OAUTH2_INVALID_TOKEN_NOT_FOUND(1002001011, "访问令牌不存在"),
+ OAUTH2_INVALID_TOKEN_EXPIRED(1002001012, "访问令牌已过期"),
+ OAUTH2_INVALID_TOKEN_INVALID(1002001013, "访问令牌已失效"),
+ OAUTH2_NOT_LOGIN(1002001015, "账号未登陆"),
+ OAUTH2_INVALID_TOKEN_ERROR_USER_TYPE(1002001016, "访问令牌用户类型不正确"),
+ OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND(1002001017, "刷新令牌不存在"),
+ OAUTH_INVALID_REFRESH_TOKEN_EXPIRED(1002001018, "访问令牌已过期"),
+ OAUTH_INVALID_REFRESH_TOKEN_INVALID(1002001019, "刷新令牌已失效"),
+
+ // ========== 管理员模块 1002002000 ==========
+ ADMIN_USERNAME_NOT_REGISTERED(1002002000, "账号不存在"),
+ ADMIN_PASSWORD_ERROR(1002002001, "密码不正确"),
+ ADMIN_IS_DISABLE(1002002002, "账号被禁用"),
+ ADMIN_USERNAME_EXISTS(1002002002, "账号已经存在"),
+ ADMIN_STATUS_EQUALS(1002002003, "账号已经是该状态"),
+ ADMIN_DELETE_ONLY_DISABLE(1002002004, "只有关闭的账号才可以删除"),
+ ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE(1002002005, "管理员的账号状态不允许变更"),
+ ADMIN_ASSIGN_ROLE_NOT_EXISTS(1002002006, "分配员工角色时,有角色不存在"),
+ ADMIN_INVALID_PERMISSION(1002002007, "没有该操作权限"),
+ ADMIN_ADMIN_CAN_NOT_UPDATE(1002002008, "管理员的账号不允许变更"),
+ ADMIN_DEMO_CAN_NOT_WRITE(1002002009, "演示账号,暂不允许写操作。欢迎加入我们的交流群:http://t.cn/EKEr5WE"),
+
+ // ========== 资源模块 1002003000 ==========
+ RESOURCE_NAME_DUPLICATE(1002003000, "已经存在该名字的资源"),
+ RESOURCE_PARENT_NOT_EXISTS(1002003001, "父资源不存在"),
+ RESOURCE_PARENT_ERROR(1002003002, "不能设置自己为父资源"),
+ RESOURCE_NOT_EXISTS(1002003003, "资源不存在"),
+ RESOURCE_EXISTS_CHILDREN(1002003004, "存在子资源,无法删除"),
+ RESOURCE_PARENT_NOT_MENU(1002003005, "父资源的类型必须是菜单"),
+
+ // ========== 角色模块 1002004000 ==========
+ ROLE_NOT_EXISTS(1002004000, "角色不存在"),
+ ROLE_ASSIGN_RESOURCE_NOT_EXISTS(1002004001, "分配角色资源时,有资源不存在"),
+
+ // ========== 数据字典模块 1002005000 ==========
+ DATA_DICT_EXISTS(1002005000, "该数据字典已经存在"),
+ DATA_DICT_NOT_EXISTS(1002005001, "该数据字典不存在"),
+
+ // ========== 短信模板 1002006000 ==========
+ SMS_PLATFORM_FAIL(1002006000, "短信平台调用失败【具体错误会动态替换】"),
+ SMS_SIGN_NOT_EXISTENT(1002006001, "短信签名不存在"),
+ SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"),
+ SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"),
+ SMS_TEMPLATE_IS_EXISTENT(1002006021, "短信签名不存在"),
+ SMS_NOT_SEND_CLIENT(1002006030, "短信没有发送的client"),
+
+ // ========== 部门模块 1002007000 ==========
+ DEPT_SAME_LEVEL_NAME_EXITS(1002007001,"当前级别部门名字已存在"),
+ DEPT_PARENT_NOT_EXITS(1002007002,"父级部门不存在"),
+ DEPT_NOT_EXITS(1002007003, "当前部门不存在"),
+ DEPT_EXITS_CHILDREN(1002007004, "当前部门存在子部门"),
+ DEPT_PARENT_NOT_LEGAL(1002007005, "父级部门不合法"),
+ ;
+
+ private final int code;
+ private final String message;
+
+ AdminErrorCodeEnum(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/package-info.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/package-info.java
new file mode 100644
index 000000000..9a1ed1792
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * author: sin
+ * time: 2020/4/20 10:12 上午
+ */
+package cn.iocoder.mall.system.biz.enums;
\ No newline at end of file
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsApplyStatusEnum.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsApplyStatusEnum.java
new file mode 100644
index 000000000..80ce41876
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsApplyStatusEnum.java
@@ -0,0 +1,31 @@
+package cn.iocoder.mall.system.biz.enums.sms;
+
+/**
+ * 短信审核状态
+ *
+ * @author Sin
+ * @time 2019/5/16 12:48 PM
+ */
+public enum SmsApplyStatusEnum {
+
+ CHECKING(1, "审核中"),
+ SUCCESS(2, "审核成功"),
+ FAIL(10, "审核失败"),
+ ;
+
+ private final Integer value;
+ private final String name;
+
+ SmsApplyStatusEnum(int code, String message) {
+ this.value = code;
+ this.name = message;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsPlatformEnum.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsPlatformEnum.java
new file mode 100644
index 000000000..ce125e1ba
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsPlatformEnum.java
@@ -0,0 +1,41 @@
+package cn.iocoder.mall.system.biz.enums.sms;
+
+import cn.iocoder.common.framework.core.IntArrayValuable;
+
+import java.util.Arrays;
+
+/**
+ * 短信审核状态
+ *
+ * @author Sin
+ * @time 2019/5/16 12:48 PM
+ */
+public enum SmsPlatformEnum implements IntArrayValuable {
+
+ YunPian(1, "云片"),
+ AliYun(2, "阿里云"),
+ ;
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsPlatformEnum::getValue).toArray();
+
+ private final Integer value;
+ private final String name;
+
+ SmsPlatformEnum(Integer code, String message) {
+ this.value = code;
+ this.name = message;
+ }
+
+ public Integer getValue() {
+ return value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsTypeEnum.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsTypeEnum.java
new file mode 100644
index 000000000..29fafc9e8
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/enums/sms/SmsTypeEnum.java
@@ -0,0 +1,42 @@
+package cn.iocoder.mall.system.biz.enums.sms;
+
+import cn.iocoder.common.framework.core.IntArrayValuable;
+
+import java.util.Arrays;
+
+/**
+ * 短信审核状态
+ *
+ * @author Sin
+ * @time 2019/5/16 12:48 PM
+ */
+public enum SmsTypeEnum implements IntArrayValuable {
+
+ VERIFICATION_CODE(1, "验证码"),
+ NOTICE(2, "通知"),
+ MARKETING(3, "营销"),
+ ;
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsTypeEnum::getValue).toArray();
+
+ private final Integer value;
+ private final String name;
+
+ SmsTypeEnum(Integer code, String message) {
+ this.value = code;
+ this.name = message;
+ }
+
+ public Integer getValue() {
+ return value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsClient.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsClient.java
new file mode 100644
index 000000000..bb1eecaab
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsClient.java
@@ -0,0 +1,64 @@
+package cn.iocoder.mall.system.biz.service.sms;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 短信平台
+ *
+ * @author Sin
+ * @time 2019/5/16 6:33 PM
+ */
+public interface SmsClient {
+
+ /**
+ * 短信发送 - 单个
+ *
+ * @param mobile 手机号
+ * @param sign 签名
+ * @param templateCode 短信模板code
+ * @param template 短信模板
+ * @param templateParams 短信模板 params
+ * @return 发送后信息
+ */
+ SendResult singleSend(String mobile, String sign, String templateCode,
+ String template, Map templateParams);
+
+ /**
+ * 短信发送 - 批量
+ *
+ * @param mobileList 手机号
+ * @param sign 签名
+ * @param templateCode 短信模板 code
+ * @param template 短信模板
+ * @param templateParams 短信模板params
+ * @return 发送后信息
+ */
+ SendResult batchSend(List mobileList, String sign, String templateCode,
+ String template, Map templateParams);
+
+ @Data
+ @Accessors(chain = true)
+ class SendResult {
+
+ public static final int SUCCESS_CODE = 0;
+ public static final int ERROR_CODE = 1;
+ public static final String SUCCESS_MESSAGE = "SUCCESS";
+
+ /**
+ * 错误码
+ */
+ private Integer code;
+ /**
+ * 错误信息
+ */
+ private String message;
+ /**
+ * 是否成功
+ */
+ private Boolean isSuccess;
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsService.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsService.java
new file mode 100644
index 000000000..69c3f698e
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsService.java
@@ -0,0 +1,117 @@
+package cn.iocoder.mall.system.biz.service.sms;
+
+import cn.iocoder.common.framework.vo.PageResult;
+import cn.iocoder.mall.system.biz.bo.smsSign.ListSmsSignBO;
+import cn.iocoder.mall.system.biz.bo.smsTemplate.ListSmsTemplateBO;
+import cn.iocoder.mall.system.biz.bo.smsSign.SmsSignBO;
+import cn.iocoder.mall.system.biz.bo.smsTemplate.SmsTemplateBO;
+import cn.iocoder.mall.system.biz.dto.smsSign.AddSignDTO;
+import cn.iocoder.mall.system.biz.dto.smsSign.ListSmsSignDTO;
+import cn.iocoder.mall.system.biz.dto.smsTemplate.ListSmsTemplateDTO;
+import cn.iocoder.mall.system.biz.dto.smsSign.UpdateSignDTO;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 短信服务
+ *
+ * @author Sin
+ * @time 2019/5/16 9:54 AM
+ */
+public interface SmsService {
+
+ /**
+ * 短信模板 - 分页
+ *
+ * @param listSmsSignDTO
+ * @return
+ */
+ PageResult listSmsSign(ListSmsSignDTO listSmsSignDTO);
+
+ /**
+ * 短信模板 - 分页
+ *
+ * @param listSmsTemplateDTO
+ * @return
+ */
+ PageResult listSmsTemplate(ListSmsTemplateDTO listSmsTemplateDTO);
+
+ /**
+ * 签名 - 创建
+ *
+ * @param addSignDTO
+ */
+ void addSign(AddSignDTO addSignDTO);
+
+ /**
+ * 签名 - 获取
+ *
+ * @param id
+ */
+ SmsSignBO getSign(Integer id);
+
+ /**
+ * 签名 - 更新
+ *
+ * @param updateSignDTO
+ */
+ void updateSign(UpdateSignDTO updateSignDTO);
+
+ /**
+ * 签名 - 更新
+ *
+ * @param id
+ */
+ void deleteSign(Integer id);
+
+ /**
+ * 模板 - 创建
+ *
+ * @param smsSignId 选用的哪个签名
+ * @param templateCode 模板code
+ * @param template 模板内容
+ * @param platform 平台
+ */
+ void addTemplate(Integer smsSignId, String templateCode,
+ String template, Integer platform, Integer smsType);
+
+ /**
+ * 模板 - 获取
+ *
+ * @param id
+ */
+ SmsTemplateBO getTemplate(Integer id, Integer platform);
+
+ /**
+ * 模板 - 更新
+ *
+ * @param id 模板id
+ * @param smsSignId 短期签名
+ * @param template 模板内容
+ * @param platform 短信平台
+ */
+ void updateTemplate(Integer id, Integer smsSignId, String templateCode,
+ String template, Integer platform, Integer smsType);
+
+ /**
+ * 模板 - 删除
+ *
+ * @param id
+ */
+ void deleteTemplate(Integer id);
+
+ /**
+ * 短信发送 - 单个
+ *
+ * @return
+ */
+ void singleSend(String mobile, Integer smsTemplateId, Map params);
+
+ /**
+ * 短信发送 - 批量
+ *
+ * @return
+ */
+ void batchSend(List mobileList, Integer smsTemplateId, Map params);
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java
new file mode 100644
index 000000000..3f2ab55ba
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/SmsServiceImpl.java
@@ -0,0 +1,423 @@
+package cn.iocoder.mall.system.biz.service.sms;
+
+import cn.iocoder.common.framework.constant.DeletedStatusEnum;
+import cn.iocoder.common.framework.exception.ServiceException;
+import cn.iocoder.common.framework.vo.PageResult;
+import cn.iocoder.mall.system.biz.bo.smsSign.ListSmsSignBO;
+import cn.iocoder.mall.system.biz.bo.smsTemplate.ListSmsTemplateBO;
+import cn.iocoder.mall.system.biz.bo.smsSign.SmsSignBO;
+import cn.iocoder.mall.system.biz.bo.smsTemplate.SmsTemplateBO;
+import cn.iocoder.mall.system.biz.convert.SmsSignConvert;
+import cn.iocoder.mall.system.biz.convert.SmsTemplateConvert;
+import cn.iocoder.mall.system.biz.dao.sms.SmsSendMapper;
+import cn.iocoder.mall.system.biz.dao.sms.SmsSignMapper;
+import cn.iocoder.mall.system.biz.dao.sms.SmsTemplateMapper;
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsSendLogDO;
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsSignDO;
+import cn.iocoder.mall.system.biz.dataobject.sms.SmsTemplateDO;
+import cn.iocoder.mall.system.biz.dto.smsSign.AddSignDTO;
+import cn.iocoder.mall.system.biz.dto.smsSign.ListSmsSignDTO;
+import cn.iocoder.mall.system.biz.dto.smsTemplate.ListSmsTemplateDTO;
+import cn.iocoder.mall.system.biz.dto.smsSign.UpdateSignDTO;
+import cn.iocoder.mall.system.biz.enums.AdminErrorCodeEnum;
+import cn.iocoder.mall.system.biz.enums.sms.SmsApplyStatusEnum;
+import cn.iocoder.mall.system.biz.enums.sms.SmsPlatformEnum;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 短信
+ *
+ * @author Sin
+ * @time 2019/5/16 10:30 AM
+ */
+@Service
+@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.SmsService.version}")
+public class SmsServiceImpl implements SmsService {
+
+ @Autowired
+ private SmsSignMapper smsSignMapper;
+ @Autowired
+ private SmsTemplateMapper smsTemplateMapper;
+ @Autowired
+ private SmsSendMapper smsSendMapper;
+
+ @Autowired
+ @Qualifier("smsYunPianClient")
+ private SmsClient smsYunPianClient;
+ @Autowired
+ @Qualifier("smsAliYunClient")
+ private SmsClient smsAliYunClient;
+
+ @Override
+ public PageResult listSmsSign(ListSmsSignDTO queryDTO) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ if (queryDTO.getApplyStatus() != null) {
+ queryWrapper.eq("apply_status", queryDTO.getApplyStatus());
+ }
+ if (!StringUtils.isEmpty(queryDTO.getSign())) {
+ queryWrapper.like("sign", queryDTO.getSign());
+ }
+ if (!StringUtils.isEmpty(queryDTO.getId())) {
+ queryWrapper.eq("id", queryDTO.getId());
+ }
+
+ Page page = new Page()
+ .setSize(queryDTO.getPageSize())
+ .setCurrent(queryDTO.getPageNo())
+ .setDesc("create_time");
+
+ IPage signPage = smsSignMapper.selectPage(page, queryWrapper);
+ List signList = SmsSignConvert.INSTANCE.convert(signPage.getRecords());
+ return new PageResult().setList(signList).setTotal((int) signPage.getTotal());
+ }
+
+ @Override
+ public PageResult listSmsTemplate(ListSmsTemplateDTO listSmsTemplateDTO) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ if (listSmsTemplateDTO.getApplyStatus() != null) {
+ queryWrapper.eq("apply_status", listSmsTemplateDTO.getApplyStatus());
+ }
+ if (listSmsTemplateDTO.getSmsSignId() != null) {
+ queryWrapper.eq("sms_sign_id", listSmsTemplateDTO.getSmsSignId());
+ }
+ if (!StringUtils.isEmpty(listSmsTemplateDTO.getTemplate())) {
+ queryWrapper.like("template", listSmsTemplateDTO.getTemplate());
+ }
+ if (!StringUtils.isEmpty(listSmsTemplateDTO.getId())) {
+ queryWrapper.eq("id", listSmsTemplateDTO.getId());
+ }
+
+ Page page = new Page()
+ .setSize(listSmsTemplateDTO.getPageSize())
+ .setCurrent(listSmsTemplateDTO.getPageNo())
+ .setDesc("create_time");
+
+ IPage signPage = smsTemplateMapper.selectPage(page, queryWrapper);
+
+ List templateList
+ = SmsTemplateConvert.INSTANCE.convert(signPage.getRecords());
+
+ if (CollectionUtils.isEmpty(templateList)) {
+ return new PageResult<>().setList(Collections.EMPTY_LIST).setTotal((int) signPage.getTotal());
+ }
+
+ // 获取 sign
+ Set smsSignIds = templateList.stream().map(
+ ListSmsTemplateBO::getSmsSignId).collect(Collectors.toSet());
+
+ List smsSignDOList = smsSignMapper.selectList(
+ new QueryWrapper().in("id", smsSignIds));
+
+ List signList = SmsTemplateConvert.INSTANCE.convertTemplateSign(smsSignDOList);
+
+ Map smsSignDOMap = signList
+ .stream().collect(Collectors.toMap(ListSmsTemplateBO.Sign::getId, o -> o));
+
+ // 设置 sign
+
+ templateList.forEach(template -> {
+ if (smsSignDOMap.containsKey(template.getSmsSignId())) {
+ template.setSign(smsSignDOMap.get(template.getSmsSignId()));
+ }
+ });
+
+ return new PageResult().setList(templateList).setTotal((int) signPage.getTotal());
+ }
+
+ @Override
+ @Transactional
+ public void addSign(AddSignDTO addSignDTO) {
+
+ // 避免重复
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper()
+ .eq("platform", addSignDTO.getPlatform())
+ .eq("sign", addSignDTO.getSign())
+ );
+
+ if (smsSignDO != null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getMessage());
+ }
+
+ // 保存数据库
+ smsSignMapper.insert(
+ (SmsSignDO) new SmsSignDO()
+ .setSign(addSignDTO.getSign())
+ .setPlatform(addSignDTO.getPlatform())
+ .setApplyStatus(SmsApplyStatusEnum.SUCCESS.getValue())
+ .setDeleted(DeletedStatusEnum.DELETED_NO.getValue())
+ .setUpdateTime(new Date())
+ .setCreateTime(new Date())
+ );
+ }
+
+ @Override
+ public SmsSignBO getSign(Integer signId) {
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper()
+ .eq("id", signId)
+ .eq("deleted", DeletedStatusEnum.DELETED_NO.getValue()));
+
+ if (smsSignDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
+ }
+
+ return SmsSignConvert.INSTANCE.convert(smsSignDO);
+ }
+
+ @Override
+ @Transactional
+ public void updateSign(UpdateSignDTO updateSignDTO) {
+ // 避免重复
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper()
+ .eq("sign", updateSignDTO.getSign())
+ .eq("platform", updateSignDTO.getPlatform()));
+
+ if (smsSignDO != null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getMessage());
+ }
+
+ // 更新
+ smsSignMapper.update(
+ (SmsSignDO) new SmsSignDO()
+ .setSign(updateSignDTO.getSign())
+ .setPlatform(updateSignDTO.getPlatform())
+ .setUpdateTime(new Date()),
+ new QueryWrapper().eq("id", updateSignDTO.getId())
+ );
+ }
+
+ @Override
+ public void deleteSign(Integer id) {
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper()
+ .eq("id", id));
+
+ if (smsSignDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
+ }
+
+ // 更新 deleted 为 YES
+ smsSignMapper.delete(new UpdateWrapper()
+ .set("deleted", DeletedStatusEnum.DELETED_YES.getName())
+ .eq("id", id)
+ );
+ }
+
+ @Override
+ @Transactional
+ public void addTemplate(Integer smsSignId, String templateCode,
+ String template, Integer platform, Integer smsType) {
+
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper().eq("id", smsSignId));
+
+ if (smsSignDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
+ }
+
+ // 保存数据库
+ smsTemplateMapper.insert(
+ (SmsTemplateDO) new SmsTemplateDO()
+ .setId(null)
+ .setSmsSignId(smsSignId)
+ .setTemplateCode(templateCode)
+ .setTemplate(template)
+ .setPlatform(platform)
+ .setSmsType(smsType)
+ .setApplyStatus(SmsApplyStatusEnum.SUCCESS.getValue())
+ .setApplyMessage("")
+ .setDeleted(DeletedStatusEnum.DELETED_NO.getValue())
+ .setCreateTime(new Date())
+ );
+ }
+
+ @Override
+ public SmsTemplateBO getTemplate(Integer id, Integer platform) {
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
+ new QueryWrapper()
+ .eq("platform", platform)
+ .eq("id", id));
+
+ if (smsTemplateDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
+ }
+
+ return SmsTemplateConvert.INSTANCE.convert(smsTemplateDO);
+ }
+
+ @Override
+ @Transactional
+ public void updateTemplate(Integer id, Integer smsSignId, String templateCode,
+ String template, Integer platform, Integer smsType) {
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
+ new QueryWrapper().eq("id", id));
+
+ if (smsTemplateDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
+ }
+
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper().eq("id", smsTemplateDO.getSmsSignId()));
+
+ if (smsSignDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
+ }
+
+ smsTemplateMapper.update(
+ (SmsTemplateDO) new SmsTemplateDO()
+ .setSmsSignId(smsSignId)
+ .setTemplateCode(templateCode)
+ .setTemplate(template)
+ .setPlatform(platform)
+ .setSmsType(smsType)
+ .setUpdateTime(new Date()),
+ new QueryWrapper().eq("id", id)
+ );
+ }
+
+ @Override
+ @Transactional
+ public void deleteTemplate(Integer id) {
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
+ new QueryWrapper().eq("id", id));
+
+ if (smsTemplateDO == null
+ || smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
+ }
+
+ // 删除 数据库模板
+ SmsTemplateDO updateTemplate =new SmsTemplateDO();
+ updateTemplate.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
+ smsTemplateMapper.delete(
+ new UpdateWrapper()
+ .set("deleted", DeletedStatusEnum.DELETED_YES)
+ .eq("id", id));
+ }
+
+ @Override
+ public void singleSend(String mobile, Integer smsTemplateId, Map params) {
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
+ new QueryWrapper().eq("id", smsTemplateId));
+
+ if (smsTemplateDO == null
+ || smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
+ }
+
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper().eq("id", smsTemplateDO.getSmsSignId()));
+
+ if (smsSignDO == null) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
+ }
+
+ // 获取 client
+ SmsClient smsClient = getSmsClient(smsTemplateDO.getPlatform());
+ // 发送短信
+ SmsClient.SendResult sendResult = smsClient.singleSend(mobile, smsSignDO.getSign(),
+ smsTemplateDO.getTemplateCode(), smsTemplateDO.getTemplate(), params);
+
+ // 添加日志
+ smsSendMapper.insert(
+ (SmsSendLogDO) new SmsSendLogDO()
+ .setTemplateId(smsTemplateDO.getId())
+ .setTemplate(smsTemplateDO.getTemplate())
+ .setMessage(sendResult.getMessage())
+ .setCreateTime(new Date())
+ );
+ }
+
+ @Override
+ public void batchSend(List mobileList, Integer smsTemplateId, Map params) {
+ SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(
+ new QueryWrapper().eq("id", smsTemplateId));
+
+ if (smsTemplateDO == null
+ || smsTemplateDO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage());
+ }
+
+ SmsSignDO smsSignDO = smsSignMapper.selectOne(
+ new QueryWrapper().eq("id", smsTemplateDO.getSmsSignId()));
+
+ if (smsSignDO == null) {
+ // 添加日志
+ smsSendMapper.insert(
+ (SmsSendLogDO) new SmsSendLogDO()
+ .setTemplateId(smsTemplateDO.getId())
+ .setTemplate(smsTemplateDO.getTemplate())
+ .setMessage("发送成功!")
+ .setCreateTime(new Date())
+ );
+
+ throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
+ AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
+ }
+
+ // 获取 client
+ SmsClient smsClient = getSmsClient(smsTemplateDO.getPlatform());
+
+ // 发送短信
+ SmsClient.SendResult sendResult = smsClient.batchSend(mobileList, smsSignDO.getSign(),
+ smsTemplateDO.getTemplateCode(), smsTemplateDO.getTemplate(), params);
+
+ // 添加日志
+ smsSendMapper.insert(
+ (SmsSendLogDO) new SmsSendLogDO()
+ .setTemplateId(smsTemplateDO.getId())
+ .setTemplate(smsTemplateDO.getTemplate())
+ .setMessage(sendResult.getMessage())
+ .setCreateTime(new Date())
+ );
+ }
+
+ /**
+ * 获取 sms 对于的 client
+ *
+ * @param platform
+ * @return
+ */
+ private SmsClient getSmsClient(Integer platform) {
+ SmsClient smsClient = null;
+ if (SmsPlatformEnum.YunPian.getValue().equals(platform)) {
+ smsClient = smsYunPianClient;
+ } else if (SmsPlatformEnum.AliYun.getValue().equals(platform)) {
+ smsClient = smsAliYunClient;
+ }
+
+ if (smsClient == null) {
+ throw new ServiceException(
+ AdminErrorCodeEnum.SMS_NOT_SEND_CLIENT.getCode(),
+ AdminErrorCodeEnum.SMS_NOT_SEND_CLIENT.getMessage());
+ }
+
+ return smsClient;
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/client/SmsAliYunClient.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/client/SmsAliYunClient.java
new file mode 100644
index 000000000..06272d09c
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/client/SmsAliYunClient.java
@@ -0,0 +1,163 @@
+package cn.iocoder.mall.system.biz.service.sms.client;
+
+import cn.iocoder.mall.system.biz.service.sms.SmsClient;
+import com.alibaba.fastjson.JSON;
+import com.aliyuncs.CommonRequest;
+import com.aliyuncs.CommonResponse;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.profile.DefaultProfile;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 短信 AliYun client
+ *
+ * @author Sin
+ * @time 2019/5/25 12:28 PM
+ */
+@Component
+public class SmsAliYunClient implements SmsClient {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SmsAliYunClient.class);
+
+ private static final String DOMAIN = "dysmsapi.aliyuncs.com";
+ private static final String SUCCESS_CODE = "OK";
+ private static final String SUCCESS_MESSAGE = "OK";
+ /**
+ * 阿里云短信 - 批量推送最大数 500,支持 1000
+ */
+ private static final int MAX_BATCH_SIZE = 500;
+
+ @Value("${sms.aliYun.accessKeyId?:'default_value'}")
+ private String accessKeyId;
+ @Value("${sms.aliYun.accessSecret?:'default_value'}")
+ private String accessSecret;
+
+ @Data
+ @Accessors(chain = true)
+ public static class Result {
+ /**
+ * 发送回执ID,可根据该ID在接口QuerySendDetails中查询具体的发送状态。
+ */
+ private String BizId;
+ /**
+ * 请求状态码。
+ *
+ * - OK 蔡成功
+ */
+ private String Code;
+ /**
+ * 状态码的描述。
+ */
+ private String Message;
+ /**
+ * 请求ID。
+ */
+ private String RequestId;
+ }
+
+ @Override
+ public SendResult singleSend(String mobile, String sign, String templateCode,
+ String template, Map templateParams) {
+ // params
+ CommonRequest request = new CommonRequest();
+ request.setMethod(MethodType.POST);
+ request.setDomain(DOMAIN);
+ request.setVersion("2017-05-25");
+ request.setAction("SendSms");
+ request.putQueryParameter("PhoneNumbers", mobile);
+ request.putQueryParameter("SignName", sign);
+ request.putQueryParameter("TemplateCode", templateCode);
+ request.putQueryParameter("TemplateParam", JSON.toJSONString(templateParams));
+
+ // 发送请求
+ return doSend(request);
+ }
+
+ @Override
+ public SendResult batchSend(List mobileList, String sign, String templateCode,
+ String template, Map templateParams) {
+
+ // 最大发送数为 1000,我们设置为 500 个, 分段发送
+ int maxSendSize = MAX_BATCH_SIZE;
+ int maxSendSizeCount = mobileList.size() % maxSendSize == 0
+ ? mobileList.size() / maxSendSize
+ : mobileList.size() / maxSendSize + 1;
+
+ SendResult sendResult = null;
+ for (int i = 0; i < maxSendSizeCount; i++) {
+ // 分批发送
+ List batchSendMobile = mobileList
+ .subList(i * maxSendSize, (i + 1) * maxSendSize);
+
+ // params
+ CommonRequest request = new CommonRequest();
+ request.setMethod(MethodType.POST);
+ request.setDomain(DOMAIN);
+ request.setVersion("2017-05-25");
+ request.setAction("SendBatchSms");
+ request.putQueryParameter("PhoneNumberJson", JSON.toJSONString(batchSendMobile));
+ request.putQueryParameter("SignNameJson", JSON.toJSONString(Collections.singletonList(sign)));
+ request.putQueryParameter("TemplateCode", templateCode);
+ request.putQueryParameter("TemplateParamJson", JSON.toJSONString(Collections.singletonList(templateParams)));
+
+ // 发送请求
+ sendResult = doSend(request);
+ }
+ return sendResult;
+ }
+
+ private SendResult doSend(CommonRequest request) {
+ // 获取 client
+ IAcsClient client = getClient();
+ try {
+ CommonResponse response = client.getCommonResponse(request);
+ Result result = JSON.parseObject(response.getData(), Result.class);
+ if (!SUCCESS_CODE.equals(result.getCode())) {
+
+ LOGGER.info("发送验证码失败 params {} res {}", JSON.toJSON(request), JSON.toJSON(result));
+
+ // 错误发送失败
+ return new SendResult()
+ .setIsSuccess(false)
+ .setCode(SendResult.ERROR_CODE)
+ .setMessage(result.getMessage());
+ } else {
+ LOGGER.info("发送验证码失败 params {} res", JSON.toJSON(request), JSON.toJSON(result));
+
+ // 发送成功
+ return new SendResult()
+ .setIsSuccess(true)
+ .setCode(SendResult.SUCCESS_CODE)
+ .setMessage(result.getMessage());
+ }
+ } catch (ClientException e) {
+ LOGGER.error("发送验证码异常 {}", ExceptionUtils.getMessage(e));
+ return new SendResult()
+ .setIsSuccess(false)
+ .setCode(SendResult.ERROR_CODE)
+ .setMessage(ExceptionUtils.getMessage(e));
+ }
+ }
+
+ /**
+ * 获取 client
+ *
+ * @return
+ */
+ private IAcsClient getClient() {
+ return new DefaultAcsClient(DefaultProfile.getProfile("default", accessKeyId, accessSecret));
+ }
+}
diff --git a/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/client/SmsYunPianClient.java b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/client/SmsYunPianClient.java
new file mode 100644
index 000000000..fe633f7c0
--- /dev/null
+++ b/system/system-biz/src/main/java/cn/iocoder/mall/system/biz/service/sms/client/SmsYunPianClient.java
@@ -0,0 +1,242 @@
+package cn.iocoder.mall.system.biz.service.sms.client;
+
+import cn.iocoder.common.framework.exception.ServiceException;
+import cn.iocoder.mall.system.biz.enums.AdminErrorCodeEnum;
+import cn.iocoder.mall.system.biz.service.sms.SmsClient;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 云片 短信平台
+ *
+ * @author Sin
+ * @time 2019/5/16 6:34 PM
+ */
+@Component
+public class SmsYunPianClient implements SmsClient {
+
+ protected static final Logger LOGGER = LoggerFactory.getLogger(SmsYunPianClient.class);
+
+ private static final int SUCCESS_CODE = 0;
+ private static final String SUCCESS_MESSAGE = "SUCCESS";
+
+ /**
+ * 云片短信 - 批量推送最大数 500,支持 1000
+ */
+ private static final int MAX_BATCH_SIZE = 500;
+ /**
+ * 模板 - 参数拼接
+ */
+ private static final String PARAM_TEMPLATE = "#%s#";
+ /**
+ * 模板 - 签名拼接
+ */
+ private static final String SIGN_TEMPLATE = "【%s】%s";
+
+ /**
+ * 签名 - 添加
+ */
+ private static final String URL_SIGN_ADD = "https://sms.yunpian.com/v2/sign/add.json";
+ /**
+ * 签名 - 获取
+ */
+ private static final String URL_SIGN_GET = "https://sms.yunpian.com/v2/sign/get.json";
+ /**
+ * 签名 - 更新
+ */
+ private static final String URL_SIGN_UPDATE = "https://sms.yunpian.com/v2/sign/update.json";
+ /**
+ * 模板 - 添加
+ */
+ private static final String URL_TEMPLATE_ADD = "https://sms.yunpian.com/v2/tpl/add.json";
+ /**
+ * 模板 - 获取
+ */
+ private static final String URL_TEMPLATE_GET = "https://sms.yunpian.com/v2/tpl/get.json";
+ /**
+ * 模板 - 更新
+ */
+ private static final String URL_TEMPLATE_UPDATE = "https://sms.yunpian.com/v2/tpl/update.json";
+ /**
+ * 模板 - 删除
+ */
+ private static final String URL_TEMPLATE_DELETE = "https://sms.yunpian.com/v2/tpl/del.json";
+ /**
+ * 短信发送 - 单个
+ */
+ private static final String URL_SEND_SINGLE = "https://sms.yunpian.com/v2/sms/single_send.json";
+ /**
+ * 短信发送 - 批量
+ */
+ private static final String URL_SEND_BATCH = "https://sms.yunpian.com/v2/sms/batch_send.json";
+
+
+ //编码格式。发送编码格式统一用UTF-8
+ private static String ENCODING = "UTF-8";
+
+ @Value("${sms.yunPian.apiKey?:'default_value'}")
+ private String apiKey;
+
+ @Override
+ public SendResult singleSend(String mobile, String sign, String templateCode, String template, Map templateParams) {
+ // build 模板
+ template = buildTemplate(sign, template, templateParams);
+
+ // 请求参数
+ Map params = new LinkedHashMap<>();
+ params.put("apikey", apiKey);
+ params.put("mobile", mobile);
+ params.put("text", template);
+ // TODO: 2019/5/19 sin 运营商发送报告 回调
+ // params.put("callback_url", template);
+ String result = post(URL_SEND_SINGLE, params);
+ JSONObject jsonObject = JSON.parseObject(result);
+ if (jsonObject.containsKey("code")
+ && !(jsonObject.getInteger("code") == SUCCESS_CODE)) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(),
+ jsonObject.getString("detail"));
+ }
+
+ return new SendResult()
+ .setIsSuccess(SUCCESS_CODE == jsonObject.getInteger("code"))
+ .setCode(jsonObject.getInteger("code"))
+ .setMessage(jsonObject.getString("detail"));
+ }
+
+ @Override
+ public SendResult batchSend(List mobileList, String sign,
+ String templateCode, String template,
+ Map templateParams) {
+ // build 模板
+ template = buildTemplate(sign, template, templateParams);
+
+ // 最大发送数为 1000,我们设置为 500 个, 分段发送
+ int maxSendSize = MAX_BATCH_SIZE;
+ int maxSendSizeCount = mobileList.size() % maxSendSize == 0
+ ? mobileList.size() / maxSendSize
+ : mobileList.size() / maxSendSize + 1;
+ int j = 0;
+ int j2 = mobileList.size();
+
+ for (int i = 0; i < maxSendSizeCount; i++) {
+ StringBuffer sendMobileStr = new StringBuffer();
+ for (int k = j; k < j2; k++) {
+ sendMobileStr.append(",");
+ sendMobileStr.append(mobileList.get(k));
+ }
+
+ String dividedMobile = sendMobileStr.toString().substring(1);
+
+ // 发送手机号
+ Map params = new LinkedHashMap<>();
+ params.put("apikey", apiKey);
+ params.put("mobile", dividedMobile);
+ params.put("text", template);
+ // TODO: 2019/5/19 sin 运营商发送报告 回调
+ // params.put("callback_url", template);
+ String result = post(URL_SEND_BATCH, params);
+ JSONObject jsonObject = JSON.parseObject(result);
+ if (jsonObject.containsKey("code")
+ && !(jsonObject.getInteger("code") == SUCCESS_CODE)) {
+ throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(),
+ jsonObject.getString("detail"));
+ }
+
+ // 用于递增 maxSendSize
+ j = j2;
+ j2 = j + maxSendSize;
+ }
+
+ return new SendResult()
+ .setIsSuccess(true)
+ .setCode(SUCCESS_CODE)
+ .setMessage(SUCCESS_MESSAGE);
+ }
+
+ /**
+ * 构建模板
+ *
+ * @param sign
+ * @param template
+ * @param templateParams
+ * @return
+ */
+ private static String buildTemplate(String sign, String template,
+ Map templateParams) {
+
+ if (CollectionUtils.isEmpty(templateParams)) {
+ return template;
+ }
+
+ for (Map.Entry entry : templateParams.entrySet()) {
+ String paramsKey = entry.getKey();
+ String value = entry.getValue();
+ String paramPlace = String.format(PARAM_TEMPLATE, paramsKey);
+ template = template.replaceAll(paramPlace, value);
+ }
+
+ template = String.format(SIGN_TEMPLATE, sign, template);
+ return template;
+ }
+
+ /**
+ * 基于HttpClient 4.3的通用POST方法
+ *
+ * @param url 提交的URL
+ * @param paramsMap 提交<参数,值>Map
+ * @return 提交响应
+ */
+
+ public static String post(String url, Map paramsMap) {
+ CloseableHttpClient client = HttpClients.createDefault();
+ String responseText = "";
+ CloseableHttpResponse response = null;
+ try {
+ HttpPost method = new HttpPost(url);
+ if (paramsMap != null) {
+ List paramList = new ArrayList<>();
+ for (Map.Entry param : paramsMap.entrySet()) {
+ NameValuePair pair = new BasicNameValuePair(param.getKey(),
+ param.getValue());
+ paramList.add(pair);
+ }
+ method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
+ }
+ response = client.execute(method);
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ responseText = EntityUtils.toString(entity, ENCODING);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ response.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ LOGGER.debug("云片短信平台 res: {}", responseText);
+ return responseText;
+ }
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/admin/AdminsSmsSignController.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/admin/AdminsSmsSignController.java
new file mode 100644
index 000000000..1359d88ee
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/admin/AdminsSmsSignController.java
@@ -0,0 +1,57 @@
+package cn.iocoder.mall.system.rest.controller.admin;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.common.framework.vo.PageResult;
+import cn.iocoder.mall.system.biz.bo.smsSign.ListSmsSignBO;
+import cn.iocoder.mall.system.biz.dto.smsSign.ListSmsSignDTO;
+import cn.iocoder.mall.system.biz.service.sms.SmsService;
+import cn.iocoder.mall.system.rest.convert.sms.AdminsSmsConvert;
+import cn.iocoder.mall.system.rest.request.smsSign.AddSignRequest;
+import cn.iocoder.mall.system.rest.request.smsSign.UpdateSignRequest;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 短信服务
+ *
+ * @author Sin
+ * @time 2019/5/26 12:26 PM
+ */
+@RestController
+@RequestMapping("admins/sms/sign")
+@Api("短信服务(签名)")
+public class AdminsSmsSignController {
+
+ @Autowired
+ private SmsService smsService;
+
+ @GetMapping("page")
+ @ApiOperation("签名-page")
+ public CommonResult> pageSign(@Validated ListSmsSignDTO listSmsSignDTO) {
+ return CommonResult.success(smsService.listSmsSign(listSmsSignDTO));
+ }
+
+ @PostMapping("add")
+ @ApiOperation("签名-添加")
+ public CommonResult addSign(@RequestBody AddSignRequest addSignRequest) {
+ smsService.addSign(AdminsSmsConvert.INSTANCE.convert(addSignRequest));
+ return CommonResult.success(null);
+ }
+
+ @PutMapping("update")
+ @ApiOperation("签名-更新")
+ public CommonResult updateSign(@RequestBody UpdateSignRequest updateSignRequest) {
+ smsService.updateSign(AdminsSmsConvert.INSTANCE.convert(updateSignRequest));
+ return CommonResult.success(null);
+ }
+
+ @DeleteMapping("deleted")
+ @ApiOperation("签名-删除")
+ public CommonResult deletedSign(@RequestParam("id") Integer id) {
+ smsService.deleteSign(id);
+ return CommonResult.success(null);
+ }
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/admin/AdminsSmsTemplateController.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/admin/AdminsSmsTemplateController.java
new file mode 100644
index 000000000..853d1b5be
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/controller/admin/AdminsSmsTemplateController.java
@@ -0,0 +1,68 @@
+package cn.iocoder.mall.system.rest.controller.admin;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.common.framework.vo.PageResult;
+import cn.iocoder.mall.system.biz.bo.smsTemplate.ListSmsTemplateBO;
+import cn.iocoder.mall.system.biz.dto.smsTemplate.ListSmsTemplateDTO;
+import cn.iocoder.mall.system.biz.service.sms.SmsService;
+import cn.iocoder.mall.system.rest.convert.sms.AdminsSmsConvert;
+import cn.iocoder.mall.system.rest.request.smsTemplate.AddSmsTemplateRequest;
+import cn.iocoder.mall.system.rest.request.smsTemplate.ListSmsTemplateRequest;
+import cn.iocoder.mall.system.rest.request.smsTemplate.UpdateSmsTemplateRequest;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 短信服务
+ *
+ * @author Sin
+ * @time 2019/5/26 12:26 PM
+ */
+@RestController
+@RequestMapping("admins/sms/template")
+@Api("短信服务(短信模板)")
+public class AdminsSmsTemplateController {
+
+ @Autowired
+ private SmsService smsService;
+
+ @PostMapping("page")
+ @ApiOperation("短信模板-page")
+ public CommonResult> pageSign(@RequestBody ListSmsTemplateRequest request) {
+ return CommonResult.success(smsService.listSmsTemplate(AdminsSmsConvert.INSTANCE.convert(request)));
+ }
+
+ @PostMapping("add")
+ @ApiOperation("短信模板-添加")
+ public CommonResult addSign(@RequestBody AddSmsTemplateRequest smsTemplateAddPO) {
+ smsService.addTemplate(
+ smsTemplateAddPO.getSmsSignId(),
+ smsTemplateAddPO.getTemplateCode(),
+ smsTemplateAddPO.getTemplate(),
+ smsTemplateAddPO.getPlatform(),
+ smsTemplateAddPO.getSmsType());
+ return CommonResult.success(null);
+ }
+
+ @PutMapping("update")
+ @ApiOperation("短信模板-更新")
+ public CommonResult updateSign(@RequestBody UpdateSmsTemplateRequest smsTemplateUpdatePO) {
+ smsService.updateTemplate(
+ smsTemplateUpdatePO.getId(),
+ smsTemplateUpdatePO.getSmsSignId(),
+ smsTemplateUpdatePO.getTemplateCode(),
+ smsTemplateUpdatePO.getTemplate(),
+ smsTemplateUpdatePO.getPlatform(),
+ smsTemplateUpdatePO.getSmsType());
+ return CommonResult.success(null);
+ }
+
+ @DeleteMapping("deleted")
+ @ApiOperation("短信模板-删除")
+ public CommonResult deletedSign(@RequestParam("id") Integer id) {
+ smsService.deleteTemplate(id);
+ return CommonResult.success(null);
+ }
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java
new file mode 100644
index 000000000..d3d559439
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/convert/sms/AdminsSmsConvert.java
@@ -0,0 +1,32 @@
+package cn.iocoder.mall.system.rest.convert.sms;
+
+import cn.iocoder.mall.system.biz.dto.smsSign.AddSignDTO;
+import cn.iocoder.mall.system.biz.dto.smsSign.UpdateSignDTO;
+import cn.iocoder.mall.system.biz.dto.smsTemplate.ListSmsTemplateDTO;
+import cn.iocoder.mall.system.rest.request.smsSign.AddSignRequest;
+import cn.iocoder.mall.system.rest.request.smsSign.UpdateSignRequest;
+import cn.iocoder.mall.system.rest.request.smsTemplate.ListSmsTemplateRequest;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * sms admins convert
+ *
+ * author: sin
+ * time: 2020/4/20 11:07 上午
+ */
+@Mapper
+public interface AdminsSmsConvert {
+
+ AdminsSmsConvert INSTANCE = Mappers.getMapper(AdminsSmsConvert.class);
+
+ @Mappings({})
+ AddSignDTO convert(AddSignRequest addSignRequest);
+
+ @Mappings({})
+ UpdateSignDTO convert(UpdateSignRequest updateSignRequest);
+
+ @Mappings({})
+ ListSmsTemplateDTO convert(ListSmsTemplateRequest listSmsTemplateRequest);
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsSign/AddSignRequest.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsSign/AddSignRequest.java
new file mode 100644
index 000000000..071711db0
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsSign/AddSignRequest.java
@@ -0,0 +1,22 @@
+package cn.iocoder.mall.system.rest.request.smsSign;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.io.Serializable;
+
+/**
+ * 添加 sign
+ *
+ * author: sin
+ * time: 2020/4/20 11:10 上午
+ */
+@Data
+@Accessors(chain = true)
+public class AddSignRequest implements Serializable {
+
+ private String sign;
+
+ private Integer platform;
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsSign/UpdateSignRequest.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsSign/UpdateSignRequest.java
new file mode 100644
index 000000000..f8d05e91b
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsSign/UpdateSignRequest.java
@@ -0,0 +1,23 @@
+package cn.iocoder.mall.system.rest.request.smsSign;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 更新签名
+ *
+ * author: sin
+ * time: 2020/4/20 11:02 上午
+ */
+@Data
+@Accessors(chain = true)
+public class UpdateSignRequest implements Serializable {
+
+ private Integer id;
+
+ private String sign;
+
+ private Integer platform;
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/AddSmsTemplateRequest.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/AddSmsTemplateRequest.java
new file mode 100644
index 000000000..36ab20484
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/AddSmsTemplateRequest.java
@@ -0,0 +1,49 @@
+package cn.iocoder.mall.system.rest.request.smsTemplate;
+
+import cn.iocoder.common.framework.validator.InEnum;
+import cn.iocoder.mall.system.biz.enums.sms.SmsPlatformEnum;
+import cn.iocoder.mall.system.biz.enums.sms.SmsTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * 短信模板 add
+ *
+ * @author Sin
+ * @time 2019/5/26 12:37 PM
+ */
+@ApiModel("短信模板-添加")
+@Data
+@Accessors(chain = true)
+public class AddSmsTemplateRequest implements Serializable {
+
+ @ApiModelProperty("短信签名id")
+ @NotNull(message = "短信短信签名id不能为空!")
+ private Integer smsSignId;
+
+ @ApiModelProperty("短信模板code")
+ @NotNull
+ @Size(min = 3, max = 50, message = "短信code在 3-50 之间")
+ private String templateCode;
+
+ @ApiModelProperty("短信模板")
+ @NotNull
+ @Size(min = 3, max = 255, message = "短信在 3-255 之间")
+ private String template;
+
+ @ApiModelProperty("短信模板-平台")
+ @NotNull
+ @InEnum(value = SmsPlatformEnum.class)
+ private Integer platform;
+
+ @ApiModelProperty("短信模板-平台")
+ @NotNull
+ @InEnum(value = SmsTypeEnum.class)
+ private Integer smsType;
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/ListSmsTemplateRequest.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/ListSmsTemplateRequest.java
new file mode 100644
index 000000000..285d11e7c
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/ListSmsTemplateRequest.java
@@ -0,0 +1,30 @@
+package cn.iocoder.mall.system.rest.request.smsTemplate;
+
+import cn.iocoder.common.framework.vo.PageParam;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * page 短信模板 query
+ *
+ * @author Sin
+ * @time 2019/5/19 4:32 PM
+ */
+@Data
+@Accessors(chain = true)
+public class ListSmsTemplateRequest extends PageParam {
+
+ @NotNull
+ private String id;
+
+ @NotNull
+ private Integer smsSignId;
+
+ @NotNull
+ private String template;
+
+ @NotNull
+ private String applyStatus;
+}
diff --git a/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/UpdateSmsTemplateRequest.java b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/UpdateSmsTemplateRequest.java
new file mode 100644
index 000000000..b879893d0
--- /dev/null
+++ b/system/system-rest/src/main/java/cn/iocoder/mall/system/rest/request/smsTemplate/UpdateSmsTemplateRequest.java
@@ -0,0 +1,53 @@
+package cn.iocoder.mall.system.rest.request.smsTemplate;
+
+import cn.iocoder.common.framework.validator.InEnum;
+import cn.iocoder.mall.system.biz.enums.sms.SmsPlatformEnum;
+import cn.iocoder.mall.system.biz.enums.sms.SmsTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * 短信模板 add
+ *
+ * @author Sin
+ * @time 2019/5/26 12:37 PM
+ */
+@ApiModel("短信模板-添加")
+@Data
+@Accessors(chain = true)
+public class UpdateSmsTemplateRequest implements Serializable {
+
+ @ApiModelProperty("短信模板id")
+ @NotNull(message = "短信模板不能为空!")
+ private Integer id;
+
+ @ApiModelProperty("短信签名id")
+ @NotNull(message = "短信短信签名id不能为空!")
+ private Integer smsSignId;
+
+ @ApiModelProperty("短信模板code")
+ @NotNull
+ @Size(min = 3, max = 50, message = "短信code在 3-50 之间")
+ private String templateCode;
+
+ @ApiModelProperty("短信模板")
+ @NotNull
+ @Size(min = 3, max = 255, message = "短信在 3-255 之间")
+ private String template;
+
+ @ApiModelProperty("短信模板-平台")
+ @NotNull
+ @InEnum(value = SmsPlatformEnum.class)
+ private Integer platform;
+
+ @ApiModelProperty("短信模板-平台")
+ @NotNull
+ @InEnum(value = SmsTypeEnum.class)
+ private Integer smsType;
+}