Browse Source

完成通知后台代码
完成通知自动服务

lideyin 6 năm trước cách đây
mục cha
commit
ac091abdec
18 tập tin đã thay đổi với 1495 bổ sung71 xóa
  1. 120 14
      examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/NoticeController.java
  2. 117 0
      examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/AddNoticeDomain.java
  3. 6 9
      examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/NoticeDomain.java
  4. 127 0
      examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/UpdateNoticeDomain.java
  5. 76 0
      examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/provider/NoticeCloudServiceProvider.java
  6. 12 0
      examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/ExamStudentRepo.java
  7. 14 0
      examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticePublishScheduleRepo.java
  8. 11 0
      examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticeReceiverRuleRepo.java
  9. 5 0
      examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticeRepo.java
  10. 7 2
      examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/UserNoticeRepo.java
  11. 7 1
      examcloud-core-examwork-service/pom.xml
  12. 35 4
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/NoticeService.java
  13. 127 0
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/AddNoticeInfo.java
  14. 48 0
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/GetLimitUserIdResp.java
  15. 5 5
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/NoticeInfo.java
  16. 15 0
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/NoticeInfoQuery.java
  17. 137 0
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/UpdateNoticeInfo.java
  18. 626 36
      examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/impl/NoticeServiceImpl.java

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

@@ -12,21 +12,22 @@ import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.core.examwork.api.controller.bean.*;
 import cn.com.qmth.examcloud.core.examwork.service.NoticeService;
-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.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.web.support.ControllerSupport;
 import com.mysql.cj.util.StringUtils;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import org.jsoup.Jsoup;
