Quellcode durchsuchen

Merge branch 'dev' of http://192.168.1.220:10080/Amoy2/wlyy2.0 into dev

huangzhiyong vor 6 Jahren
Ursprung
Commit
540119cb9f
22 geänderte Dateien mit 1017 neuen und 30 gelöschten Zeilen
  1. 70 0
      common/common-entity/src/main/java/com/yihu/jw/entity/base/notice/NoticeDO.java
  2. 28 0
      common/common-entity/src/main/java/com/yihu/jw/entity/base/notice/UserNoticeDO.java
  3. 12 0
      common/common-exception/src/main/java/com/yihu/jw/exception/code/BaseErrorCode.java
  4. 15 0
      common/common-request-mapping/src/main/java/com/yihu/jw/rm/base/BaseRequestMapping.java
  5. 13 6
      common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/module/InterfaceErrorCodeVO.java
  6. 24 12
      common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/module/InterfaceParamVO.java
  7. 2 0
      common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/notice/NoticeVO.java
  8. 2 10
      common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/notice/UserNoticeVO.java
  9. 3 1
      svr/svr-base/src/main/java/com/yihu/jw/base/dao/notice/NoticeDao.java
  10. 4 0
      svr/svr-base/src/main/java/com/yihu/jw/base/dao/user/UserDao.java
  11. 123 0
      svr/svr-base/src/main/java/com/yihu/jw/base/endpoint/notice/NoticeEndPoint.java
  12. 54 0
      svr/svr-base/src/main/java/com/yihu/jw/base/endpoint/notice/UserNoticeEndpoint.java
  13. 5 0
      svr/svr-base/src/main/java/com/yihu/jw/base/listener/ApplicationReadyListener.java
  14. 168 0
      svr/svr-base/src/main/java/com/yihu/jw/base/service/notice/NoticeService.java
  15. 62 0
      svr/svr-base/src/main/java/com/yihu/jw/base/service/notice/UserNoticeService.java
  16. 1 1
      svr/svr-base/src/main/java/com/yihu/jw/base/util/ErrorCodeUtil.java
  17. 79 0
      svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/DelayService.java
  18. 53 0
      svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/Notice.java
  19. 12 0
      svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/OnDelayedListener.java
  20. 196 0
      svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/RedisLock.java
  21. 59 0
      svr/svr-base/src/main/java/com/yihu/jw/base/util/threadPool/ThreadPool.java
  22. 32 0
      svr/svr-base/src/main/java/com/yihu/jw/base/util/threadPool/ThreadPoolUtil.java

+ 70 - 0
common/common-entity/src/main/java/com/yihu/jw/entity/base/notice/NoticeDO.java

