yonge 3 vuotta sitten
vanhempi
commit
130a0059f5
35 muutettua tiedostoa jossa 2940 lisäystä ja 3 poistoa
  1. 10 1
      .gitignore
  2. 11 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/AdminApplication.java
  3. 88 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SmsCodeController.java
  4. 29 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysConfigDao.java
  5. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMessageConfigDao.java
  6. 55 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMessageDao.java
  7. 24 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/Mapper.java
  8. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/SysMessageDto.java
  9. 107 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysConfig.java
  10. 208 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMessage.java
  11. 103 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMessageConfig.java
  12. 36 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageSendMode.java
  13. 248 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java
  14. 36 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SendStatusEnum.java
  15. 18 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SmsCodeService.java
  16. 404 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysConfigService.java
  17. 15 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMessageConfigService.java
  18. 130 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMessageService.java
  19. 61 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SmsCodeServiceImpl.java
  20. 40 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysConfigServiceImpl.java
  21. 29 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMessageConfigServiceImpl.java
  22. 412 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMessageServiceImpl.java
  23. 106 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysConfigMapper.xml
  24. 117 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMessageConfigMapper.xml
  25. 204 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMessageMapper.xml
  26. 108 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysSuggestionMapper.xml
  27. 6 0
      cooleshow-user/user-student/pom.xml
  28. 88 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SmsCodeController.java
  29. 48 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/UploadFileController.java
  30. 6 0
      cooleshow-user/user-teacher/pom.xml
  31. 88 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SmsCodeController.java
  32. 48 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/UploadFileController.java
  33. BIN
      toolset/thirdparty-component/libs/smUtil-1.0.jar
  34. BIN
      toolset/thirdparty-component/libs/tgtext-3.2.14.jar
  35. 23 2
      toolset/thirdparty-component/pom.xml

+ 10 - 1
.gitignore

@@ -42,4 +42,13 @@ toolset/codegen/src/main/resources/generateConfigration.xml
 /nbbuild/
 /dist/
 /nbdist/
-/.nb-gradle/
+/.nb-gradle/
+
+.gitignore
+*.class
+.metadata
+target
+*.classpath
+.settings
+.project
+bin

+ 11 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/AdminApplication.java

@@ -1,11 +1,22 @@
 package com.yonge.cooleshow.admin;
 
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
 
 @SpringBootApplication
 @EnableDiscoveryClient
