Prechádzať zdrojové kódy

通知代码重构与优化

lideyin 6 rokov pred
rodič
commit
bfe31808f6

+ 3 - 3
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/NoticeController.java

@@ -65,7 +65,7 @@ public class NoticeController extends ControllerSupport {
     @ApiOperation(value = "修改通知信息")
     @PostMapping("disposeNotice")
     public void disposeNotice() {
-        noticeService.disposePublishingUserNotice();
+//        noticeService.disposePublishingUserNotice();
     }
 
 
@@ -235,7 +235,7 @@ public class NoticeController extends ControllerSupport {
         if (notice==null){
             throw new StatusException("500013","该通知已不存在,请刷新后重试");
         }
-        if (notice.getNoticeStatus()!= NoticeStatus.CREATION){
+        if (notice.getNoticeStatus()!= NoticeStatus.DRAFT){
             throw new StatusException("500014","该通知状态已变更,请刷新后重试");
         }
     }
@@ -252,7 +252,7 @@ public class NoticeController extends ControllerSupport {
             throw new StatusException("500015","通知id格式不正确",e);
         }
         List<NoticeEntity> noticeList = noticeRepo.findByIdIn(noticeIdList);
-        boolean existPublishingData = noticeList.stream().anyMatch(p->p.getNoticeStatus()==NoticeStatus.PUBLISH);
+        boolean existPublishingData = noticeList.stream().anyMatch(p->p.getNoticeStatus()!=NoticeStatus.DRAFT);
         if (existPublishingData){
             throw new StatusException("500016","通知状态已改变,请刷新后重试");
         }

+ 5 - 4
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/NoticeDomain.java

@@ -7,8 +7,8 @@
 
 package cn.com.qmth.examcloud.core.examwork.api.controller.bean;
 
-import cn.com.qmth.examcloud.api.commons.enums.NoticePublishStatus;
 import cn.com.qmth.examcloud.api.commons.enums.NoticeReceiverRuleType;
+import cn.com.qmth.examcloud.api.commons.enums.NoticeStatus;
 import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -53,7 +53,8 @@ public class NoticeDomain implements JsonSerializable {
      * 发送状态
      */
     @ApiModelProperty("发送状态")
-    private NoticePublishStatus publishStatus;
+    @Enumerated(EnumType.STRING)
+    private NoticeStatus publishStatus;
     /**
      * 规则类型
      */
@@ -120,11 +121,11 @@ public class NoticeDomain implements JsonSerializable {
         this.publishTime = publishTime;
     }
 
-    public NoticePublishStatus getPublishStatus() {
+    public NoticeStatus getPublishStatus() {
         return publishStatus;
     }
 
-    public void setPublishStatus(NoticePublishStatus publishStatus) {
+    public void setPublishStatus(NoticeStatus publishStatus) {
         this.publishStatus = publishStatus;
     }
 }

+ 67 - 15
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/provider/NoticeCloudServiceProvider.java

@@ -1,5 +1,11 @@
 package cn.com.qmth.examcloud.core.examwork.api.provider;
 
+import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeRulePublishProgressEntity;
+import cn.com.qmth.examcloud.examwork.api.bean.NoticeRulePublishProgressBean;
+import cn.com.qmth.examcloud.examwork.api.request.DisposePublishingUserNoticeReq;
+import cn.com.qmth.examcloud.examwork.api.request.UpdateNoticeStatusReq;
+import cn.com.qmth.examcloud.examwork.api.response.DisposePublishingUserNoticeResp;
+import cn.com.qmth.examcloud.examwork.api.response.GetNoticeRulePublishProgressListResp;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -11,6 +17,9 @@ import cn.com.qmth.examcloud.examwork.api.NoticeCloudService;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import io.swagger.annotations.ApiOperation;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * 考试云服务
  *
@@ -23,23 +32,66 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping("${$rmp.cloud.examwork}" + "notice")
 public class NoticeCloudServiceProvider extends ControllerSupport implements NoticeCloudService {
 
-	private static final long serialVersionUID = 4359829563744893206L;
+    private static final long serialVersionUID = 4359829563744893206L;
+
+    @Autowired
+    private NoticeService noticeService;
+
+    @ApiOperation(value = "获取待处理的通知进度数据")
+    @PostMapping("getToBeDisposedNoticeRulePublishProgressList")
+    @Override
+    public GetNoticeRulePublishProgressListResp getToBeDisposedNoticeRulePublishProgressList() {
+        GetNoticeRulePublishProgressListResp resp = new GetNoticeRulePublishProgressListResp();
+        List<NoticeRulePublishProgressEntity> progressEntityList = noticeService.getToBeDisposedNoticeRulePublishProgressList();
+        if (progressEntityList != null && !progressEntityList.isEmpty()) {
+            List<NoticeRulePublishProgressBean> beanList = new ArrayList<>();
+            for (NoticeRulePublishProgressEntity entity : progressEntityList) {
+                NoticeRulePublishProgressBean bean = new NoticeRulePublishProgressBean();
+                bean.setId(entity.getId());
+                bean.setMaxCommonUserId(entity.getMaxCommonUserId());
+                bean.setMaxStudentId(entity.getMaxStudentId());
+                bean.setNoticeId(entity.getNoticeId());
+                bean.setNoticeReceiverRuleType(entity.getNoticeReceiverRuleType());
+                bean.setRootOrgId(entity.getRootOrgId());
+                beanList.add(bean);
+            }
+            resp.setList(beanList);
+        }
+        return resp;
+    }
+
+    @ApiOperation(value = "处理待发布和发布中的数据")
+    @PostMapping("disposePublishingUserNotice")
+    @Override
+    public DisposePublishingUserNoticeResp disposePublishingUserNotice(DisposePublishingUserNoticeReq req) {
+        DisposePublishingUserNoticeResp resp = new DisposePublishingUserNoticeResp();
+        NoticeRulePublishProgressBean processBean = req.getNoticeRulePublishProgress();
+        NoticeRulePublishProgressEntity processEntity = new NoticeRulePublishProgressEntity();
+        processEntity.setId(processBean.getId());
+        processEntity.setMaxCommonUserId(processBean.getMaxCommonUserId());
+        processEntity.setMaxStudentId(processBean.getMaxStudentId());
+        processEntity.setNoticeId(processBean.getNoticeId());
+        processEntity.setNoticeReceiverRuleType(processBean.getNoticeReceiverRuleType());
+        processEntity.setRootOrgId(processBean.getRootOrgId());
+        Long nextUserId = noticeService.disposePublishingUserNotice(req.getStartUserId(),processEntity);
+
 
-	@Autowired
-	private NoticeService noticeService;
+        resp.setNextUserId(nextUserId);
+        return resp;
+    }
 
-	@ApiOperation(value = "处理发布中的用户通知数据")
-	@PostMapping("disposePublishingUserNotice")
-	@Override
-	public void disposePublishingUserNotice() {
-		noticeService.disposePublishingUserNotice();
-	}
+    @ApiOperation(value = "清理过期的通知数据")
+    @PostMapping("disposeOverdueNotice")
+    @Override
+    public void disposeOverdueNotice() {
+        noticeService.disposeOverdueNotice();
+    }
 
-	@ApiOperation(value = "清理过期的通知数据")
-	@PostMapping("disposeOverdueNotice")
-	@Override
-	public void disposeOverdueNotice() {
-		noticeService.disposeOverdueNotice();
-	}
+    @ApiOperation(value = "更新通知状态")
+    @PostMapping("updateNoticeStatus")
+    @Override
+    public void updateNoticeStatus(UpdateNoticeStatusReq updateNoticeStatusReq) {
+        noticeService.updateNoticeStatus(updateNoticeStatusReq.getNoticeId(),updateNoticeStatusReq.getNoticeStatus());
+    }
 
 }

+ 11 - 0
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticeRepo.java

@@ -1,9 +1,13 @@
 package cn.com.qmth.examcloud.core.examwork.dao;
 
+import cn.com.qmth.examcloud.api.commons.enums.NoticeStatus;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeEntity;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.QueryByExampleExecutor;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.Date;
 import java.util.List;
@@ -15,4 +19,11 @@ public interface NoticeRepo extends JpaRepository<NoticeEntity, Long>,
     int deleteByIdIn(List<Long> noticeIdList);
 
     List<NoticeEntity> findByCreationTimeBefore(Date lastYear);
+
+    List<NoticeEntity> findNoticeStatus(NoticeStatus noticeStatus);
+
+    @Transactional
+    @Modifying
+    @Query(value = "update EC_E_NOTICE set notice_status=?2 where id=?1",nativeQuery = true)
+    int updateNoticeStatus(Long noticeId,String noticeStatus);
 }

+ 2 - 6
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticePublishScheduleRepo.java → examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticeRulePublishProgressRepo.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.examcloud.core.examwork.dao;
 
-import cn.com.qmth.examcloud.api.commons.enums.NoticePublishStatus;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeRulePublishProgressEntity;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -11,13 +10,10 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
-public interface NoticePublishScheduleRepo extends JpaRepository<NoticeRulePublishProgressEntity, Long>,
+public interface NoticeRulePublishProgressRepo extends JpaRepository<NoticeRulePublishProgressEntity, Long>,
         QueryByExampleExecutor<NoticeRulePublishProgressEntity>, JpaSpecificationExecutor<NoticeRulePublishProgressEntity> {
-    List<NoticeRulePublishProgressEntity> findByRootOrgIdAndPublishStatus(Long rootOrgId, NoticePublishStatus publishStatus);
 
-    NoticeRulePublishProgressEntity findByRootOrgIdAndNoticeId(Long rootOrgId,Long noticeId);
-
-    List<NoticeRulePublishProgressEntity> findByPublishStatus(NoticePublishStatus publishStatus);
+    List<NoticeRulePublishProgressEntity> findByNoticeIdIn(List<Long> noticeIdList);
 
     @Transactional
     @Modifying

+ 16 - 1
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/NoticeService.java

@@ -7,6 +7,7 @@
 
 package cn.com.qmth.examcloud.core.examwork.service;
 
+import cn.com.qmth.examcloud.api.commons.enums.NoticeStatus;
 import cn.com.qmth.examcloud.api.commons.exchange.PageInfo;
 import cn.com.qmth.examcloud.api.commons.security.bean.UserType;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeRulePublishProgressEntity;
@@ -76,14 +77,28 @@ public interface NoticeService {
 	 */
 	NoticeRulePublishProgressEntity updateNotice(UpdateNoticeInfo info);
 
+	/**
+	 * 获取待处理的通知规则发布进度集合
+	 * @return
+	 */
+    List<NoticeRulePublishProgressEntity> getToBeDisposedNoticeRulePublishProgressList();
+
 	/**
 	 * 处理待发送的用户通知(自动服务调用)
+	 * @param startUserId
+	 * @return 下次请求的用户id
 	 */
-	void disposePublishingUserNotice();
+	Long disposePublishingUserNotice(Long startUserId,NoticeRulePublishProgressEntity rulePublishProcess);
 
 	/**
 	 * 处理过期的通知数据(自动服务调用)
 	 */
 	void disposeOverdueNotice();
 
+	/**
+	 * 更新通知状态
+	 * @param noticeId
+	 * @param noticeStatus
+	 */
+	void updateNoticeStatus(Long noticeId, NoticeStatus noticeStatus);
 }

+ 11 - 11
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/NoticeInfo.java

@@ -7,18 +7,17 @@
 
 package cn.com.qmth.examcloud.core.examwork.service.bean;
 
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-
-import cn.com.qmth.examcloud.api.commons.enums.NoticePublishStatus;
 import cn.com.qmth.examcloud.api.commons.enums.NoticeReceiverRuleType;
+import cn.com.qmth.examcloud.api.commons.enums.NoticeStatus;
 import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
 import io.swagger.annotations.ApiModelProperty;
 
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 考试分数信息
  *
@@ -63,7 +62,8 @@ public class NoticeInfo implements JsonSerializable {
 	 * 发送状态
 	 */
 	@ApiModelProperty("发送状态")
-	private NoticePublishStatus publishStatus;
+	@Enumerated(EnumType.STRING)
+	private NoticeStatus publishStatus;
 
 	/**
 	 * 规则类型
@@ -132,11 +132,11 @@ public class NoticeInfo implements JsonSerializable {
 		this.publishTime = publishTime;
 	}
 
-	public NoticePublishStatus getPublishStatus() {
+	public NoticeStatus getPublishStatus() {
 		return publishStatus;
 	}
 
-	public void setPublishStatus(NoticePublishStatus publishStatus) {
+	public void setPublishStatus(NoticeStatus publishStatus) {
 		this.publishStatus = publishStatus;
 	}
 }

+ 8 - 4
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/NoticeInfoQuery.java

@@ -7,11 +7,14 @@
 
 package cn.com.qmth.examcloud.core.examwork.service.bean;
 
-import cn.com.qmth.examcloud.api.commons.enums.NoticePublishStatus;
+import cn.com.qmth.examcloud.api.commons.enums.NoticeStatus;
 import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+
 /**
  * 公告查询类
  */
@@ -37,7 +40,8 @@ public class NoticeInfoQuery implements JsonSerializable {
      * 发送状态
      */
     @ApiModelProperty("发送状态")
-    private NoticePublishStatus publishStatus;
+    @Enumerated(EnumType.STRING)
+    private NoticeStatus publishStatus;
 
     public Long getRootOrgId() {
         return rootOrgId;
@@ -63,11 +67,11 @@ public class NoticeInfoQuery implements JsonSerializable {
         this.title = title;
     }
 
-    public NoticePublishStatus getPublishStatus() {
+    public NoticeStatus getPublishStatus() {
         return publishStatus;
     }
 
-    public void setPublishStatus(NoticePublishStatus publishStatus) {
+    public void setPublishStatus(NoticeStatus publishStatus) {
         this.publishStatus = publishStatus;
     }
 }

+ 683 - 810
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/impl/NoticeServiceImpl.java

@@ -1,33 +1,5 @@
 package cn.com.qmth.examcloud.core.examwork.service.impl;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.Predicate;
-
-import org.apache.commons.lang.time.DateUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.mysql.cj.util.StringUtils;
-
-import cn.com.qmth.examcloud.api.commons.enums.NoticePublishStatus;
 import cn.com.qmth.examcloud.api.commons.enums.NoticeReceiverRuleType;
 import cn.com.qmth.examcloud.api.commons.enums.NoticeStatus;
 import cn.com.qmth.examcloud.api.commons.exchange.PageInfo;
@@ -38,25 +10,10 @@ import cn.com.qmth.examcloud.commons.util.DBUtil;
 import cn.com.qmth.examcloud.core.basic.api.UserCloudService;
 import cn.com.qmth.examcloud.core.basic.api.request.GetAllUsersByRoleReq;
 import cn.com.qmth.examcloud.core.basic.api.response.GetAllUsersByRoleResp;
-import cn.com.qmth.examcloud.core.examwork.dao.ExamRepo;
-import cn.com.qmth.examcloud.core.examwork.dao.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.examwork.dao.NoticePublishScheduleRepo;
-import cn.com.qmth.examcloud.core.examwork.dao.NoticeReceiverRuleRepo;
-import cn.com.qmth.examcloud.core.examwork.dao.NoticeRepo;
-import cn.com.qmth.examcloud.core.examwork.dao.UserNoticeRepo;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamEntity;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeEntity;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeRulePublishProgressEntity;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeReceiverRuleEntity;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.UserNoticeEntity;
+import cn.com.qmth.examcloud.core.examwork.dao.*;
+import cn.com.qmth.examcloud.core.examwork.dao.entity.*;
 import cn.com.qmth.examcloud.core.examwork.service.NoticeService;
-import cn.com.qmth.examcloud.core.examwork.service.bean.AddNoticeInfo;
-import cn.com.qmth.examcloud.core.examwork.service.bean.GetLimitUserIdResp;
-import cn.com.qmth.examcloud.core.examwork.service.bean.NoticeInfo;
-import cn.com.qmth.examcloud.core.examwork.service.bean.NoticeInfoQuery;
-import cn.com.qmth.examcloud.core.examwork.service.bean.UpdateNoticeInfo;
-import cn.com.qmth.examcloud.core.examwork.service.bean.UserNoticeInfo;
-import cn.com.qmth.examcloud.core.examwork.service.bean.UserNoticeInfoQuery;
+import cn.com.qmth.examcloud.core.examwork.service.bean.*;
 import cn.com.qmth.examcloud.marking.api.MarkWorkCloudService;
 import cn.com.qmth.examcloud.marking.api.bean.MarkWorkMainBean;
 import cn.com.qmth.examcloud.marking.api.request.GetMarkWorkMainByIdsReq;
@@ -65,6 +22,19 @@ import cn.com.qmth.examcloud.marking.api.response.GetMarkWorkMainByIdsResp;
 import cn.com.qmth.examcloud.marking.api.response.GetMarkersByWorkIdsResp;
 import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
 import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
+import com.mysql.cj.util.StringUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.persistence.criteria.Predicate;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Description 通知实现类
@@ -74,769 +44,672 @@ import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
  */
 @Service("noticeService")
 public class NoticeServiceImpl implements NoticeService {
-	@Autowired
-	private NoticeRepo noticeRepo;
-
-	@Autowired
-	private UserNoticeRepo userNoticeRepo;
-
-	@Autowired
-	private NoticePublishScheduleRepo noticePublishScheduleRepo;
-
-	@Autowired
-	private NoticeReceiverRuleRepo noticeReceiverRuleRepo;
-
-	@Autowired
-	private ExamRepo examRepo;
-
-	@Autowired
-	MarkWorkCloudService markWorkCloudService;
-
-	@Autowired
-	ExamStudentRepo examStudentRepo;
-
-	@Autowired
-	UserCloudService userCloudService;
-
-	private static final Log log = LogFactory.getLog(NoticeServiceImpl.class);
-
-	@Override
-	public List<UserNoticeInfo> getNoticeList(UserNoticeInfoQuery query) {
-		List<UserNoticeInfo> resultList = new ArrayList<>();
-		List<UserNoticeEntity> userNoticeList;
-		if (query.getHasRead() != null) {
-			userNoticeList = userNoticeRepo
-					.findByRootOrgIdAndUserTypeAndUserIdAndHasReadOrderByCreationTimeDesc(
-							query.getRootOrgId(), query.getUserType(), query.getUserId(),
-							query.getHasRead());
-		} else {
-			userNoticeList = userNoticeRepo
-					.findByRootOrgIdAndUserTypeAndUserIdOrderByCreationTimeDesc(
-							query.getRootOrgId(), query.getUserType(), query.getUserId());
-		}
-		if (null != userNoticeList && !userNoticeList.isEmpty()) {
-			List<Long> noticeIdList = userNoticeList.stream().map(UserNoticeEntity::getNoticeId)
-					.collect(Collectors.toList());
-			List<NoticeEntity> noticeList = noticeRepo.findByIdIn(noticeIdList);
-			for (UserNoticeEntity un : userNoticeList) {
-				NoticeEntity noticeEntity = getNoticeById(noticeList, un.getNoticeId());
-				if (noticeEntity == null) {
-					throw new StatusException("501005", "找不到id为:" + un.getNoticeId() + "的通知");
-				}
-				UserNoticeInfo info = new UserNoticeInfo();
-				info.setId(noticeEntity.getId());
-				info.setTitle(noticeEntity.getTitle());
-				info.setContent(noticeEntity.getContent());
-				info.setPublisher(noticeEntity.getPublisher());
-				info.setPublishTime(noticeEntity.getPublishTime());
-				info.setHasRead(un.getHasRead());
-				resultList.add(info);
-			}
-		}
-		return resultList;
-	}
-
-	@Override
-	public int updateNoticeReadStatus(String noticeId, UserType userType, Long userId) {
-		List<Long> noticeIdList;
-		if (noticeId.contains(",")) {
-			noticeIdList = Arrays.asList(noticeId.split(",")).stream().map(p -> Long.parseLong(p))
-					.collect(Collectors.toList());
-		} else {
-			noticeIdList = Arrays.asList(noticeId).stream().map(p -> Long.parseLong(p))
-					.collect(Collectors.toList());
-		}
-		return userNoticeRepo.updateNoticeReadStatus(noticeIdList, userType.toString(), userId);
-	}
-
-	@Override
-	public PageInfo<NoticeInfo> getPagedNoticeList(Integer curPage, Integer pageSize,
-			NoticeInfoQuery infoQuery) {
-		List<NoticeInfo> resultList = new ArrayList<>();
-		Long rootOrgId = infoQuery.getRootOrgId();
-		Specification<NoticeEntity> specification = (root, query, cb) -> {
-			List<Predicate> predicates = new ArrayList<>();
-			predicates.add(cb.equal(root.get("rootOrgId"), rootOrgId));
-			if (!StringUtils.isNullOrEmpty(infoQuery.getTitle())) {
-				predicates.add(cb.like(root.get("title"),
-						DBUtil.toSqlSearchPattern(infoQuery.getTitle())));
-			}
-			if (null != infoQuery.getPublishStatus()) {
-				List<NoticeRulePublishProgressEntity> byPublishStatusNoticeScheduleList = noticePublishScheduleRepo
-						.findByRootOrgIdAndPublishStatus(rootOrgId, infoQuery.getPublishStatus());
-				if (null == byPublishStatusNoticeScheduleList
-						|| byPublishStatusNoticeScheduleList.isEmpty()) {
-					throw new StatusException("501001", "通知发布状态数据异常");
-				}
-				// 获取相应发布状态的通知id集合
-				List<Long> noticeIdList = byPublishStatusNoticeScheduleList.stream()
-						.map(NoticeRulePublishProgressEntity::getNoticeId).collect(Collectors.toList());
-				CriteriaBuilder.In<Object> inCriteriaBuilder = cb.in(root.get("id"));
-				for (Long nid : noticeIdList) {
-					inCriteriaBuilder.value(nid);
-				}
-				predicates.add(inCriteriaBuilder);
-			}
-
-			return cb.and(predicates.toArray(new Predicate[predicates.size()]));
-		};
-		PageRequest pageRequest = PageRequest.of(curPage, pageSize,
-				new Sort(Sort.Direction.DESC, "creationTime"));
-		Page<NoticeEntity> pagedNoticeEntityList = noticeRepo.findAll(specification, pageRequest);
-		List<Long> noticeIdList = pagedNoticeEntityList.stream().map(p -> p.getId())
-				.collect(Collectors.toList());
-		List<NoticeReceiverRuleEntity> ruleList = getReceiverRuleList(rootOrgId,
-				noticeIdList.toArray(new Long[noticeIdList.size()]));
-
-		for (NoticeEntity ne : pagedNoticeEntityList) {
-			NoticeReceiverRuleType ruleType = getNoticeReceiverRuleType(ne.getId(), ruleList);
-			NoticeInfo ni = new NoticeInfo();
-			ni.setId(ne.getId());
-			ni.setPublisher(ne.getPublisher());
-			ni.setPublishTime(ne.getPublishTime());
-			ni.setTitle(ne.getTitle());
-			ni.setContent(ne.getContent());
-			ni.setPublishObject(getPublishObject(rootOrgId, ruleType, ruleList));
-			ni.setPublishStatus(getNoticePublishStatus(rootOrgId, ne));
-			ni.setRuleType(ruleType);
-			resultList.add(ni);
-		}
-		return new PageInfo<>(pagedNoticeEntityList, resultList);
-
-	}
-
-	@Transactional
-	@Override
-	public int deleteNotice(Long rootOrgId, List<Long> noticeIdList) {
-		int result = 0;
-		// 删除通知进度相关信息
-		result += noticePublishScheduleRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
-		// 删除通知规则相关信息
-		result += noticeReceiverRuleRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
-		// 删除通知相关信息
-		result += noticeRepo.deleteByIdIn(noticeIdList);
-		return result;
-	}
-
-	@Transactional
-	@Override
-	public int addNotice(AddNoticeInfo addNoticeInfo) {
-		// 保存公告基本信息
-		NoticeEntity noticeEntity = getNoticeEntityFrom(addNoticeInfo);
-		NoticeEntity savedNotice = noticeRepo.save(noticeEntity);
-
-		Long noticeId = savedNotice.getId();
-
-		// 保存公告接收规则
-		List<NoticeReceiverRuleEntity> ruleList = getNoticeReceiverRuleEntityListFrom(addNoticeInfo,
-				noticeId);
-		noticeReceiverRuleRepo.saveAll(ruleList);
-
-		// 保存公告发布进度
-		NoticeRulePublishProgressEntity publishScheduleEntity = getNoticePublishScheduleEntityFrom(
-				addNoticeInfo, noticeId);
-		noticePublishScheduleRepo.save(publishScheduleEntity);
-
-		return noticeId > 0 ? 1 : 0;
-
-	}
-
-	@Transactional
-	@Override
-	public NoticeRulePublishProgressEntity updateNotice(UpdateNoticeInfo info) {
-		Long rootOrgId = info.getRootOrgId();
-		List<Long> noticeIdList = Collections.singletonList(info.getId());
-		// 校验通知状态,正在发送的通知不允许修改
-		NoticeRulePublishProgressEntity publishSchedule = noticePublishScheduleRepo
-				.findByRootOrgIdAndNoticeId(info.getRootOrgId(), info.getId());
-		if (publishSchedule == null) {
-			throw new StatusException("501007", "找不到通知id为:" + info.getId() + "的通知进度数据");
-		}
-		if (publishSchedule.getPublishStatus() != NoticePublishStatus.UNPUBLISHED) {
-			throw new StatusException("501008", "发布中或已发布的通知不允许修改");
-		}
-
-		// 更新通知表
-		NoticeEntity originalNotice = GlobalHelper.getEntity(noticeRepo, info.getId(),
-				NoticeEntity.class);
-		if (originalNotice == null) {
-			throw new StatusException("501006", "找不到通知id为:" + info.getId() + "的数据");
-		}
-		originalNotice.setTitle(info.getTitle());
-		originalNotice.setPublisher(info.getPublisher());
-		originalNotice.setNoticeStatus(info.getNoticeStatus());
-		if (info.getNoticeStatus() == NoticeStatus.PUBLISH) {
-			originalNotice.setPublishTime(new Date());
-		}
-		originalNotice.setContent(info.getContent());
-		originalNotice.setUpdateTime(new Date());
-		noticeRepo.save(originalNotice);
-
-		// 更新公告接收规则实体
-		noticeReceiverRuleRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
-		List<NoticeReceiverRuleEntity> ruleList = getNoticeReceiverRuleEntityListFrom(info);
-		noticeReceiverRuleRepo.saveAll(ruleList);
-
-		// 更新公告发布进度实体
-		noticePublishScheduleRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
-		NoticeRulePublishProgressEntity publishScheduleEntity = getNoticePublishScheduleEntityFrom(
-				info);
-		NoticeRulePublishProgressEntity saved = noticePublishScheduleRepo.save(publishScheduleEntity);
-
-		return saved;
-	}
-
-	@Override
-	public void disposePublishingUserNotice() {
-		List<NoticeRulePublishProgressEntity> publishingScheduleList = noticePublishScheduleRepo
-				.findByPublishStatus(NoticePublishStatus.PUBLISHING);
-		// 如果没有状态为发布中的数据,则直接返回
-		if (publishingScheduleList == null || publishingScheduleList.isEmpty()) {
-			return;
-		}
-		// 发布通知每次处理的用户id数量 // TODO: 2019/7/10 需要将参数放到配置文件
-		int rowNumber = PropertyHolder.getInt("notice.dispose.userId.size", 100);
-		for (NoticeRulePublishProgressEntity publishSchedule : publishingScheduleList) {
-			Long rootOrgId = publishSchedule.getRootOrgId();
-			Long noticeId = publishSchedule.getNoticeId();
-			List<NoticeReceiverRuleEntity> ruleList = getReceiverRuleList(rootOrgId, noticeId);
-
-			// 按通知对象的类型进行分组
-			Map<NoticeReceiverRuleType, List<NoticeReceiverRuleEntity>> groupedRuleMap = ruleList
-					.stream().collect(Collectors.groupingBy(p -> p.getRuleType()));
-			Set<NoticeReceiverRuleType> groupRuleMapKeySet = groupedRuleMap.keySet();
-			// 目前的业务是一个通知只能发给一种规则类型,代码为了兼容,先写成支持多种
-			for (NoticeReceiverRuleType ruleType : groupRuleMapKeySet) {
-				Long lastMaxUserId = getLastMaxUserId(ruleType, publishSchedule);
-				long startUserId = 0;
-				if (lastMaxUserId != null) {
-					startUserId = lastMaxUserId + 1;
-				}
-				List<NoticeReceiverRuleEntity> currentRuleList = groupedRuleMap.get(ruleType);
-
-				try {
-					// 递归添加通知用户
-					batchAddUserNotice(rootOrgId, noticeId, rowNumber, startUserId, ruleType,
-							currentRuleList, publishSchedule);
-				} catch (Exception e) {
-					// 特殊处理:此处为了不影响自动服务的其它正常数据,所以吃掉了异常
-					log.error("[DISPOSE-NOTICE]:处理用户通知任务出现异常,rootOrgId=" + rootOrgId + ",noticeId="
-							+ noticeId, e);
-				}
-			}
-
-		}
-
-	}
-
-	@Override
-	public void disposeOverdueNotice() {
-		// 通知过期年限阈值// TODO: 2019/7/10
-		int overdueYearThreshold = PropertyHolder.getInt("notice.dispose.overdue.year", 1);
-		Date now = new Date();
-		Date lastYear = DateUtils.addYears(now, -overdueYearThreshold);
-		List<NoticeEntity> overdueNoticeList = noticeRepo.findByCreationTimeBefore(lastYear);
-		if (overdueNoticeList != null && !overdueNoticeList.isEmpty()) {
-			for (NoticeEntity notice : overdueNoticeList) {
-				deleteAllRelatedNotice(notice.getId());
-			}
-		}
-
-	}
-
-	/**
-	 * 删除所有相关的通知数据
-	 *
-	 * @param noticeId
-	 */
-	@Transactional
-	public void deleteAllRelatedNotice(Long noticeId) {
-		userNoticeRepo.deleteByNoticeId(noticeId);
-		noticeReceiverRuleRepo.deleteByNoticeId(noticeId);
-		noticePublishScheduleRepo.deleteByNoticeId(noticeId);
-		noticeRepo.deleteById(noticeId);
-	}
-
-	/**
-	 * 递归调用批量处理方法 TODO 此方法需要保证事务互不影响,待确认
-	 *
-	 * @param rootOrgId
-	 * @param noticeId
-	 * @param rowNumber
-	 *            目前只支持100行
-	 * @param startUserId
-	 * @param publishSchedule
-	 */
-	private void batchAddUserNotice(Long rootOrgId, Long noticeId, int rowNumber, Long startUserId,
-			NoticeReceiverRuleType ruleType, List<NoticeReceiverRuleEntity> ruleList,
-			NoticeRulePublishProgressEntity publishSchedule) {
-		if (rowNumber < 1) {
-			throw new StatusException("501010", "读取的数据行数不得少于1行");
-		}
-		GetLimitUserIdResp getLimitUserIdResp = getSpecifiedUserIdList(rootOrgId, rowNumber,
-				startUserId, ruleType, ruleList);
-		Long nextId = getLimitUserIdResp.getNextId();
-		Long maxUserId = getLimitUserIdResp.getMaxId();
-		// 满足条件的用户id集合(可能为空)
-		List<Long> limitStudentIdList = getLimitUserIdResp.getIdList();
-
-		// 如果起始id和方法返回的下次查询id相同,说明数据已经取完,否则继续查询
-		if (startUserId.equals(nextId)) {
-			finishNoticePublishSchedule(publishSchedule);
-		} else {
-			saveUserNoticeAndUpdatePublishSchedule(rootOrgId, noticeId, ruleType, publishSchedule,
-					limitStudentIdList, maxUserId);
-			batchAddUserNotice(rootOrgId, noticeId, rowNumber, nextId, ruleType, ruleList,
-					publishSchedule);
-		}
-	}
-
-	/**
-	 * 更新发布进度
-	 *
-	 * @param publishSchedule
-	 * @param maxUserId
-	 */
-	@Transactional
-	void saveUserNoticeAndUpdatePublishSchedule(Long rootOrgId, Long noticeId,
-			NoticeReceiverRuleType ruleType, NoticeRulePublishProgressEntity publishSchedule,
-			List<Long> limitStudentIdList, Long maxUserId) {
-		// 保存并更新发布状态为发布完成
-		List<UserNoticeEntity> userNoticeList = new ArrayList<>();
-		for (Long userId : limitStudentIdList) {
-			UserNoticeEntity userNotice = initUserNoticeEntity(rootOrgId, userId, noticeId,
-					ruleType);
-			userNoticeList.add(userNotice);
-		}
-		userNoticeRepo.saveAll(userNoticeList);
-		publishSchedule.setMaxStudentId(maxUserId);
-		noticePublishScheduleRepo.save(publishSchedule);
-	}
-
-	/**
-	 * 最终完成发布状态
-	 *
-	 * @param rootOrgId
-	 * @param noticeId
-	 * @param ruleType
-	 * @param publishSchedule
-	 * @param limitStudentIdList
-	 */
-	private void finishNoticePublishSchedule(NoticeRulePublishProgressEntity publishSchedule) {
-		publishSchedule.setPublishStatus(NoticePublishStatus.PUBLISHED);
-		noticePublishScheduleRepo.save(publishSchedule);
-	}
-
-	/**
-	 * 获取指定数量的考试记录id
-	 *
-	 * @param rootOrgId
-	 *            组织机构id
-	 * @param rowNumber
-	 *            获取的行数
-	 * @param startUserId
-	 *            起始用户id
-	 * @param ruleType
-	 *            通知对象规则类型
-	 * @param ruleList
-	 *            当前规则类型下对应的规则明细
-	 * @return 返回用户id集合, 和下一次请求id
-	 */
-	private GetLimitUserIdResp getSpecifiedUserIdList(Long rootOrgId, int rowNumber,
-			Long startUserId, NoticeReceiverRuleType ruleType,
-			List<NoticeReceiverRuleEntity> ruleList) {
-		GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
-		List<Long> limitUserIdList = null;
-		long nextUserId = 0;
-		switch (ruleType) {
-			case TEACHER_OF_MARK_WORK :
-				return getGetLimitUserIdByMarkWork(rootOrgId, rowNumber, startUserId, ruleList);
-			case COMMON_USERS_OF_ROLE :
-				return getGetLimitUserIdByRole(rootOrgId, startUserId);
-			case STUDENTS_OF_EXAM :
-				return getLimitUserIdByExamStudent(rootOrgId, startUserId, rowNumber, ruleList);
-			case ALL_STUDENTS_OF_ROOT_ORG :
-				return getLimitUserIdByAllStudent(rootOrgId, rowNumber, startUserId);
-		}
-		resultResp.setNextId(nextUserId);
-		resultResp.setIdList(limitUserIdList);
-		return resultResp;
-	}
-
-	private GetLimitUserIdResp getGetLimitUserIdByMarkWork(Long rootOrgId, int rowNumber,
-			Long startUserId, List<NoticeReceiverRuleEntity> ruleList) {
-		GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
-		// 获取当前规则下所有问卷工作id
-		List<Long> markWorkIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
-				.collect(Collectors.toList());
-		GetMarkersByWorkIdsReq markWorkerReq = new GetMarkersByWorkIdsReq();
-		markWorkerReq.setRootOrgId(rootOrgId);
-		markWorkerReq.setWorkIds(markWorkIdList);
-		markWorkerReq.setStarId(startUserId);
-		markWorkerReq.setSize(rowNumber);
-		// FIXME: 2019/7/11
-		GetMarkersByWorkIdsResp markWorkerResp = markWorkCloudService
-				.getMarkersByWorkIds(markWorkerReq);
-		List<Long> limitUserIdList = markWorkerResp.getMarkers();
-		if (markWorkerResp.getMarkers() != null && !markWorkerResp.getMarkers().isEmpty()) {
-			resultResp.setMaxId(Collections.max(limitUserIdList));
-		}
-		resultResp.setNextId(markWorkerResp.getNextId());
-		resultResp.setIdList(markWorkerResp.getMarkers());
-		return resultResp;
-	}
-
-	private GetLimitUserIdResp getGetLimitUserIdByRole(Long rootOrgId, Long startUserId) {
-		GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
-		List<Long> limitUserIdList = new ArrayList<>();
-		long nextUserId;// 当前需求只有考试中心
-		GetAllUsersByRoleReq getLcUserReq = new GetAllUsersByRoleReq();
-		getLcUserReq.setRootOrgId(rootOrgId);
-		getLcUserReq.setRoleCode(RoleMeta.LC_USER.toString());
-		getLcUserReq.setStart(startUserId);
-		GetAllUsersByRoleResp getLcUserResp = userCloudService.getAllUsersByRole(getLcUserReq);
-		nextUserId = getLcUserResp.getNext();
-		if (getLcUserResp.getUserBeanList() != null && !getLcUserResp.getUserBeanList().isEmpty()) {
-			limitUserIdList = getLcUserResp.getUserBeanList().stream().map(p -> p.getUserId())
-					.collect(Collectors.toList());
-			resultResp.setMaxId(Collections.max(limitUserIdList));
-		}
-		resultResp.setNextId(nextUserId);
-		resultResp.setIdList(limitUserIdList);
-		return resultResp;
-	}
-
-	private GetLimitUserIdResp getLimitUserIdByAllStudent(Long rootOrgId, int rowNumber,
-			Long startUserId) {
-		GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
-		long nextId = startUserId;
-		Long maxUserId = null;
-		List<Long> limitUserIdList = examStudentRepo.findLimitStudentIdList(rootOrgId, startUserId,
-				rowNumber);
-		if (limitUserIdList != null && !limitUserIdList.isEmpty()) {
-			maxUserId = Collections.max(limitUserIdList);
-			nextId = maxUserId;
-		}
-		if (nextId != startUserId) {
-			nextId++;
-		}
-		resultResp.setNextId(nextId);
-		resultResp.setMaxId(maxUserId);
-		resultResp.setIdList(limitUserIdList);
-		return resultResp;
-	}
-
-	private GetLimitUserIdResp getLimitUserIdByExamStudent(Long rootOrgId, Long startUserId,
-			int rowNumber, List<NoticeReceiverRuleEntity> ruleList) {
-		GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
-		// 获取当前规则下所有的考试批次id
-		List<Long> examIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
-				.collect(Collectors.toList());
-		long nextId = startUserId;
-		Long maxUserId = null;
-		List<Long> limitUserIdList = examStudentRepo.findByExamIdLimitStudentIdList(rootOrgId,
-				examIdList, startUserId, rowNumber);
-		if (limitUserIdList != null && !limitUserIdList.isEmpty()) {
-			maxUserId = Collections.max(limitUserIdList);
-			nextId = maxUserId;
-		}
-		if (nextId != startUserId) {
-			nextId++;
-		}
-		resultResp.setMaxId(maxUserId);
-		resultResp.setNextId(nextId);
-		resultResp.setIdList(limitUserIdList);
-		return resultResp;
-	}
-
-	private UserNoticeEntity initUserNoticeEntity(Long rootOrgId, Long userId, Long noticeId,
-			NoticeReceiverRuleType ruleType) {
-		UserType userType = (ruleType == NoticeReceiverRuleType.STUDENTS_OF_EXAM
-				|| ruleType == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG)
-						? UserType.STUDENT
-						: UserType.COMMON;
-		UserNoticeEntity userNotice = new UserNoticeEntity();
-		userNotice.setRootOrgId(rootOrgId);
-		userNotice.setHasRead(false);
-		userNotice.setNoticeId(noticeId);
-		userNotice.setUserType(userType);
-		userNotice.setUserId(userId);
-		return userNotice;
-	}
-
-	/**
-	 * 获取上次更新的最大用户id
-	 *
-	 * @param ruleType
-	 * @param publishSchedule
-	 * @return
-	 */
-	private Long getLastMaxUserId(NoticeReceiverRuleType ruleType,
-			NoticeRulePublishProgressEntity publishSchedule) {
-		if (ruleType == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG
-				|| ruleType == NoticeReceiverRuleType.STUDENTS_OF_EXAM) {
-			return publishSchedule.getMaxStudentId();
-		} else {
-			return publishSchedule.getMaxCommonUserId();
-		}
-	}
-
-	/**
-	 * 获取通知的发布状态
-	 *
-	 * @param rootOrgId
-	 * @param ne
-	 * @return 发布状态枚举
-	 */
-	private NoticePublishStatus getNoticePublishStatus(Long rootOrgId, NoticeEntity ne) {
-		NoticeRulePublishProgressEntity publishSchedule = noticePublishScheduleRepo
-				.findByRootOrgIdAndNoticeId(rootOrgId, ne.getId());
-
-		if (publishSchedule == null) {
-			throw new StatusException("501003", "未找到发布进度相关信息");
-		}
-		return publishSchedule.getPublishStatus();
-	}
-
-	/**
-	 * 获取发布对象
-	 *
-	 * @param rootOrgId
-	 * @param noticeId
-	 * @return
-	 */
-	private List<Map<String, Object>> getPublishObject(Long rootOrgId,
-			NoticeReceiverRuleType ruleType, List<NoticeReceiverRuleEntity> ruleList) {
-		List<Map<String, Object>> resultList = new ArrayList<>();
-		Map<String, Object> objectMap;
-		List<NoticeReceiverRuleEntity> currentRuleList;
-		switch (ruleType) {
-			case STUDENTS_OF_EXAM :
-				currentRuleList = ruleList.stream().filter(p -> p.getRuleType() == ruleType)
-						.collect(Collectors.toList());
-				return getExamStudentObject(currentRuleList);
-			case ALL_STUDENTS_OF_ROOT_ORG :
-				objectMap = new HashMap<>();
-				objectMap.put("id", 0);
-				objectMap.put("name", "所有学生");
-				objectMap.put("ruleType", "ALL_STUDENTS_OF_ROOT_ORG");
-				resultList.add(objectMap);
-				return resultList;
-			case COMMON_USERS_OF_ROLE :
-				objectMap = new HashMap<>();
-				objectMap.put("id", 0);
-				objectMap.put("name", "所有学习中心用户");
-				objectMap.put("ruleType", "COMMON_USERS_OF_ROLE");
-				resultList.add(objectMap);
-				return resultList;
-			case TEACHER_OF_MARK_WORK :
-				currentRuleList = ruleList.stream().filter(p -> p.getRuleType() == ruleType)
-						.collect(Collectors.toList());
-				return getMarkTeacherObject(rootOrgId, currentRuleList);
-		}
-		return resultList;
-	}
-
-	/**
-	 * 组装学生发布对象
-	 *
-	 * @param ruleList
-	 * @return
-	 */
-	private List<Map<String, Object>> getExamStudentObject(
-			List<NoticeReceiverRuleEntity> ruleList) {
-		List<Map<String, Object>> resultList = new ArrayList<>();
-		// 考试批次id
-		List<Long> examIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
-				.collect(Collectors.toList());
-		List<ExamEntity> examList = examRepo.findByIdIn(examIdList);
-		for (ExamEntity e : examList) {
-			Map<String, Object> map = new HashMap<>();
-			map.put("id", e.getId());
-			map.put("name", "学生-" + e.getName());
-			map.put("ruleType", "STUDENTS_OF_EXAM");
-			resultList.add(map);
-		}
-		return resultList;
-	}
-
-	/**
-	 * 组装阅卷老师发布对象
-	 *
-	 * @param rootOrgId
-	 * @param ruleList
-	 * @return
-	 */
-	private List<Map<String, Object>> getMarkTeacherObject(Long rootOrgId,
-			List<NoticeReceiverRuleEntity> ruleList) {
-		List<Map<String, Object>> resultList = new ArrayList<>();
-		List<Long> markWorkIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
-				.collect(Collectors.toList());
-		GetMarkWorkMainByIdsReq req = new GetMarkWorkMainByIdsReq();
-		req.setRootOrgId(rootOrgId);
-		req.setWorkIds(markWorkIdList);
-
-		GetMarkWorkMainByIdsResp markWorkResp = markWorkCloudService.getMarkWorkMainByIds(req);
-		List<MarkWorkMainBean> markWorkList = markWorkResp.getList();
-		for (MarkWorkMainBean mw : markWorkList) {
-			Map<String, Object> map = new HashMap<>();
-			map.put("id", mw.getId());
-			map.put("name", "老师-" + mw.getName());
-			map.put("ruleType", "TEACHER_OF_MARK_WORK");
-			resultList.add(map);
-		}
-		return resultList;
-	}
-
-	/**
-	 * 根据通知id获取通知
-	 *
-	 * @param noticeList
-	 * @param noticeId
-	 * @return
-	 */
-	private NoticeEntity getNoticeById(List<NoticeEntity> noticeList, Long noticeId) {
-		Optional<NoticeEntity> optional = noticeList.stream()
-				.filter(p -> p.getId().equals(noticeId)).findFirst();
-		if (optional.isPresent()) {
-			return optional.get();
-		} else {
-			return null;
-		}
-	}
-
-	private NoticeRulePublishProgressEntity getNoticePublishScheduleEntityFrom(
-			AddNoticeInfo addNoticeInfo, Long noticeId) {
-		NoticeRulePublishProgressEntity publishScheduleEntity = new NoticeRulePublishProgressEntity();
-		publishScheduleEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
-		publishScheduleEntity.setNoticeId(noticeId);
-		if (addNoticeInfo.getNoticeStatus() == NoticeStatus.PUBLISH) {
-			publishScheduleEntity.setPublishStatus(NoticePublishStatus.PUBLISHING);
-		} else {
-			publishScheduleEntity.setPublishStatus(NoticePublishStatus.UNPUBLISHED);
-		}
-		return publishScheduleEntity;
-	}
-
-	private NoticeEntity getNoticeEntityFrom(AddNoticeInfo addNoticeInfo) {
-		NoticeEntity noticeEntity = new NoticeEntity();
-		noticeEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
-		noticeEntity.setTitle(addNoticeInfo.getTitle());
-		noticeEntity.setContent(addNoticeInfo.getContent());
-		noticeEntity.setNoticeStatus(addNoticeInfo.getNoticeStatus());
-		noticeEntity.setPublisher(addNoticeInfo.getPublisher());
-		// 只有为立即发布的才有发布时间
-		if (addNoticeInfo.getNoticeStatus() == NoticeStatus.PUBLISH) {
-			noticeEntity.setPublishTime(new Date());
-		}
-		return noticeEntity;
-	}
-
-	private List<NoticeReceiverRuleEntity> getNoticeReceiverRuleEntityListFrom(
-			AddNoticeInfo addNoticeInfo, Long noticeId) {
-		List<NoticeReceiverRuleEntity> ruleList = new ArrayList<>();
-		// 如果发送对象规则类型为所有学生或学习中心不需要赋值
-		if (addNoticeInfo.getRuleType() == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG
-				|| addNoticeInfo.getRuleType() == NoticeReceiverRuleType.COMMON_USERS_OF_ROLE) {
-			NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
-			ruleEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
-			ruleEntity.setNoticeId(noticeId);
-			ruleEntity.setRuleType(addNoticeInfo.getRuleType());
-			ruleEntity.setRuleValue(null);
-			ruleList.add(ruleEntity);
-		} else {
-			String publishObjectIds = getStandardIds(addNoticeInfo.getPublishObjectId(), ",");
-			String[] publishObjectIdArr = publishObjectIds.split(",");
-			for (String publishObjectId : publishObjectIdArr) {
-				NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
-				ruleEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
-				ruleEntity.setNoticeId(noticeId);
-				ruleEntity.setRuleType(addNoticeInfo.getRuleType());
-				ruleEntity.setRuleValue(publishObjectId);
-				ruleList.add(ruleEntity);
-			}
-		}
-
-		return ruleList;
-	}
-
-	/**
-	 * 获取标准的id字符串,去掉最后一个字符
-	 *
-	 * @param strIds
-	 *            id字符串
-	 * @param separator
-	 *            分隔符
-	 * @return
-	 */
-	private String getStandardIds(String strIds, String separator) {
-		if (!StringUtils.isNullOrEmpty(strIds)) {
-			if (strIds.lastIndexOf(separator) == strIds.length() - 1) {
-				return strIds.substring(0, strIds.lastIndexOf(separator));
-			}
-		}
-		return strIds;
-	}
-
-	private NoticeRulePublishProgressEntity getNoticePublishScheduleEntityFrom(UpdateNoticeInfo info) {
-		NoticeRulePublishProgressEntity publishScheduleEntity = new NoticeRulePublishProgressEntity();
-		publishScheduleEntity.setRootOrgId(info.getRootOrgId());
-		publishScheduleEntity.setNoticeId(info.getId());
-		if (info.getNoticeStatus() == NoticeStatus.PUBLISH) {
-			publishScheduleEntity.setPublishStatus(NoticePublishStatus.PUBLISHING);
-		} else {
-			publishScheduleEntity.setPublishStatus(NoticePublishStatus.UNPUBLISHED);
-		}
-		return publishScheduleEntity;
-	}
-
-	private List<NoticeReceiverRuleEntity> getNoticeReceiverRuleEntityListFrom(
-			UpdateNoticeInfo info) {
-		List<NoticeReceiverRuleEntity> ruleList = new ArrayList<>();
-		// 如果发送对象规则类型为所有学生或学习中心不需要赋值
-		if (info.getRuleType() == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG
-				|| info.getRuleType() == NoticeReceiverRuleType.COMMON_USERS_OF_ROLE) {
-			NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
-			ruleEntity.setRootOrgId(info.getRootOrgId());
-			ruleEntity.setNoticeId(info.getId());
-			ruleEntity.setRuleType(info.getRuleType());
-			ruleEntity.setRuleValue(null);
-			ruleList.add(ruleEntity);
-		} else {
-			String publishObjectIds = getStandardIds(info.getPublishObjectId(), ",");
-			String[] publishObjectIdArr = publishObjectIds.split(",");
-			for (String publishObjectId : publishObjectIdArr) {
-				NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
-				ruleEntity.setRootOrgId(info.getRootOrgId());
-				ruleEntity.setNoticeId(info.getId());
-				ruleEntity.setRuleType(info.getRuleType());
-				ruleEntity.setRuleValue(publishObjectId);
-				ruleList.add(ruleEntity);
-			}
-		}
-
-		return ruleList;
-	}
-
-	private List<NoticeReceiverRuleEntity> getReceiverRuleList(Long rootOrgId, Long... noticeId) {
-		List<NoticeReceiverRuleEntity> ruleList = noticeReceiverRuleRepo
-				.findByRootOrgIdAndNoticeIdIn(rootOrgId, Arrays.asList(noticeId));
-		if (ruleList == null) {
-			throw new StatusException("501009", "找不到通知id为:" + noticeId + "的通知对象信息");
-		}
-		return ruleList;
-	}
-
-	private NoticeReceiverRuleType getNoticeReceiverRuleType(Long noticeId,
-			List<NoticeReceiverRuleEntity> ruleList) {
-		Optional<NoticeReceiverRuleType> first = ruleList.stream()
-				.filter(p -> p.getNoticeId().equals(noticeId)).map(p -> p.getRuleType())
-				.findFirst();
-		if (first.isPresent()) {
-			return first.get();
-		} else {
-			throw new StatusException("501012", "找不到通知id为:" + noticeId + "的通知规则类型");
-		}
-	}
+    @Autowired
+    private NoticeRepo noticeRepo;
+
+    @Autowired
+    private UserNoticeRepo userNoticeRepo;
+
+    @Autowired
+    private NoticeRulePublishProgressRepo noticeRulePublishProgressRepo;
+
+    @Autowired
+    private NoticeReceiverRuleRepo noticeReceiverRuleRepo;
+
+    @Autowired
+    private ExamRepo examRepo;
+
+    @Autowired
+    MarkWorkCloudService markWorkCloudService;
+
+    @Autowired
+    ExamStudentRepo examStudentRepo;
+
+    @Autowired
+    UserCloudService userCloudService;
+
+    @Override
+    public List<UserNoticeInfo> getNoticeList(UserNoticeInfoQuery query) {
+        List<UserNoticeInfo> resultList = new ArrayList<>();
+        List<UserNoticeEntity> userNoticeList;
+        if (query.getHasRead() != null) {
+            userNoticeList = userNoticeRepo
+                    .findByRootOrgIdAndUserTypeAndUserIdAndHasReadOrderByCreationTimeDesc(
+                            query.getRootOrgId(), query.getUserType(), query.getUserId(),
+                            query.getHasRead());
+        } else {
+            userNoticeList = userNoticeRepo
+                    .findByRootOrgIdAndUserTypeAndUserIdOrderByCreationTimeDesc(
+                            query.getRootOrgId(), query.getUserType(), query.getUserId());
+        }
+        if (null != userNoticeList && !userNoticeList.isEmpty()) {
+            List<Long> noticeIdList = userNoticeList.stream().map(UserNoticeEntity::getNoticeId)
+                    .collect(Collectors.toList());
+            List<NoticeEntity> noticeList = noticeRepo.findByIdIn(noticeIdList);
+            for (UserNoticeEntity un : userNoticeList) {
+                NoticeEntity noticeEntity = getNoticeById(noticeList, un.getNoticeId());
+                if (noticeEntity == null) {
+                    throw new StatusException("501005", "找不到id为:" + un.getNoticeId() + "的通知");
+                }
+                UserNoticeInfo info = new UserNoticeInfo();
+                info.setId(noticeEntity.getId());
+                info.setTitle(noticeEntity.getTitle());
+                info.setContent(noticeEntity.getContent());
+                info.setPublisher(noticeEntity.getPublisher());
+                info.setPublishTime(noticeEntity.getPublishTime());
+                info.setHasRead(un.getHasRead());
+                resultList.add(info);
+            }
+        }
+        return resultList;
+    }
+
+    @Override
+    public int updateNoticeReadStatus(String noticeId, UserType userType, Long userId) {
+        List<Long> noticeIdList;
+        if (noticeId.contains(",")) {
+            noticeIdList = Arrays.asList(noticeId.split(",")).stream().map(p -> Long.parseLong(p))
+                    .collect(Collectors.toList());
+        } else {
+            noticeIdList = Arrays.asList(noticeId).stream().map(p -> Long.parseLong(p))
+                    .collect(Collectors.toList());
+        }
+        return userNoticeRepo.updateNoticeReadStatus(noticeIdList, userType.toString(), userId);
+    }
+
+    @Override
+    public PageInfo<NoticeInfo> getPagedNoticeList(Integer curPage, Integer pageSize,
+                                                   NoticeInfoQuery infoQuery) {
+        List<NoticeInfo> resultList = new ArrayList<>();
+        Long rootOrgId = infoQuery.getRootOrgId();
+        Specification<NoticeEntity> specification = (root, query, cb) -> {
+            List<Predicate> predicates = new ArrayList<>();
+            predicates.add(cb.equal(root.get("rootOrgId"), rootOrgId));
+            if (!StringUtils.isNullOrEmpty(infoQuery.getTitle())) {
+                predicates.add(cb.like(root.get("title"),
+                        DBUtil.toSqlSearchPattern(infoQuery.getTitle())));
+            }
+            if (null != infoQuery.getPublishStatus()) {
+                predicates.add(cb.equal(root.get("noticeStatus"), infoQuery.getPublishStatus()));
+            }
+
+            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
+        };
+        PageRequest pageRequest = PageRequest.of(curPage, pageSize,
+                new Sort(Sort.Direction.DESC, "creationTime"));
+        Page<NoticeEntity> pagedNoticeEntityList = noticeRepo.findAll(specification, pageRequest);
+        List<Long> noticeIdList = pagedNoticeEntityList.stream().map(p -> p.getId())
+                .collect(Collectors.toList());
+        List<NoticeReceiverRuleEntity> ruleList = getReceiverRuleList(rootOrgId,
+                noticeIdList.toArray(new Long[noticeIdList.size()]));
+
+        for (NoticeEntity ne : pagedNoticeEntityList) {
+            NoticeReceiverRuleType ruleType = getNoticeReceiverRuleType(ne.getId(), ruleList);
+            NoticeInfo ni = new NoticeInfo();
+            ni.setId(ne.getId());
+            ni.setPublisher(ne.getPublisher());
+            ni.setPublishTime(ne.getPublishTime());
+            ni.setTitle(ne.getTitle());
+            ni.setContent(ne.getContent());
+            ni.setPublishObject(getPublishObject(rootOrgId, ruleType, ruleList));
+            ni.setPublishStatus(ne.getNoticeStatus());
+            ni.setRuleType(ruleType);
+            resultList.add(ni);
+        }
+        return new PageInfo<>(pagedNoticeEntityList, resultList);
+
+    }
+
+    @Transactional
+    @Override
+    public int deleteNotice(Long rootOrgId, List<Long> noticeIdList) {
+        int result = 0;
+        // 删除通知进度相关信息
+        result += noticeRulePublishProgressRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
+        // 删除通知规则相关信息
+        result += noticeReceiverRuleRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
+        // 删除通知相关信息
+        result += noticeRepo.deleteByIdIn(noticeIdList);
+        return result;
+    }
+
+    @Transactional
+    @Override
+    public int addNotice(AddNoticeInfo addNoticeInfo) {
+        // 保存公告基本信息
+        NoticeEntity noticeEntity = getNoticeEntityFrom(addNoticeInfo);
+        NoticeEntity savedNotice = noticeRepo.save(noticeEntity);
+
+        Long noticeId = savedNotice.getId();
+
+        // 保存公告接收规则
+        List<NoticeReceiverRuleEntity> ruleList = getNoticeReceiverRuleEntityListFrom(addNoticeInfo,
+                noticeId);
+        noticeReceiverRuleRepo.saveAll(ruleList);
+
+        // 保存公告发布进度
+        NoticeRulePublishProgressEntity publishScheduleEntity = getNoticeRulePublishProgressEntityFrom(
+                addNoticeInfo, noticeId);
+        noticeRulePublishProgressRepo.save(publishScheduleEntity);
+
+        return noticeId > 0 ? 1 : 0;
+
+    }
+
+    @Transactional
+    @Override
+    public NoticeRulePublishProgressEntity updateNotice(UpdateNoticeInfo info) {
+        Long rootOrgId = info.getRootOrgId();
+        List<Long> noticeIdList = Collections.singletonList(info.getId());
+        // 校验通知状态,正在发送的通知不允许修改
+        NoticeEntity originalNotice = GlobalHelper.getEntity(noticeRepo, info.getId(),
+                NoticeEntity.class);
+        if (originalNotice == null) {
+            throw new StatusException("501006", "找不到通知id为:" + info.getId() + "的数据");
+        }
+        if (originalNotice.getNoticeStatus() != NoticeStatus.DRAFT) {
+            throw new StatusException("501008", "发布中或已发布的通知不允许修改");
+        }
+
+        // 更新通知表
+
+        originalNotice.setTitle(info.getTitle());
+        originalNotice.setPublisher(info.getPublisher());
+        originalNotice.setNoticeStatus(info.getNoticeStatus());
+        if (info.getNoticeStatus() == NoticeStatus.TO_BE_PUBLISHED) {
+            originalNotice.setPublishTime(new Date());
+        }
+        originalNotice.setContent(info.getContent());
+        originalNotice.setUpdateTime(new Date());
+        noticeRepo.save(originalNotice);
+
+        // 更新公告接收规则实体
+        noticeReceiverRuleRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
+        List<NoticeReceiverRuleEntity> ruleList = getNoticeReceiverRuleEntityListFrom(info);
+        noticeReceiverRuleRepo.saveAll(ruleList);
+
+        // 更新公告发布进度实体
+        noticeRulePublishProgressRepo.deleteByRootOrgIdAndNoticeIdIn(rootOrgId, noticeIdList);
+        NoticeRulePublishProgressEntity publishScheduleEntity = getNoticeRulePublishProgressEntityFrom(
+                info);
+        NoticeRulePublishProgressEntity saved = noticeRulePublishProgressRepo.save(publishScheduleEntity);
+
+        return saved;
+    }
+
+    @Override
+    public List<NoticeRulePublishProgressEntity> getToBeDisposedNoticeRulePublishProgressList() {
+        List<NoticeRulePublishProgressEntity> resultList = null;
+        List<NoticeEntity> publishingNoticeList = noticeRepo.findNoticeStatus(NoticeStatus.PUBLISHING);
+        List<NoticeEntity> toBePublishedNoticeList = noticeRepo.findNoticeStatus(NoticeStatus.TO_BE_PUBLISHED);
+        List<Long> noticeIdList = new ArrayList<>();
+        if (publishingNoticeList != null && !publishingNoticeList.isEmpty()) {
+            noticeIdList = publishingNoticeList.stream().map(p -> p.getId()).collect(Collectors.toList());
+        }
+        if (toBePublishedNoticeList != null && !toBePublishedNoticeList.isEmpty()) {
+            noticeIdList.addAll(toBePublishedNoticeList.stream().map(p -> p.getId()).collect(Collectors.toList()));
+        }
+        if (!noticeIdList.isEmpty()) {
+            resultList = noticeRulePublishProgressRepo.findByNoticeIdIn(noticeIdList);
+        }
+        return resultList;
+    }
+
+    @Override
+    public Long disposePublishingUserNotice(Long startUserId, NoticeRulePublishProgressEntity ruleProgress) {
+        Long nextUserId;
+        // 发布通知每次处理的用户id数量 // TODO: 2019/7/10 需要将参数放到配置文件
+        int rowNumber = PropertyHolder.getInt("notice.dispose.userId.size", 100);
+        Long rootOrgId = ruleProgress.getRootOrgId();
+        Long noticeId = ruleProgress.getNoticeId();
+        NoticeReceiverRuleType ruleType = ruleProgress.getNoticeReceiverRuleType();
+        List<NoticeReceiverRuleEntity> currentRuleList = getReceiverRuleList(rootOrgId, noticeId);
+
+        GetLimitUserIdResp getLimitUserIdResp = getSpecifiedUserIdList(rootOrgId, rowNumber,
+                startUserId, ruleType, currentRuleList);
+        nextUserId = getLimitUserIdResp.getNextId();
+        Long maxUserId = getLimitUserIdResp.getMaxId();
+        // 满足条件的用户id集合(可能为空)
+        List<Long> limitStudentIdList = getLimitUserIdResp.getIdList();
+        saveUserNoticeAndUpdateRulePublishProgress(rootOrgId, noticeId, ruleType, ruleProgress,
+                limitStudentIdList, maxUserId);
+        return nextUserId;
+
+    }
+
+    @Override
+    public void disposeOverdueNotice() {
+        // 通知过期年限阈值// TODO: 2019/7/10
+        int overdueYearThreshold = PropertyHolder.getInt("notice.dispose.overdue.year", 1);
+        Date now = new Date();
+        Date lastYear = DateUtils.addYears(now, -overdueYearThreshold);
+        List<NoticeEntity> overdueNoticeList = noticeRepo.findByCreationTimeBefore(lastYear);
+        if (overdueNoticeList != null && !overdueNoticeList.isEmpty()) {
+            for (NoticeEntity notice : overdueNoticeList) {
+                deleteAllRelatedNotice(notice.getId());
+            }
+        }
+
+    }
+
+    @Override
+    public void updateNoticeStatus(Long noticeId, NoticeStatus noticeStatus) {
+        noticeRepo.updateNoticeStatus(noticeId, noticeStatus.toString());
+    }
+
+    /**
+     * 删除所有相关的通知数据
+     *
+     * @param noticeId
+     */
+    @Transactional
+    public void deleteAllRelatedNotice(Long noticeId) {
+        userNoticeRepo.deleteByNoticeId(noticeId);
+        noticeReceiverRuleRepo.deleteByNoticeId(noticeId);
+        noticeRulePublishProgressRepo.deleteByNoticeId(noticeId);
+        noticeRepo.deleteById(noticeId);
+    }
+
+
+    /**
+     * 更新发布进度
+     *
+     * @param publishSchedule
+     * @param maxUserId
+     */
+    @Transactional
+    public void saveUserNoticeAndUpdateRulePublishProgress(Long rootOrgId, Long noticeId,
+                                                           NoticeReceiverRuleType ruleType, NoticeRulePublishProgressEntity rulePublishProgress,
+                                                           List<Long> limitStudentIdList, Long maxUserId) {
+        // 保存并更新发布状态为发布完成
+        List<UserNoticeEntity> userNoticeList = new ArrayList<>();
+        for (Long userId : limitStudentIdList) {
+            UserNoticeEntity userNotice = initUserNoticeEntity(rootOrgId, userId, noticeId,
+                    ruleType);
+            userNoticeList.add(userNotice);
+        }
+        userNoticeRepo.saveAll(userNoticeList);
+        rulePublishProgress.setMaxStudentId(maxUserId);
+        noticeRulePublishProgressRepo.save(rulePublishProgress);
+    }
+
+
+    /**
+     * 获取指定数量的考试记录id
+     *
+     * @param rootOrgId   组织机构id
+     * @param rowNumber   获取的行数
+     * @param startUserId 起始用户id
+     * @param ruleType    通知对象规则类型
+     * @param ruleList    当前规则类型下对应的规则明细
+     * @return 返回用户id集合, 和下一次请求id
+     */
+    private GetLimitUserIdResp getSpecifiedUserIdList(Long rootOrgId, int rowNumber,
+                                                      Long startUserId, NoticeReceiverRuleType ruleType,
+                                                      List<NoticeReceiverRuleEntity> ruleList) {
+        GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
+        List<Long> limitUserIdList = null;
+        long nextUserId = 0;
+        switch (ruleType) {
+            case TEACHER_OF_MARK_WORK:
+                return getGetLimitUserIdByMarkWork(rootOrgId, rowNumber, startUserId, ruleList);
+            case COMMON_USERS_OF_ROLE:
+                return getGetLimitUserIdByRole(rootOrgId, startUserId);
+            case STUDENTS_OF_EXAM:
+                return getLimitUserIdByExamStudent(rootOrgId, startUserId, rowNumber, ruleList);
+            case ALL_STUDENTS_OF_ROOT_ORG:
+                return getLimitUserIdByAllStudent(rootOrgId, rowNumber, startUserId);
+        }
+        resultResp.setNextId(nextUserId);
+        resultResp.setIdList(limitUserIdList);
+        return resultResp;
+    }
+
+    private GetLimitUserIdResp getGetLimitUserIdByMarkWork(Long rootOrgId, int rowNumber,
+                                                           Long startUserId, List<NoticeReceiverRuleEntity> ruleList) {
+        GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
+        // 获取当前规则下所有问卷工作id
+        List<Long> markWorkIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
+                .collect(Collectors.toList());
+        GetMarkersByWorkIdsReq markWorkerReq = new GetMarkersByWorkIdsReq();
+        markWorkerReq.setRootOrgId(rootOrgId);
+        markWorkerReq.setWorkIds(markWorkIdList);
+        markWorkerReq.setStarId(startUserId);
+        markWorkerReq.setSize(rowNumber);
+        // FIXME: 2019/7/11
+        GetMarkersByWorkIdsResp markWorkerResp = markWorkCloudService
+                .getMarkersByWorkIds(markWorkerReq);
+        List<Long> limitUserIdList = markWorkerResp.getMarkers();
+        if (markWorkerResp.getMarkers() != null && !markWorkerResp.getMarkers().isEmpty()) {
+            resultResp.setMaxId(Collections.max(limitUserIdList));
+        }
+        resultResp.setNextId(markWorkerResp.getNextId());
+        resultResp.setIdList(markWorkerResp.getMarkers());
+        return resultResp;
+    }
+
+    private GetLimitUserIdResp getGetLimitUserIdByRole(Long rootOrgId, Long startUserId) {
+        GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
+        List<Long> limitUserIdList = new ArrayList<>();
+        long nextUserId;// 当前需求只有考试中心
+        GetAllUsersByRoleReq getLcUserReq = new GetAllUsersByRoleReq();
+        getLcUserReq.setRootOrgId(rootOrgId);
+        getLcUserReq.setRoleCode(RoleMeta.LC_USER.toString());
+        getLcUserReq.setStart(startUserId);
+        GetAllUsersByRoleResp getLcUserResp = userCloudService.getAllUsersByRole(getLcUserReq);
+        nextUserId = getLcUserResp.getNext();
+        if (getLcUserResp.getUserBeanList() != null && !getLcUserResp.getUserBeanList().isEmpty()) {
+            limitUserIdList = getLcUserResp.getUserBeanList().stream().map(p -> p.getUserId())
+                    .collect(Collectors.toList());
+            resultResp.setMaxId(Collections.max(limitUserIdList));
+        }
+        resultResp.setNextId(nextUserId);
+        resultResp.setIdList(limitUserIdList);
+        return resultResp;
+    }
+
+    private GetLimitUserIdResp getLimitUserIdByAllStudent(Long rootOrgId, int rowNumber,
+                                                          Long startUserId) {
+        GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
+        long nextId = startUserId;
+        Long maxUserId = null;
+        List<Long> limitUserIdList = examStudentRepo.findLimitStudentIdList(rootOrgId, startUserId,
+                rowNumber);
+        if (limitUserIdList != null && !limitUserIdList.isEmpty()) {
+            maxUserId = Collections.max(limitUserIdList);
+            nextId = maxUserId;
+        }
+        if (nextId != startUserId) {
+            nextId++;
+        }
+        resultResp.setNextId(nextId);
+        resultResp.setMaxId(maxUserId);
+        resultResp.setIdList(limitUserIdList);
+        return resultResp;
+    }
+
+    private GetLimitUserIdResp getLimitUserIdByExamStudent(Long rootOrgId, Long startUserId,
+                                                           int rowNumber, List<NoticeReceiverRuleEntity> ruleList) {
+        GetLimitUserIdResp resultResp = new GetLimitUserIdResp();
+        // 获取当前规则下所有的考试批次id
+        List<Long> examIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
+                .collect(Collectors.toList());
+        long nextId = startUserId;
+        Long maxUserId = null;
+        List<Long> limitUserIdList = examStudentRepo.findByExamIdLimitStudentIdList(rootOrgId,
+                examIdList, startUserId, rowNumber);
+        if (limitUserIdList != null && !limitUserIdList.isEmpty()) {
+            maxUserId = Collections.max(limitUserIdList);
+            nextId = maxUserId;
+        }
+        if (nextId != startUserId) {
+            nextId++;
+        }
+        resultResp.setMaxId(maxUserId);
+        resultResp.setNextId(nextId);
+        resultResp.setIdList(limitUserIdList);
+        return resultResp;
+    }
+
+    private UserNoticeEntity initUserNoticeEntity(Long rootOrgId, Long userId, Long noticeId,
+                                                  NoticeReceiverRuleType ruleType) {
+        UserType userType = (ruleType == NoticeReceiverRuleType.STUDENTS_OF_EXAM
+                || ruleType == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG)
+                ? UserType.STUDENT
+                : UserType.COMMON;
+        UserNoticeEntity userNotice = new UserNoticeEntity();
+        userNotice.setRootOrgId(rootOrgId);
+        userNotice.setHasRead(false);
+        userNotice.setNoticeId(noticeId);
+        userNotice.setUserType(userType);
+        userNotice.setUserId(userId);
+        return userNotice;
+    }
+
+    /**
+     * 获取上次更新的最大用户id
+     *
+     * @param ruleType
+     * @param publishSchedule
+     * @return
+     */
+    private Long getLastMaxUserId(NoticeReceiverRuleType ruleType,
+                                  NoticeRulePublishProgressEntity publishSchedule) {
+        if (ruleType == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG
+                || ruleType == NoticeReceiverRuleType.STUDENTS_OF_EXAM) {
+            return publishSchedule.getMaxStudentId();
+        } else {
+            return publishSchedule.getMaxCommonUserId();
+        }
+    }
+
+    /**
+     * 获取发布对象
+     *
+     * @param rootOrgId
+     * @param noticeId
+     * @return
+     */
+    private List<Map<String, Object>> getPublishObject(Long rootOrgId,
+                                                       NoticeReceiverRuleType ruleType, List<NoticeReceiverRuleEntity> ruleList) {
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        Map<String, Object> objectMap;
+        List<NoticeReceiverRuleEntity> currentRuleList;
+        switch (ruleType) {
+            case STUDENTS_OF_EXAM:
+                currentRuleList = ruleList.stream().filter(p -> p.getRuleType() == ruleType)
+                        .collect(Collectors.toList());
+                return getExamStudentObject(currentRuleList);
+            case ALL_STUDENTS_OF_ROOT_ORG:
+                objectMap = new HashMap<>();
+                objectMap.put("id", 0);
+                objectMap.put("name", "所有学生");
+                objectMap.put("ruleType", "ALL_STUDENTS_OF_ROOT_ORG");
+                resultList.add(objectMap);
+                return resultList;
+            case COMMON_USERS_OF_ROLE:
+                objectMap = new HashMap<>();
+                objectMap.put("id", 0);
+                objectMap.put("name", "所有学习中心用户");
+                objectMap.put("ruleType", "COMMON_USERS_OF_ROLE");
+                resultList.add(objectMap);
+                return resultList;
+            case TEACHER_OF_MARK_WORK:
+                currentRuleList = ruleList.stream().filter(p -> p.getRuleType() == ruleType)
+                        .collect(Collectors.toList());
+                return getMarkTeacherObject(rootOrgId, currentRuleList);
+        }
+        return resultList;
+    }
+
+    /**
+     * 组装学生发布对象
+     *
+     * @param ruleList
+     * @return
+     */
+    private List<Map<String, Object>> getExamStudentObject(
+            List<NoticeReceiverRuleEntity> ruleList) {
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        // 考试批次id
+        List<Long> examIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
+                .collect(Collectors.toList());
+        List<ExamEntity> examList = examRepo.findByIdIn(examIdList);
+        for (ExamEntity e : examList) {
+            Map<String, Object> map = new HashMap<>();
+            map.put("id", e.getId());
+            map.put("name", "学生-" + e.getName());
+            map.put("ruleType", "STUDENTS_OF_EXAM");
+            resultList.add(map);
+        }
+        return resultList;
+    }
+
+    /**
+     * 组装阅卷老师发布对象
+     *
+     * @param rootOrgId
+     * @param ruleList
+     * @return
+     */
+    private List<Map<String, Object>> getMarkTeacherObject(Long rootOrgId,
+                                                           List<NoticeReceiverRuleEntity> ruleList) {
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        List<Long> markWorkIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue()))
+                .collect(Collectors.toList());
+        GetMarkWorkMainByIdsReq req = new GetMarkWorkMainByIdsReq();
+        req.setRootOrgId(rootOrgId);
+        req.setWorkIds(markWorkIdList);
+
+        GetMarkWorkMainByIdsResp markWorkResp = markWorkCloudService.getMarkWorkMainByIds(req);
+        List<MarkWorkMainBean> markWorkList = markWorkResp.getList();
+        for (MarkWorkMainBean mw : markWorkList) {
+            Map<String, Object> map = new HashMap<>();
+            map.put("id", mw.getId());
+            map.put("name", "老师-" + mw.getName());
+            map.put("ruleType", "TEACHER_OF_MARK_WORK");
+            resultList.add(map);
+        }
+        return resultList;
+    }
+
+    /**
+     * 根据通知id获取通知
+     *
+     * @param noticeList
+     * @param noticeId
+     * @return
+     */
+    private NoticeEntity getNoticeById(List<NoticeEntity> noticeList, Long noticeId) {
+        Optional<NoticeEntity> optional = noticeList.stream()
+                .filter(p -> p.getId().equals(noticeId)).findFirst();
+        if (optional.isPresent()) {
+            return optional.get();
+        } else {
+            return null;
+        }
+    }
+
+    private NoticeRulePublishProgressEntity getNoticeRulePublishProgressEntityFrom(
+            AddNoticeInfo addNoticeInfo, Long noticeId) {
+        NoticeRulePublishProgressEntity publishScheduleEntity = new NoticeRulePublishProgressEntity();
+        publishScheduleEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
+        publishScheduleEntity.setNoticeId(noticeId);
+        return publishScheduleEntity;
+    }
+
+    private NoticeEntity getNoticeEntityFrom(AddNoticeInfo addNoticeInfo) {
+        NoticeEntity noticeEntity = new NoticeEntity();
+        noticeEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
+        noticeEntity.setTitle(addNoticeInfo.getTitle());
+        noticeEntity.setContent(addNoticeInfo.getContent());
+        noticeEntity.setNoticeStatus(addNoticeInfo.getNoticeStatus());
+        noticeEntity.setPublisher(addNoticeInfo.getPublisher());
+        // 只有为立即发布的才有发布时间
+        if (addNoticeInfo.getNoticeStatus() == NoticeStatus.TO_BE_PUBLISHED) {
+            noticeEntity.setPublishTime(new Date());
+        }
+        return noticeEntity;
+    }
+
+    private List<NoticeReceiverRuleEntity> getNoticeReceiverRuleEntityListFrom(
+            AddNoticeInfo addNoticeInfo, Long noticeId) {
+        List<NoticeReceiverRuleEntity> ruleList = new ArrayList<>();
+        // 如果发送对象规则类型为所有学生或学习中心不需要赋值
+        if (addNoticeInfo.getRuleType() == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG
+                || addNoticeInfo.getRuleType() == NoticeReceiverRuleType.COMMON_USERS_OF_ROLE) {
+            NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
+            ruleEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
+            ruleEntity.setNoticeId(noticeId);
+            ruleEntity.setRuleType(addNoticeInfo.getRuleType());
+            ruleEntity.setRuleValue(null);
+            ruleList.add(ruleEntity);
+        } else {
+            String publishObjectIds = getStandardIds(addNoticeInfo.getPublishObjectId(), ",");
+            String[] publishObjectIdArr = publishObjectIds.split(",");
+            for (String publishObjectId : publishObjectIdArr) {
+                NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
+                ruleEntity.setRootOrgId(addNoticeInfo.getRootOrgId());
+                ruleEntity.setNoticeId(noticeId);
+                ruleEntity.setRuleType(addNoticeInfo.getRuleType());
+                ruleEntity.setRuleValue(publishObjectId);
+                ruleList.add(ruleEntity);
+            }
+        }
+
+        return ruleList;
+    }
+
+    /**
+     * 获取标准的id字符串,去掉最后一个字符
+     *
+     * @param strIds    id字符串
+     * @param separator 分隔符
+     * @return
+     */
+    private String getStandardIds(String strIds, String separator) {
+        if (!StringUtils.isNullOrEmpty(strIds)) {
+            if (strIds.lastIndexOf(separator) == strIds.length() - 1) {
+                return strIds.substring(0, strIds.lastIndexOf(separator));
+            }
+        }
+        return strIds;
+    }
+
+    private NoticeRulePublishProgressEntity getNoticeRulePublishProgressEntityFrom(UpdateNoticeInfo info) {
+        NoticeRulePublishProgressEntity publishScheduleEntity = new NoticeRulePublishProgressEntity();
+        publishScheduleEntity.setRootOrgId(info.getRootOrgId());
+        publishScheduleEntity.setNoticeId(info.getId());
+        return publishScheduleEntity;
+    }
+
+    private List<NoticeReceiverRuleEntity> getNoticeReceiverRuleEntityListFrom(
+            UpdateNoticeInfo info) {
+        List<NoticeReceiverRuleEntity> ruleList = new ArrayList<>();
+        // 如果发送对象规则类型为所有学生或学习中心不需要赋值
+        if (info.getRuleType() == NoticeReceiverRuleType.ALL_STUDENTS_OF_ROOT_ORG
+                || info.getRuleType() == NoticeReceiverRuleType.COMMON_USERS_OF_ROLE) {
+            NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
+            ruleEntity.setRootOrgId(info.getRootOrgId());
+            ruleEntity.setNoticeId(info.getId());
+            ruleEntity.setRuleType(info.getRuleType());
+            ruleEntity.setRuleValue(null);
+            ruleList.add(ruleEntity);
+        } else {
+            String publishObjectIds = getStandardIds(info.getPublishObjectId(), ",");
+            String[] publishObjectIdArr = publishObjectIds.split(",");
+            for (String publishObjectId : publishObjectIdArr) {
+                NoticeReceiverRuleEntity ruleEntity = new NoticeReceiverRuleEntity();
+                ruleEntity.setRootOrgId(info.getRootOrgId());
+                ruleEntity.setNoticeId(info.getId());
+                ruleEntity.setRuleType(info.getRuleType());
+                ruleEntity.setRuleValue(publishObjectId);
+                ruleList.add(ruleEntity);
+            }
+        }
+
+        return ruleList;
+    }
+
+    private List<NoticeReceiverRuleEntity> getReceiverRuleList(Long rootOrgId, Long... noticeId) {
+        List<NoticeReceiverRuleEntity> ruleList = noticeReceiverRuleRepo
+                .findByRootOrgIdAndNoticeIdIn(rootOrgId, Arrays.asList(noticeId));
+        if (ruleList == null) {
+            throw new StatusException("501009", "找不到通知id为:" + noticeId + "的通知对象信息");
+        }
+        return ruleList;
+    }
+
+    private NoticeReceiverRuleType getNoticeReceiverRuleType(Long noticeId,
+                                                             List<NoticeReceiverRuleEntity> ruleList) {
+        Optional<NoticeReceiverRuleType> first = ruleList.stream()
+                .filter(p -> p.getNoticeId().equals(noticeId)).map(p -> p.getRuleType())
+                .findFirst();
+        if (first.isPresent()) {
+            return first.get();
+        } else {
+            throw new StatusException("501012", "找不到通知id为:" + noticeId + "的通知规则类型");
+        }
+    }
 
 }