Browse Source

去重黄色提示

WANG 6 years ago
parent
commit
1138ad1b7b

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

@@ -1,15 +1,16 @@
 package cn.com.qmth.examcloud.core.examwork.api.provider;
 
-import cn.com.qmth.examcloud.core.examwork.service.NoticeService;
-import cn.com.qmth.examcloud.examwork.api.NoticeCloudService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import cn.com.qmth.examcloud.core.examwork.service.NoticeService;
+import cn.com.qmth.examcloud.examwork.api.NoticeCloudService;
+import cn.com.qmth.examcloud.web.support.ControllerSupport;
+import io.swagger.annotations.ApiOperation;
+
 /**
  * 考试云服务
  *
@@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("${$rmp.cloud.examwork}" + "notice")
 public class NoticeCloudServiceProvider extends ControllerSupport implements NoticeCloudService {
 
+	private static final long serialVersionUID = 4359829563744893206L;
 
 	@Autowired
 	private NoticeService noticeService;
@@ -33,7 +35,6 @@ public class NoticeCloudServiceProvider extends ControllerSupport implements Not
 		noticeService.disposePublishingUserNotice();
 	}
 
-
 	@ApiOperation(value = "清理过期的通知数据")
 	@PostMapping("disposeOverdueNotice")
 	@Override

+ 59 - 50
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/NoticeService.java

@@ -19,62 +19,71 @@ import java.util.List;
  */
 public interface NoticeService {
 
-    /**
-     * 获取用户通知列表
-     * @param query
-     * @return
-     */
-    List<UserNoticeInfo> getNoticeList(UserNoticeInfoQuery query);
+	/**
+	 * 获取用户通知列表
+	 * 
+	 * @param query
+	 * @return
+	 */
+	List<UserNoticeInfo> getNoticeList(UserNoticeInfoQuery query);
 
-    /**
-     *  更新用户的通知状态为已读
-     * @param noticeId  通知id(多个以逗号分隔)
-     * @param userType 用户类型
-     * @param userId 用户id
-     * @return
-     */
-    int updateNoticeReadStatus(String noticeId, UserType userType, Long userId);
+	/**
+	 * 更新用户的通知状态为已读
+	 * 
+	 * @param noticeId
+	 *            通知id(多个以逗号分隔)
+	 * @param userType
+	 *            用户类型
+	 * @param userId
+	 *            用户id
+	 * @return
+	 */
+	int updateNoticeReadStatus(String noticeId, UserType userType, Long userId);
 
-    /**
-     * 分页获取通知列表
-     * @param curPage
-     * @param pageSize
-     * @param infoQuery
-     * @return
-     */
-    PageInfo<NoticeInfo> getPagedNoticeList(Integer curPage, Integer pageSize, NoticeInfoQuery infoQuery);
+	/**
+	 * 分页获取通知列表
+	 * 
+	 * @param curPage
+	 * @param pageSize
+	 * @param infoQuery
+	 * @return
+	 */
+	PageInfo<NoticeInfo> getPagedNoticeList(Integer curPage, Integer pageSize,
+			NoticeInfoQuery infoQuery);
 
+	/**
+	 * 删除通知
+	 * 
+	 * @param rootOrgId
+	 * @param noticeIdList
+	 * @return
+	 */
+	int deleteNotice(Long rootOrgId, List<Long> noticeIdList);
 
-    /**
-     * 删除通知
-     * @param rootOrgId
-     * @param noticeIdList
-     * @return
-     */
-    int deleteNotice(Long rootOrgId,List<Long> noticeIdList);
+	/**
+	 * 添加通知
+	 * 
+	 * @param addNoticeInfo
+	 * @return
+	 */
+	int addNotice(AddNoticeInfo addNoticeInfo);
 
-    /**
-     * 添加通知
-     * @param addNoticeInfo
-     * @return
-     */
-    int addNotice(AddNoticeInfo addNoticeInfo);
+	/**
+	 * 更新通知信息
+	 * 
+	 * @param info
+	 * @return
+	 */
+	NoticePublishScheduleEntity updateNotice(UpdateNoticeInfo info);
 
-    /**
-     * 获取通知信息
-     * @param info
-     * @return
-     */
-    int updateNotice(UpdateNoticeInfo info);
+	/**
+	 * 处理待发送的用户通知(自动服务调用)
+	 */
+	void disposePublishingUserNotice();
 
-    /**
-     * 处理待发送的用户通知(自动服务调用)
-     */
-    void disposePublishingUserNotice();
-
-    /**
-     * 处理过期的通知数据(自动服务调用)
-     */
-    void disposeOverdueNotice();
+	/**
+	 * 处理过期的通知数据(自动服务调用)
+	 */
+	void disposeOverdueNotice();
 
 }

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