+@EnableFeignClients("com.yonge.cooleshow")
+@MapperScan("com.yonge.cooleshow.biz.dal.dao")
+@ComponentScan(basePackages = { "com.yonge.cooleshow.admin", "com.yonge.cooleshow.auth", "com.yonge.cooleshow.biz", "com.yonge.cooleshow.common", "com.yonge.cooleshow.common.security", "com.yonge.toolset.log", "com.yonge.toolset.thirdparty" })
+@Configuration
+@EnableSwagger2Doc
 public class AdminApplication {
 
 	public static void main(String[] args) {

+ 88 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/web/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.web.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+
+@RestController
+@RequestMapping("code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String")
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile) throws Exception {
+        smsCodeService.sendValidCode(mobile);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String") })
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone,String code) {
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if(smsCodeService.verifyValidCode(phone,code)){
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
+    public Object verifyImageCode(String phone,String code){
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if(redisTemplate.hasKey(redisKey)){
+            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response,String phone) throws Exception {
+        if(StringUtils.isEmpty(phone)){
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone,specCaptcha.text(),3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

+ 29 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysConfigDao.java

@@ -0,0 +1,29 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+
+public interface SysConfigDao extends BaseDAO<Long, SysConfig> {
+
+    /**
+     * @Author: Joburgess
+     * @Date: 2019/10/9
+     * @params [paramName]
+     * @return com.ym.mec.biz.dal.entity.SysConfig
+     * @describe 根据配置名称获取配置信息
+     */
+    SysConfig findByParamName(String paramName);
+
+    /**
+     * 获取value
+     * @param paramName
+     * @return
+     */
+    String findConfigValue(String paramName);
+
+    void batchUpdate(@Param("configList") List<SysConfig> configList);
+}

+ 17 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMessageConfigDao.java

@@ -0,0 +1,17 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.yonge.cooleshow.biz.dal.entity.SysMessageConfig;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+
+public interface SysMessageConfigDao extends BaseDAO<Integer, SysMessageConfig> {
+
+	/**
+	 * 根据消息类型查询对象
+	 * @param messageType
+	 * @return
+	 */
+	SysMessageConfig queryByType(@Param("messageType") String messageType);
+
+}

+ 55 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMessageDao.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.annotations.Param;
+
+import com.yonge.cooleshow.biz.dal.dto.SysMessageDto;
+import com.yonge.cooleshow.biz.dal.entity.SysMessage;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+import com.yonge.cooleshow.common.entity.Mapper;
+
+public interface SysMessageDao extends BaseDAO<Long, SysMessage> {
+	
+	public List<SysMessageDto> queryListPage(Map<String, Object> params);
+
+	public List<SysMessage> queryUserInRecentMinList(@Param("mobile") String mobile, @Param("recentMin") int recentMin, @Param("type") MessageSendMode type);
+
+	/**
+	 * 根据状态查询最近N分钟的记录
+	 *
+	 * @param status    状态值
+	 * @param recentMin 最近分钟数
+	 * @return
+	 */
+	public List<SysMessage> queryByStatusAndTime(@Param("status") int status, @Param("recentMin") int recentMin);
+
+	/**
+	 * 批量插入
+	 *
+	 * @param messages
+	 * @return
+	 */
+	public int batchInsert(List<SysMessage> messages);
+
+	/**
+	 * 查询消息未读条数
+	 *
+	 * @param type
+	 * @param userId
+	 * @return
+	 */
+	public List<Mapper> queryCountOfUnread(@Param("type") MessageSendMode type, @Param("userId") Integer userId, @Param("jpushType") String jpushType, @Param("tenantId") Integer tenantId);
+
+	/**
+	 * 修改用户所有消息阅读状态
+	 */
+	public int updateStatus(@Param("userId") Integer userId, @Param("status") int status, @Param("jpushType") String jpushType);
+
+	/**
+	 * 修改单个消息状态
+	 */
+	public int updateOneStatus(@Param("id") Long id, @Param("status") int status);
+}

+ 24 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/Mapper.java

@@ -0,0 +1,24 @@
+package com.yonge.cooleshow.biz.dal.dto;
+
+public class Mapper {
+
+	private Object key;
+	
+	private Object value;
+
+	public Object getKey() {
+		return key;
+	}
+
+	public void setKey(Object key) {
+		this.key = key;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public void setValue(Object value) {
+		this.value = value;
+	}
+}

+ 17 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/SysMessageDto.java

@@ -0,0 +1,17 @@
+package com.yonge.cooleshow.biz.dal.dto;
+
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysMessage;
+
+public class SysMessageDto extends SysMessage {
+
+	private SysUser user = new SysUser();
+
+	public SysUser getUser() {
+		return user;
+	}
+
+	public void setUser(SysUser user) {
+		this.user = user;
+	}
+}

+ 107 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysConfig.java

@@ -0,0 +1,107 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.yonge.cooleshow.common.entity.BaseEntity;
+
+/**
+ * 对应数据库表(sys_config):
+ */
+public class SysConfig extends BaseEntity {
+
+	/**  */
+	private Long id;
+	
+	/** 参数名称 */
+	@ApiModelProperty(value = "参数名称", required = true)
+	private String paramName;
+	
+	/** 参数值 */
+	@ApiModelProperty(value = "参数值", required = true)
+	private String paranValue;
+	
+	/** 描述 */
+	@ApiModelProperty(value = "描述", required = true)
+	private String description;
+	
+	/** 创建时间 */
+	private java.util.Date createOn;
+	
+	/** 修改时间 */
+	private java.util.Date modifyOn;
+	
+	@ApiModelProperty(value = "消息组", required = true)
+	private String group;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setParamName(String paramName){
+		this.paramName = paramName;
+	}
+	
+	public String getParamName(){
+		return this.paramName;
+	}
+			
+	public void setParanValue(String paranValue){
+		this.paranValue = paranValue;
+	}
+	
+	public String getParanValue(){
+		return this.paranValue;
+	}
+
+	public <T> T getParanValue(Class<T> cla){
+		try {
+			return cla.cast(cla.getMethod("valueOf", String.class).invoke(cla.getInterfaces(),this.paranValue));
+		} catch (Exception e) {
+			return (T)this.paranValue.getClass();
+		}
+	}
+			
+	public void setDescription(String description){
+		this.description = description;
+	}
+	
+	public String getDescription(){
+		return this.description;
+	}
+			
+	public void setCreateOn(java.util.Date createOn){
+		this.createOn = createOn;
+	}
+	
+	public java.util.Date getCreateOn(){
+		return this.createOn;
+	}
+			
+	public void setModifyOn(java.util.Date modifyOn){
+		this.modifyOn = modifyOn;
+	}
+	
+	public java.util.Date getModifyOn(){
+		return this.modifyOn;
+	}
+			
+	public String getGroup() {
+		return group;
+	}
+
+	public void setGroup(String group) {
+		this.group = group;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 208 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMessage.java

@@ -0,0 +1,208 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.SendStatusEnum;
+import com.yonge.cooleshow.common.entity.BaseEntity;
+
+/**
+ * 对应数据库表(sys_message):
+ */
+public class SysMessage extends BaseEntity {
+
+	/** 主键 */
+	private Long id;
+	
+	/** 标题 */
+	@ApiModelProperty(value = "标题",required = false)
+	private String title;
+	
+	/** 消息内容 */
+	@ApiModelProperty(value = "消息内容",required = false)
+	private String content;
+	
+	/** 消息类型;1,表示短信;2,表示邮件; 3,app推送消息 */
+	@ApiModelProperty(value = "消息类型",required = false)
+	private MessageSendMode type;
+	
+	/** 状态,-1,发送失败;0,待发送;1,发送中;2,发送完成 */
+	@ApiModelProperty(value = "状态",required = false)
+	private SendStatusEnum status;
+	
+	/** 接收人(多个人用逗号分隔) */
+	@ApiModelProperty(value = "接收人(多个人用逗号分隔)",required = false)
+	private String receiver;
+	
+	/** 发送时间 */
+	@ApiModelProperty(value = "发送时间",required = false)
+	private java.util.Date sendTime;
+	
+	/** 错误信息 */
+	@ApiModelProperty(value = "错误信息",required = false)
+	private String errorMsg;
+	
+	/** 创建时间 */
+	private java.util.Date createOn;
+	
+	/** 修改时间 */
+	private java.util.Date modifyOn;
+	
+	/** 用户编号 */
+	@ApiModelProperty(value = "用户编号",required = false)
+	private Integer userId;
+	
+	/** 备注 */
+	@ApiModelProperty(value = "备注",required = false)
+	private String memo;
+	
+	/** 是否已读 */
+	@ApiModelProperty(value = "是否已读",required = false)
+	private Integer readStatus;
+	
+	@ApiModelProperty(value = "消息组",required = false)
+	private String group;
+
+	@ApiModelProperty(value = "极光推送客户端标识",required = false)
+	private String clientId;
+
+	public String getClientId() {
+		return clientId;
+	}
+
+	public void setClientId(String clientId) {
+		this.clientId = clientId;
+	}
+
+	public SysMessage() {
+	}
+
+	public SysMessage(String title, String content, MessageSendMode type, String receiver, Integer userId, String memo) {
+		this.title = title;
+		this.content = content;
+		this.type = type;
+		this.receiver = receiver;
+		this.userId = userId;
+		this.memo = memo;
+	}
+
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setTitle(String title){
+		this.title = title;
+	}
+	
+	public String getTitle(){
+		return this.title;
+	}
+			
+	public void setContent(String content){
+		this.content = content;
+	}
+	
+	public String getContent(){
+		return this.content;
+	}
+			
+	public void setReceiver(String receiver){
+		this.receiver = receiver;
+	}
+	
+	public String getReceiver(){
+		return this.receiver;
+	}
+			
+	public void setSendTime(java.util.Date sendTime){
+		this.sendTime = sendTime;
+	}
+	
+	public java.util.Date getSendTime(){
+		return this.sendTime;
+	}
+			
+	public void setErrorMsg(String errorMsg){
+		this.errorMsg = errorMsg;
+	}
+	
+	public String getErrorMsg(){
+		return this.errorMsg;
+	}
+			
+	public void setCreateOn(java.util.Date createOn){
+		this.createOn = createOn;
+	}
+	
+	public java.util.Date getCreateOn(){
+		return this.createOn;
+	}
+			
+	public void setModifyOn(java.util.Date modifyOn){
+		this.modifyOn = modifyOn;
+	}
+	
+	public java.util.Date getModifyOn(){
+		return this.modifyOn;
+	}
+			
+	public void setUserId(Integer userId){
+		this.userId = userId;
+	}
+	
+	public Integer getUserId(){
+		return this.userId;
+	}
+			
+	public void setMemo(String memo){
+		this.memo = memo;
+	}
+	
+	public String getMemo(){
+		return this.memo;
+	}
+
+	public MessageSendMode getType() {
+		return type;
+	}
+
+	public void setType(MessageSendMode type) {
+		this.type = type;
+	}
+
+	public SendStatusEnum getStatus() {
+		return status;
+	}
+
+	public void setStatus(SendStatusEnum status) {
+		this.status = status;
+	}
+
+	public Integer getReadStatus() {
+		return readStatus;
+	}
+
+	public void setReadStatus(Integer readStatus) {
+		this.readStatus = readStatus;
+	}
+
+	public String getGroup() {
+		return group;
+	}
+
+	public void setGroup(String group) {
+		this.group = group;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 103 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysMessageConfig.java

@@ -0,0 +1,103 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+
+/**
+ * 对应数据库表(sys_message_config):
+ */
+public class SysMessageConfig {
+
+	/**  */
+	private Integer id;
+
+	/** 消息类型 */
+	private MessageTypeEnum messageType;
+
+	/** 消息内容 */
+	private String content;
+
+	/** 描述 */
+	private String description;
+
+	/** 最后修改时间 */
+	private java.util.Date modifyOn;
+
+	/** 跳转url */
+	private String url;
+	
+	private String group;
+
+	private Integer sendFlag;
+
+	public Integer getSendFlag() {
+		return sendFlag;
+	}
+
+	public void setSendFlag(Integer sendFlag) {
+		this.sendFlag = sendFlag;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public Integer getId() {
+		return this.id;
+	}
+
+	public MessageTypeEnum getMessageType() {
+		return messageType;
+	}
+
+	public void setMessageType(MessageTypeEnum messageType) {
+		this.messageType = messageType;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public String getContent() {
+		return this.content;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getDescription() {
+		return this.description;
+	}
+
+	public void setModifyOn(java.util.Date modifyOn) {
+		this.modifyOn = modifyOn;
+	}
+
+	public java.util.Date getModifyOn() {
+		return this.modifyOn;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getUrl() {
+		return this.url;
+	}
+
+	public String getGroup() {
+		return group;
+	}
+
+	public void setGroup(String group) {
+		this.group = group;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 36 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageSendMode.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.yonge.cooleshow.common.enums.BaseEnum;
+
+/**
+ 状态,1,表示短信;2,表示邮件; 3,app推送消息
+ */
+public enum MessageSendMode implements BaseEnum<Integer, MessageSendMode> {
+	SMS(1, "短信"), EMAIL(2, "邮件"), PUSH(3, "app推送消息"), SEO(4, "站内推送消息");
+
+	private Integer code;
+
+	private String msg;
+
+	MessageSendMode(Integer code, String msg) {
+		this.code = code;
+		this.msg = msg;
+	}
+
+	public void setCode(Integer code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	@Override
+	public Integer getCode() {
+		return this.code;
+	}
+}

+ 248 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java

@@ -0,0 +1,248 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.yonge.cooleshow.common.enums.BaseEnum;
+
+public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
+    SMS_APPLY_MESSAGE("SMS_APPLY_MESSAGE", "报名通知"),
+    SYSTEM_REMIND_EDUCATION_COURSE_TIME("SYSTEM_REMIND_EDUCATION_COURSE_TIME", "排课提醒"),
+    STUDENT_MEMBER_RENEW_MESSAGE("STUDENT_MEMBER_RENEW_MESSAGE", "会员续费提醒"),
+    PUSH_EXPERIENCE_MEMBERSHIP_MESSAGE("PUSH_EXPERIENCE_MEMBERSHIP_MESSAGE", "会员试用提醒"),
+    SMS_AUTO_STUDENT_MEMBER_RENEW_MESSAGE("SMS_AUTO_STUDENT_MEMBER_RENEW_MESSAGE", "会员续费提醒"),
+    PUSH_AUTO_STUDENT_MEMBER_RENEW_MESSAGE("PUSH_AUTO_STUDENT_MEMBER_RENEW_MESSAGE", "会员续费提醒"),
+    STUDENT_MEMBER_RENEW_QUIT_MESSAGE("STUDENT_MEMBER_RENEW_QUIT_MESSAGE", "会员续费提醒"),
+    SMS_VERIFY_CODE_LOGIN("SMS_VERIFY_CODE_LOGIN", "验证码登录"),
+    KAPTCHA_SESSION_KEY("KAPTCHA_SESSION_KEY", "登录图形验证码"),
+    SMS_PAYMENT_MESSAGE("SMS_PAYMENT_MESSAGE", "缴费通知"),
+//    SMS_PAYMENT_SUCCESS("SMS_PAYMENT_SUCCESS", "缴费成功"),
+//    SMS_RENEW_SUCCESS("SMS_RENEW_SUCCESS", "续费成功"),
+//    SMS_BALANCE_PAY("SMS_BALANCE_PAY", "余额充值"),
+//    SMS_BASICS_SKILL_APPLY_MESSAGE("SMS_BASICS_SKILL_APPLY_MESSAGE", "基础技能训练报名通知"),
+//    SMS_VIP_COURSE_BUY_SUCCESS("SMS_VIP_COURSE_BUY_SUCCESS", "VIP课购买成功"),
+//    SMS_VIP_COURSE_SIGN("SMS_VIP_COURSE_SIGN", "VIP课签到"),
+//    SMS_QUIT_COURSE_SUCCESS("SMS_QUIT_COURSE_SUCCESS", "退课成功"),
+//    SMS_WITHDRAW_SUCCESS("SMS_WITHDRAW_SUCCESS", "提现成功"),
+//    SMS_MUSIC_GROUP_CLOSE("SMS_MUSIC_GROUP_CLOSE", "乐团关闭(关闭后)"),
+
+    STUDENT_SMS_PUSH_PAYMENT_SUCCESS("STUDENT_SMS_PUSH_PAYMENT_SUCCESS", "缴费成功结果通知"),
+    STUDENT_SMS_BALANCE_CONSUME("STUDENT_SMS_BALANCE_CONSUME", "余额消费"),
+    STUDENT_PUSH_VIP_BUY("STUDENT_PUSH_VIP_BUY", "VIP课购买"),
+    STUDENT_PUSH_HAVE_COURSE_MESSAGE("STUDENT_PUSH_HAVE_COURSE_MESSAGE", "有课提醒"),
+    STUDENT_PUSH_ONLINE_COURSE_ACTION("STUDENT_PUSH_ONLINE_COURSE_ACTION", "线上课开始"),
+    STUDENT_PUSH_NAMES_ACHIEVE("STUDENT_PUSH_NAMES_ACHIEVE", "点名完成"),
+    SYSTEM_PUSH_NAMES_ACHIEVE("SYSTEM_PUSH_NAMES_ACHIEVE", "点名完成"),
+    //    SCHEDULE_CHANGE("SCHEDULE_CHANGE", "课表变动"),
+//    STUDENT_SMS_TEACHING_SCHOOL_CHANGE("STUDENT_SMS_TEACHING_SCHOOL_CHANGE", "教学点变动"),
+    STUDENT_PUSH_JOB_MESSAGE("STUDENT_PUSH_JOB_MESSAGE", "训练提醒"),
+    //    STUDENT_PUSH_CLASS_MESSAGE("STUDENT_PUSH_CLASS_MESSAGE", "班级消息"),
+    TEACHER_PUSH_MUSIC_GROUP_COURSE_ADD_PLAN("TEACHER_PUSH_MUSIC_GROUP_COURSE_ADD_PLAN", "乐团课新增安排"),
+    TEACHER_SMS_PUSH_VIP_COURSE_APPLY_RESULT("TEACHER_SMS_PUSH_VIP_COURSE_APPLY_RESULT", "VIP课申请结果"),
+    TEACHER_SMS_VIP_COURSE_ADD("TEACHER_SMS_VIP_COURSE_ADD", "VIP课新增"),
+    TEACHER_PUSH_VIP_COURSE_STOP("TEACHER_PUSH_VIP_COURSE_STOP", "VIP课停止"),
+    //    TEACHER_PUSH_ACTION_COURSE_MESSAGE("TEACHER_PUSH_ACTION_COURSE_MESSAGE", "开课提醒"),
+    TEACHER_PUSH_HAVE_COURSE_MESSAGE("TEACHER_PUSH_HAVE_COURSE_MESSAGE", "有课提醒"),
+    TEACHER_PUSH_ATTEND_CLASS_MESSAGE("TEACHER_PUSH_ATTEND_CLASS_MESSAGE", "上课提醒"),
+    //    TEACHER_PUSH_SIGN_IN_MESSAGE("TEACHER_PUSH_SIGN_IN_MESSAGE", "签到提醒"),
+//    TEACHER_PUSH_NAMES_MESSAGE("TEACHER_PUSH_NAMES_MESSAGE", "点名提醒"),
+    TEACHER_PUSH_SIGN_OUT_MESSAGE("TEACHER_PUSH_SIGN_OUT_MESSAGE", "签退提醒"),
+    TEACHER_PUSH_JOB_WAIT_REPLY("TEACHER_PUSH_JOB_WAIT_REPLY", "训练待回复"),
+    //    TEACHER_PUSH_SUBSTITUTE_PLAN("TEACHER_PUSH_SUBSTITUTE_PLAN", "代课安排"),
+    TEACHER_PUSH_LEAVE_RESULT("TEACHER_PUSH_LEAVE_RESULT", "请假结果"),
+    TEACHER_PUSH_COURSE_SCHEDULE_CHANGE_RESULT("TEACHER_PUSH_COURSE_SCHEDULE_CHANGE_RESULT", "课时调整结果"),
+    TEACHER_PUSH_STUDENT_LEAVE("TEACHER_PUSH_STUDENT_LEAVE", "学员请假"),
+    //    TEACHER_PUSH_CLASS_MESSAGE("TEACHER_PUSH_CLASS_MESSAGE", "班级消息"),
+    STUDENT_SMS_PAYMENT_FAILED("STUDENT_SMS_PAYMENT_FAILED", "缴费失败结果通知"),
+    //    STUDENT_PUSH_MUSIC_GROUP_RENEW_FAILED("STUDENT_PUSH_MUSIC_GROUP_RENEW_FAILED", "乐团续费失败结果"),
+    STUDENT_PUSH_VIP_STOP("STUDENT_PUSH_VIP_STOP", "VIP课取消"),
+    //    SMS_MUSIC_GROUP_ADD_STUDENT("SMS_MUSIC_GROUP_ADD_STUDENT", "入团通知"),
+    TEACHER_PUSH_VIP_STOP("TEACHER_PUSH_VIP_STOP", "VIP课取消"),
+    STUDENT_SMS_OPEN_PAYMENT("STUDENT_SMS_OPEN_PAYMENT", "开启缴费"),
+    //    SMS_MUSIC_GROUP_ADD_STUDENT_FREE("SMS_MUSIC_GROUP_ADD_STUDENT_FREE", "入团通知"),
+    STUDENT_SMS_PUSH_SPORADIC_PAYMENT_SUCCESS("STUDENT_SMS_PUSH_SPORADIC_PAYMENT_SUCCESS", "零星支付成功结果"),
+    STUDENT_SMS_PUSH_SPORADIC_PAYMENT_FAILED("STUDENT_SMS_PUSH_SPORADIC_PAYMENT_FAILED", "零星支付失败结果"),
+    TEACHER_PUSH_COURSE_COLLIDE("TEACHER_PUSH_COURSE_COLLIDE", "课程冲突"),
+    //    PUSH_STUDY_REPORT("PUSH_STUDY_REPORT", "陪练报告"),
+    STUDENT_SMS_PUSH_PAY_PRACTICE_BUY_SUCCESS("STUDENT_SMS_PUSH_PAY_PRACTICE_BUY_SUCCESS", "网管课购买成功"),
+    STUDENT_SMS_PUSH_PRACTICE_COMPLETED_STUDY_REPORT("STUDENT_SMS_PUSH_PRACTICE_COMPLETED_STUDY_REPORT", "网管课完成学习报告"),
+    STUDENT_SMS_PUSH_FREE_PRACTICE_APPLY_PUSH("STUDENT_SMS_PUSH_FREE_PRACTICE_APPLY_PUSH", "免费陪练课预约推送"),
+    TEACHER_PUSH_NEED_POST_STUDY_REPORT("TEACHER_PUSH_NEED_POST_STUDY_REPORT", "新增待填写月报"),
+    STUDENT_PUSH_HOMEWORK_REMIND("STUDENT_PUSH_HOMEWORK_REMIND", "训练提醒-网管课"),
+    TEACHER_PUSH_COMM_NO_STUDENTS_PUSH("TEACHER_PUSH_COMM_NO_STUDENTS_PUSH", "对外课程组无学生提醒"),
+    TEACHER_PUSH_HOMEWORK_SUBMIT("TEACHER_PUSH_HOMEWORK_SUBMIT", "学生提交训练提醒"),
+    TEACHER_PUSH_HOMEWORK_REPLY("TEACHER_PUSH_HOMEWORK_REPLY", "学生训练回复提醒"),
+    STUDENT_PUSH_HOMEWORK_REPLY("STUDENT_PUSH_HOMEWORK_REPLY", "教师回复训练提醒"),
+
+    IM_HOMEWORK_REMIND("IM_HOMEWORK_REMIND", "训练提醒"),
+    IM_HOMEWORK_SUBMIT_PUSH("IM_HOMEWORK_SUBMIT_PUSH", "训练提交提醒"),
+    IM_HOMEWORK_SUBMIT_PUSH_GROUP("IM_HOMEWORK_SUBMIT_PUSH_GROUP", "训练提交提醒"),
+    IM_HOMEWORK_STUDENT_REPLY_PUSH("IM_HOMEWORK_STUDENT_REPLY_PUSH", "训练回复提醒"),
+    IM_HOMEWORK_TEACHER_REPLY_PUSH("IM_HOMEWORK_TEACHER_REPLY_PUSH", "训练点评提醒"),
+    IM_HOMEWORK_REMIND_DETAIL("IM_HOMEWORK_REMIND_DETAIL", "训练提醒"),
+
+    /**
+     * 课外训练消息
+     */
+    STUDENT_PUSH_EXTRA_REMIND("STUDENT_PUSH_EXTRA_REMIND", "训练提醒"),
+    EXTRA_REMIND_IM("EXTRA_REMIND_IM", "训练提醒"),
+    EXTRA_REMIND_IM_DETAIL("EXTRA_REMIND_IM_DETAIL", "训练提醒"),
+    STUDENT_PUSH_EXTRA_REPLY("STUDENT_PUSH_EXTRA_REPLY", "训练点评提醒"),
+    EXTRA_TEACHER_REPLY_IM("EXTRA_TEACHER_REPLY_IM", "训练点评提醒"),
+    TEACHER_PUSH_EXTRA_SUBMIT("TEACHER_PUSH_EXTRA_SUBMIT", "训练提交提醒"),
+    EXTRA_SUBMIT_IM("EXTRA_SUBMIT_IM", "训练提交提醒"),
+    TEACHER_PUSH_EXTRA_REPLY("TEACHER_PUSH_EXTRA_REPLY", "训练回复提醒"),
+    EXTRA_STUDENT_REPLY_IM("EXTRA_STUDENT_REPLY_IM", "训练回复提醒"),
+
+    TEACHER_PUSH_COURSE_SALARY_COMPLAINTS_RESULT("TEACHER_PUSH_COURSE_SALARY_COMPLAINTS_RESULT", "课酬申述结果"),
+    TEACHER_PUSH_SALARY_CONFIRM("TEACHER_PUSH_SALARY_CONFIRM", "课酬确认"),
+    STUDENT_PUSH_TRIAL_PRACTICE_CREATE("STUDENT_PUSH_TRIAL_PRACTICE_CREATE", "试听课安排"),
+    TEACHER_SMS_PUSH_PRACTICE_CREATE("TEACHER_SMS_PUSH_PRACTICE_CREATE", "新增网管课程"),
+    STUDENT_PUSH_REPAIR_UNSEND_COMPLETED("STUDENT_PUSH_REPAIR_UNSEND_COMPLETED", "乐器维修完成自取"),
+    STUDENT_PUSH_REPAIR_SEND_COMPLETED("STUDENT_PUSH_REPAIR_SEND_COMPLETED", "乐器维修完成邮寄"),
+    STUDENT_PUSH_REPAIR_ONLINE_PAYMENT_SUCCESS("STUDENT_PUSH_REPAIR_ONLINE_PAYMENT_SUCCESS", "乐器线上维修支付成功"),
+    STUDENT_PUSH_REPAIR_OFFLINE_PAYMENT_SUCCESS("STUDENT_PUSH_REPAIR_OFFLINE_PAYMENT_SUCCESS", "乐器线下维修支付成功"),
+
+    TEACHER_PUSH_MUSIC_NETWORK_CRATE("TEACHER_PUSH_MUSIC_NETWORK_CRATE", "乐团网管课安排"),
+    STUDENT_PUSH_MUSIC_NETWORK_CRATE("STUDENT_PUSH_MUSIC_NETWORK_CRATE", "乐团课通知"),
+    TEACHER_PUSH_EXCEPTION_ATTENDANCE("TEACHER_PUSH_EXCEPTION_ATTENDANCE", "异常考勤通知"),
+    STUDENT_PUSH_PRACTICE_RENEW_REMIND("STUDENT_PUSH_PRACTICE_RENEW_REMIND", "网管课续费推送"),
+    TEACHER_PUSH_ATTENDANCE_COMPLAINTS_RESULT("TEACHER_PUSH_ATTENDANCE_COMPLAINTS_RESULT", "考勤申述结果"),
+    TEACHER_PUSH_PUBLIC_EXTRA_REMIND("TEACHER_PUSH_PUBLIC_EXTRA_REMIND", "本周应布置课外训练"),
+    SYSTEM_SMS_PUSH_PAYMENT_DETAIL("SYSTEM_SMS_PUSH_PAYMENT_DETAIL", "缴费项目缴费详情提醒"),
+    SYSTEM_SMS_PUSH_PAYMENT_CREATE("SYSTEM_SMS_PUSH_PAYMENT_CREATE", "缴费项目创建提醒"),
+    SYSTEM_SMS_GOODS_REPERTORY_WARN("SYSTEM_SMS_GOODS_REPERTORY_WARN", "商品库存预警"),
+    SYSTEM_PUSH_STUDENT_COMMIT_QUIT_MUSIC_APPLY("SYSTEM_PUSH_STUDENT_COMMIT_QUIT_MUSIC_APPLY", "学员申请退团"),
+    SYSTEM_PUSH_STUDENT_REVOKE_QUIT_MUSIC_APPLY("SYSTEM_PUSH_STUDENT_REVOKE_QUIT_MUSIC_APPLY", "撤销退团申请"),
+    STUDENT_SMS_IM_MUSIC_GROUP_PARENT_MEETING_NOTICE("STUDENT_SMS_IM_MUSIC_GROUP_PARENT_MEETING_NOTICE", "乐团家长会通知"),
+    SYSTEM_PUSH_SMS_INSPECTION_NOTICE("SYSTEM_PUSH_SMS_INSPECTION_NOTICE", "巡查日程提醒"),
+    STUDENT_SMS_WAIT_RENEW_MESSAGE("STUDENT_SMS_WAIT_RENEW_MESSAGE", "待续费通知"),
+    TEACHER_PUSH_SERVE("TEACHER_PUSH_SERVE", "服务指标未完成提醒"),
+    STUDENT_PUSH_MAINTENANCE_NOTICE("STUDENT_PUSH_MAINTENANCE_NOTICE", "乐保到期提醒"),
+    TEACHER_IM_STUDENT_LEAVE("TEACHER_IM_STUDENT_LEAVE", "学员请假"),
+    STUDENT_SMS_PUSH_REPLACEMENT_PAY("STUDENT_SMS_PUSH_REPLACEMENT_PAY", "乐器置换支付提醒"),
+    TEACHER_PUSH_INCOME_REMIND("TEACHER_PUSH_INCOME_REMIND", "今日收入"),
+    STUDENT_PUSH_PAYMENT_RESULT("STUDENT_PUSH_PAYMENT_RESULT", "缴费结果"),
+    STUDENT_PUSH_MUSIC_GROUP_CLOSE("STUDENT_PUSH_MUSIC_GROUP_CLOSE", "乐团关闭(确认后)"),
+    STUDENT_PUSH_BASICS_SKILL_APPLY_MESSAGE("STUDENT_PUSH_BASICS_SKILL_APPLY_MESSAGE", "基础技能训练报名通知"),
+    STUDENT_PUSH_WAIT_RENEW_MESSAGE("STUDENT_PUSH_WAIT_RENEW_MESSAGE", "待续费通知"),
+    STUDENT_SMS_PUSH_MUSIC_GROUP_RENEW_SUCCESS("STUDENT_SMS_PUSH_MUSIC_GROUP_RENEW_SUCCESS", "乐团续费成功结果"),
+    STUDENT_PUSH_BALANCE_CONSUME("STUDENT_PUSH_BALANCE_CONSUME", "余额消费"),
+    STUDENT_PUSH_ATTEND_COURSE_MESSAGE("STUDENT_PUSH_ATTEND_COURSE_MESSAGE", "上课提醒"),
+    STUDENT_PUSH_TEACHING_SCHOOL_CHANGE("STUDENT_PUSH_TEACHING_SCHOOL_CHANGE", "教学点变动"),
+    TEACHER_PUSH_VIP_COURSE_APPLY_RESULT("TEACHER_PUSH_VIP_COURSE_APPLY_RESULT", "VIP课申请结果"),
+    TEACHER_PUSH_VIP_COURSE_ADD("TEACHER_PUSH_VIP_COURSE_ADD", "VIP课新增"),
+
+
+    //    EDUCATION_PUSH_MUSIC_GROUP_FOUND("EDUCATION_PUSH_MUSIC_GROUP_FOUND", "乐团成立"),
+//    EDUCATION_PUSH_MUSIC_GROUP_CLOSE("EDUCATION_PUSH_MUSIC_GROUP_CLOSE", "乐团关闭"),
+//    EDUCATION_PUSH_COURSE_CHANGE("EDUCATION_PUSH_COURSE_CHANGE", "课程调整"),
+//    EDUCATION_PUSH_TOMORROW_COURSE_PLAN("EDUCATION_PUSH_TOMORROW_COURSE_PLAN", "明日课程安排"),
+//    EDUCATION_PUSH_TEACHER_NO_SIGN_IN("EDUCATION_PUSH_TEACHER_NO_SIGN_IN", "老师未签到"),
+//    EDUCATION_PUSH_TEACHER_EXCEPTION_SING_IN("EDUCATION_PUSH_TEACHER_EXCEPTION_SING_IN", "老师异常签到"),
+//    EDUCATION_PUSH_TEACHER_NO_SIGN_OUT("EDUCATION_PUSH_TEACHER_NO_SIGN_OUT", "老师未签退"),
+//    EDUCATION_PUSH_STUDENT_LEAVE("EDUCATION_PUSH_STUDENT_LEAVE", "学员请假"),
+//    EDUCATION_PUSH_STUDENT_CONTINUE_NO_ARRIVAL("EDUCATION_PUSH_STUDENT_CONTINUE_NO_ARRIVAL", "学员连续未到"),
+//    EDUCATION_PUSH_STUDENT_NO_PAYMENT("EDUCATION_PUSH_STUDENT_NO_PAYMENT", "学员未交费"),
+//    EDUCATION_PUSH_VIP_COURSE_APPLY("EDUCATION_PUSH_VIP_COURSE_APPLY", "VIP课申请"),
+    EDUCATION_PUSH_TEACHER_LEAVE_APPLY("EDUCATION_PUSH_TEACHER_LEAVE_APPLY", "老师请假申请"),
+//    EDUCATION_PUSH_STUDENT_QUIT_MUSIC_GROUP_APPLY("EDUCATION_PUSH_STUDENT_QUIT_MUSIC_GROUP_APPLY", "学员退团申请"),
+//    EDUCATION_PUSH_STUDENT_QUIT_COURSE_APPLY("EDUCATION_PUSH_STUDENT_QUIT_COURSE_APPLY", "学员退课申请"),
+//    EDUCATION_PUSH_STUDENT_WITHDRAW_APPLY("EDUCATION_PUSH_STUDENT_WITHDRAW_APPLY", "学员提现申请"),
+//    EDUCATION_PUSH_STUDENT_APPEAL("EDUCATION_PUSH_STUDENT_APPEAL", "学员申诉"),
+
+    BACKSTAGE_CREATE_MUSIC_GROUP_APPLY("BACKSTAGE_CREATE_MUSIC_GROUP_APPLY", "建团申请"),
+    BACKSTAGE_CREATE_MUSIC_GROUP_ADJUST_SUCCESS("BACKSTAGE_CREATE_MUSIC_GROUP_ADJUST_SUCCESS", "建团申请审核通过"),
+    //    BACKSTAGE_ACTION_APPLY("BACKSTAGE_ACTION_APPLY", "开启报名"),
+    BACKSTAGE_PAYMENT_CALENDER_AUDIT("BACKSTAGE_PAYMENT_CALENDER_AUDIT", "缴费项目审核"),
+    BACKSTAGE_ACTION_PAYMENT("BACKSTAGE_ACTION_PAYMENT", "开启缴费"),
+
+    BACKSTAGE_LENGTHEN_PAYMENT("BACKSTAGE_LENGTHEN_PAYMENT", "延长缴费"),
+    BACKSTAGE_ACTION_GROUP("BACKSTAGE_ACTION_GROUP", "开团"),
+    BACKSTAGE_STUDENT_SUBJECT_CHANGE("BACKSTAGE_STUDENT_SUBJECT_CHANGE", "学员声部调整"),
+    BACKSTAGE_MUSIC_GROUP_MARKING("BACKSTAGE_MUSIC_GROUP_MARKING", "乐团筹备中"),
+    //    BACKSTAGE_MARK_OK("BACKSTAGE_MARK_OK", "筹备完成"),
+//    BACKSTAGE_MARK_QUIT("BACKSTAGE_MARK_QUIT", "筹备中,退回"),
+    BACKSTAGE_MUSIC_GROUP_ADD_STUDENT("BACKSTAGE_MUSIC_GROUP_ADD_STUDENT", "乐团添加学员"),
+    //    BACKSTAGE_TEACHER_AMOUNT_CHANGE("BACKSTAGE_TEACHER_AMOUNT_CHANGE", "老师课酬调整"),
+//    BACKSTAGE_COURSE_CHANGE("BACKSTAGE_COURSE_CHANGE", "课时、课程调整"),
+//    BACKSTAGE_MUSIC_GROUP_IN_CHANGE("BACKSTAGE_MUSIC_GROUP_IN_CHANGE", "乐团内调整"),
+//    BACKSTAGE_SPAN_GROUP_CHANGE("BACKSTAGE_SPAN_GROUP_CHANGE", "跨越团调整"),
+    BACKSTAGE_MUSIC_GROUP_STOP("BACKSTAGE_MUSIC_GROUP_STOP", "乐团暂停"),
+    //    BACKSTAGE_MUSIC_GROUP_CLOSE("BACKSTAGE_MUSIC_GROUP_CLOSE", "乐团结束"),
+//    BACKSTAGE_VIP_COURSE_APPLY("BACKSTAGE_VIP_COURSE_APPLY", "VIP课申请"),
+    BACKSTAGE_TEACHER_APPLY_VIP("BACKSTAGE_TEACHER_APPLY_VIP", "VIP课申请"),
+    BACKSTAGE_TEACHER_APPLY_PRACTICE("BACKSTAGE_TEACHER_APPLY_PRACTICE", "网管课申请"),
+    //    BACKSTAGE_VIP_COURSE_STOP("BACKSTAGE_VIP_COURSE_STOP", "VIP课停止"),
+//    BACKSTAGE_TEACHER_FREEZE("BACKSTAGE_TEACHER_FREEZE", "老师冻结"),
+//    BACKSTAGE_TEACHER_POSITIVE("BACKSTAGE_TEACHER_POSITIVE", "老师转正"),
+//    BACKSTAGE_STUDENT_OK_QUIT_GROUP("BACKSTAGE_STUDENT_OK_QUIT_GROUP", "学员确认退团"),
+//    BACKSTAGE_STUDENT_OK_QUIT_COURSE("BACKSTAGE_STUDENT_OK_QUIT_COURSE", "学员确认退课"),
+    BACKSTAGE_STUDENT_APPEAL("BACKSTAGE_STUDENT_APPEAL", "学员申述"),
+    BACKSTAGE_STUDENT_APPLY_QUIT_GROUP("BACKSTAGE_STUDENT_APPLY_QUIT_GROUP", "学员申请退团"),
+
+    CHILDREN_DAY_VIP_COURSE_TEACHER_PUSH("CHILDREN_DAY_VIP_COURSE_TEACHER_PUSH", "六一活动课程安排"),
+    CHILDREN_DAY_VIP_COURSE_STUDENT_PUSH("CHILDREN_DAY_VIP_COURSE_STUDENT_PUSH", "六一活动课程安排"),
+
+    BACKSTAGE_STUDENT_APPLY_QUIT_COURSE("BACKSTAGE_STUDENT_APPLY_QUIT_COURSE", "学员申请退课"),
+    BACKSTAGE_STUDENT_APPLY_WITHDRAW("BACKSTAGE_STUDENT_APPLY_WITHDRAW", "学员申请提现"),
+    CHILDREN_DAY_NOTICE_PUSH("CHILDREN_DAY_NOTICE_PUSH", "技能评测考级报名推送"),
+    CHILDREN_DAY_NOTICE_MSG("CHILDREN_DAY_NOTICE_MSG", "技能评测考级报名短信"),
+    NO_BUY_CLOUD_TEACHER_MSG("NO_BUY_CLOUD_TEACHER_MSG", "未购买买团练宝短信"),
+    OA_NOTICE_PUSH("OA_NOTICE_PUSH", "待审批提醒"),
+    OA_CC_NOTICE_PUSH("OA_CC_NOTICE_PUSH", "审批抄送提醒"),
+
+    //团练宝
+    TRAIN_NO_RANK_STUDENT_PUSH("TRAIN_NO_RANK_STUDENT_PUSH", "团练宝训练提醒"),
+    TRAIN_RANK_STUDENT_PUSH("TRAIN_RANK_STUDENT_PUSH", "团练宝训练提醒"),
+    NO_TRAIN_STUDENT_PUSH("NO_TRAIN_STUDENT_PUSH", "团练宝训练提醒"),
+
+    COUPON_STOCK_WARNING("COUPON_STOCK_WARNING", "优惠券库存预警"),
+
+    APP_REDEMPTION_CODE("APP_REDEMPTION_CODE", "兑换码分配量预警"),
+    CLOUD_TEACHER_ORDER_SUCCESS("CLOUD_TEACHER_ORDER_SUCCESS", "团练宝激活成功"),
+
+    EMAIL_TENANT_ACTIVATION_SUCCESSFUL("EMAIL_TENANT_ACTIVATION_SUCCESSFUL",   "开通成功"),
+    EMAIL_TENANT_RENEWAL_SUCCESSFUL("EMAIL_TENANT_RENEWAL_SUCCESSFUL", "续费成功"),
+    EMAIL_TENANT_EXPIRATION_REMINDERS("EMAIL_TENANT_EXPIRATION_REMINDERS",   "服务即将到期"),
+    EMAIL_TENANT_RECHARGE("EMAIL_TENANT_RECHARGE",   "云教室充值"),
+    EMAIL_TENANT_INSUFFICIENT_BALANCE("EMAIL_TENANT_INSUFFICIENT_BALANCE",  "余额不足"),
+    EMAIL_TENANT_EXPIRE("EMAIL_TENANT_EXPIRE",  "云教室欠费"),
+
+
+    SMS_TENANT_ACTIVATION_SUCCESSFUL("SMS_TENANT_ACTIVATION_SUCCESSFUL",   "开通成功"),
+    SMS_TENANT_RENEWAL_SUCCESSFUL("SMS_TENANT_RENEWAL_SUCCESSFUL", "续费成功"),
+    SMS_TENANT_EXPIRATION_REMINDERS("SMS_TENANT_EXPIRATION_REMINDERS",   "服务即将到期"),
+    SMS_TENANT_RECHARGE("SMS_TENANT_RECHARGE",   "云教室充值"),
+    SMS_TENANT_INSUFFICIENT_BALANCE("SMS_TENANT_INSUFFICIENT_BALANCE",  "余额不足"),
+    SMS_TENANT_EXPIRE("SMS_TENANT_EXPIRE",  "云教室欠费"),
+
+
+    STUDENT_SMS_CLOUD_PAYMENT("STUDENT_SMS_CLOUD_PAYMENT",  "待缴费订单"),
+    STUDENT_PUSH_CLOUD_PAYMENT("STUDENT_PUSH_CLOUD_PAYMENT",  "待缴费订单"),
+    IM_SHARE_LIVE_URL("IM_SHARE_LIVE_URL",  "直播链接分享")
+    ;
+
+    MessageTypeEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    private String code;
+
+    private String msg;
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    @Override
+    public String getCode() {
+        return code;
+    }
+}

+ 36 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SendStatusEnum.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.yonge.cooleshow.common.enums.BaseEnum;
+
+/**
+ 状态,-1,发送失败;0,待发送;1,发送中;2,发送完成
+ */
+public enum SendStatusEnum implements BaseEnum<Integer, SendStatusEnum> {
+	FAILED(-1, "发送失败"), WAIT(0, "待发送"), SENDING(1, "发送中"), SUCCESSED(2, "发送完成");
+
+	private Integer code;
+
+	private String msg;
+
+	SendStatusEnum(Integer code, String msg) {
+		this.code = code;
+		this.msg = msg;
+	}
+
+	public void setCode(Integer code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	@Override
+	public Integer getCode() {
+		return this.code;
+	}
+}

+ 18 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SmsCodeService.java

@@ -0,0 +1,18 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+public interface SmsCodeService {
+
+	/**
+	 * 校验验证码
+	 * @param mobile
+	 * @param authCode
+	 * @return
+	 */
+	boolean verifyValidCode(String mobile, String authCode);
+
+	/**
+	 * 发送登录验证码
+	 * @return
+	 */
+	boolean sendValidCode(String mobile) throws Exception;
+}

+ 404 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysConfigService.java

@@ -0,0 +1,404 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import java.util.List;
+
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.common.service.BaseService;
+
+public interface SysConfigService extends BaseService<Long, SysConfig> {
+    //乐团基础规则
+
+    //乐团预报名人数达到指定数量,可将乐团状态变更为创建缴费中
+    String MUSIC_MIN_STUDENT_NUM = "music_min_student_num";
+    //报名缴费阶段乐团若未合并学员,缴费人数达到指定人数时可确认开团(用于校验是否回访)
+    String NEW_MUSIC_PAYMENT_STUDENT_NUM = "new_music_payment_student_num";
+    //报名缴费阶段乐团若合并学员,缴费人数达到指定人数时可确认开团(用于校验是否回访)
+    String OLD_MUSIC_PAYMENT_STUDENT_NUM = "old_music_payment_student_num";
+    //乐团问卷调查编号
+    String MUSIC_GROUP_TOPIC_ID = "music_group_topic_id";
+
+    //考勤和课酬规则
+
+    //线下课课程开始前指定时间打卡为正常签到
+    String OFFLINE_ADVANCE_SIGN_IN_MINUTES = "offline_advance_sign_in_minutes";
+    //线下课课程开始后指定时间内签到为迟到
+    String OFFLINE_ADVANCE_SIGN_IN_LATE_MINUTES = "offline_advance_sign_in_late_minutes";
+    //线下课课程结束前指定时间签退为异常
+    String OFFLINE_ADVANCE_SIGN_OUT_MINUTES = "offline_advance_sign_out_minutes";
+    //线下课老师异常签到扣减课酬金额
+    String OFFLINE_ERROR_SIGN_IN_CUT_SALARY = "offline_error_sign_in_cut_salary";
+    //线下课老师异常签到扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_ERROR_SIGN_IN_CUT_SALARY_UNIT = "offline_error_sign_in_cut_salary_unit";
+    //线下课老师迟到扣减课酬金额
+    String OFFLINE_LATE_CUT_SALARY = "offline_late_cut_salary";
+    //线下课老师迟到扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_LATE_CUT_SALARY_UNIT = "offline_late_cut_salary_unit";
+    //线下课老师旷课扣减课酬金额
+    String OFFLINE_LEVEL_SIGN_IN_CUT_SALARY = "offline_level_sign_in_cut_salary";
+    //线下课老师旷课扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_LEVEL_SIGN_IN_CUT_SALARY_UNIT = "offline_level_sign_in_cut_salary_unit";
+    //线下课老师旷课扣减课酬金额
+    String OFFLINE_NO_SIGN_IN_CUT_SALARY = "offline_no_sign_in_cut_salary";
+    //线下课老师旷课扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_NO_SIGN_IN_CUT_SALARY_UNIT = "offline_no_sign_in_cut_salary_unit";
+    //线下课老师异常签退扣减课酬金额
+    String OFFLINE_ERROR_SIGN_OUT_CUT_SALARY = "offline_error_sign_out_cut_salary";
+    //线下课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_ERROR_SIGN_OUT_CUT_SALARY_UNIT = "offline_error_sign_out_cut_salary_unit";
+    //线下课老师异常签退扣减课酬金额
+    String OFFLINE_EARLY_SIGN_OUT_CUT_SALARY = "offline_early_sign_out_cut_salary";
+    //线下课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_EARLY_SIGN_OUT_CUT_SALARY_UNIT = "offline_early_sign_out_cut_salary_unit";
+    //线下课老师异常签退扣减课酬金额
+    String OFFLINE_NO_SIGN_OUT_CUT_SALARY = "offline_no_sign_out_cut_salary";
+    //线下课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String OFFLINE_NO_SIGN_OUT_CUT_SALARY_UNIT = "offline_no_sign_out_cut_salary_unit";
+    //vip课开课前可点名时间段,开课前{}分钟
+    String ENABLE_STUDENT_ATTENDANCE_BEFOR_COURSE_START_TIME_RANGE_VIP = "enable_student_attendance_befor_course_start_time_range_vip";
+    //vip课程可更新学生签到状态时间限制,课程结束后{}分钟
+    String ENABLE_STUDENT_ATTENDANCE_TIME_RANGE_VIP = "enable_student_attendance_time_range_vip";
+    //如果没有签退,{}分钟后自动发送推送信息
+    String SIGN_OUT_MESSAGE_PUSH_MINUTE = "sign_out_message_push_minute";
+    //乐团课老师课程结束后可正常签退时间范围为课程结束后{}分钟内
+    String ADVANCE_SIGN_OUT_MINUTES = "advance_sign_out_minutes";
+
+    //线上连堂课间隔时间
+    String ONLINE_CONTINUE_COURSE_TIME = "online_continue_course_time";
+    //线上课课程开始前指定时间打卡为正常签到
+    String ONLINE_ADVANCE_SIGN_IN_MINUTES = "online_advance_sign_in_minutes";
+    //线上课课程开始后指定时间内签到为迟到
+    String ONLINE_ADVANCE_SIGN_IN_LATE_MINUTES = "online_advance_sign_in_late_minutes";
+    //线上课课程结束前指定时间内签退为早退
+    String ONLINE_EARLY_SIGN_OUT_MINUTES = "online_early_sign_out_minutes";
+    //线上课老师迟到扣减课酬金额
+    String ONLINE_LATE_CUT_SALARY = "online_late_cut_salary";
+    //线上课老师迟到扣减课酬单位(1、元,2、百分比)
+    String ONLINE_LATE_CUT_SALARY_UNIT = "online_late_cut_salary_unit";
+    //线上课老师旷课扣减课酬金额
+    String ONLINE_LEVEL_SIGN_IN_CUT_SALARY = "online_level_sign_in_cut_salary";
+    //线上课老师旷课扣减课酬单位(1、元,2、百分比)
+    String ONLINE_LEVEL_SIGN_IN_CUT_SALARY_UNIT = "online_level_sign_in_cut_salary_unit";
+    //线上课老师旷课扣减课酬金额
+    String ONLINE_NO_SIGN_IN_CUT_SALARY = "online_no_sign_in_cut_salary";
+    //线上课老师旷课扣减课酬单位(1、元,2、百分比)
+    String ONLINE_NO_SIGN_IN_CUT_SALARY_UNIT = "online_no_sign_in_cut_salary_unit";
+    //线上课老师异常签退扣减课酬金额
+    String ONLINE_ERROR_SIGN_OUT_CUT_SALARY = "online_error_sign_out_cut_salary";
+    //线上课老师异常签退扣减课酬单位(1、元,2、百分比)
+    String ONLINE_ERROR_SIGN_OUT_CUT_SALARY_UNIT = "online_error_sign_out_cut_salary_unit";
+    //线上课老师早退扣减课酬金额
+    String ONLINE_EARLY_SIGN_OUT_CUT_SALARY = "online_early_sign_out_cut_salary";
+    //线上课老师早退扣减课酬单位(1、元,2、百分比)
+    String ONLINE_EARLY_SIGN_OUT_CUT_SALARY_UNIT = "online_early_sign_out_cut_salary_unit";
+    //线上课老师未签退扣减课酬金额
+    String ONLINE_NO_SIGN_OUT_CUT_SALARY = "online_no_sign_out_cut_salary";
+    //线上课老师未签退扣减课酬单位(1、元,2、百分比)
+    String ONLINE_NO_SIGN_OUT_CUT_SALARY_UNIT = "online_no_sign_out_cut_salary_unit";
+
+    //线下课老师可以打卡范围,GPS定位距离教学点距离
+    String ATTENDANCE_RANGE = "attendance_range";
+    //线下课签到定位异常扣除金额
+    String OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY = "offline_sign_in_gps_error_cut_salary";
+    //线下课签到定位异常扣除金额
+    String OFFLINE_SIGN_IN_GPS_ERROR_CUT_SALARY_UNIT = "offline_sign_in_gps_error_cut_salary_unit";
+    //线下课签退定位异常扣除金额
+    String OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY = "offline_sign_out_gps_error_cut_salary";
+    //线下课签退定位异常扣除金额
+    String OFFLINE_SIGN_OUT_GPS_ERROR_CUT_SALARY_UNIT = "offline_sign_out_gps_error_cut_salary_unit";
+    //vip线下课点名定位异常扣除金额
+    String VIP_OFFLINE_GPS_ERROR_CUT_SALARY = "vip_offline_gps_error_cut_salary";
+    //vip线下课点名定位异常扣除金额单位
+    String VIP_OFFLINE_GPS_ERROR_CUT_SALARY_UNIT = "vip_offline_gps_error_cut_salary_unit";
+    //vip线下课未点名扣除金额
+    String VIP_OFFLINE_NO_GPS_ERROR_CUT_SALARY = "vip_offline_no_gps_error_cut_salary";
+    //vip线下课未点名扣除金额单位
+    String VIP_OFFLINE_NO_GPS_ERROR_CUT_SALARY_UNIT = "vip_offline_no_gps_error_cut_salary_unit";
+
+    //试用期老师课酬发放百分比
+    String PROBATION_TEACHER_SALARY = "probation_teacher_salary";
+
+    //老师端可申诉考勤时间限制(天)
+    String TEACHER_APP_SALARY_COMPLAINTS_TIME = "teacher_app_salary_complaints_time";
+    //后台老师考勤申诉时间限制
+    String WEB_TEACHER_COMPLAINTS_SALARY = "web_teacher_complaints_salary";
+
+    //线下连堂课间隔时间
+    String OFFLINE_CONTINUE_COURSE_MINUTES = "offline_continue_course_minutes";
+    //学生允许请假的时间,为开课前{}小时
+    String ADVANCE_LEAVE_HOURS = "advance_leave_hours";
+    //教师可调整课程默认时间,开课前{}小时
+    String ENABLE_TEACHER_COURSE_ADJUST_DEFAULT_HOURS = "enable_teacher_course_adjust_default_hours";
+    //退款周期
+    String REFUND_PERIOD = "refund_period";
+
+    //服务异常提醒
+    //学员当月请假指定次数及以上提醒异常请假
+    String STUDENT_ERROR_LEAVE_NUM = "student_error_leave_num";
+    //上课时间在指定时间段内提醒时间安排异常
+    String COURSE_START_TIME_ERROR = "course_start_time_error";
+    //上课时间在指定时间段内提醒时间安排异常
+    String COURSE_END_TIME_ERROR = "course_end_time_error";
+
+    //乐保
+    //是否开启乐保
+    String MUSICAL_REPAIR_OPEN_FLAG = "musical_repair_open_flag";
+    //一年期乐保零售价
+    String ONE_YEAR_MUSICAL_REPAIR_AMOUNT = "one_year_musical_repair_amount";
+    //一年期乐保原价
+    String ONE_YEAR_MUSICAL_REPAIR_ORIGINAL_AMOUNT = "one_year_musical_repair_original_amount";
+
+
+    //特殊规则默认值--》网管&试听课规则
+    //试听课默认单节课时长
+    String DEMO_GROUP_SINGLE_CLASS_MINUTES_ = "demo_group_single_class_minutes_";
+    //陪练课可选老师的分部
+    String PRACTICE_TEACHER_ORGAN_RANGE = "practice_teacher_organ_range";
+    //陪练课可预约声部列表
+    String PRACTICE_SUBJECT_ID_LIST = "practice_subject_id_list";
+    //陪练课预约开始时间
+//    String PRACTICE_APPLY_START_TIME = "practice_apply_start_time";
+    //陪练课预约结束时间
+//    String PRACTICE_APPLY_END_TIME = "practice_apply_end_time";
+
+    //特殊规则默认值--》商品规则设置
+    //内部库存预警值
+    String INNER_REPERTORY_WARN_NUM = "inner_repertory_warn_num";
+    //外部库存预警值
+    String OUTER_REPERTORY_WARN_NUM = "outer_repertory_warn_num";
+    //库存预警手机号
+    String REPERTORY_WARN_PHONE = "repertory_warn_phone";
+
+    //课程默认值规则---》乐团规则设置
+    //自动确认收货时间
+    String AUTO_AFFIRM_RECEIVE_TIME = "auto_affirm_receive_time";
+    //提醒老师创建新的缴费项目,距离缴费项有效期前{}天
+    String PUSH_CREATE_PAYMENT_CALENDER = "push_create_payment_calender";
+    //提醒乐团主管排下学期的课程的时间节点(默认提前14天)
+    String REMIND_COURSE_TIME = "remind_course_time";
+    //会员结束前15天自动创建乐团续费(默认提前15天)
+    String AUTO_CREATE_MEMBER_RENEW = "auto_create_member_renew";
+    //会员团每学期赠送课程分钟数
+    String MEMBER_GROUP_TERM_GIVE_COURSE_TIME = "member_group_term_give_course_time";
+    //各声部不购买会员入团资格限制学员数
+    String MEMBER_GROUP_FEE_STUDENT_NUM = "member_group_fee_student_num";
+
+
+    //乐团所有未开始课程组、商品等服务及产品退费时,退费金额扣减百分比(默认0.005)
+    String MUSIC_RETURN_FEE_CHARGES = "music_return_fee_charges";
+    //乐团课退费时若课程组已开始,退费金额扣减百分比(默认0.8)
+    String MUSIC_COURSE_START_RETURN_FEE_CHARGES = "music_course_start_return_fee_charges";
+    //1v1小班课退费时若课程组已开始,退费金额扣减百分比(默认0.8)
+    String VIP_1V1_COURSE_NOT_START_RETURN_FEE_CHARGES = "VIP_1V1_COURSE_NOT_START_RETURN_FEE_CHARGES";
+    //1vn小班课退费时若课程组已开始,退费金额扣减百分比(默认0.7)
+    String VIP_1VN_COURSE_NOT_START_RETURN_FEE_CHARGES = "VIP_1VN_COURSE_NOT_START_RETURN_FEE_CHARGES";
+
+
+    public static final String BASE_API_URL = "base_api_url";
+
+    /**
+     * 缴费状态提前{}天刷新
+     */
+    public static final String REFRESH_PAYMENT_STATUS_EARLY_DAYS = "refresh_payment_status_early_days";
+
+    /**
+     * VIP课结束后,用户可申诉时间,为课程结束后的{}天
+     */
+    public static final String VIP_APPEAL_DAYS_RANGE = "vip_appeal_days_range";
+
+    /**
+     * 线下课最早打卡时间可提前分钟数
+     */
+    String OFFLINE_SIGN_IN_EARLY_FORWARD_TIME = "offline_sign_in_early_forward_time";
+
+    /**
+     * 最早请假提前时间
+     */
+    String EARLIEST_TIME_FOR_LEAVE="earliest_time_for_leave";
+
+
+    /**
+     * 单技课梯度结算规则设置
+     */
+    public static final String SIGLE_GRADIENT_SETTLEMENT_RULE = "sigle_gradient_settlement_rule";
+
+    /**
+     * 合奏课梯度结算规则设置
+     */
+    public static final String MAX_GRADIENT_SETTLEMENT_RULE = "max_gradient_settlement_rule";
+
+    /**
+     * 小班课梯度结算规则设置
+     */
+    public static final String HIGH_GRADIENT_SETTLEMENT_RULE = "high_gradient_settlement_rule";
+
+    String STUDENT_APPLY_URL = "student_apply_url";
+    String SERVER_PHONE = "server_phone";
+
+    String MUSIC_GROUP_SETTLEMENT_CLASS_MINUTES = "music_group_settlement_class_minutes";
+
+    String MUSIC_GROUP_SETTLEMENT_DAY = "music_group_settlement_day";
+
+    String MUSIC_GROUP_SETTLEMENT_SINGLE_CLASS_MINUTES = "music_group_settlement_single_class_minutes";
+
+    /**
+     * 可签退时间限制(自然天)
+     */
+    String ENABLE_SIGN_OUT_TIME_RANGE = "enable_sign_out_time_range";
+
+    /**
+     * 可更新学生签到状态时间限制,课程结束后{}分钟(和前端核实过,乐团的已弃用)
+     */
+    String ENABLE_STUDENT_ATTENDANCE_TIME_RANGE = "enable_student_attendance_time_range";
+
+    /**
+     * @describe 陪练课课酬
+     */
+    String PRACTICE_COURSE_SALARY = "practice_course_salary";
+
+    /**
+     * @describe 陪练课时长
+     */
+    String PRACTICE_COURSE_MINUTES = "practice_course_minutes";
+
+    /**
+     * @describe 陪练课预约时间间隔
+     */
+    String PRACTICE_APPLY_INTERVAL_TIME = "practice_apply_interval_time";
+
+    /**
+     * @describe 教师请假数据
+     */
+    String TEACHER_LEAVE_DATA = "teacher_leave_data";
+
+    /**
+     * 十分钟内最大可发送的短信次数
+     */
+    String SMS_MAX_TIMES = "sms_max_times";
+
+
+    /**
+     * 连堂课间隔时间
+     */
+    String AUTO_CLOSE_NETWORK_ROOM = "auto_close_network_room";
+
+    /**
+     * @describe 付费陪练课可购买最大月数
+     */
+    String PRACTICE_PAY_MAX_MONTH = "practice_pay_max_month";
+
+    /**
+     * @describe 付费陪练课单月上课数量
+     */
+    String PRACTICE_PAY_DRILL_TIMES_ON_ONE_WEEK = "practice_pay_drill_times_on_one_week";
+
+    /**
+     * @describe 付费陪练课活动截至日期
+     */
+    String PRACTICE_BUY_ACTIVITY_EXPIRE_DATE = "practice_buy_activity_expire_date";
+
+    /**
+     * 陪练老师端入口地址
+     */
+    String TEACHER_STUDY_REPORT_URL = "teacher_study_report_url";
+
+    /**
+     * 陪练课报告地址
+     */
+    String STUDENT_STUDY_REPORT_URL = "student_study_report_url";
+
+    /**
+     * @describe 陪练课续费地址
+     */
+    String PRACTICE_RENEW_URL = "practice_renew_url";
+
+    /**
+     * @describe 老师端baseUrl
+     */
+    String TEACHER_BASE_URL = "teacher_base_url";
+
+    String PRACTICE_PROMOTION_ACTIVITY_START_DATE = "practice_promotion_activity_start_date";
+
+    String NEW_MSG_PUSH = "您收到一条训练回复,请点击查看";
+
+    /**
+     * @describe 教务端baseUrl
+     */
+    String EDU_TEACHER_BASE_URL = "edu_teacher_base_url";
+
+    String HOLIDAY_SETTING = "holiday_setting";
+
+    String PRACTICE_FREE_APPLY_EXPIRE_DATE = "practice_free_apply_expire_date";
+    
+    String START_TIME_OF_1111 = "start_time_of_1111";
+    
+    String END_TIME_OF_1111 = "end_time_of_1111";
+
+    String VIP_SPECIAL_ACTIVITY_IDS = "vip_special_activity_ids";
+
+    //特殊规则默认值--》其他参数设置
+    //基本课酬{}元
+    String DAYA_BASE_SALARY_AMOUNT = "daya_base_salary_amount";
+    //对外课程课后缓冲时间{}分钟
+    String COURSE_BEFORE_BUFFER_TIME = "course_before_buffer_time";
+    //对外课程课后缓冲时间{}分钟
+    String COURSE_AFTER_BUFFER_TIME = "course_after_buffer_time";
+    //全职资源公摊金额
+    String FULL_JOB_FEE = "full_job_fee";
+    //云教练训练时长小于80分钟需要回访
+    String STUDENT_CLOUD_TEACHER_TOTAL_PLAY_TIME = "student_cloud_teacher_total_play_time";
+    //云教练训练次数小于4次需要回访
+    String STUDENT_CLOUD_TEACHER_TRAIN_NUM = "student_cloud_teacher_train_num";
+    //考级活动开始时间
+    String DEGREE_ACTIVITY_START_TIME = "degree_activity_start_time";
+    //考级活动开始时间
+    String DEGREE_ACTIVITY_END_TIME = "degree_activity_end_time";
+    //支持考级活动报名的分部列表
+    String DEGREE_SUPPORT_ORGAN_LIST = "degree_support_organ_list";
+
+
+
+    String WARNING_MIN_COURSE_SALARY = "warning_min_course_salary";
+
+    //会员结束前15天提醒学员续费(默认提前15天)
+    String PUSH_MEMBER_RENEW = "push_member_renew";
+
+    //试用会员结束前3天提醒学员续费(默认提前3天)
+    String EXPERIENCE_PUSH_MEMBER_RENEW = "experience_push_member_renew";
+
+    //云教练活动分部目标JSON
+    String CLOUD_TEACHER_ACTIVE_TARGET = "cloud_teacher_active_target";
+
+    //会员结束前15天提醒学员续费(默认提前5天)
+    String PUSH_MEMBER_RENEW_AGAIN = "push_member_renew_again";
+
+    //会员结束前5天提醒学员续费(退团提醒)(默认提前5天)
+    String PUSH_MEMBER_RENEW_QUIT = "push_member_renew_quit";
+
+    String CHILDREN_DAY_VIP_ACTIVITY_IDS = "children_day_vip_activity_ids";
+
+    //云教练作业开关0关1开
+    String HOMEWORK_OPEN_FLAG = "homework_open_flag";
+
+    //云教练免费体验开关0关1开
+    String FREE_CLOUD_OPEN_FLAG = "free_cloud_open_flag";
+
+    //云教练试用时间最晚截止时间
+    String EXPERIENCE_MEMBERSHIP_END_TIME = "experience_membership_end_time";
+
+    //小课收入是否由平台收款
+    String IS_OPEN_SMALL_CLASS_INCOME_TO_PLATFORM = "is_open_small_class_income_to_platform";
+
+    //平台收款账户
+    String PLATFORM_PAYEE_ACCOUNT = "platform_payee_account";
+
+    /**
+     * @return com.ym.mec.biz.dal.entity.SysConfig
+     * @params paramName
+     * @describe 根据配置名称获取配置信息
+     */
+    SysConfig findByParamName(String paramName);
+
+    void batchUpdate(List<SysConfig> configList);
+
+    void updateConfig(SysConfig config);
+}

+ 15 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMessageConfigService.java

@@ -0,0 +1,15 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.yonge.cooleshow.biz.dal.entity.SysMessageConfig;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.common.service.BaseService;
+
+public interface SysMessageConfigService extends BaseService<Integer, SysMessageConfig> {
+
+	/**
+	 * 根据消息类型查询对象
+	 * @param type
+	 * @return
+	 */
+	SysMessageConfig queryByType(MessageTypeEnum type);
+}

+ 130 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMessageService.java

@@ -0,0 +1,130 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.yonge.cooleshow.biz.dal.dto.SysMessageDto;
+import com.yonge.cooleshow.biz.dal.entity.SysMessage;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.common.page.PageInfo;
+import com.yonge.cooleshow.common.page.QueryInfo;
+import com.yonge.cooleshow.common.service.BaseService;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext.MessageSender;
+
+public interface SysMessageService extends BaseService<Long, SysMessage> {
+	
+	public PageInfo<SysMessageDto> queryListPage(QueryInfo queryInfo);
+
+	/**
+	 * 修改消息对象
+	 * @param message
+	 * @return
+	 */
+	public int updateMessage(SysMessage message);
+
+	/**
+	 * 推送站内消息
+	 * @param userIds
+	 * @param messageType
+	 * @return
+	 */
+	boolean batchSeoMessage(Set<Integer> userIds, MessageTypeEnum messageType,String memo, Object... args);
+
+	/**
+	 * 发送消息
+	 * @param messageSender 消息发送者
+	 * @param messageType 消息类型
+	 * @param receivers 消息接收者(Key:用户编号  value:消息接收对象)
+	 * @param triggerTime 触发时间
+	 * @param readStatus 阅读状态(0-未读  1-已读)
+	 * @param url 超链接地址
+	 * @param args 参数
+	 * @return
+	 */
+	public void batchSendMessage(MessageSender messageSender, MessageTypeEnum messageType, Map<Integer, String> receivers, Date triggerTime,
+			Integer readStatus, String url,String jpushType, Object... args);
+
+
+	/**
+	 * 推送极光自定义消息
+	 * @param messageType 消息类型
+	 * @param receivers 消息接收者(Key:用户编号  value:消息接收对象)
+	 * @param triggerTime 触发时间
+	 * @param readStatus 阅读状态(0-未读  1-已读)
+	 * @param url 超链接地址
+	 * @param args 参数
+	 * @return
+	 */
+	public void batchPushMessage(MessageTypeEnum messageType, Map<Integer, String> receivers, Date triggerTime,
+			Integer readStatus, String url,String jpushType,String sound,String channelId, Object... args);
+
+	/**
+	 * 发送消息
+	 * @param messageSender 消息发送者
+	 * @param userId 用户编号
+	 * @param mode 消息模式
+	 * @param title 消息标题
+	 * @param content 消息内容
+	 * @param receiver 消息接受者
+	 * @param triggerTime 触发时间
+	 * @param readStatus 阅读状态(0-未读  1-已读)
+	 * @param url 超链接地址
+	 * @param group 组
+	 * @return
+	 */
+	public void sendMessage(MessageSender messageSender, Integer userId, String title, String content, String receiver, Date triggerTime, Integer readStatus,
+			String url, String group,String jpushType);
+
+	/**
+	 * 发送验证码
+	 * @param messageSender 消息发送者
+	 * @param userId 用户编号
+	 * @param mode 消息模式
+	 * @param messageType 消息类型
+	 * @param receiver 消息接受者
+	 * @return
+	 */
+	public boolean sendSecurityCode(MessageSender messageSender, Integer userId, MessageTypeEnum messageType, String receiver);
+
+	/**
+	 * 获取已经发送的验证码
+	 * @param type
+	 * @param mobileNOOrEmailAddr
+	 * @return
+	 */
+	public String getSendedVerificationCode(MessageTypeEnum type, String mobileNOOrEmailAddr);
+
+	/**
+	 * 删除已有的key
+	 * @param type
+	 * @param mobileNOOrEmailAddr
+	 */
+	public void delSendedVerificationCode(MessageTypeEnum type, String mobileNOOrEmailAddr);
+
+	/**
+	 * 查询消息未读条数
+	 * @param type
+	 * @param userId
+	 * @return
+	 */
+	public Map<String, Integer> queryCountOfUnread(MessageSendMode type, Integer userId,String jpushType, Integer tenantId);
+
+	/**
+	 *
+	 * @param userId 用户id
+	 * @param status 状态/1 已读,0未读
+	 * @return
+	 */
+	public int updateStatus(Integer userId, int status,String jpushType);
+
+	/**
+	 * 修改单条消息状态
+	 */
+	public int updateOneStatus(Long id, int status);
+	
+	public List<SysMessage> queryUserInRecentMinList(String mobile, int recentMin, MessageSendMode type);
+
+}

+ 61 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SmsCodeServiceImpl.java

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.entity.SysMessage;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
+
+@Service
+public class SmsCodeServiceImpl implements SmsCodeService {
+
+	@Autowired
+	private SysMessageService sysMessageService;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+	@Autowired
+	private SysConfigService sysConfigService;
+
+	@Override
+	public boolean verifyValidCode(String mobile, String authCode) {
+		String verifyCode = sysMessageService.getSendedVerificationCode(MessageTypeEnum.SMS_VERIFY_CODE_LOGIN, mobile);
+		if (StringUtils.isNoneEmpty(verifyCode) && StringUtils.equalsIgnoreCase(verifyCode, authCode)) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public boolean sendValidCode(String mobile) {
+		SysUser sysUser = sysUserFeignService.queryUserByMobile(mobile);
+		Integer userId = null;
+		if (sysUser != null) {
+			userId = sysUser.getId();
+		}
+		SysConfig sysConfig = sysConfigService.findByParamName(SysConfigService.SMS_MAX_TIMES);
+		int times = 3;
+		if (sysConfig != null) {
+			times = Integer.parseInt(sysConfig.getParanValue());
+		}
+		// 十分钟内只能发3条
+		List<SysMessage> list = sysMessageService.queryUserInRecentMinList(mobile, 10, MessageSendMode.SMS);
+		if (list != null && list.size() >= times) {
+			throw new BizException("对不起,您发送太频繁请稍后重试!");
+		}
+		sysMessageService.sendSecurityCode(MessageSenderPluginContext.MessageSender.AWSMS, userId, MessageTypeEnum.SMS_VERIFY_CODE_LOGIN, mobile);
+		return true;
+	}
+
+}

+ 40 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysConfigServiceImpl.java

@@ -0,0 +1,40 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.biz.dal.dao.SysConfigDao;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+import com.yonge.cooleshow.common.service.impl.BaseServiceImpl;
+
+@Service
+public class SysConfigServiceImpl extends BaseServiceImpl<Long, SysConfig> implements SysConfigService {
+
+	@Autowired
+	private SysConfigDao sysConfigDao;
+
+	@Override
+	public BaseDAO<Long, SysConfig> getDAO() {
+		return sysConfigDao;
+	}
+
+	@Override
+	public SysConfig findByParamName(String paramName) {
+		return sysConfigDao.findByParamName(paramName);
+	}
+
+	@Override
+	public void batchUpdate(List<SysConfig> configList) {
+		sysConfigDao.batchUpdate(configList);
+	}
+
+	@Override
+	public void updateConfig(SysConfig config) {
+		sysConfigDao.update(config);
+	}
+
+}

+ 29 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMessageConfigServiceImpl.java

@@ -0,0 +1,29 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.biz.dal.dao.SysMessageConfigDao;
+import com.yonge.cooleshow.biz.dal.entity.SysMessageConfig;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SysMessageConfigService;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+import com.yonge.cooleshow.common.service.impl.BaseServiceImpl;
+
+@Service
+public class SysMessageConfigServiceImpl extends BaseServiceImpl<Integer, SysMessageConfig>  implements SysMessageConfigService {
+	
+	@Autowired
+	private SysMessageConfigDao sysMessageConfigDao;
+
+	@Override
+	public BaseDAO<Integer, SysMessageConfig> getDAO() {
+		return sysMessageConfigDao;
+	}
+
+	@Override
+	public SysMessageConfig queryByType(MessageTypeEnum type) {
+		return sysMessageConfigDao.queryByType(type.getCode());
+	}
+	
+}

+ 412 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMessageServiceImpl.java

@@ -0,0 +1,412 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dao.SysConfigDao;
+import com.yonge.cooleshow.biz.dal.dao.SysMessageDao;
+import com.yonge.cooleshow.biz.dal.dto.SysMessageDto;
+import com.yonge.cooleshow.biz.dal.entity.SysMessage;
+import com.yonge.cooleshow.biz.dal.entity.SysMessageConfig;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.SendStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.SysMessageConfigService;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.common.dal.BaseDAO;
+import com.yonge.cooleshow.common.entity.Mapper;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.cooleshow.common.page.PageInfo;
+import com.yonge.cooleshow.common.page.QueryInfo;
+import com.yonge.cooleshow.common.redis.service.RedisCache;
+import com.yonge.cooleshow.common.service.impl.BaseServiceImpl;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext.MessageSender;
+import com.yonge.toolset.utils.collection.MapUtil;
+import com.yonge.toolset.utils.string.MessageFormatter;
+
+@Service
+public class SysMessageServiceImpl extends BaseServiceImpl<Long, SysMessage> implements SysMessageService {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(SysMessageServiceImpl.class);
+
+	@Autowired
+	private SysMessageDao sysMessageDao;
+	@Autowired
+	private SysMessageConfigService sysMessageConfigService;
+	@Autowired
+	private MessageSenderPluginContext messageSenderPluginContext;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+	@Autowired
+	private SysConfigDao sysConfigDao;
+	@Autowired
+	private RedisCache<String, Object> redisCache;
+	// 验证码有效期
+	public static final int CODE_EXPIRE = 60 * 5;
+	// 发送验证码的间隔时间
+	public static final int CODE_INTERVAL_TIME = 60;
+
+	private final int DEFAULT_CODE = 888888;
+
+	@Value("${message.debugMode}")
+	private boolean debugMode;
+
+	@Override
+	public BaseDAO<Long, SysMessage> getDAO() {
+		return sysMessageDao;
+	}
+
+	@Override
+	public PageInfo<SysMessageDto> queryListPage(QueryInfo queryInfo) {
+		PageInfo<SysMessageDto> pageInfo = new PageInfo<SysMessageDto>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+
+		List<SysMessageDto> dataList = null;
+		int count = this.findCount(params);
+		if (count > 0) {
+			pageInfo.setTotal(count);
+			params.put("offset", pageInfo.getOffset());
+			dataList = sysMessageDao.queryListPage(params);
+		}
+		if (count == 0) {
+			dataList = new ArrayList<SysMessageDto>();
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
+	/**
+	 * 添加消息
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receivers 接收人,多个人用逗号分开
+	 * @param triggerTime 触发时间
+	 * @param mode 消息的发送模式
+	 * @param status 消息的当前状态
+	 * @param errorMsg 错误消息
+	 * @param readStatus 阅读状态
+	 * @param memo 备注
+	 * @param group 消息组
+	 * @return
+	 */
+	private int addMessage(Map<Integer, String> receivers, String subject, String content, Date triggerTime, MessageSendMode mode, SendStatusEnum status,
+			String errorMsg, Integer readStatus, String memo, String group,String jpushType) {
+		SysMessage message = null;
+		Date date = new Date();
+
+		List<SysMessage> messages = new ArrayList<>();
+
+		Integer userId = null;
+		String receiver;
+		for (Entry<Integer, String> entry : receivers.entrySet()) {
+			userId = entry.getKey();
+			receiver = entry.getValue();
+
+			message = new SysMessage();
+			if (userId == null) {
+				SysUser user = sysUserFeignService.queryUserByMobile(receiver);
+				if (user != null) {
+					userId = user.getId();
+				}
+			}
+			message.setUserId(userId);
+			message.setContent(content);
+			message.setCreateOn(date);
+			message.setModifyOn(date);
+			message.setReceiver(receiver);
+			if (triggerTime == null) {
+				triggerTime = date;
+			}
+			message.setSendTime(triggerTime);
+			message.setTitle(subject);
+			message.setStatus(status);
+			message.setType(mode);
+			message.setErrorMsg(errorMsg);
+			message.setReadStatus(readStatus);
+			message.setMemo(memo);
+			message.setGroup(group);
+			message.setClientId(jpushType);
+			messages.add(message);
+		}
+
+		return sysMessageDao.batchInsert(messages);
+	}
+
+	@Override
+	public int updateMessage(SysMessage message) {
+		return sysMessageDao.update(message);
+	}
+
+	@Override
+	public boolean batchSeoMessage(Set<Integer> userIds, MessageTypeEnum messageType,String memo, Object... args) {
+		if(userIds != null){
+			userIds.removeAll(Collections.singleton(null));
+		}
+		if (userIds == null || userIds.size() == 0) {
+			LOGGER.error("接收地址不能为空");
+			return false;
+		}
+		SysMessageConfig messageConfig = sysMessageConfigService.queryByType(messageType);
+		if (messageConfig == null) {
+			throw new BizException("消息类型错误");
+		}else if(messageConfig.getSendFlag() == null || messageConfig.getSendFlag() == 0){
+			return true;
+		}
+		Date date = new Date();
+		SendStatusEnum status = SendStatusEnum.SUCCESSED;
+		String content = MessageFormatter.arrayFormat(messageConfig.getContent(), args);
+		SysMessage message = null;
+
+		List<SysMessage> messages = new ArrayList<>();
+		for (Integer userId : userIds) {
+			message = new SysMessage();
+			message.setUserId(userId);
+			message.setContent(content);
+			message.setCreateOn(date);
+			message.setModifyOn(date);
+			message.setReceiver(userId.toString());
+			message.setSendTime(date);
+			message.setStatus(status);
+			message.setType(MessageSendMode.SEO);
+			message.setTitle(messageConfig.getDescription());
+			message.setReadStatus(0);
+			message.setMemo(memo);
+			message.setGroup(messageConfig.getGroup());
+			messages.add(message);
+		}
+		sysMessageDao.batchInsert(messages);
+		return true;
+	}
+
+	@Override
+	public void batchSendMessage(MessageSender messageSender, MessageTypeEnum type, Map<Integer, String> receivers, Date triggerTime, Integer readStatus,
+			String url,String jpushType, Object... args) {
+		LOGGER.info("batchSendMessage msgSender {}, type {}, receivers {} ", messageSender, type, receivers);
+		if (receivers == null || receivers.size() == 0) {
+			LOGGER.error("接收地址不能为空");
+			return;
+		}
+		Integer userId = receivers.keySet().iterator().next();
+
+		String[] tos = receivers.values().toArray(new String[receivers.size()]);
+		SysMessageConfig messageConfig = sysMessageConfigService.queryByType(type);
+		if (messageConfig == null) {
+			throw new BizException("消息类型错误");
+		}else if(messageConfig.getSendFlag() == null || messageConfig.getSendFlag() == 0){
+			LOGGER.error("batch 发送标志为空" );
+			return;
+		}
+		Date date = new Date();
+		SendStatusEnum status = SendStatusEnum.WAIT;
+		String errorMsg = null;
+		// 立即发送
+		if (triggerTime == null || date.after(triggerTime)) {
+			status = SendStatusEnum.SENDING;
+			try {
+				if (debugMode == true
+						|| messageSenderPluginContext.batchSend(messageSender, messageConfig.getDescription(),
+								MessageFormatter.arrayFormat(messageConfig.getContent(), args), tos, url,jpushType,"default",null)) {
+					status = SendStatusEnum.SUCCESSED;
+				} else {
+					status = SendStatusEnum.FAILED;
+				}
+			} catch (Exception e) {
+				status = SendStatusEnum.FAILED;
+				errorMsg = e.getMessage();
+				LOGGER.warn("消息发送失败", e);
+			}
+		}
+		MessageSendMode mode = MessageSendMode.SMS;
+		if (messageSender.getSendMode().equals("PUSH")) {
+			mode = MessageSendMode.PUSH;
+		} else if (messageSender.getSendMode().equals("EMAIL")) {
+			mode = MessageSendMode.EMAIL;
+		}
+		addMessage(receivers, messageConfig.getDescription(), MessageFormatter.arrayFormat(messageConfig.getContent(), args), triggerTime, mode, status, errorMsg, readStatus,
+				url, messageConfig.getGroup(),jpushType);
+	}
+
+	@Override
+	public void batchPushMessage(MessageTypeEnum type, Map<Integer, String> receivers, Date triggerTime, Integer readStatus,
+			String url,String jpushType,String sound,String channelId, Object... args) {
+		if (receivers == null || receivers.size() == 0) {
+			throw new BizException("接收地址不能为空");
+		}
+		String[] tos = receivers.values().toArray(new String[receivers.size()]);
+		SysMessageConfig messageConfig = sysMessageConfigService.queryByType(type);
+		if (messageConfig == null) {
+			throw new BizException("消息类型错误");
+		}else if(messageConfig.getSendFlag() == null || messageConfig.getSendFlag() == 0){
+			return;
+		}
+		Date date = new Date();
+		SendStatusEnum status = SendStatusEnum.WAIT;
+		String errorMsg = null;
+		// 立即发送
+		if (triggerTime == null || date.after(triggerTime)) {
+			status = SendStatusEnum.SENDING;
+			try {
+				if (debugMode == true
+						|| messageSenderPluginContext.batchSend(MessageSender.JIGUANG, messageConfig.getDescription(),
+								MessageFormatter.arrayFormat(messageConfig.getContent(), args), tos, url,jpushType,sound,channelId)) {
+					status = SendStatusEnum.SUCCESSED;
+				} else {
+					status = SendStatusEnum.FAILED;
+				}
+			} catch (Exception e) {
+				status = SendStatusEnum.FAILED;
+				errorMsg = e.getMessage();
+				LOGGER.warn("消息发送失败", e);
+			}
+		}
+		addMessage(receivers, messageConfig.getDescription(), MessageFormatter.arrayFormat(messageConfig.getContent(), args), triggerTime, MessageSendMode.PUSH, status, errorMsg, readStatus,
+				url, messageConfig.getGroup(),jpushType);
+	}
+
+	@Override
+	public void sendMessage(MessageSender messageSender, Integer userId, String title, String content, String receiver, Date triggerTime, Integer readStatus, String url, String group,String jpushType) {
+		LOGGER.info("batchSendMessage {}, userId {}, receivers {} ", messageSender, userId, receiver);
+		if (StringUtils.isBlank(receiver)) {
+			throw new BizException("接收地址不能为空");
+		}
+
+		Date date = new Date();
+		SendStatusEnum status = SendStatusEnum.WAIT;
+		String errorMsg = null;
+		// 立即发送
+		if (triggerTime == null || date.after(triggerTime)) {
+			status = SendStatusEnum.SENDING;
+			try {
+				if (debugMode == true || messageSenderPluginContext.send(messageSender, receiver, title, content, url,jpushType,"default",null)) {
+					status = SendStatusEnum.SUCCESSED;
+				} else {
+					status = SendStatusEnum.FAILED;
+				}
+			} catch (Exception e) {
+				status = SendStatusEnum.FAILED;
+				errorMsg = e.getMessage();
+				LOGGER.warn("消息发送失败", e);
+			}
+		}
+		MessageSendMode mode = MessageSendMode.SMS;
+		if (messageSender.getSendMode().equals("PUSH")) {
+			mode = MessageSendMode.PUSH;
+		} else if (messageSender.getSendMode().equals("EMAIL")) {
+			mode = MessageSendMode.EMAIL;
+			LOGGER.info("发送邮件 {} ");
+		}
+		Map<Integer, String> receivers = new HashMap<Integer, String>();
+		receivers.put(userId, receiver);
+		addMessage(receivers, title, content, triggerTime, mode, status, errorMsg, readStatus, url, null,jpushType);
+	}
+
+	@Override
+	public boolean sendSecurityCode(MessageSender messageSender, Integer userId, MessageTypeEnum messageType, String receiver) {
+		String key1 = getVerificationCode1CacheKey(messageType, receiver);
+		if (redisCache.get(key1) != null) {
+			throw new BizException("请勿频繁操作,获取验证码间隔时间为60秒");
+		}
+
+		String key = getVerificationCodeCacheKey(messageType, receiver);
+		int code = DEFAULT_CODE;
+		if (debugMode == false) {
+			code = getRandomCode(messageType, receiver);
+		}
+		Map<Integer, String> receivers = new HashMap<>(1);
+		receivers.put(userId, receiver);
+		batchSendMessage(messageSender, messageType, receivers, null, 1, "","", code);
+		redisCache.put(key, code + "", CODE_EXPIRE);
+		redisCache.put(key1, code + "", CODE_INTERVAL_TIME);
+		return true;
+	}
+
+	@Override
+	public String getSendedVerificationCode(MessageTypeEnum type, String mobileNOOrEmailAddr) {
+		if (debugMode == true) {
+			return DEFAULT_CODE + "";
+		}
+		String key = getVerificationCodeCacheKey(type, mobileNOOrEmailAddr);
+		Object object = redisCache.get(key);
+		return object == null ? null : object.toString();
+	}
+
+	@Override
+	public void delSendedVerificationCode(MessageTypeEnum type, String mobileNOOrEmailAddr) {
+		String key = getVerificationCodeCacheKey(type, mobileNOOrEmailAddr);
+		if (StringUtils.isNotBlank(key)) {
+			redisCache.delete(key);
+		}
+	}
+
+	@Override
+	public Map<String, Integer> queryCountOfUnread(MessageSendMode type, Integer userId, String jpushType, Integer tenantId) {
+		List<Mapper> mappers = sysMessageDao.queryCountOfUnread(type, userId, jpushType, tenantId);
+
+		Map<String, Integer> map = new HashMap<String, Integer>();
+
+		for (Mapper mapper : mappers) {
+			map.put(mapper.getKey().toString(), Integer.parseInt(mapper.getValue().toString()));
+		}
+
+		return map;
+	}
+
+	public void setDebugMode(boolean debugMode) {
+		this.debugMode = debugMode;
+	}
+
+	private int getRandomCode(MessageTypeEnum type, String mobileNo) {
+		int min = 100000;
+		int max = 999999;
+		Random random = new Random();
+
+		return random.nextInt(max) % (max - min + 1) + min;
+	}
+
+	private static String getVerificationCodeCacheKey(MessageTypeEnum type, String mobileNOOrEmailAddr) {
+		return "verificationCode" + type.name() + mobileNOOrEmailAddr;
+	}
+
+	private static String getVerificationCode1CacheKey(MessageTypeEnum type, String mobileNOOrEmailAddr) {
+		return "verificationCode" + mobileNOOrEmailAddr;
+	}
+
+	/**
+	 *
+	 * @param userId 用户id数组
+	 * @param status 状态/1 已读,0未读
+	 * @return 修改的条数
+	 */
+	@Override
+	public int updateStatus(Integer userId, int status,String jpushType) {
+		return sysMessageDao.updateStatus(userId, status,jpushType);
+	}
+
+	@Override
+	public int updateOneStatus(Long id, int status) {
+		return sysMessageDao.updateOneStatus(id, status);
+	}
+
+	@Override
+	public List<SysMessage> queryUserInRecentMinList(String mobile, int recentMin, MessageSendMode type) {
+		return sysMessageDao.queryUserInRecentMinList(mobile, recentMin, type);
+	}
+}

+ 106 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysConfigMapper.xml

@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- 这个文件是自动生成的。 不要修改此文件。所有改动将在下次重新自动生成时丢失。 -->
+<mapper namespace="com.yonge.cooleshow.biz.dal.dao.SysConfigDao">
+
+	<resultMap type="com.yonge.cooleshow.biz.dal.entity.SysConfig" id="SysConfig">
+		<result column="id_" property="id" />
+		<result column="param_name_" property="paramName" />
+		<result column="paran_value_" property="paranValue" />
+		<result column="description_" property="description" />
+		<result column="create_on_" property="createOn" />
+		<result column="modify_on_" property="modifyOn" />
+		<result column="group_" property="group" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="SysConfig">
+		SELECT * FROM sys_config WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="SysConfig">
+		SELECT * FROM sys_config where 1=1
+		<if test="group != null">
+			and group_ = #{group}
+		</if>
+		ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysConfig"
+		useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO sys_config
+		(id_,param_name_,paran_value_,description_,create_on_,modify_on_,group_)
+		VALUES(#{id},#{paramName},#{paranValue},#{description},#{createOn},#{modifyOn},#{group})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.yonge.cooleshow.biz.dal.entity.SysConfig">
+		UPDATE sys_config
+		<set>
+			<if test="modifyOn != null">
+				modify_on_ = #{modifyOn},
+			</if>
+			<if test="paranValue != null">
+				paran_value_ = #{paranValue},
+			</if>
+			<if test="description != null">
+				description_ = #{description},
+			</if>
+			<if test="paramName != null">
+				param_name_ = #{paramName},
+			</if>
+			<if test="group != null">
+				group_ = #{group},
+			</if>
+		</set>
+		WHERE id_ = #{id}
+	</update>
+    <update id="batchUpdate">
+		<foreach collection="configList" item="config" index="index" open="" close="" separator=";">
+			UPDATE sys_config
+			<set>
+				<if test="config.paranValue != null">
+					paran_value_ = #{config.paranValue},
+				</if>
+				<if test="config.description != null">
+					description_ = #{config.description},
+				</if>
+				<if test="config.paramName != null">
+					param_name_ = #{config.paramName},
+				</if>
+				<if test="config.group != null">
+					group_ = #{config.group},
+				</if>
+					modify_on_ = NOW()
+			</set>
+				WHERE id_ = #{config.id}
+		</foreach>
+	</update>
+
+    <!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM sys_config WHERE id_ = #{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="SysConfig" parameterType="map">
+		SELECT * FROM sys_config ORDER BY id_
+		<include refid="global.limit" />
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM sys_config
+	</select>
+	
+	<select id="findByParamName" resultMap="SysConfig">
+		SELECT * FROM sys_config WHERE param_name_ = #{paramName}
+	</select>
+    <select id="findConfigValue" resultType="java.lang.String">
+		SELECT paran_value_ FROM sys_config WHERE param_name_ = #{paramName}
+	</select>
+</mapper>

+ 117 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMessageConfigMapper.xml

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- 这个文件是自动生成的。 不要修改此文件。所有改动将在下次重新自动生成时丢失。 -->
+<mapper namespace="com.yonge.cooleshow.biz.dal.dao.SysMessageConfigDao">
+
+	<resultMap type="com.yonge.cooleshow.biz.dal.entity.SysMessageConfig"
+		id="SysMessageConfig">
+		<result column="id_" property="id" />
+		<result column="message_type_" property="messageType"
+			typeHandler="com.yonge.cooleshow.common.dal.CustomEnumTypeHandler" />
+		<result column="content_" property="content" />
+		<result column="description_" property="description" />
+		<result column="modify_on_" property="modifyOn" />
+		<result column="url_" property="url" />
+		<result column="group_" property="group" />
+		<result column="send_flag_" property="sendFlag" />
+	</resultMap>
+
+	<sql id="queryCondition">
+		<where>
+			<if test="messageType != null">
+				and message_type_ =
+				#{messageType,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},
+			</if>
+			<if test="content != null">
+				and content_ = #{content,jdbcType=VARCHAR},
+			</if>
+			<if test="description != null">
+				and description_ = #{description,jdbcType=VARCHAR}
+			</if>
+			<if test="group != null">
+				and group_ = #{group,jdbcType=VARCHAR}
+			</if>
+			<if test="sendFlag != null">
+				and send_flag_ = #{sendFlag}
+			</if>
+		</where>
+	</sql>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="SysMessageConfig">
+		SELECT * FROM
+		sys_message_config WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="SysMessageConfig">
+		SELECT * FROM sys_message_config
+		ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysMessageConfig"
+		useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO sys_message_config
+		(id_,message_type_,content_,description_,modify_on_,url_,group_)
+		VALUES(#{id},#{messageType},#{content},#{description},#{modifyOn},#{url},#{group})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.yonge.cooleshow.biz.dal.entity.SysMessageConfig">
+		UPDATE sys_message_config
+		<set>
+			<if test="modifyOn != null">
+				modify_on_ = #{modifyOn},
+			</if>
+			<if test="messageType != null">
+				message_type_ = #{messageType},
+			</if>
+			<if test="id != null">
+				id_ = #{id},
+			</if>
+			<if test="url != null">
+				url_ = #{url},
+			</if>
+			<if test="group != null">
+				group_ = #{group},
+			</if>
+			<if test="content != null">
+				content_ = #{content},
+			</if>
+			<if test="description != null">
+				description_ = #{description},
+			</if>
+			<if test="sendFlag != null">
+				send_flag_ = #{sendFlag}
+			</if>
+		</set>
+		WHERE id_ = #{id}
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM sys_message_config WHERE id_ =
+		#{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="SysMessageConfig"
+		parameterType="map">
+		select * from sys_message_config
+		<include refid="queryCondition" />
+		order by update_time_ desc
+		<include refid="global.limit" />
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		select count(*) from sys_message_config
+		<include refid="queryCondition" />
+	</select>
+	<select id="queryByType" resultMap="SysMessageConfig">
+		SELECT * FROM sys_message_config WHERE message_type_ = #{messageType}
+	</select>
+</mapper>

+ 204 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMessageMapper.xml

@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+这个文件是自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<mapper namespace="com.yonge.cooleshow.biz.dal.dao.SysMessageDao">
+
+    <resultMap type="com.yonge.cooleshow.biz.dal.entity.SysMessage" id="message">
+        <result column="id_" property="id"/>
+        <result column="title_" property="title"/>
+        <result column="content_" property="content"/>
+        <result column="type_" property="type" typeHandler="com.yonge.cooleshow.common.dal.CustomEnumTypeHandler"/>
+        <result column="status_" property="status" typeHandler="com.yonge.cooleshow.common.dal.CustomEnumTypeHandler"/>
+        <result column="receiver_" property="receiver"/>
+        <result column="send_time_" property="sendTime"/>
+        <result column="error_msg_" property="errorMsg"/>
+        <result column="create_on_" property="createOn"/>
+        <result column="modify_on_" property="modifyOn"/>
+        <result column="user_id_" property="userId"/>
+        <result column="memo_" property="memo"/>
+        <result column="read_status_" property="readStatus"/>
+        <result column="group_" property="group"/>
+        <result column="client_id_" property="clientId"/>
+    </resultMap>
+    
+    <resultMap type="com.yonge.cooleshow.biz.dal.dto.SysMessageDto" id="messageDto" extends="message">
+        <result column="username_" property="user.username"/>
+    </resultMap>
+    
+    <resultMap type="com.yonge.cooleshow.biz.dal.dto.Mapper" id="Mapper">
+    	<result column="key_" property="key"/>
+        <result column="value_" property="value"/>
+    </resultMap>
+
+	<sql id="queryCondition">
+		<where>
+			<if test="clientId != null and clientId != ''">
+				and (m.client_id_ = #{clientId} OR m.client_id_ IS NULL)
+			</if>
+			<if test="userId != null">
+				and m.user_id_ = #{userId}
+			</if>
+			<if test="receiver != null">
+				and m.receiver_ like '%' #{receiver} '%'
+			</if>
+			<if test="status != null">
+				and m.status_ = #{status,jdbcType=TINYINT}
+			</if>
+			<if test="readStatus != null">
+				and m.read_status_ = #{readStatus,jdbcType=TINYINT}
+			</if>
+			<if test="title != null">
+				and m.title_ like '%' #{title} '%'
+			</if>
+			<if test="type != null">
+				and m.type_ = #{type}
+			</if>
+			<if test="group != null">
+				and m.group_ = #{group}
+			</if>
+			<if test="readStatus != null">
+				and m.read_status_ = #{readStatus}
+			</if>
+		</where>
+	</sql>
+
+    <select id="get" resultMap="message" parameterType="java.lang.Long">
+		select *
+		from sys_message
+		where id_ = #{id,jdbcType=BIGINT}
+	</select>
+
+	<delete id="delete" parameterType="java.lang.Long">
+		delete from
+		sys_message
+		where
+		id_ = #{id,jdbcType=BIGINT}
+	</delete>
+
+	<insert id="insert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysMessage">
+		insert into sys_message (user_id_,title_, content_,type_, receiver_,
+		send_time_, error_msg_,memo_, create_on_,modify_on_,group_,client_id_)
+		values (#{userId}, #{title},#{content},#{type,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},
+				#{receiver},now(),#{errorMsg},#{memo},now(),now(),#{group},#{clientId})
+	</insert>
+
+	<insert id="batchInsert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysMessage">
+		insert into sys_message (id_, user_id_,
+		title_, content_,
+		type_, status_, receiver_,
+		send_time_, error_msg_,read_status_,memo_, create_on_,
+		modify_on_,group_,client_id_)
+		values
+		<foreach collection="list" item="item" index="index"
+			separator=",">
+			(
+			#{item.id,jdbcType=BIGINT},#{item.userId,jdbcType=BIGINT}, #{item.title,jdbcType=VARCHAR},
+			#{item.content,jdbcType=VARCHAR},
+			#{item.type,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},
+			#{item.status,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler}, #{item.receiver,jdbcType=VARCHAR},
+			#{item.sendTime},#{item.errorMsg,jdbcType=VARCHAR},#{item.readStatus},#{item.memo},
+			#{item.createOn},
+			#{item.modifyOn},#{item.group},#{item.clientId})
+		</foreach>
+	</insert>
+
+	<update id="update" parameterType="com.yonge.cooleshow.biz.dal.entity.SysMessage">
+		update sys_message
+		<set>
+			<if test="userId != null">
+				user_id_ = #{userId,jdbcType=BIGINT},
+			</if>
+			<if test="title != null">
+				title_ = #{title,jdbcType=VARCHAR},
+			</if>
+			<if test="content != null">
+				content_ = #{content,jdbcType=VARCHAR},
+			</if>
+			<if test="type != null">
+				type_ = #{type,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},
+			</if>
+			<if test="status != null">
+				status_ = #{status,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},
+			</if>
+			<if test="receiver != null">
+				receiver_ = #{receiver,jdbcType=VARCHAR},
+			</if>
+			<if test="sendTime != null">
+				send_time_ = #{sendTime},
+			</if>
+			<if test="errorMsg != null">
+				error_msg_ = #{errorMsg,jdbcType=VARCHAR},
+			</if>
+			<if test="readStatus != null">
+				read_status_ = #{readStatus,jdbcType=TINYINT},
+			</if>
+			<if test="memo != null">
+				memo_ = #{memo,jdbcType=VARCHAR},
+			</if>
+			<if test="createOn != null">
+				create_on_ = #{createOn},
+			</if>
+			<if test="modifyOn != null">
+				modify_on_ = #{modifyOn},
+			</if>
+			<if test="group != null">
+				group_ = #{group},
+			</if>
+		</set>
+		where id_ = #{id,jdbcType=BIGINT}
+	</update>
+	<update id="updateStatus">
+		update sys_message set read_status_=#{status}
+		where user_id_ = #{userId} AND (client_id_ = #{clientId} OR client_id_ IS NULL)
+	</update>
+
+    <update id="updateOneStatus">
+       update sys_message set read_status_=#{status}
+		where id_ =#{id}
+    </update>
+
+    <select id="queryCount" parameterType="map" resultType="int">
+		select count(m.id_) from sys_message m
+		<include refid="queryCondition" />
+		order by m.create_on_ desc
+	</select>
+
+	<select id="queryPage" parameterType="map" resultMap="message">
+		select m.* from sys_message m
+		<include refid="queryCondition" />
+		order by m.create_on_ desc
+		<include refid="global.limit" />
+	</select>
+
+	<select id="queryListPage" parameterType="map" resultMap="messageDto">
+		select m.*,u.username_ from sys_message m left join sys_user u on m.user_id_ = u.id_
+		<include refid="queryCondition" />
+		order by m.create_on_ desc
+		<include refid="global.limit" />
+	</select>
+
+	<select id="queryByStatusAndTime" resultMap="message">
+		select *
+		from sys_message where status_ = #{status} and <![CDATA[DATE_ADD(CURDATE(),
+		INTERVAL #{recentMin} MINUTE) >= date(send_time_)]]>
+	</select>
+
+	<select id="queryCountOfUnread" resultMap="Mapper" parameterType="map">
+		SELECT group_ key_,COUNT(*) value_ FROM sys_message
+		WHERE user_id_ = #{userId} AND read_status_ = 0 and status_ = 2
+		AND (client_id_ = #{clientId} OR client_id_ IS NULL)
+		<if test="type != null">
+		and type_ = #{type,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler}
+		</if>
+		group by group_
+	</select>
+
+	<select id="queryUserInRecentMinList" resultMap="message" parameterType="map">
+		select *
+		from sys_message where receiver_ = #{mobile} and type_ = #{type,typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler} and <![CDATA[DATE_ADD(send_time_,
+		INTERVAL #{recentMin} MINUTE) >= now()]]>
+	</select>
+</mapper>

+ 108 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysSuggestionMapper.xml

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+这个文件是自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<mapper namespace="com.yonge.cooleshow.biz.dal.dao.SysSuggestionDao">
+
+    <resultMap type="com.yonge.cooleshow.biz.dal.entity.SysSuggestion" id="SysSuggestion">
+        <result column="id_" property="id"/>
+        <result column="mobile_no_" property="mobileNo"/>
+        <result column="title_" property="title"/>
+        <result column="content_" property="content"/>
+        <result column="url_" property="url"/>
+        <result column="user_id_" property="userId"/>
+        <result column="username_" property="username"/>
+        <result column="create_time_" property="createTime"/>
+        <result column="client_type_" property="clientType"/>
+        <result column="type_" property="type" typeHandler="com.yonge.cooleshow.common.dal.CustomEnumTypeHandler"/>
+    </resultMap>
+
+    <!-- 根据主键查询一条记录 -->
+    <select id="get" resultMap="SysSuggestion">
+		SELECT * FROM sys_suggestion WHERE id_ = #{id}
+	</select>
+
+    <!-- 全查询 -->
+    <select id="findAll" resultMap="SysSuggestion">
+		SELECT * FROM sys_suggestion ORDER BY id_
+	</select>
+
+    <!-- 向数据库增加一条记录 -->
+    <insert id="insert" parameterType="com.yonge.cooleshow.biz.dal.entity.SysSuggestion" useGeneratedKeys="true" keyColumn="id"
+            keyProperty="id">
+        INSERT INTO sys_suggestion (mobile_no_,title_,content_,user_id_,create_time_,client_type_,type_,url_)
+        VALUES(#{mobileNo},#{title},#{content},#{userId},now(),#{clientType},#{type, typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},#{url})
+    </insert>
+
+    <!-- 根据主键查询一条记录 -->
+    <update id="update" parameterType="com.yonge.cooleshow.biz.dal.entity.SysSuggestion">
+        UPDATE sys_suggestion
+        <set>
+            <if test="url != null">
+                url_ = #{url},
+            </if>
+            <if test="clientType != null">
+                client_type_ = #{clientType},
+            </if>
+            <if test="userId != null">
+                user_id_ = #{userId},
+            </if>
+            <if test="title != null">
+                title_ = #{title},
+            </if>
+            <if test="content != null">
+                content_ = #{content},
+            </if>
+            <if test="mobileNo != null">
+                mobile_no_ = #{mobileNo},
+            </if>
+            <if test="type != null">
+                type_ = #{type, typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler},
+            </if>
+        </set>
+        WHERE id_ = #{id} 
+    </update>
+
+    <!-- 根据主键删除一条记录 -->
+    <delete id="delete">
+		DELETE FROM sys_suggestion WHERE id_ = #{id} 
+	</delete>
+
+    <sql id="queryCondition">
+        <where>
+            <if test="type!=null">
+                AND ss.type_ = #{type, typeHandler=com.yonge.cooleshow.common.dal.CustomEnumTypeHandler}
+            </if>
+            <if test="clientType!=null">
+                AND ss.client_type_ = #{clientType}
+            </if>
+            <if test="startTime!=null and startTime!=''">
+                AND DATE_FORMAT(ss.create_time_,'%Y-%m-%d') &gt;= #{startTime}
+            </if>
+            <if test="endTime!=null and endTime!=''">
+                AND DATE_FORMAT(ss.create_time_,'%Y-%m-%d') &lt;= #{endTime}
+            </if>
+            <if test="search!=null and search!=''">
+                AND (su.real_name_ LIKE CONCAT('%', #{search}, '%') OR su.username_ LIKE CONCAT('%', #{search}, '%') OR ss.user_id_=#{search} OR su.phone_=#{search})
+            </if>
+        </where>
+    </sql>
+
+    <!-- 分页查询 -->
+    <select id="queryPage" resultMap="SysSuggestion" parameterType="map">
+        SELECT ss.*,CASE WHEN ss.client_type_='STUDENT' THEN su.username_ ELSE su.real_name_ END username_ FROM sys_suggestion ss
+        LEFT JOIN sys_user su ON su.id_ = ss.user_id_
+        <include refid="queryCondition" />
+        ORDER BY ss.id_ DESC
+        <include refid="global.limit"/>
+    </select>
+
+    <!-- 查询当前表的总记录数 -->
+    <select id="queryCount" resultType="int">
+		SELECT COUNT(ss.id_) FROM sys_suggestion ss
+        LEFT JOIN sys_user su ON su.id_ = ss.user_id_
+        <include refid="queryCondition" />
+	</select>
+</mapper>

+ 6 - 0
cooleshow-user/user-student/pom.xml

@@ -63,6 +63,12 @@
 			<groupId>com.yonge.cooleshow</groupId>
 			<artifactId>user-biz</artifactId>
 		</dependency>
+
+		<dependency>
+			<groupId>com.github.whvcse</groupId>
+			<artifactId>easy-captcha</artifactId>
+			<version>1.6.2</version>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 88 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.student.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+
+@RestController
+@RequestMapping("code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String")
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile) throws Exception {
+        smsCodeService.sendValidCode(mobile);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String") })
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone,String code) {
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if(smsCodeService.verifyValidCode(phone,code)){
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
+    public Object verifyImageCode(String phone,String code){
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if(redisTemplate.hasKey(redisKey)){
+            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response,String phone) throws Exception {
+        if(StringUtils.isEmpty(phone)){
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone,specCaptcha.text(),3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

+ 48 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/UploadFileController.java

@@ -0,0 +1,48 @@
+package com.yonge.cooleshow.student.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
+import com.yonge.toolset.utils.upload.UploadUtil;
+
+/** 
+ * 上传控制层
+ */
+@RestController
+@Api(tags = "文件上传服务")
+public class UploadFileController extends BaseController {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(UploadFileController.class);
+
+	@Autowired
+	private UploadFileService uploadFileService;
+
+	@PostMapping(value = "uploadFile")
+	public Object uploadFile(@ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) {
+		try {
+			if (file != null && StringUtils.isNotBlank(file.getOriginalFilename())) {
+				UploadReturnBean bean = uploadFileService.uploadFile(file.getInputStream(), UploadUtil.getExtension(file.getOriginalFilename()));
+				bean.setName(file.getOriginalFilename());
+				if (bean.isStatus()) {
+					return succeed(bean);
+				}
+				return failed(bean.getMessage());
+			}
+		} catch (Exception e) {
+			LOGGER.error("上传失败", e);
+		}
+		return failed("上传失败");
+	}
+}

+ 6 - 0
cooleshow-user/user-teacher/pom.xml

@@ -63,6 +63,12 @@
 			<groupId>com.yonge.cooleshow</groupId>
 			<artifactId>user-biz</artifactId>
 		</dependency>
+
+		<dependency>
+			<groupId>com.github.whvcse</groupId>
+			<artifactId>easy-captcha</artifactId>
+			<version>1.6.2</version>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 88 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+
+@RestController
+@RequestMapping("code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String")
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile) throws Exception {
+        smsCodeService.sendValidCode(mobile);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String") })
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone,String code) {
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if(smsCodeService.verifyValidCode(phone,code)){
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
+    public Object verifyImageCode(String phone,String code){
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if(redisTemplate.hasKey(redisKey)){
+            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response,String phone) throws Exception {
+        if(StringUtils.isEmpty(phone)){
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone,specCaptcha.text(),3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

+ 48 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/UploadFileController.java

@@ -0,0 +1,48 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
+import com.yonge.toolset.utils.upload.UploadUtil;
+
+/** 
+ * 上传控制层
+ */
+@RestController
+@Api(tags = "文件上传服务")
+public class UploadFileController extends BaseController {
+
+	private final static Logger LOGGER = LoggerFactory.getLogger(UploadFileController.class);
+
+	@Autowired
+	private UploadFileService uploadFileService;
+
+	@PostMapping(value = "uploadFile")
+	public Object uploadFile(@ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) {
+		try {
+			if (file != null && StringUtils.isNotBlank(file.getOriginalFilename())) {
+				UploadReturnBean bean = uploadFileService.uploadFile(file.getInputStream(), UploadUtil.getExtension(file.getOriginalFilename()));
+				bean.setName(file.getOriginalFilename());
+				if (bean.isStatus()) {
+					return succeed(bean);
+				}
+				return failed(bean.getMessage());
+			}
+		} catch (Exception e) {
+			LOGGER.error("上传失败", e);
+		}
+		return failed("上传失败");
+	}
+}

BIN
toolset/thirdparty-component/libs/smUtil-1.0.jar


BIN
toolset/thirdparty-component/libs/tgtext-3.2.14.jar


+ 23 - 2
toolset/thirdparty-component/pom.xml

@@ -3,7 +3,7 @@
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
 	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 	<modelVersion>4.0.0</modelVersion>
-	
+
 	<parent>
 		<groupId>com.yonge.toolset</groupId>
 		<artifactId>toolset</artifactId>
@@ -56,7 +56,7 @@
 			<artifactId>ks3-kss-java-sdk</artifactId>
 			<version>0.8.14</version>
 		</dependency>
-		
+
 		<dependency>
 			<groupId>com.timevale</groupId>
 			<artifactId>tech-sdk</artifactId>
@@ -67,11 +67,32 @@
 
 		<dependency>
 			<groupId>com.timevale</groupId>
+			<artifactId>smUtil</artifactId>
+			<version>1.0</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/smUtil-1.0.jar</systemPath>
+		</dependency>
+
+		<dependency>
+			<groupId>com.timevale</groupId>
+			<artifactId>tgtext</artifactId>
+			<version>3.2.14</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/tgtext-3.2.14.jar</systemPath>
+		</dependency>
+
+		<dependency>
+			<groupId>com.timevale</groupId>
 			<artifactId>utils</artifactId>
 			<version>3.0.6</version>
 			<scope>system</scope>
 			<systemPath>${project.basedir}/libs/utils-3.0.6.jar</systemPath>
 		</dependency>
+
+		<dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+		</dependency>
 	</dependencies>
 
 	<build>