+import org.jsoup.safety.Whitelist;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 公告类
@@ -42,23 +43,77 @@ public class NoticeController extends ControllerSupport {
     @GetMapping("getPagedNoticeList/{curPage}/{pageSize}")
     public PageInfo<NoticeDomain> getPagedNoticeList(@PathVariable Integer curPage,
                                                      @PathVariable Integer pageSize, NoticeDomainQuery query) {
+        PageInfo<NoticeDomain> resultPageInfo = new PageInfo<>();
+        NoticeInfoQuery infoQuery = new NoticeInfoQuery();
+        PageInfo<NoticeInfo> pagedNoticeInfo = noticeService.getPagedNoticeList(curPage, pageSize, infoQuery);
+        resultPageInfo = getPageInfoFrom(pagedNoticeInfo);
+        return resultPageInfo;
+    }
+
+    @ApiOperation(value = "添加新通知")
+    @PostMapping("addNotice")
+    public void addNotice(@Validated @RequestBody AddNoticeDomain addNoticeDomain) {
+        String content = addNoticeDomain.getContent();
+        String simpleText =  Jsoup.clean(content, Whitelist.simpleText());
+        //普通文本内容不允许超过500个字 TODO 该方法待校验,因为不确定富文本框中图片的保存格式
+        if (simpleText.length()>500){
+            throw new StatusException("500007","通知内容不得超过500个字符");
+        }
+        AddNoticeInfo info = getAddNoticeInfoFrom(addNoticeDomain);
+        int result =noticeService.addNotice(info);
+        if (result==0){
+            throw new StatusException("500008","添加新通知失败");
+        }
+    }
+
+    @ApiOperation(value = "修改通知信息")
+    @PostMapping("updateNotice")
+    public void updateNotice(@Validated @RequestBody UpdateNoticeDomain updateNoticeDomain) {
+        String content = updateNoticeDomain.getContent();
+        String simpleText =  Jsoup.clean(content, Whitelist.simpleText());
+        //普通文本内容不允许超过500个字 TODO 该方法待校验,因为不确定富文本框中图片的保存格式
+        if (simpleText.length()>500){
+            throw new StatusException("500007","通知内容不得超过500个字符");
+        }
+
+        //校验状态
+        UpdateNoticeInfo info = getUpdateNoticeInfoFrom(updateNoticeDomain);
+
+        //因为有可能内容没有发生过变化,更新条目可能为0。所以不判断返回值
+        noticeService.updateNotice(info);
+    }
 
-        NoticeInfoQuery infoQuery= new NoticeInfoQuery();
-        PageInfo<NoticeInfo> pagedNoticeInfo =  noticeService.getPagedNoticeList(curPage,pageSize,infoQuery);
-        // TOOD
-        return null;
+    @ApiOperation(value = "删除通知信息")
+    @DeleteMapping("/{noticeId}")
+    public void deleteNotice(@Validated @ApiParam(value = "通知id,多个以逗号分隔") @PathVariable(required = true) String noticeId) {
+        if (noticeId.indexOf(",")>-1 && noticeId.lastIndexOf(",")==noticeId.length()-1){
+            noticeId=noticeId.substring(0, noticeId.length()-1);
+        }
+        String[] noticeIdArr = noticeId.split(",");
+        List<Long> noticeIdList = Arrays.asList(noticeIdArr).stream()
+                .map(p -> {
+                    try{
+                        return Long.parseLong(p);
+                    }catch (Exception e){
+                        throw new StatusException("500005","通知id格式不正确");
+                    }
+                }).collect(Collectors.toList());
+        int result = noticeService.deleteNotice(getRootOrgId(),noticeIdList);
+        if (result==0){
+            throw new StatusException("500006","删除失败");
+        }
     }
 
     @GetMapping("/getUserNoticeList")
     @ApiOperation(value = "获取用户公告列表")
     public List<UserNoticeDomain> getUserNoticeList(UserNoticeDomainQuery query) {
         List<UserNoticeDomain> resultList = new ArrayList<>();
-        UserNoticeInfoQuery noticeQuery = getNoticeQuery(query);
+        UserNoticeInfoQuery noticeQuery = getNoticeInfoQueryFrom(query);
 
         List<UserNoticeInfo> noticeInfoList = noticeService.getNoticeList(noticeQuery);
 
         if (null != noticeInfoList && !noticeInfoList.isEmpty()) {
-            resultList = getNoticeDomainList(noticeInfoList);
+            resultList = getNoticeDomainListFrom(noticeInfoList);
         }
         return resultList;
     }
@@ -67,13 +122,13 @@ public class NoticeController extends ControllerSupport {
     @ApiOperation(value = "更新通知状态为已读")
     public void updateNoticeReadStatus(@ApiParam(value = "通知id,多个以逗号分隔") @RequestParam(required = true) String noticeId) {
         if (StringUtils.isNullOrEmpty(noticeId)) {
-            throw new StatusException("100001", "通知id不允许为空");
+            throw new StatusException("500001", "通知id不允许为空");
         }
         User user = this.getAccessUser();
         noticeService.updateNoticeReadStatus(noticeId, user.getUserType(), user.getUserId());
     }
 
-    private UserNoticeInfoQuery getNoticeQuery(UserNoticeDomainQuery query) {
+    private UserNoticeInfoQuery getNoticeInfoQueryFrom(UserNoticeDomainQuery query) {
         User user = this.getAccessUser();
         UserNoticeInfoQuery noticeQuery = new UserNoticeInfoQuery();
         noticeQuery.setHasRead(query.getHasRead());
@@ -83,7 +138,33 @@ public class NoticeController extends ControllerSupport {
         return noticeQuery;
     }
 
-    private List<UserNoticeDomain> getNoticeDomainList(List<UserNoticeInfo> noticeInfoList) {
+    private AddNoticeInfo getAddNoticeInfoFrom(AddNoticeDomain addNoticeDomain) {
+        AddNoticeInfo info = new AddNoticeInfo();
+        User accessUser = this.getAccessUser();
+        info.setContent(addNoticeDomain.getContent());
+        info.setPublisher(addNoticeDomain.getPublisher());
+        info.setPublishObjectId(addNoticeDomain.getPublishObjectId());
+        info.setRootOrgId(accessUser.getRootOrgId());
+        info.setRuleType(addNoticeDomain.getRuleType());
+        info.setUserId(accessUser.getUserId());
+        info.setNoticeStatus(addNoticeDomain.getNoticeStatus());
+        return info;
+    }
+    private UpdateNoticeInfo getUpdateNoticeInfoFrom(UpdateNoticeDomain updateNoticeDomain) {
+        UpdateNoticeInfo info = new UpdateNoticeInfo();
+        User accessUser = this.getAccessUser();
+        info.setId(updateNoticeDomain.getId());
+        info.setContent(updateNoticeDomain.getContent());
+        info.setPublisher(updateNoticeDomain.getPublisher());
+        info.setPublishObjectId(updateNoticeDomain.getPublishObjectId());
+        info.setRootOrgId(accessUser.getRootOrgId());
+        info.setRuleType(updateNoticeDomain.getRuleType());
+        info.setUserId(accessUser.getUserId());
+        info.setNoticeStatus(updateNoticeDomain.getNoticeStatus());
+        return info;
+    }
+
+    private List<UserNoticeDomain> getNoticeDomainListFrom(List<UserNoticeInfo> noticeInfoList) {
         List<UserNoticeDomain> resultList = new ArrayList<>();
         for (UserNoticeInfo info : noticeInfoList) {
             UserNoticeDomain domain = new UserNoticeDomain();
@@ -97,4 +178,29 @@ public class NoticeController extends ControllerSupport {
         }
         return resultList;
     }
+
+    private PageInfo<NoticeDomain> getPageInfoFrom(PageInfo<NoticeInfo> pagedNoticeInfo) {
+        PageInfo<NoticeDomain> resultPageInfo = new PageInfo<>();
+        resultPageInfo.setTotal(pagedNoticeInfo.getTotal());
+        resultPageInfo.setIndex(pagedNoticeInfo.getIndex());
+        resultPageInfo.setLimit(pagedNoticeInfo.getLimit());
+        resultPageInfo.setPages(pagedNoticeInfo.getPages());
+        resultPageInfo.setSize(pagedNoticeInfo.getSize());
+        List<NoticeInfo> infoList = pagedNoticeInfo.getList();
+        List<NoticeDomain> domainList = new ArrayList<>();
+        if (infoList != null && !infoList.isEmpty()) {
+            for (NoticeInfo ni : infoList) {
+                NoticeDomain domain = new NoticeDomain();
+                domain.setId(ni.getId());
+                domain.setPublisher(ni.getPublisher());
+                domain.setPublishStatus(ni.getPublishStatus());
+                domain.setPublishTime(ni.getPublishTime());
+                domain.setTitle(ni.getTitle());
+                domain.setPublishObject(ni.getPublishObject());
+                domainList.add(domain);
+            }
+        }
+        resultPageInfo.setList(domainList);
+        return resultPageInfo;
+    }
 }

+ 117 - 0
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/AddNoticeDomain.java

@@ -0,0 +1,117 @@
+/*
+ * *************************************************
+ * Copyright (c) 2018 QMTH. All Rights Reserved.
+ * Created by Deason on 2018-08-31 09:35:22.
+ * *************************************************
+ */
+
+package cn.com.qmth.examcloud.core.examwork.api.controller.bean;
+
+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.enums.PublishStatus;
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 添加通知信息实体
+ */
+public class AddNoticeDomain implements JsonSerializable {
+
+    private static final long serialVersionUID = -7739022488162924094L;
+
+    /**
+     * 标题
+     */
+    @ApiModelProperty("标题")
+    @NotNull(message = "标题不允许为空")
+    @Length(min = 1, max = 50, message = "标题长度不得超过50")
+    private String title;
+    /**
+     *  内容
+     */
+    @ApiModelProperty("内容")
+    @NotNull(message = "内容不允许为空")
+    private String content;
+
+    /**
+     * 规则类型
+     */
+    @Enumerated(EnumType.STRING)
+    @NotNull(message = "发送方式不允许为空")
+    private NoticeReceiverRuleType ruleType;
+
+    /**
+     * 公告状态
+     */
+    @Enumerated(EnumType.STRING)
+    @NotNull(message = "公告状态")
+    private NoticeStatus noticeStatus;
+    /**
+     * 发送对象
+     */
+    @ApiModelProperty("发送对象,多个以逗号分隔")
+    @NotNull(message = "发送对象不允许为空")
+    private String publishObjectId;
+    /**
+     * 发布者
+     */
+    @ApiModelProperty("发布者")
+    @NotNull(message = "发送人不允许为空")
+    private String publisher;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getPublishObjectId() {
+        return publishObjectId;
+    }
+
+    public void setPublishObjectId(String publishObjectId) {
+        this.publishObjectId = publishObjectId;
+    }
+
+    public String getPublisher() {
+        return publisher;
+    }
+
+    public void setPublisher(String publisher) {
+        this.publisher = publisher;
+    }
+
+
+    public NoticeReceiverRuleType getRuleType() {
+        return ruleType;
+    }
+
+    public void setRuleType(NoticeReceiverRuleType ruleType) {
+        this.ruleType = ruleType;
+    }
+
+    public NoticeStatus getNoticeStatus() {
+        return noticeStatus;
+    }
+
+    public void setNoticeStatus(NoticeStatus noticeStatus) {
+        this.noticeStatus = noticeStatus;
+    }
+}

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

@@ -14,10 +14,7 @@ import io.swagger.annotations.ApiModelProperty;
 import java.util.Date;
 
 /**
- * 考试分数信息
- *
- * @author: fengdesheng
- * @since: 2018/8/31
+ * 通知信息实体
  */
 public class NoticeDomain implements JsonSerializable {
 
@@ -36,7 +33,7 @@ public class NoticeDomain implements JsonSerializable {
      * 发送对象
      */
     @ApiModelProperty("发送对象")
-    private String receiverObject;
+    private String publishObject;
     /**
      * 发布者
      */
@@ -69,12 +66,12 @@ public class NoticeDomain implements JsonSerializable {
         this.title = title;
     }
 
-    public String getReceiverObject() {
-        return receiverObject;
+    public String getPublishObject() {
+        return publishObject;
     }
 
-    public void setReceiverObject(String receiverObject) {
-        this.receiverObject = receiverObject;
+    public void setPublishObject(String publishObject) {
+        this.publishObject = publishObject;
     }
 
     public String getPublisher() {

+ 127 - 0
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/UpdateNoticeDomain.java

@@ -0,0 +1,127 @@
+/*
+ * *************************************************
+ * Copyright (c) 2018 QMTH. All Rights Reserved.
+ * Created by Deason on 2018-08-31 09:35:22.
+ * *************************************************
+ */
+
+package cn.com.qmth.examcloud.core.examwork.api.controller.bean;
+
+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 org.hibernate.validator.constraints.Length;
+
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 添加通知信息实体
+ */
+public class UpdateNoticeDomain implements JsonSerializable {
+
+    private static final long serialVersionUID = -7739022488162924094L;
+
+    /**
+     * 通知id
+     */
+    @ApiModelProperty("通知id")
+    @NotNull(message = "通知id不允许为空")
+    private Long id;
+    /**
+     * 标题
+     */
+    @ApiModelProperty("标题")
+    @NotNull(message = "标题不允许为空")
+    @Length(min = 1, max = 50, message = "标题长度不得超过50")
+    private String title;
+    /**
+     *  内容
+     */
+    @ApiModelProperty("内容")
+    @NotNull(message = "内容不允许为空")
+    private String content;
+
+    /**
+     * 规则类型
+     */
+    @Enumerated(EnumType.STRING)
+    @NotNull(message = "发送方式不允许为空")
+    private NoticeReceiverRuleType ruleType;
+    /**
+     * 发送对象
+     */
+    @ApiModelProperty("发送对象,多个以逗号分隔")
+    @NotNull(message = "发送对象不允许为空")
+    private String publishObjectId;
+    /**
+     * 发布者
+     */
+    @ApiModelProperty("发布者")
+    @NotNull(message = "发送人不允许为空")
+    private String publisher;
+    /**
+     * 公告状态
+     */
+    @Enumerated(EnumType.STRING)
+    @NotNull(message = "公告状态")
+    private NoticeStatus noticeStatus;
+
+    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 String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getPublishObjectId() {
+        return publishObjectId;
+    }
+
+    public void setPublishObjectId(String publishObjectId) {
+        this.publishObjectId = publishObjectId;
+    }
+
+    public String getPublisher() {
+        return publisher;
+    }
+
+    public void setPublisher(String publisher) {
+        this.publisher = publisher;
+    }
+
+    public NoticeReceiverRuleType getRuleType() {
+        return ruleType;
+    }
+
+    public void setRuleType(NoticeReceiverRuleType ruleType) {
+        this.ruleType = ruleType;
+    }
+
+    public NoticeStatus getNoticeStatus() {
+        return noticeStatus;
+    }
+
+    public void setNoticeStatus(NoticeStatus noticeStatus) {
+        this.noticeStatus = noticeStatus;
+    }
+}

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

@@ -0,0 +1,76 @@
+package cn.com.qmth.examcloud.core.examwork.api.provider;
+
+import cn.com.qmth.examcloud.api.commons.enums.CURD;
+import cn.com.qmth.examcloud.api.commons.enums.ExamType;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.commons.helpers.DynamicEnum;
+import cn.com.qmth.examcloud.commons.helpers.DynamicEnumManager;
+import cn.com.qmth.examcloud.core.examwork.base.enums.ExamProperty;
+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.ExamInfo;
+import cn.com.qmth.examcloud.core.examwork.service.impl.ExamServiceImpl;
+import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
+import cn.com.qmth.examcloud.examwork.api.NoticeCloudService;
+import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
+import cn.com.qmth.examcloud.examwork.api.bean.ExamCourseRelationBean;
+import cn.com.qmth.examcloud.examwork.api.bean.ExamPaperTypeRelation;
+import cn.com.qmth.examcloud.examwork.api.bean.ExamSpecialSettingsBean;
+import cn.com.qmth.examcloud.examwork.api.request.*;
+import cn.com.qmth.examcloud.examwork.api.response.*;
+import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
+import cn.com.qmth.examcloud.web.support.ControllerSupport;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.persistence.criteria.Predicate;
+import java.util.*;
+
+/**
+ * 考试云服务
+ *
+ * @author WANGWEI
+ * @date 2018年11月23日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+@Transactional
+@RestController
+@RequestMapping("${$rmp.cloud.examwork}" + "notice")
+public class NoticeCloudServiceProvider extends ControllerSupport implements NoticeCloudService {
+
+
+	@Autowired
+	private NoticeService noticeService;
+
+	@ApiOperation(value = "处理发布中的用户通知数据")
+	@PostMapping("disposePublishingUserNotice")
+	@Override
+	public void disposePublishingUserNotice() {
+		noticeService.disposePublishingUserNotice();
+	}
+
+
+	@ApiOperation(value = "清理过期的通知数据")
+	@PostMapping("disposeOverdueNotice")
+	@Override
+	public void disposeOverdueNotice() {
+		noticeService.disposeOverdueNotice();
+	}
+
+}

+ 12 - 0
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/ExamStudentRepo.java

@@ -6,6 +6,7 @@ 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.Param;
 import org.springframework.data.repository.query.QueryByExampleExecutor;
 
 import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamStudentEntity;
@@ -71,4 +72,15 @@ public interface ExamStudentRepo
 	@Query(value = "select distinct course_level from ec_e_exam_student t where t.student_id=?1", nativeQuery = true)
 	List<String> queryCourseLevelList(Long studentId);
 
+//	@Query(value = "select DISTINCT student_id  from ec_e_exam_student where root_org_id=?1 order by student_id asc limit ?2", nativeQuery = true)
+//    List<Long> findLimitStudentIdList(Long rootOrgId, int rowNumber);
+
+	@Query(value = "select DISTINCT student_id  from ec_e_exam_student where root_org_id=?1 and student_id>=?2 order by student_id asc limit ?3", nativeQuery = true)
+	List<Long> findLimitStudentIdList(Long rootOrgId, Long maxStudentId,int rowNumber);
+
+//	@Query(value = "select DISTINCT student_id  from ec_e_exam_student where root_org_id= :rootOrgId  and exam_id in (:examIds) order by student_id asc limit :rowNumber", nativeQuery = true)
+//	List<Long> findByExamIdLimitStudentIdList(@Param("rootOrgId") Long rootOrgId,@Param("examIds")  List<Long> examIds,@Param("rowNumber")  int rowNumber);
+
+	@Query(value = "select DISTINCT student_id  from ec_e_exam_student where root_org_id= :rootOrgId and student_id>= :maxStudentId and exam_id in (:examIds) order by student_id asc limit :rowNumber", nativeQuery = true)
+	List<Long> findByExamIdLimitStudentIdList(@Param("rootOrgId") Long rootOrgId,@Param("examIds")  List<Long> examIds,@Param("maxStudentId") Long maxStudentId,@Param("rowNumber")  int rowNumber);
 }

+ 14 - 0
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/NoticePublishScheduleRepo.java

@@ -4,11 +4,25 @@ import cn.com.qmth.examcloud.api.commons.enums.PublishStatus;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticePublishScheduleEntity;
 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.List;
 
 public interface NoticePublishScheduleRepo extends JpaRepository<NoticePublishScheduleEntity, Long>,
         QueryByExampleExecutor<NoticePublishScheduleEntity>, JpaSpecificationExecutor<NoticePublishScheduleEntity> {
     List<NoticePublishScheduleEntity> findByRootOrgIdAndPublishStatus(Long rootOrgId, PublishStatus publishStatus);
+
+    NoticePublishScheduleEntity findByRootOrgIdAndNoticeId(Long rootOrgId,Long noticeId);
+
+    List<NoticePublishScheduleEntity> findByPublishStatus(PublishStatus publishStatus);
+
+    @Modifying
+    int deleteByRootOrgIdAndNoticeIdIn(Long rootOrgId,List<Long> noticeId);
+
+    @Transactional
+    @Modifying
+    void deleteByNoticeId(Long noticeId);
 }

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

@@ -3,8 +3,19 @@ package cn.com.qmth.examcloud.core.examwork.dao;
 import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticeReceiverRuleEntity;
 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.repository.query.QueryByExampleExecutor;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
 
 public interface NoticeReceiverRuleRepo extends JpaRepository<NoticeReceiverRuleEntity, Long>,
         QueryByExampleExecutor<NoticeReceiverRuleEntity>, JpaSpecificationExecutor<NoticeReceiverRuleEntity> {
+    List<NoticeReceiverRuleEntity> findByRootOrgIdAndNoticeId(Long rootOrgId,Long noticeId);
+
+    int deleteByRootOrgIdAndNoticeIdIn(Long rootOrgId, List<Long> noticeIdList);
+
+    @Transactional
+    @Modifying
+    void deleteByNoticeId(Long noticeId);
 }

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

@@ -5,9 +5,14 @@ import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.repository.query.QueryByExampleExecutor;
 
+import java.util.Date;
 import java.util.List;
 
 public interface NoticeRepo extends JpaRepository<NoticeEntity, Long>,
         QueryByExampleExecutor<NoticeEntity>, JpaSpecificationExecutor<NoticeEntity> {
     List<NoticeEntity> findByIdIn(List<Long> ids);
+
+    int deleteByIdIn(List<Long> noticeIdList);
+
+    List<NoticeEntity> findByCreationTimeBefore(Date lastYear);
 }

+ 7 - 2
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/UserNoticeRepo.java

@@ -7,16 +7,21 @@ 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.List;
 
 public interface UserNoticeRepo extends JpaRepository<UserNoticeEntity, Long>,
         QueryByExampleExecutor<UserNoticeEntity>, JpaSpecificationExecutor<UserNoticeEntity> {
-    List<UserNoticeEntity> findByRootOrgIdAndUserTypeAndUserId(Long rootOrgId,UserType userType,Long userId);
+    List<UserNoticeEntity> findByRootOrgIdAndUserTypeAndUserIdOrderByCreationTimeDesc(Long rootOrgId,UserType userType,Long userId);
 
-    List<UserNoticeEntity> findByRootOrgIdAndUserTypeAndUserIdAndHasRead(Long rootOrgId,UserType userType,Long userId,Boolean hasRead);
+    List<UserNoticeEntity> findByRootOrgIdAndUserTypeAndUserIdAndHasReadOrderByCreationTimeDesc(Long rootOrgId,UserType userType,Long userId,Boolean hasRead);
 
     @Modifying
     @Query(value = "update EC_E_USER_NOTICE set has_read = 1 where notice_id in ?1 and user_type = ?2 and user_id = ?3",nativeQuery = true)
     int updateNoticeReadStatus(String noticeId, UserType userType, Long userId);
+
+    @Transactional
+    @Modifying
+    void deleteByNoticeId(Long noticeId);
 }

+ 7 - 1
examcloud-core-examwork-service/pom.xml

@@ -32,7 +32,13 @@
 			<artifactId>examcloud-task-api-client</artifactId>
 			<version>${examcloud.version}</version>
 		</dependency>
+        <dependency>
+            <groupId>cn.com.qmth.examcloud.rpc</groupId>
+            <artifactId>examcloud-core-marking-api</artifactId>
+            <version>2019-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
 
-	</dependencies>
+    </dependencies>
 
 </project>

+ 35 - 4
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/NoticeService.java

@@ -9,10 +9,8 @@ package cn.com.qmth.examcloud.core.examwork.service;
 
 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.service.bean.NoticeInfo;
-import cn.com.qmth.examcloud.core.examwork.service.bean.NoticeInfoQuery;
-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.dao.entity.NoticePublishScheduleEntity;
+import cn.com.qmth.examcloud.core.examwork.service.bean.*;
 
 import java.util.List;
 
@@ -45,4 +43,37 @@ public interface NoticeService {
      * @return
      */
     PageInfo<NoticeInfo> getPagedNoticeList(Integer curPage, Integer pageSize, NoticeInfoQuery infoQuery);
+
+
+    /**
+     * 删除通知
+     * @param rootOrgId
+     * @param noticeIdList
+     * @return
+     */
+    int deleteNotice(Long rootOrgId,List<Long> noticeIdList);
+
+    /**
+     * 添加通知
+     * @param addNoticeInfo
+     * @return
+     */
+    int addNotice(AddNoticeInfo addNoticeInfo);
+
+    /**
+     * 获取通知信息
+     * @param info
+     * @return
+     */
+    int updateNotice(UpdateNoticeInfo info);
+
+    /**
+     * 处理待发送的用户通知(自动服务调用)
+     */
+    void disposePublishingUserNotice();
+
+    /**
+     * 处理过期的通知数据(自动服务调用)
+     */
+    void disposeOverdueNotice();
 }

+ 127 - 0
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/AddNoticeInfo.java

@@ -0,0 +1,127 @@
+/*
+ * *************************************************
+ * Copyright (c) 2018 QMTH. All Rights Reserved.
+ * Created by Deason on 2018-08-31 09:35:22.
+ * *************************************************
+ */
+
+package cn.com.qmth.examcloud.core.examwork.service.bean;
+
+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 javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 添加通知信息实体
+ */
+public class AddNoticeInfo implements JsonSerializable {
+
+    private static final long serialVersionUID = -7739022488162924094L;
+
+    /**
+     * 组织机构id
+     */
+    private Long rootOrgId;
+    /**
+     * 用户id
+     */
+    private Long userId;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 规则类型
+     */
+    @Enumerated(EnumType.STRING)
+    private NoticeReceiverRuleType ruleType;
+
+    /**
+     * 公告状态
+     */
+    @Enumerated(EnumType.STRING)
+    @NotNull(message = "公告状态")
+    private NoticeStatus noticeStatus;
+    /**
+     * 发送对象
+     */
+    private String publishObjectId;
+    /**
+     * 发布者
+     */
+    private String publisher;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getPublishObjectId() {
+        return publishObjectId;
+    }
+
+    public void setPublishObjectId(String publishObjectId) {
+        this.publishObjectId = publishObjectId;
+    }
+
+    public String getPublisher() {
+        return publisher;
+    }
+
+    public void setPublisher(String publisher) {
+        this.publisher = publisher;
+    }
+
+
+    public NoticeReceiverRuleType getRuleType() {
+        return ruleType;
+    }
+
+    public void setRuleType(NoticeReceiverRuleType ruleType) {
+        this.ruleType = ruleType;
+    }
+
+    public Long getRootOrgId() {
+        return rootOrgId;
+    }
+
+    public void setRootOrgId(Long rootOrgId) {
+        this.rootOrgId = rootOrgId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public NoticeStatus getNoticeStatus() {
+        return noticeStatus;
+    }
+
+    public void setNoticeStatus(NoticeStatus noticeStatus) {
+        this.noticeStatus = noticeStatus;
+    }
+}

+ 48 - 0
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/GetLimitUserIdResp.java

@@ -0,0 +1,48 @@
+package cn.com.qmth.examcloud.core.examwork.service.bean;
+
+import java.util.List;
+
+/**
+ * @Description 获取指定数量用户id的响应类
+ * @Author THINKPAD
+ * @Date 2019/7/10 15:08
+ * @Version 1.0
+ */
+public class GetLimitUserIdResp {
+    /**
+     * id集合
+     */
+    List<Long> idList;
+    /**
+     * 集合中最大用户id
+     */
+    Long maxId;
+    /**
+     * 下一个id
+     */
+    Long nextId;
+
+    public List<Long> getIdList() {
+        return idList;
+    }
+
+    public void setIdList(List<Long> idList) {
+        this.idList = idList;
+    }
+
+    public Long getNextId() {
+        return nextId;
+    }
+
+    public void setNextId(Long nextId) {
+        this.nextId = nextId;
+    }
+
+    public Long getMaxId() {
+        return maxId;
+    }
+
+    public void setMaxId(Long maxId) {
+        this.maxId = maxId;
+    }
+}

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

@@ -36,7 +36,7 @@ public class NoticeInfo implements JsonSerializable {
      * 发送对象
      */
     @ApiModelProperty("发送对象")
-    private String receiverObject;
+    private String publishObject;
     /**
      * 发布者
      */
@@ -69,12 +69,12 @@ public class NoticeInfo implements JsonSerializable {
         this.title = title;
     }
 
-    public String getReceiverObject() {
-        return receiverObject;
+    public String getPublishObject() {
+        return publishObject;
     }
 
-    public void setReceiverObject(String receiverObject) {
-        this.receiverObject = receiverObject;
+    public void setPublishObject(String publishObject) {
+        this.publishObject = publishObject;
     }
 
     public String getPublisher() {

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

@@ -20,7 +20,14 @@ public class NoticeInfoQuery implements JsonSerializable {
 
     private static final long serialVersionUID = -1962646957678995495L;
 
+    /**
+     * 学校id
+     */
     private Long rootOrgId;
+    /**
+     * 用户id
+     */
+    private long userId;
     /**
      * 标题
      */
@@ -40,6 +47,14 @@ public class NoticeInfoQuery implements JsonSerializable {
         this.rootOrgId = rootOrgId;
     }
 
+    public long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(long userId) {
+        this.userId = userId;
+    }
+
     public String getTitle() {
         return title;
     }

+ 137 - 0
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/bean/UpdateNoticeInfo.java

@@ -0,0 +1,137 @@
+/*
+ * *************************************************
+ * Copyright (c) 2018 QMTH. All Rights Reserved.
+ * Created by Deason on 2018-08-31 09:35:22.
+ * *************************************************
+ */
+
+package cn.com.qmth.examcloud.core.examwork.service.bean;
+
+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 javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 添加通知信息实体
+ */
+public class UpdateNoticeInfo implements JsonSerializable {
+
+    private static final long serialVersionUID = -7739022488162924094L;
+
+    /**
+     * 通知id
+     */
+    private Long id;
+    /**
+     * 组织机构id
+     */
+    private Long rootOrgId;
+    /**
+     * 用户id
+     */
+    private Long userId;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 规则类型
+     */
+    private NoticeReceiverRuleType ruleType;
+    /**
+     * 发送对象
+     */
+    private String publishObjectId;
+    /**
+     * 发布者
+     */
+    private String publisher;
+
+    /**
+     * 公告状态
+     */
+    @Enumerated(EnumType.STRING)
+    @NotNull(message = "公告状态")
+    private NoticeStatus noticeStatus;
+
+    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 String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getPublishObjectId() {
+        return publishObjectId;
+    }
+
+    public void setPublishObjectId(String publishObjectId) {
+        this.publishObjectId = publishObjectId;
+    }
+
+    public String getPublisher() {
+        return publisher;
+    }
+
+    public void setPublisher(String publisher) {
+        this.publisher = publisher;
+    }
+
+    public NoticeReceiverRuleType getRuleType() {
+        return ruleType;
+    }
+
+    public void setRuleType(NoticeReceiverRuleType ruleType) {
+        this.ruleType = ruleType;
+    }
+
+    public Long getRootOrgId() {
+        return rootOrgId;
+    }
+
+    public void setRootOrgId(Long rootOrgId) {
+        this.rootOrgId = rootOrgId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public NoticeStatus getNoticeStatus() {
+        return noticeStatus;
+    }
+
+    public void setNoticeStatus(NoticeStatus noticeStatus) {
+        this.noticeStatus = noticeStatus;
+    }
+}

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

@@ -1,31 +1,44 @@
 package cn.com.qmth.examcloud.core.examwork.service.impl;
 
+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.enums.PublishStatus;
 import cn.com.qmth.examcloud.api.commons.exchange.PageInfo;
 import cn.com.qmth.examcloud.api.commons.security.bean.UserType;
+import cn.com.qmth.examcloud.api.commons.security.enums.RoleMeta;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.util.DBUtil;
-import cn.com.qmth.examcloud.commons.util.StringUtil;
-import cn.com.qmth.examcloud.core.examwork.dao.NoticePublishScheduleRepo;
-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.NoticeEntity;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.NoticePublishScheduleEntity;
-import cn.com.qmth.examcloud.core.examwork.dao.entity.UserNoticeEntity;
+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.service.NoticeService;
-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.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.MarkWorkBean;
+import cn.com.qmth.examcloud.marking.api.request.GetMarkWorkReq;
+import cn.com.qmth.examcloud.marking.api.request.GetMarkersByWorkIdsReq;
+import cn.com.qmth.examcloud.marking.api.response.GetMarkWorkResp;
+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.assertj.core.util.DateUtil;
 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.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -42,22 +55,34 @@ public class NoticeServiceImpl implements NoticeService {
     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.findByRootOrgIdAndUserTypeAndUserIdAndHasRead(query.getRootOrgId(),query.getUserType(), query.getUserId(),query.getHasRead());
-        }else {
-            userNoticeList = userNoticeRepo.findByRootOrgIdAndUserTypeAndUserId(query.getRootOrgId(),query.getUserType(), query.getUserId());
+        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()){
+        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("500001","找不到id为:"+un.getNoticeId()+"的通知");
+            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());
@@ -74,26 +99,27 @@ public class NoticeServiceImpl implements NoticeService {
 
     @Override
     public int updateNoticeReadStatus(String noticeId, UserType userType, Long userId) {
-        return userNoticeRepo.updateNoticeReadStatus(noticeId,userType,userId);
+        return userNoticeRepo.updateNoticeReadStatus(noticeId, userType, userId);
     }
 
     @Override
     public PageInfo<NoticeInfo> getPagedNoticeList(Integer curPage, Integer pageSize, NoticeInfoQuery infoQuery) {
-        Specification<NoticeEntity> specification = (root,query,cb)->{
+        Long rootOrgId = infoQuery.getRootOrgId();
+        Specification<NoticeEntity> specification = (root, query, cb) -> {
             List<Predicate> predicates = new ArrayList<>();
-            predicates.add(cb.equal(root.get("rootOrgId"),infoQuery.getPublishStatus()));
-            if (!StringUtils.isNullOrEmpty(infoQuery.getTitle())){
+            predicates.add(cb.equal(root.get("rootOrgId"), infoQuery.getPublishStatus()));
+            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(infoQuery.getRootOrgId(), infoQuery.getPublishStatus());
-                if (null == byPublishStatusNoticeScheduleList || byPublishStatusNoticeScheduleList.isEmpty()){
-                    throw  new StatusException("500001","通知发布状态数据异常");
+            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){
+                for (Long nid : noticeIdList) {
                     inCriteriaBuilder.value(nid);
                 }
                 predicates.add(inCriteriaBuilder);
@@ -101,17 +127,581 @@ public class NoticeServiceImpl implements NoticeService {
 
             return cb.and(predicates.toArray(new Predicate[predicates.size()]));
         };
-        //TODO
-        return  null;
+        PageRequest pageRequest = PageRequest.of(curPage, pageSize,
+                new Sort(Sort.Direction.DESC, "creationTime"));
+        Page<NoticeEntity> pagedNoticeEntityList = noticeRepo.findAll(specification, pageRequest);
+        List<NoticeInfo> resultList = new ArrayList<>();
+        for (NoticeEntity ne : pagedNoticeEntityList) {
+            NoticeInfo ni = new NoticeInfo();
+            ni.setId(ne.getId());
+            ni.setPublisher(ne.getPublisher());
+            ni.setPublishTime(ne.getPublishTime());
+            ni.setTitle(ne.getTitle());
+            ni.setPublishObject(getPublishObject(rootOrgId, ne.getId()));
+            ni.setPublishStatus(getNoticePublishStatus(rootOrgId, ne));
+            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 = Arrays.asList(info.getId());
+        //校验通知状态,正在发送的通知不允许修改
+        NoticePublishScheduleEntity publishSchedule = noticePublishScheduleRepo.findByRootOrgIdAndNoticeId(info.getRootOrgId(), info.getId());
+        if (publishSchedule == null) {
+            throw new StatusException("501007", "找不到通知id为:" + info.getId() + "的通知进度数据");
+        }
+        if (publishSchedule.getPublishStatus() != PublishStatus.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 savedSchedule == null ? 0 : 1;
+    }
+
+    @Override
+    public void disposePublishingUserNotice() {
+        List<NoticePublishScheduleEntity> publishingScheduleList = noticePublishScheduleRepo.findByPublishStatus(PublishStatus.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 = noticeReceiverRuleRepo.findByRootOrgIdAndNoticeId(rootOrgId, noticeId);
+            if (ruleList == null) {
+                throw new StatusException("501009", "找不到通知id为:" + 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);
+        //返回的下一个用户id
+        Long nextId = getLimitUserIdResp.getNextId();
+        //满足条件集合中的最大用户id
+        Long maxUserId = getLimitUserIdResp.getMaxId();
+        //满足条件的用户id集合(可能为空)
+        List<Long> limitStudentIdList = getLimitUserIdResp.getIdList();
+
+        //如果起始id和方法返回的下次查询id相同,说明数据已经取完,否则继续查询
+        if (startUserId == nextId) {
+            finishNoticePublishSchedule(rootOrgId, noticeId, ruleType, publishSchedule, limitStudentIdList);
+        } else {
+            updateNoticePublishSchedule(publishSchedule, maxUserId);
+            batchAddUserNotice(rootOrgId, noticeId, rowNumber, startUserId, ruleType, ruleList, publishSchedule);
+        }
+    }
+
+    /**
+     * 更新发布进度
+     *
+     * @param publishSchedule
+     * @param maxUserId
+     */
+    private void updateNoticePublishSchedule(NoticePublishScheduleEntity publishSchedule, Long maxUserId) {
+        publishSchedule.setMaxStudentId(maxUserId);
+        noticePublishScheduleRepo.save(publishSchedule);
+    }
+
+    /**
+     * 最终完成发布状态
+     *
+     * @param rootOrgId
+     * @param noticeId
+     * @param ruleType
+     * @param publishSchedule
+     * @param limitStudentIdList
+     */
+    @Transactional
+    public void finishNoticePublishSchedule(Long rootOrgId, Long noticeId, NoticeReceiverRuleType ruleType, NoticePublishScheduleEntity publishSchedule, List<Long> limitStudentIdList) {
+        //保存并更新发布状态为发布完成
+        List<UserNoticeEntity> userNoticeList = new ArrayList<>();
+        for (Long userId : limitStudentIdList) {
+            UserNoticeEntity userNotice = initUserNoticeEntity(rootOrgId, userId, noticeId, ruleType);
+            userNoticeList.add(userNotice);
+        }
+        userNoticeRepo.saveAll(userNoticeList);
+        publishSchedule.setPublishStatus(PublishStatus.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);
+        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());
+        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.setRoleId(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 PublishStatus 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 String getPublishObject(Long rootOrgId, Long noticeId) {
+        List<NoticeReceiverRuleEntity> ruleList =
+                noticeReceiverRuleRepo.findByRootOrgIdAndNoticeId(rootOrgId, noticeId);
+        if (ruleList == null || ruleList.isEmpty()) {
+            throw new StatusException("501002", "未找到公告接收人相关信息");
+        }
+        //公告接收人类型
+        NoticeReceiverRuleType ruleType = ruleList.stream().map(NoticeReceiverRuleEntity::getRuleType).findFirst().get();
+
+        switch (ruleType) {
+            case STUDENTS_OF_EXAM:
+                return getExamStudentObject(ruleList);
+            case ALL_STUDENTS_OF_ROOT_ORG:
+                return "所有学生";
+            case COMMON_USERS_OF_ROLE:
+                return "所有学习中心用户";
+            case TEACHER_OF_MARK_WORK:
+                return getMarkTeacherObject(rootOrgId, ruleList);
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * 组装学生发布对象
+     *
+     * @param ruleList
+     * @return
+     */
+    private String getExamStudentObject(List<NoticeReceiverRuleEntity> ruleList) {
+        String publishObject = "";
+        //考试批次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) {
+            publishObject += "学生-" + e.getName() + ";";
+        }
+        return publishObject;
+    }
+
+    /**
+     * 组装阅卷老师发布对象
+     *
+     * @param rootOrgId
+     * @param ruleList
+     * @return
+     */
+    private String getMarkTeacherObject(Long rootOrgId, List<NoticeReceiverRuleEntity> ruleList) {
+        String publishObject = "";
+        List<Long> markWorkIdList = ruleList.stream().map(p -> Long.parseLong(p.getRuleValue())).collect(Collectors.toList());
+        GetMarkWorkReq req = new GetMarkWorkReq();
+        MarkWorkBean bean = new MarkWorkBean();
+        bean.setRootOrgId(rootOrgId);
+        bean.setStatus(1);
+        req.setMarkWorkBean(bean);
+        GetMarkWorkResp markWorkResp = markWorkCloudService.getMarkWork(req);
+        List<MarkWorkBean> markWorkList = markWorkResp.getMarkWorkBeanList();
+        for (Long mwId : markWorkIdList) {
+            Optional<MarkWorkBean> workBeanOptional = markWorkList.stream().filter(p -> p.getId().equals(mwId)).findFirst();
+            if (!workBeanOptional.isPresent()) {
+                throw new StatusException("501004", "找不到id为:" + mwId + "的教务工作信息");
+            }
+            MarkWorkBean mw = workBeanOptional.get();
+            publishObject += "老师-" + mw.getName() + ";";
+        }
+        return publishObject;
     }
 
 
+    /**
+     * 根据通知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()){
+        if (optional.isPresent()) {
             return optional.get();
-        }else{
+        } 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(PublishStatus.PUBLISHING);
+        } else {
+            publishScheduleEntity.setPublishStatus(PublishStatus.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(PublishStatus.PUBLISHING);
+        } else {
+            publishScheduleEntity.setPublishStatus(PublishStatus.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;
+    }
 }