@@ -7,18 +7,18 @@
 
 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.exchange.JsonSerializable;
 import io.swagger.annotations.ApiModelProperty;
 
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Lob;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
 /**
  * 考试分数信息
  *
@@ -27,110 +27,116 @@ import java.util.Map;
  */
 public class NoticeInfo implements JsonSerializable {
 
-    private static final long serialVersionUID = -7739022488162924094L;
-    /**
-     * 公告id
-     */
-    @ApiModelProperty("公告id")
-    private Long id;
-    /**
-     * 标题
-     */
-    @ApiModelProperty("标题")
-    private String title;
-    /**
-     * 发送对象
-     */
-    @ApiModelProperty("发送对象")
-    private java.util.List<Map<String,Object>> publishObject;
-
-    /**
-     * 发布者
-     */
-    @ApiModelProperty("发布者")
-    private String publisher;
-    /**
-     * 发布时间
-     */
-    @ApiModelProperty("发布时间")
-    private Date publishTime;
-    /**
-     * 发送状态
-     */
-    @ApiModelProperty("发送状态")
-    private NoticePublishStatus publishStatus;
-    /**
-     * 规则类型
-     */
-    @Enumerated(EnumType.STRING)
-    private NoticeReceiverRuleType ruleType;
-
-    /**
-     * 内容
-     */
-    private String content;
-
-    public String getContent() {
-        return content;
-    }
-
-    public void setContent(String content) {
-        this.content = content;
-    }
-
-    public NoticeReceiverRuleType getRuleType() {
-        return ruleType;
-    }
-
-    public void setRuleType(NoticeReceiverRuleType ruleType) {
-        this.ruleType = ruleType;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public List<Map<String, Object>> getPublishObject() {
-        return publishObject;
-    }
-
-    public void setPublishObject(List<Map<String, Object>> publishObject) {
-        this.publishObject = publishObject;
-    }
-
-    public String getPublisher() {
-        return publisher;
-    }
-
-    public void setPublisher(String publisher) {
-        this.publisher = publisher;
-    }
-
-    public Date getPublishTime() {
-        return publishTime;
-    }
-
-    public void setPublishTime(Date publishTime) {
-        this.publishTime = publishTime;
-    }
-
-    public NoticePublishStatus getPublishStatus() {
-        return publishStatus;
-    }
-
-    public void setPublishStatus(NoticePublishStatus publishStatus) {
-        this.publishStatus = publishStatus;
-    }
+	private static final long serialVersionUID = -7739022488162924094L;
+
+	/**
+	 * 公告id
+	 */
+	@ApiModelProperty("公告id")
+	private Long id;
+
+	/**
+	 * 标题
+	 */
+	@ApiModelProperty("标题")
+	private String title;
+
+	/**
+	 * 发送对象
+	 */
+	@ApiModelProperty("发送对象")
+	private java.util.List<Map<String, Object>> publishObject;
+
+	/**
+	 * 发布者
+	 */
+	@ApiModelProperty("发布者")
+	private String publisher;
+
+	/**
+	 * 发布时间
+	 */
+	@ApiModelProperty("发布时间")
+	private Date publishTime;
+
+	/**
+	 * 发送状态
+	 */
+	@ApiModelProperty("发送状态")
+	private NoticePublishStatus publishStatus;
+
+	/**
+	 * 规则类型
+	 */
+	@Enumerated(EnumType.STRING)
+	private NoticeReceiverRuleType ruleType;
+
+	/**
+	 * 内容
+	 */
+	private String content;
+
+	public String getContent() {
+		return content;
+	}
+
+	public void setContent(String content) {
+		this.content = content;
+	}
+
+	public NoticeReceiverRuleType getRuleType() {
+		return ruleType;
+	}
+
+	public void setRuleType(NoticeReceiverRuleType ruleType) {
+		this.ruleType = ruleType;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public List<Map<String, Object>> getPublishObject() {
+		return publishObject;
+	}
+
+	public void setPublishObject(List<Map<String, Object>> publishObject) {
+		this.publishObject = publishObject;
+	}
+
+	public String getPublisher() {
+		return publisher;
+	}
+
+	public void setPublisher(String publisher) {
+		this.publisher = publisher;
+	}
+
+	public Date getPublishTime() {
+		return publishTime;
+	}
+
+	public void setPublishTime(Date publishTime) {
+		this.publishTime = publishTime;
+	}
+
+	public NoticePublishStatus getPublishStatus() {
+		return publishStatus;
+	}
+
+	public void setPublishStatus(NoticePublishStatus publishStatus) {
+		this.publishStatus = publishStatus;
+	}
 }

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

@@ -1,5 +1,32 @@
 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;
@@ -11,10 +38,25 @@ 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.*;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.*;
+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.NoticePublishScheduleEntity;
+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.service.NoticeService;
-import cn.com.qmth.examcloud.core.examwork.service.bean.*;
+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.marking.api.MarkWorkCloudService;
 import cn.com.qmth.examcloud.marking.api.bean.MarkWorkMainBean;
 import cn.com.qmth.examcloud.marking.api.request.GetMarkWorkMainByIdsReq;
@@ -23,22 +65,6 @@ 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.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 javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.Predicate;
-import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * @Description 通知实现类
@@ -48,697 +74,769 @@ import java.util.stream.Collectors;
  */
 @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<NoticePublishScheduleEntity> byPublishStatusNoticeScheduleList = noticePublishScheduleRepo.findByRootOrgIdAndPublishStatus(rootOrgId, infoQuery.getPublishStatus());
-                if (null == byPublishStatusNoticeScheduleList || byPublishStatusNoticeScheduleList.isEmpty()) {
-                    throw new StatusException("501001", "通知发布状态数据异常");
-                }
-                //获取相应发布状态的通知id集合
-                List<Long> noticeIdList = byPublishStatusNoticeScheduleList.stream().map(NoticePublishScheduleEntity::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);
-
-        //保存公告发布进度
-        NoticePublishScheduleEntity publishScheduleEntity = getNoticePublishScheduleEntityFrom(addNoticeInfo, noticeId);
-        noticePublishScheduleRepo.save(publishScheduleEntity);
-
-        return noticeId > 0 ? 1 : 0;
-
-    }
-
-    @Transactional
-    @Override
-    public int updateNotice(UpdateNoticeInfo info) {
-        Long rootOrgId = info.getRootOrgId();
-        List<Long> noticeIdList = Collections.singletonList(info.getId());
-        //校验通知状态,正在发送的通知不允许修改
-        NoticePublishScheduleEntity 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);
-        NoticePublishScheduleEntity publishScheduleEntity = getNoticePublishScheduleEntityFrom(info);
-        NoticePublishScheduleEntity savedSchedule = noticePublishScheduleRepo.save(publishScheduleEntity);
-
-        return 1;
-    }
-
-    @Override
-    public void disposePublishingUserNotice() {
-        List<NoticePublishScheduleEntity> 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 (NoticePublishScheduleEntity 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, NoticePublishScheduleEntity 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, NoticePublishScheduleEntity 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(NoticePublishScheduleEntity 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, NoticePublishScheduleEntity 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) {
-        NoticePublishScheduleEntity 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 NoticePublishScheduleEntity getNoticePublishScheduleEntityFrom(AddNoticeInfo addNoticeInfo, Long noticeId) {
-        NoticePublishScheduleEntity publishScheduleEntity = new NoticePublishScheduleEntity();
-        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 NoticePublishScheduleEntity getNoticePublishScheduleEntityFrom(UpdateNoticeInfo info) {
-        NoticePublishScheduleEntity publishScheduleEntity = new NoticePublishScheduleEntity();
-        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 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<NoticePublishScheduleEntity> byPublishStatusNoticeScheduleList = noticePublishScheduleRepo
+						.findByRootOrgIdAndPublishStatus(rootOrgId, infoQuery.getPublishStatus());
+				if (null == byPublishStatusNoticeScheduleList
+						|| byPublishStatusNoticeScheduleList.isEmpty()) {
+					throw new StatusException("501001", "通知发布状态数据异常");
+				}
+				// 获取相应发布状态的通知id集合
+				List<Long> noticeIdList = byPublishStatusNoticeScheduleList.stream()
+						.map(NoticePublishScheduleEntity::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);
+
+		// 保存公告发布进度
+		NoticePublishScheduleEntity publishScheduleEntity = getNoticePublishScheduleEntityFrom(
+				addNoticeInfo, noticeId);
+		noticePublishScheduleRepo.save(publishScheduleEntity);
+
+		return noticeId > 0 ? 1 : 0;
+
+	}
+
+	@Transactional
+	@Override
+	public NoticePublishScheduleEntity updateNotice(UpdateNoticeInfo info) {
+		Long rootOrgId = info.getRootOrgId();
+		List<Long> noticeIdList = Collections.singletonList(info.getId());
+		// 校验通知状态,正在发送的通知不允许修改
+		NoticePublishScheduleEntity 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);
+		NoticePublishScheduleEntity publishScheduleEntity = getNoticePublishScheduleEntityFrom(
+				info);
+		NoticePublishScheduleEntity saved = noticePublishScheduleRepo.save(publishScheduleEntity);
+
+		return saved;
+	}
+
+	@Override
+	public void disposePublishingUserNotice() {
+		List<NoticePublishScheduleEntity> 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 (NoticePublishScheduleEntity 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,
+			NoticePublishScheduleEntity 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, NoticePublishScheduleEntity 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(NoticePublishScheduleEntity 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,
+			NoticePublishScheduleEntity 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) {
+		NoticePublishScheduleEntity 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 NoticePublishScheduleEntity getNoticePublishScheduleEntityFrom(
+			AddNoticeInfo addNoticeInfo, Long noticeId) {
+		NoticePublishScheduleEntity publishScheduleEntity = new NoticePublishScheduleEntity();
+		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 NoticePublishScheduleEntity getNoticePublishScheduleEntityFrom(UpdateNoticeInfo info) {
+		NoticePublishScheduleEntity publishScheduleEntity = new NoticePublishScheduleEntity();
+		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 + "的通知规则类型");
+		}
+	}
 
 }