@ -1,5 +1,6 @@
package com.yihu.jw.entity.base.notice;
package com.yihu.jw.entity.base.notice;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yihu.jw.entity.UuidIdentityEntityWithOperator;
import com.yihu.jw.entity.UuidIdentityEntityWithOperator;
import javax.persistence.Column;
import javax.persistence.Column;
@ -15,6 +16,62 @@ import java.util.Date;
@Table(name = "base_notice")
@Table(name = "base_notice")
public class NoticeDO extends UuidIdentityEntityWithOperator{
public class NoticeDO extends UuidIdentityEntityWithOperator{
    public enum Status{
        wait("待发布",1),
        released("已发布",2);
        private String name;
        private Integer value;
        Status(String name, Integer value) {
            this.name = name;
            this.value = value;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getValue() {
            return value;
        }
        public void setValue(Integer value) {
            this.value = value;
        }
    }
    public enum SendType{
        manual_release("手动发布",1),
        automatic_release("自动发布",2);
        private String name;
        private Integer value;
        SendType(String name, Integer value) {
            this.name = name;
            this.value = value;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getValue() {
            return value;
        }
        public void setValue(Integer value) {
            this.value = value;
        }
    }
    private String title;//公告标题
    private String title;//公告标题
    private Integer status;//状态(1待发布,2已发布)
    private Integer status;//状态(1待发布,2已发布)
    private Date sendTime;//发布时间
    private Date sendTime;//发布时间
@ -50,6 +107,7 @@ public class NoticeDO extends UuidIdentityEntityWithOperator{
    }
    }
    @Column(name = "send_time")
    @Column(name = "send_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08:00")
    public Date getSendTime() {
    public Date getSendTime() {
        return sendTime;
        return sendTime;
    }
    }
@ -75,4 +133,16 @@ public class NoticeDO extends UuidIdentityEntityWithOperator{
    public void setDel(Integer del) {
    public void setDel(Integer del) {
        this.del = del;
        this.del = del;
    }
    }
    @Override
    public String toString() {
        return "NoticeDO{" +
                "title='" + title + '\'' +
                ", status=" + status +
                ", sendTime=" + sendTime +
                ", content='" + content + '\'' +
                ", sendType=" + sendType +
                ", del=" + del +
                '}';
    }
}
}

+ 28 - 0
common/common-entity/src/main/java/com/yihu/jw/entity/base/notice/UserNoticeDO.java

@ -14,6 +14,34 @@ import javax.persistence.Table;
@Table(name = "base_user_notice")
@Table(name = "base_user_notice")
public class UserNoticeDO extends UuidIdentityEntity{
public class UserNoticeDO extends UuidIdentityEntity{
    public enum Read{
        unRead("未读",0),
        read("已读",1);
        private String name;
        private Integer value;
        Read(String name, Integer value) {
            this.name = name;
            this.value = value;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getValue() {
            return value;
        }
        public void setValue(Integer value) {
            this.value = value;
        }
    }
    private String noticeId;//公告id
    private String noticeId;//公告id
    private String userId;//用户id
    private String userId;//用户id
    private Integer isRead;//是否已读(1已读,0未读)
    private Integer isRead;//是否已读(1已读,0未读)

+ 12 - 0
common/common-exception/src/main/java/com/yihu/jw/exception/code/BaseErrorCode.java

@ -63,6 +63,18 @@ public class BaseErrorCode {
     */
     */
    public static class Notice{
    public static class Notice{
        public static final String FINDDICTBYCODE = "-105000";
        public static final String FINDDICTBYCODE = "-105000";
        /**
         * 请输入50个字以内的公告标题
         */
        public static final String LIMIT_TITLE = "-105001";
        /**
         * 已经发布,请不要重复发布
         */
        public static final String HAD_RELEASE = "-105002";
        /**
         * 自动发布,不允许手动发布
         */
        public static final String AUTO_RELEASE = "-105003";
    }
    }
    /**
    /**

+ 15 - 0
common/common-request-mapping/src/main/java/com/yihu/jw/rm/base/BaseRequestMapping.java

@ -155,6 +155,21 @@ public class BaseRequestMapping {
        public static final String PREFIX  = "/error";
        public static final String PREFIX  = "/error";
    }
    }
    /**
     * 通知公告
     */
    public static class Notice extends Basic {
        public static final String PREFIX  = "/notice";
        public static final String RELEASE  = "/release";
    }
    /**
     * 用户通知公告
     */
    public static class UserNotice extends Basic {
        public static final String PREFIX  = "/userNotice";
    }
    /**
    /**
     * 角色权限
     * 角色权限
     */
     */

+ 13 - 6
common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/module/InterfaceErrorCodeVO.java

@ -2,6 +2,7 @@ package com.yihu.jw.restmodel.base.module;
import com.yihu.jw.restmodel.UuidIdentityVO;
import com.yihu.jw.restmodel.UuidIdentityVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
/**
 * @author yeshijie on 2018/9/28.
 * @author yeshijie on 2018/9/28.
@ -9,12 +10,18 @@ import io.swagger.annotations.ApiModel;
@ApiModel(value = "InterfaceErrorCodeVO", description = "接口错误说明")
@ApiModel(value = "InterfaceErrorCodeVO", description = "接口错误说明")
public class InterfaceErrorCodeVO extends UuidIdentityVO {
public class InterfaceErrorCodeVO extends UuidIdentityVO {
    private String interfaceId;//接口id
    private String name;//错误码名称
    private String description;//错误码描述
    private String solution;//解决方案
    private Integer sort;//排序
    private Integer del;//删除标志
    @ApiModelProperty(value = "接口id", example = "接口id")
    private String interfaceId;
    @ApiModelProperty(value = "错误码名称", example = "错误码名称")
    private String name;
    @ApiModelProperty(value = "错误码描述", example = "错误码描述")
    private String description;
    @ApiModelProperty(value = "解决方案", example = "解决方案")
    private String solution;
    @ApiModelProperty(value = "排序", example = "1")
    private Integer sort;
    @ApiModelProperty(value = "删除标志", example = "1")
    private Integer del;
    public String getInterfaceId() {
    public String getInterfaceId() {
        return interfaceId;
        return interfaceId;

+ 24 - 12
common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/module/InterfaceParamVO.java

@ -2,24 +2,36 @@ package com.yihu.jw.restmodel.base.module;
import com.yihu.jw.restmodel.UuidIdentityVO;
import com.yihu.jw.restmodel.UuidIdentityVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
/**
 * @author yeshijie on 2018/9/28.
 * @author yeshijie on 2018/9/28.
 */
 */
@ApiModel(value = "InterfaceParamVO", description = "接口入参出参")
@ApiModel(value = "InterfaceParamVO", description = "接口入参出参")
public class InterfaceParamVO extends UuidIdentityVO {
public class InterfaceParamVO extends UuidIdentityVO {
    
    private String interfaceId;//接口id
    private String name;//参数名
    private Integer paramType;//参数类型
    private Integer dataType;//数据类型
    private Integer isRequire;//是否必填(1是,0否)
    private Integer maxLength;//最大长度
    private String description;//描述
    private String example;//示例
    private Integer type;//类型(1入参,2出参)
    private Integer sort;//排序
    private Integer del;//删除标志
    @ApiModelProperty(value = "接口id", example = "接口id")
    private String interfaceId;
    @ApiModelProperty(value = "参数名", example = "user")
    private String name;
    @ApiModelProperty(value = "参数类型", example = "HEADER")
    private Integer paramType;
    @ApiModelProperty(value = "数据类型", example = "VERCHAR")
    private Integer dataType;
    @ApiModelProperty(value = "是否必填(1是,0否)", example = "1")
    private Integer isRequire;
    @ApiModelProperty(value = "最大长度", example = "1")
    private Integer maxLength;
    @ApiModelProperty(value = "描述", example = "")
    private String description;
    @ApiModelProperty(value = "示例", example = "")
    private String example;
    @ApiModelProperty(value = "类型(1入参,2出参)", example = "1")
    private Integer type;
    @ApiModelProperty(value = "排序", example = "1")
    private Integer sort;
    @ApiModelProperty(value = "删除标志", example = "1")
    private Integer del;
    public String getInterfaceId() {
    public String getInterfaceId() {
        return interfaceId;
        return interfaceId;

+ 2 - 0
common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/notice/NoticeVO.java

@ -1,5 +1,6 @@
package com.yihu.jw.restmodel.base.notice;
package com.yihu.jw.restmodel.base.notice;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yihu.jw.restmodel.UuidIdentityVOWithOperator;
import com.yihu.jw.restmodel.UuidIdentityVOWithOperator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiModelProperty;
@ -18,6 +19,7 @@ public class NoticeVO extends UuidIdentityVOWithOperator {
    @ApiModelProperty(value = "状态(1待发布,2已发布)", example = "1")
    @ApiModelProperty(value = "状态(1待发布,2已发布)", example = "1")
    private Integer status;
    private Integer status;
    @ApiModelProperty(value = "发布时间", example = "2019-01-01 12:20:59")
    @ApiModelProperty(value = "发布时间", example = "2019-01-01 12:20:59")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08:00")
    private Date sendTime;
    private Date sendTime;
    @ApiModelProperty(value = "公告内容", example = "内容")
    @ApiModelProperty(value = "公告内容", example = "内容")
    private String content;
    private String content;

+ 2 - 10
common/common-rest-model/src/main/java/com/yihu/jw/restmodel/base/notice/UserNoticeVO.java

@ -1,5 +1,6 @@
package com.yihu.jw.restmodel.base.notice;
package com.yihu.jw.restmodel.base.notice;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yihu.jw.entity.UuidIdentityEntity;
import com.yihu.jw.entity.UuidIdentityEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiModelProperty;
@ -24,9 +25,8 @@ public class UserNoticeVO extends UuidIdentityEntity{
    @ApiModelProperty(value = "公告标题", example = "标题")
    @ApiModelProperty(value = "公告标题", example = "标题")
    private String title;
    private String title;
    @ApiModelProperty(value = "发布时间", example = "2019-01-01 12:20:59")
    @ApiModelProperty(value = "发布时间", example = "2019-01-01 12:20:59")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08:00")
    private Date sendTime;
    private Date sendTime;
    @ApiModelProperty(value = "公告内容", example = "内容")
    private String content;
    public String getNoticeId() {
    public String getNoticeId() {
        return noticeId;
        return noticeId;
@ -75,12 +75,4 @@ public class UserNoticeVO extends UuidIdentityEntity{
    public void setSendTime(Date sendTime) {
    public void setSendTime(Date sendTime) {
        this.sendTime = sendTime;
        this.sendTime = sendTime;
    }
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}
}

+ 3 - 1
svr/svr-base/src/main/java/com/yihu/jw/base/dao/notice/NoticeDao.java

@ -4,11 +4,13 @@ import com.yihu.jw.entity.base.notice.NoticeDO;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
/**
/**
 * 公告通知
 * 公告通知
 * @author yeshijie on 2018/9/30.
 * @author yeshijie on 2018/9/30.
 */
 */
public interface NoticeDao extends PagingAndSortingRepository<NoticeDO, String>, JpaSpecificationExecutor<NoticeDO> {
public interface NoticeDao extends PagingAndSortingRepository<NoticeDO, String>, JpaSpecificationExecutor<NoticeDO> {
    List<NoticeDO> findByStatusAndSendType(Integer status,Integer sendType);
}
}

+ 4 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/dao/user/UserDao.java

@ -4,9 +4,13 @@ import com.yihu.jw.entity.base.user.UserDO;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
/**
/**
 * Dao - 后台管理员
 * Dao - 后台管理员
 * Created by progr1mmer on 2018/8/20.
 * Created by progr1mmer on 2018/8/20.
 */
 */
public interface UserDao extends PagingAndSortingRepository<UserDO, String>, JpaSpecificationExecutor<UserDO> {
public interface UserDao extends PagingAndSortingRepository<UserDO, String>, JpaSpecificationExecutor<UserDO> {
    List<UserDO> findByEnabled(boolean enabled);
}
}

+ 123 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/endpoint/notice/NoticeEndPoint.java

@ -0,0 +1,123 @@
package com.yihu.jw.base.endpoint.notice;
import com.yihu.jw.base.service.notice.NoticeService;
import com.yihu.jw.base.util.ErrorCodeUtil;
import com.yihu.jw.entity.base.notice.NoticeDO;
import com.yihu.jw.exception.code.BaseErrorCode;
import com.yihu.jw.restmodel.base.notice.NoticeVO;
import com.yihu.jw.restmodel.web.Envelop;
import com.yihu.jw.restmodel.web.ListEnvelop;
import com.yihu.jw.restmodel.web.ObjEnvelop;
import com.yihu.jw.restmodel.web.PageEnvelop;
import com.yihu.jw.restmodel.web.endpoint.EnvelopRestEndpoint;
import com.yihu.jw.rm.base.BaseRequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * 公告通知
 * @author yeshijie on 2018/10/9.
 */
@RestController
@RequestMapping(value = BaseRequestMapping.Notice.PREFIX)
@Api(value = "公告通知管理", description = "公告通知管理服务接口", tags = {"基础服务 - 公告通知管理服务接口"})
public class NoticeEndPoint extends EnvelopRestEndpoint {
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private ErrorCodeUtil errorCodeUtil;
    @PostMapping(value = BaseRequestMapping.Notice.CREATE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "创建")
    public ObjEnvelop<NoticeVO> create (
            @ApiParam(name = "json_data", value = "Json数据", required = true)
            @RequestBody String jsonData) throws Exception {
        NoticeDO noticeDO = toEntity(jsonData, NoticeDO.class);
        if(StringUtils.isBlank(noticeDO.getTitle())||noticeDO.getTitle().length()>50){
            return failed(errorCodeUtil.getErrorMsg(BaseErrorCode.Notice.LIMIT_TITLE), ObjEnvelop.class);
        }
        noticeDO = noticeService.addNotice(noticeDO);
        return success(noticeDO, NoticeVO.class);
    }
    @PostMapping(value = BaseRequestMapping.Notice.DELETE)
    @ApiOperation(value = "删除")
    public Envelop delete(
            @ApiParam(name = "id", value = "id", required = true)
            @RequestParam(value = "id") String id) {
        noticeService.deleteNotice(id);
        return success("删除成功");
    }
    @PostMapping(value = BaseRequestMapping.Notice.RELEASE)
    @ApiOperation(value = "发布")
    public Envelop release(
            @ApiParam(name = "id", value = "id", required = true)
            @RequestParam(value = "id") String id) {
        NoticeDO noticeDO = noticeService.findById(id);
        if (NoticeDO.Status.released.getValue().equals(noticeDO.getStatus())){
            return failed(errorCodeUtil.getErrorMsg(BaseErrorCode.Notice.HAD_RELEASE), Envelop.class);
        }
        if (NoticeDO.SendType.automatic_release.getValue().equals(noticeDO.getSendType())){
            return failed(errorCodeUtil.getErrorMsg(BaseErrorCode.Notice.AUTO_RELEASE), Envelop.class);
        }
        noticeService.release(noticeDO);
        return success("发布成功");
    }
    @PostMapping(value = BaseRequestMapping.Notice.UPDATE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "更新")
    public ObjEnvelop<NoticeVO> update (
            @ApiParam(name = "json_data", value = "Json数据", required = true)
            @RequestBody String jsonData) throws Exception {
        NoticeDO noticeDO = toEntity(jsonData, NoticeDO.class);
        if (null == noticeDO.getId()) {
            return failed(errorCodeUtil.getErrorMsg(BaseErrorCode.Common.ID_IS_NULL), ObjEnvelop.class);
        }
        if(StringUtils.isBlank(noticeDO.getTitle())||noticeDO.getTitle().length()>50){
            return failed(errorCodeUtil.getErrorMsg(BaseErrorCode.Notice.LIMIT_TITLE), ObjEnvelop.class);
        }
        noticeDO = noticeService.updateNotice(noticeDO);
        return success(noticeDO, NoticeVO.class);
    }
    @GetMapping(value = BaseRequestMapping.Notice.PAGE)
    @ApiOperation(value = "获取分页")
    public PageEnvelop<NoticeVO> page (
            @ApiParam(name = "fields", value = "返回的字段,为空返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "过滤器,为空检索所有条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序,规则参见说明文档")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
            @RequestParam(value = "page") int page,
            @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
            @RequestParam(value = "size") int size) throws Exception {
        List<NoticeDO> noticeDOs = noticeService.search(fields, filters, sorts, page, size);
        int count = (int)noticeService.getCount(filters);
        return success(noticeDOs, count, page, size, NoticeVO.class);
    }
    @GetMapping(value = BaseRequestMapping.Notice.LIST)
    @ApiOperation(value = "获取列表")
    public ListEnvelop<NoticeVO> list (
            @ApiParam(name = "fields", value = "返回的字段,为空返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "过滤器,为空检索所有条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序,规则参见说明文档")
            @RequestParam(value = "sorts", required = false) String sorts) throws Exception {
        List<NoticeDO> noticeDOs = noticeService.search(fields, filters, sorts);
        return success(noticeDOs, NoticeVO.class);
    }
}

+ 54 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/endpoint/notice/UserNoticeEndpoint.java

@ -0,0 +1,54 @@
package com.yihu.jw.base.endpoint.notice;
import com.yihu.jw.base.service.notice.UserNoticeService;
import com.yihu.jw.entity.base.notice.NoticeDO;
import com.yihu.jw.restmodel.base.notice.NoticeVO;
import com.yihu.jw.restmodel.base.notice.UserNoticeVO;
import com.yihu.jw.restmodel.web.ObjEnvelop;
import com.yihu.jw.restmodel.web.PageEnvelop;
import com.yihu.jw.restmodel.web.endpoint.EnvelopRestEndpoint;
import com.yihu.jw.rm.base.BaseRequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 *
 * @author yeshijie on 2018/10/9.
 */
@RestController
@RequestMapping(value = BaseRequestMapping.UserNotice.PREFIX)
@Api(value = "用户公告通知管理", description = "用户公告通知管理服务接口", tags = {"基础服务 - 用户公告通知管理服务接口"})
public class UserNoticeEndpoint extends EnvelopRestEndpoint {
    @Autowired
    private UserNoticeService userNoticeService;
    @GetMapping(value = BaseRequestMapping.Module.FINDBYID)
    @ApiOperation(value = "查看文章详情")
    public ObjEnvelop<NoticeVO> findById(
            @ApiParam(name = "id", value = "id", required = true)
            @RequestParam(value = "id") String id) {
        NoticeDO noticeDO = userNoticeService.findNoticeDetail(id);
        return success(noticeDO, NoticeVO.class);
    }
    @GetMapping(value = BaseRequestMapping.Module.PAGE)
    @ApiOperation(value = "获取分页")
    public PageEnvelop<UserNoticeVO> page (
            @ApiParam(name = "userId", value = "用户id")
            @RequestParam(value = "userId", required = true) String userId,
            @ApiParam(name = "page", value = "分页大小", required = true, defaultValue = "1")
            @RequestParam(value = "page") int page,
            @ApiParam(name = "size", value = "页码", required = true, defaultValue = "15")
            @RequestParam(value = "size") int size) throws Exception {
        return userNoticeService.queryPage(page,size,userId);
    }
}

+ 5 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/listener/ApplicationReadyListener.java

@ -2,6 +2,7 @@ package com.yihu.jw.base.listener;
import com.yihu.jw.base.activemq.MessageManager;
import com.yihu.jw.base.activemq.MessageManager;
import com.yihu.jw.base.service.errorCode.ErrorCodeService;
import com.yihu.jw.base.service.errorCode.ErrorCodeService;
import com.yihu.jw.base.service.notice.NoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ApplicationListener;
@ -18,6 +19,8 @@ public class ApplicationReadyListener implements ApplicationListener<Application
    private MessageManager messageManager;
    private MessageManager messageManager;
    @Autowired
    @Autowired
    private ErrorCodeService errorCodeService;
    private ErrorCodeService errorCodeService;
    @Autowired
    private NoticeService noticeService;
    @Override
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
@ -25,6 +28,8 @@ public class ApplicationReadyListener implements ApplicationListener<Application
        messageManager.initConsumer();
        messageManager.initConsumer();
        //初始化错误码
        //初始化错误码
        errorCodeService.initErrorCode();
        errorCodeService.initErrorCode();
        //初始化延迟队列
        noticeService.initDelayNotice();
    }
    }
}
}

+ 168 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/service/notice/NoticeService.java

@ -1,9 +1,27 @@
package com.yihu.jw.base.service.notice;
package com.yihu.jw.base.service.notice;
import com.yihu.jw.base.dao.notice.NoticeDao;
import com.yihu.jw.base.dao.notice.NoticeDao;
import com.yihu.jw.base.dao.notice.UserNoticeDao;
import com.yihu.jw.base.dao.user.UserDao;
import com.yihu.jw.base.util.threadPool.ThreadPoolUtil;
import com.yihu.jw.base.util.delay.DelayService;
import com.yihu.jw.base.util.delay.Notice;
import com.yihu.jw.base.util.delay.OnDelayedListener;
import com.yihu.jw.base.util.delay.RedisLock;
import com.yihu.jw.entity.base.notice.NoticeDO;
import com.yihu.jw.entity.base.notice.NoticeDO;
import com.yihu.jw.entity.base.notice.UserNoticeDO;
import com.yihu.jw.entity.base.user.UserDO;
import com.yihu.mysql.query.BaseJpaService;
import com.yihu.mysql.query.BaseJpaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.yihu.jw.entity.base.notice.NoticeDO.Status.released;
/**
/**
 * 公告通知
 * 公告通知
@ -12,5 +30,155 @@ import org.springframework.stereotype.Service;
@Service
@Service
public class NoticeService extends BaseJpaService<NoticeDO, NoticeDao> {
public class NoticeService extends BaseJpaService<NoticeDO, NoticeDao> {
    @Autowired
    private NoticeDao noticeDao;
    @Autowired
    private UserNoticeDao userNoticeDao;
    @Autowired
    private DelayService delayService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ThreadPoolUtil threadPoolUtil;
    /**
     * redis锁的key
     */
    private final String rediskey = "notice:";
    /**
     * 发布公告
     * @param noticeDO
     */
    @Transactional(rollbackFor = Exception.class)
    public void release(NoticeDO noticeDO){
        noticeDO.setStatus(NoticeDO.Status.released.getValue());
        noticeDO.setSendTime(new Date());
        List<UserDO> userDOList = userDao.findByEnabled(true);
        List<UserNoticeDO> userNoticeDOs = new ArrayList<>(userDOList.size());
        userDOList.forEach(userDO -> {
            UserNoticeDO userNoticeDO = new UserNoticeDO();
            userNoticeDO.setDel(1);
            userNoticeDO.setIsRead(UserNoticeDO.Read.unRead.getValue());
            userNoticeDO.setNoticeId(noticeDO.getId());
            userNoticeDO.setUserId(userDO.getId());
            userNoticeDOs.add(userNoticeDO);
        });
        userNoticeDao.save(userNoticeDOs);
        noticeDao.save(noticeDO);
    }
    /**
     * 按id查找
     * @param id
     * @return
     */
    public NoticeDO findById(String id){
        return noticeDao.findOne(id);
    }
    /**
     * 新增消息公告
     * @param noticeDO
     * @return
     */
    public NoticeDO addNotice(NoticeDO noticeDO){
        noticeDO.setDel(1);
        noticeDO.setStatus(NoticeDO.Status.wait.getValue());
        noticeDao.save(noticeDO);
        //自动发布
        if(NoticeDO.SendType.automatic_release.getValue().equals(noticeDO.getSendType())){
            Notice notice = new Notice(noticeDO.getId(), noticeDO.getSendTime().getTime());
            delayService.add(notice);
        }
        return noticeDO;
    }
    /**
     * 修改公告
     * @param noticeDO
     * @return
     */
    public NoticeDO updateNotice(NoticeDO noticeDO){
        NoticeDO noticeOld = noticeDao.findOne(noticeDO.getId());
        if(released.getValue().equals(noticeDO.getStatus())){
            //已发布的不能修改
            return noticeDO;
        }
        if(!noticeOld.getSendType().equals(noticeDO.getSendType())){
            if(NoticeDO.SendType.automatic_release.getValue().equals(noticeDO.getSendType())){
                //自动发布
                Notice notice = new Notice(noticeDO.getId(), noticeDO.getSendTime().getTime());
                delayService.add(notice);
            }else {
                //手动发布
                delayService.remove(noticeDO.getId());
            }
        }
        noticeOld.setContent(noticeDO.getContent());
        noticeOld.setTitle(noticeDO.getTitle());
        noticeOld.setSendTime(noticeDO.getSendTime());
        noticeOld.setSendType(noticeDO.getSendType());
        noticeDao.save(noticeOld);
        return noticeDO;
    }
    /**
     * 删除
     * @param noticeId
     */
    public void deleteNotice(String noticeId){
        NoticeDO noticeDO = noticeDao.findOne(noticeId);
        noticeDO.setDel(0);
        noticeDao.save(noticeDO);
    }
    /**
     * 初始化延迟队列,项目启动的时候吧数据库的数据重新加入到队列中
     */
    public void initDelayNotice(){
        //启动监听
        delayService.start(new OnDelayedListener() {
            @Override
            public void onDelayedArrived(final Notice notice) {
                //异步来做
                threadPoolUtil.execute(new Runnable() {
                    @Override
                    public void run() {
                        String noticeId = notice.getNoticeId();
                        //分布式事务锁,防止代码在多台机器上执行
                        RedisLock lock = new RedisLock(redisTemplate, rediskey+noticeId, 10000, 20000);
                        try {
                            if(lock.lock()) {
                                //需要加锁的代码
                                NoticeDO noticeDO = noticeDao.findOne(noticeId);
                                if (NoticeDO.Status.wait.getValue().equals(noticeDO.getStatus())
                                        &&NoticeDO.SendType.automatic_release.getValue().equals(noticeDO.getSendType())){
                                    release(noticeDO);
                                }
                            }
                        } catch (InterruptedException e){
                            e.printStackTrace();
                        } finally {
                            lock.unlock();
                        }
                    }
                });
            }
        });
        //查找需要加入队列的数据
        List<NoticeDO> noticeDOList = noticeDao.findByStatusAndSendType(NoticeDO.Status.wait.getValue(),
                NoticeDO.SendType.automatic_release.getValue());
        noticeDOList.forEach(noticeDO -> {
            Notice notice = new Notice(noticeDO.getId(), noticeDO.getSendTime().getTime());
            delayService.add(notice);
        });
    }
}
}

+ 62 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/service/notice/UserNoticeService.java

@ -1,10 +1,22 @@
package com.yihu.jw.base.service.notice;
package com.yihu.jw.base.service.notice;
import com.yihu.jw.base.dao.notice.NoticeDao;
import com.yihu.jw.base.dao.notice.UserNoticeDao;
import com.yihu.jw.base.dao.notice.UserNoticeDao;
import com.yihu.jw.entity.base.notice.NoticeDO;
import com.yihu.jw.entity.base.notice.UserNoticeDO;
import com.yihu.jw.entity.base.notice.UserNoticeDO;
import com.yihu.jw.restmodel.base.notice.UserNoticeVO;
import com.yihu.jw.restmodel.web.PageEnvelop;
import com.yihu.mysql.query.BaseJpaService;
import com.yihu.mysql.query.BaseJpaService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
/**
 * 用户公告通知
 * 用户公告通知
 * @author yeshijie on 2018/9/30.
 * @author yeshijie on 2018/9/30.
@ -12,5 +24,55 @@ import org.springframework.stereotype.Service;
@Service
@Service
public class UserNoticeService extends BaseJpaService<UserNoticeDO, UserNoticeDao> {
public class UserNoticeService extends BaseJpaService<UserNoticeDO, UserNoticeDao> {
    @Autowired
    private UserNoticeDao userNoticeDao;
    @Autowired
    private NoticeDao noticeDao;
    @Autowired
    private JdbcTemplate jdbcTempalte;
    /**
     * 查看文章详情
     * @param id
     * @return
     */
    public NoticeDO findNoticeDetail(String id){
        UserNoticeDO userNoticeDO = userNoticeDao.findOne(id);
        if(UserNoticeDO.Read.unRead.getValue().equals(userNoticeDO.getIsRead())){
            userNoticeDO.setIsRead(UserNoticeDO.Read.read.getValue());
            userNoticeDao.save(userNoticeDO);
        }
        NoticeDO noticeDO = noticeDao.findOne(userNoticeDO.getNoticeId());
        return noticeDO;
    }
    /**
     * 按类型分页查找
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public PageEnvelop<UserNoticeVO> queryPage(Integer page, Integer size, String userId){
        StringBuffer sql = new StringBuffer("SELECT n.id noticeId,n.title,n.send_time sendTime,u.id,u.is_read isRead,u.user_id userId from base_notice n , base_user_notice u WHERE n.del = '1' ");
        StringBuffer sqlCount = new StringBuffer("SELECT COUNT(*) count from base_notice n , base_user_notice u WHERE n.del = '1' ");
        List<Object> args = new ArrayList<>();
        if(StringUtils.isNotBlank(userId)){
            sql.append(" and u.user_id=? ");
            sqlCount.append(" and u.user_id='").append(userId).append("' ");
            args.add(userId);
        }
        sql.append(" and u.notice_id = n.id and u.del = '1' ");
        sqlCount.append(" and u.notice_id = n.id and u.del = '1'");
        sql.append(" ORDER BY n.send_time desc limit ").append((page-1)*size).append(",").append(size);
        List<UserNoticeVO> list = jdbcTempalte.query(sql.toString(),args.toArray(),new BeanPropertyRowMapper(UserNoticeVO.class));
        List<Map<String,Object>> countList = jdbcTempalte.queryForList(sqlCount.toString());
        long count = Long.valueOf(countList.get(0).get("count").toString());
        return PageEnvelop.getSuccessListWithPage("查找成功",list, page, size,count);
    }
}
}

+ 1 - 1
svr/svr-base/src/main/java/com/yihu/jw/base/util/ErrorCodeUtil.java

@ -21,6 +21,6 @@ public class ErrorCodeUtil {
     * @return
     * @return
     */
     */
    public String getErrorMsg(String errorCode){
    public String getErrorMsg(String errorCode){
        return redisTemplate.opsForValue().get(BaseErrorCode.PREFIX+errorCode);
        return redisTemplate.opsForValue().get(BaseErrorCode.PREFIX + errorCode);
    }
    }
}
}

+ 79 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/DelayService.java

@ -0,0 +1,79 @@
package com.yihu.jw.base.util.delay;
import com.yihu.jw.base.util.threadPool.ThreadPoolUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.DelayQueue;
/**
 * @author yeshijie on 2018/9/29.
 */
@Component
public class DelayService {
    private final Logger log = LoggerFactory.getLogger(DelayService.class);
    @Autowired
    private ThreadPoolUtil threadPoolUtil;
    private boolean start;
    private OnDelayedListener listener;
    public DelayQueue<Notice> delayQueue = new DelayQueue<Notice>();
    public void start(OnDelayedListener listener) {
        if (start) {
            return;
        }
        log.info("DelayService 启动");
        start = true;
        this.listener = listener;
        threadPoolUtil.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        Notice notice = delayQueue.take();
                        if (DelayService.this.listener != null) {
                            DelayService.this.listener.onDelayedArrived(notice);
                        }
                        log.info("执行任务+"+notice.getNoticeId()+","+notice.getStartTime());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public void add(Notice notice) {
        delayQueue.put(notice);
    }
    public boolean remove(Notice notice) {
        return delayQueue.remove(notice);
    }
    public void add(String noticeId,long startTime) {
        delayQueue.put(new Notice(noticeId, startTime));
    }
    public void remove(String noticeId) {
        Notice[] array = delayQueue.toArray(new Notice[]{});
        if (array == null || array.length <= 0) {
            return;
        }
        Notice target = null;
        for (Notice notice : array) {
            if (notice.getNoticeId().equals(noticeId)) {
                target = notice;
                break;
            }
        }
        if (target != null) {
            delayQueue.remove(target);
        }
    }
}

+ 53 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/Notice.java

@ -0,0 +1,53 @@
package com.yihu.jw.base.util.delay;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
 * 消息公告的延迟队列
 * @author yeshijie on 2018/10/9.
 */
public class Notice implements Delayed {
    private String noticeId;
    private long startTime;
    public Notice(String noticeId, long timeout){
        this.noticeId = noticeId;
        this.startTime = timeout;
    }
    @Override
    public int compareTo(Delayed other) {
        if (other == this) {
            return 0;
        }
        if (other instanceof Notice) {
            Notice otherRequest = (Notice) other;
            long otherStartTime = otherRequest.getStartTime();
            return (int) (this.startTime - otherStartTime);
        }
        return 0;
    }
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(startTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }
    public String getNoticeId() {
        return noticeId;
    }
    public void setNoticeId(String noticeId) {
        this.noticeId = noticeId;
    }
    public long getStartTime() {
        return startTime;
    }
    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
}

+ 12 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/OnDelayedListener.java

@ -0,0 +1,12 @@
package com.yihu.jw.base.util.delay;
/**
 * @author yeshijie on 2018/10/9.
 */
public interface OnDelayedListener {
    /**
     * 延迟时间到了,执行处理订单
     * @param notice
     */
    void onDelayedArrived(Notice notice);
}

+ 196 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/util/delay/RedisLock.java

@ -0,0 +1,196 @@
package com.yihu.jw.base.util.delay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.concurrent.TimeUnit;
/**
 * @author yeshijie on 2018/10/9.
 */
public class RedisLock {
    private static Logger logger = LoggerFactory.getLogger(RedisLock.class);
    private RedisTemplate redisTemplate;
    private static final int DEFAULT_ACQUIRY_RESOLUTION_MILLIS = 100;
    /**
     * Lock key path.
     */
    private String lockKey;
    /**
     * 锁超时时间,防止线程在入锁以后,无限的执行等待
     */
    private int expireMsecs = 60 * 1000;
    /**
     * 锁等待时间,防止线程饥饿
     */
    private int timeoutMsecs = 10 * 1000;
    private volatile boolean locked = false;
    /**
     * Detailed constructor with default acquire timeout 10000 msecs and lock expiration of 60000 msecs.
     *
     * @param lockKey lock key (ex. account:1, ...)
     */
    public RedisLock(RedisTemplate redisTemplate, String lockKey) {
        this.redisTemplate = redisTemplate;
        this.lockKey = lockKey + "_lock";
    }
    /**
     * Detailed constructor with default lock expiration of 60000 msecs.
     *
     */
    public RedisLock(RedisTemplate redisTemplate, String lockKey, int timeoutMsecs) {
        this(redisTemplate, lockKey);
        this.timeoutMsecs = timeoutMsecs;
    }
    /**
     * Detailed constructor.
     *
     */
    public RedisLock(RedisTemplate redisTemplate, String lockKey, int timeoutMsecs, int expireMsecs) {
        this(redisTemplate, lockKey, timeoutMsecs);
        this.expireMsecs = expireMsecs;
    }
    /**
     * @return lock key
     */
    public String getLockKey() {
        return lockKey;
    }
    private String get(final String key) {
        Object obj = null;
        try {
            obj = redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection) throws DataAccessException {
                    StringRedisSerializer serializer = new StringRedisSerializer();
                    byte[] data = connection.get(serializer.serialize(key));
                    connection.close();
                    if (data == null) {
                        return null;
                    }
                    return serializer.deserialize(data);
                }
            });
        } catch (Exception e) {
            logger.error("get redis error, key : {}", key);
        }
        return obj != null ? obj.toString() : null;
    }
    private boolean setNX(final String key, final String value) {
        Object obj = null;
        try {
            obj = redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection) throws DataAccessException {
                    StringRedisSerializer serializer = new StringRedisSerializer();
                    Boolean success = connection.setNX(serializer.serialize(key), serializer.serialize(value));
                    connection.close();
                    return success;
                }
            });
        } catch (Exception e) {
            logger.error("setNX redis error, key : {}", key);
        }
        return obj != null ? (Boolean) obj : false;
    }
    private String getSet(final String key, final String value) {
        Object obj = null;
        try {
            obj = redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection connection) throws DataAccessException {
                    StringRedisSerializer serializer = new StringRedisSerializer();
                    byte[] ret = connection.getSet(serializer.serialize(key), serializer.serialize(value));
                    connection.close();
                    return serializer.deserialize(ret);
                }
            });
        } catch (Exception e) {
            logger.error("setNX redis error, key : {}", key);
        }
        return obj != null ? (String) obj : null;
    }
    /**
     * 获得 lock.
     * 实现思路: 主要是使用了redis 的setnx命令,缓存了锁.
     * reids缓存的key是锁的key,所有的共享, value是锁的到期时间(注意:这里把过期时间放在value了,没有时间上设置其超时时间)
     * 执行过程:
     * 1.通过setnx尝试设置某个key的值,成功(当前没有这个锁)则返回,成功获得锁
     * 2.锁已经存在则获取锁的到期时间,和当前时间比较,超时的话,则设置新的值
     *
     * @return true if lock is acquired, false acquire timeouted
     * @throws InterruptedException in case of thread interruption
     */
    public synchronized boolean lock() throws InterruptedException {
        int timeout = timeoutMsecs;
        while (timeout >= 0) {
            long expires = System.currentTimeMillis() + expireMsecs + 1;
            //锁到期时间
            String expiresStr = String.valueOf(expires);
            if (this.setNX(lockKey, expiresStr)) {
                // lock acquired
                locked = true;
                return true;
            }
            //redis里的时间
            String currentValueStr = this.get(lockKey);
            if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
                //判断是否为空,不为空的情况下,如果被其他线程设置了值,则第二个条件判断是过不去的
                // lock is expired
                String oldValueStr = this.getSet(lockKey, expiresStr);
                //获取上一个锁到期时间,并设置现在的锁到期时间,
                //只有一个线程才能获取上一个线上的设置时间,因为jedis.getSet是同步的
                if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
                    //防止误删(覆盖,因为key是相同的)了他人的锁——这里达不到效果,这里值会被覆盖,但是因为什么相差了很少的时间,所以可以接受
                    //[分布式的情况下]:如过这个时候,多个线程恰好都到了这里,但是只有一个线程的设置值和当前值相同,他才有权利获取锁
                    // lock acquired
                    locked = true;
                    return true;
                }
            }
            timeout -= DEFAULT_ACQUIRY_RESOLUTION_MILLIS;
            /*
                延迟100 毫秒,  这里使用随机时间可能会好一点,可以防止饥饿进程的出现,即,当同时到达多个进程,
                只会有一个进程获得锁,其他的都用同样的频率进行尝试,后面有来了一些进行,也以同样的频率申请锁,这将可能导致前面来的锁得不到满足.
                使用随机的等待时间可以一定程度上保证公平性
             */
            TimeUnit.MILLISECONDS.sleep(DEFAULT_ACQUIRY_RESOLUTION_MILLIS);
        }
        return false;
    }
    /**
     * Acqurired lock release.
     */
    public synchronized void unlock() {
        if (locked) {
            redisTemplate.delete(lockKey);
            locked = false;
        }
    }
}

+ 59 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/util/threadPool/ThreadPool.java

@ -0,0 +1,59 @@
package com.yihu.jw.base.util.threadPool;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * @author yeshijie on 2018/10/10.
 */
@Configuration
public class ThreadPool {
    /**
     * 线程池核心线程数
     */
    private int CORE_POOL_SIZE = 5;
    /**
     * 线程池最大线程数
     */
    private int MAX_POOL_SIZE = 100;
    /**
     * 额外线程空状态生存时间
     */
    private int KEEP_ALIVE_TIME = 10000;
    /**
     * 额外线程空状态生存时间单位秒
     */
    private TimeUnit unit = TimeUnit.SECONDS;
    /**
     * 阻塞队列。当核心线程都被占用,且阻塞队列已满的情况下,才会开启额外线程。
     */
    private BlockingQueue workQueue = new ArrayBlockingQueue(10);
    /**
     * 线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
     */
    private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
    /**
     * 线程工厂
     */
    private ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "myThreadPool thread:" + integer.getAndIncrement());
        }
    };
    @Bean
    ThreadPoolUtil threadPoolUtil(){
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME,
                unit, workQueue, threadFactory ,rejectedExecutionHandler);
        ThreadPoolUtil threadPoolUtil = new ThreadPoolUtil(threadPool);
        return threadPoolUtil;
    }
}

+ 32 - 0
svr/svr-base/src/main/java/com/yihu/jw/base/util/threadPool/ThreadPoolUtil.java

@ -0,0 +1,32 @@
package com.yihu.jw.base.util.threadPool;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
/**
 * @author yeshijie on 2018/9/30.
 */
public class ThreadPoolUtil {
    /**
     * 线程池
     */
    private ThreadPoolExecutor threadPool;
    public ThreadPoolUtil(ThreadPoolExecutor threadPool) {
        this.threadPool = threadPool;
    }
    public void execute(Runnable runnable) {
        threadPool.execute(runnable);
    }
    public void execute(FutureTask futureTask) {
        threadPool.execute(futureTask);
    }
    public void cancel(FutureTask futureTask) {
        futureTask.cancel(true);
    }
}