소스 검색

Merge branch 'err_data_export'

Joburgess 4 년 전
부모
커밋
105becc28d
19개의 변경된 파일2085개의 추가작업 그리고 2개의 파일을 삭제
  1. 147 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/IndexErrDataRecordDao.java
  2. 21 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleEndDto.java
  3. 75 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/IndexErrorDataExportDto.java
  4. 105 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/IndexErrDataRecord.java
  5. 22 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/InspectionItem.java
  6. 22 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/InspectionItemPlan.java
  7. 40 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/EndCourseScheduleQueryInfo.java
  8. 50 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/IndexErrRecordQueryInfo.java
  9. 40 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/InspectionItemPlanQueryInfo.java
  10. 40 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/InspectionQueryInfo.java
  11. 87 0
      mec-biz/src/main/java/com/ym/mec/biz/service/IndexErrDataRecordService.java
  12. 527 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexErrDataRecordServiceImpl.java
  13. 622 0
      mec-biz/src/main/resources/config/mybatis/IndexErrDataRecordMapper.xml
  14. 4 0
      mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java
  15. 5 0
      mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java
  16. 23 0
      mec-task/src/main/java/com/ym/mec/task/jobs/IndexErrDataRecordTask.java
  17. 56 0
      mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java
  18. 190 0
      mec-web/src/main/java/com/ym/mec/web/controller/IndexErrDataRecordController.java
  19. 9 0
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

+ 147 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/IndexErrDataRecordDao.java

@@ -0,0 +1,147 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.ym.mec.biz.dal.dto.CourseScheduleEndDto;
+import com.ym.mec.biz.dal.entity.InspectionItem;
+import com.ym.mec.biz.dal.entity.InspectionItemPlan;
+import com.ym.mec.biz.dal.enums.IndexErrorType;
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.biz.dal.entity.IndexErrDataRecord;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface IndexErrDataRecordDao extends BaseDAO<Long, IndexErrDataRecord> {
+
+    int batchInsert(@Param("datas") List<IndexErrDataRecord> datas);
+
+    int batchUpdate(@Param("datas") List<IndexErrDataRecord> datas);
+
+    int deleteWithGenerateTimeAndType(@Param("generateTime") String generateTime,
+                                      @Param("dataType") IndexErrorType dataType);
+
+    /**
+     * @describe 统计指定日期产生的异常数量
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param generateTime:
+     * @return int
+     */
+    int countWithGenerateTime(@Param("generateTime") String generateTime);
+
+    /**
+     * @describe 获取所有异常相关教务老师编号
+     * @author Joburgess
+     * @date 2021/6/2 0002
+     * @param organIds:
+     * @return java.util.List<java.lang.Integer>
+     */
+    List<Integer> getAllDealUserIds(@Param("organIds") Collection organIds);
+
+    /**
+     * @describe 根据产生日期
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param generateStartTime:
+     * @param generateEndTime:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> getWithGenerateTime(@Param("organIds") Set<Integer> organIds,
+                                                 @Param("generateStartTime") String generateStartTime,
+                                                @Param("generateEndTime") String generateEndTime);
+
+    /**
+     * @describe 查询未处理记录
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> findUntreatedRecord();
+
+    /**
+     * @describe 乐团巡查事项异常
+     * @author Joburgess
+     * @date 2021/5/27 0027
+     * @param date:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> queryErrInspection(@Param("date") String date,
+                                                @Param("dates") Set<String> dates);
+
+    /**
+     * @describe 乐团巡查任务未提交
+     * @author Joburgess
+     * @date 2021/5/27 0027
+     * @param date:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> queryInspectionItemPlan(@Param("date") String date,
+                                                     @Param("dates") Set<String> dates);
+
+    /**
+     * @describe 回访任务未完成
+     * @author Joburgess
+     * @date 2021/5/27 0027
+     * @param date:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> queryStudentVisit(@Param("date") String date,
+                                               @Param("dates") Set<String> dates);
+
+    /**
+     * @describe 课程考勤异常
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param date:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> getAttendanceError(@Param("date") String date,
+                                                @Param("dates") Set<String> dates);
+
+    /**
+     * @describe 课程异常
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param date:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrDataRecord> getNoAttendance(@Param("date") String date,
+                                             @Param("dates") Set<String> dates);
+
+    List<String> queryErrStrings(Map<String, Object> params);
+    int queryErrStringsCount(Map<String, Object> params);
+    List<IndexErrDataRecord> getWithOrganMonthUserStr(@Param("omuStrings") List<String> omuStrings);
+    List<IndexErrDataRecord> getAllErrDatas(Map<String, Object> params);
+
+    /**
+     * @describe 历史异常数据-乐团巡查事项异常/乐团巡查任务未提交
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param params:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.InspectionItemPlan>
+     */
+    List<InspectionItemPlan> queryErrInspectionData(Map<String, Object> params);
+    int errInspectionDataCount(Map<String, Object> params);
+
+    /**
+     * @describe 历史异常数据-回访任务未完成
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param params:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.InspectionItem>
+     */
+    List<InspectionItem> queryErrStudentVisit(Map<String, Object> params);
+    int studentVisitCount(Map<String, Object> params);
+
+    /**
+     * @return java.util.List<com.ym.mec.biz.dal.dto.CourseScheduleEndDto>
+     * @describe 历史异常数据-课程(课程考勤异常/课程异常)
+     * @author Joburgess
+     * @date 2019/12/27
+     */
+    List<CourseScheduleEndDto> queryHistoryErrCourseData(Map<String, Object> params);
+    int historyErrCourseDataCount(Map<String, Object> params);
+	
+}

+ 21 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseScheduleEndDto.java

@@ -50,6 +50,27 @@ public class CourseScheduleEndDto extends CourseSchedule {
 
     private boolean beMerged;
 
+    private Date generateTime;
+
+    /** 处理时间 */
+    private java.util.Date dealTime;
+
+    public Date getGenerateTime() {
+        return generateTime;
+    }
+
+    public void setGenerateTime(Date generateTime) {
+        this.generateTime = generateTime;
+    }
+
+    public Date getDealTime() {
+        return dealTime;
+    }
+
+    public void setDealTime(Date dealTime) {
+        this.dealTime = dealTime;
+    }
+
     public String getEducationTeacherName() {
         return educationTeacherName;
     }

+ 75 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/IndexErrorDataExportDto.java

@@ -12,12 +12,19 @@ public class IndexErrorDataExportDto {
 
     private String organName;
 
+    private String generateTime;
+
+    private String dealUserName;
+
     @ApiModelProperty(value = "基础技能班学员数量异常")
     private int highClassStudentLessThanThreeNum;
 
     @ApiModelProperty(value = "乐团巡查事项异常")
     private int musicPatrolItem;
 
+    @ApiModelProperty(value = "乐团巡查事项异常-剩余")
+    private int musicPatrolItemSurplus;
+
     @ApiModelProperty(value = "未加入任何班级学员")
     private int noClassMusicGroupStudentInfo;
 
@@ -39,15 +46,27 @@ public class IndexErrorDataExportDto {
     @ApiModelProperty(value = "乐团巡查任务未提交")
     private int inspectionItemPlan;
 
+    @ApiModelProperty(value = "乐团巡查任务未提交-剩余")
+    private int inspectionItemPlanSurplus;
+
     @ApiModelProperty(value = "回访任务未完成")
     private int studentVisit;
 
+    @ApiModelProperty(value = "回访任务未完成-剩余")
+    private int studentVisitSurplus;
+
     @ApiModelProperty(value = "课程考勤异常")
     private int teacherExceptionAttendance;
 
+    @ApiModelProperty(value = "课程考勤异常-剩余")
+    private int teacherExceptionAttendanceSurplus;
+
     @ApiModelProperty(value = "课程异常")
     private int teacherNotAClass;
 
+    @ApiModelProperty(value = "课程异常-剩余")
+    private int teacherNotAClassSurplus;
+
     @ApiModelProperty(value = "服务指标异常")
     private int teacherServeError;
 
@@ -70,6 +89,22 @@ public class IndexErrorDataExportDto {
         this.organName = organName;
     }
 
+    public String getGenerateTime() {
+        return generateTime;
+    }
+
+    public void setGenerateTime(String generateTime) {
+        this.generateTime = generateTime;
+    }
+
+    public String getDealUserName() {
+        return dealUserName;
+    }
+
+    public void setDealUserName(String dealUserName) {
+        this.dealUserName = dealUserName;
+    }
+
     public int getHighClassStudentLessThanThreeNum() {
         return highClassStudentLessThanThreeNum;
     }
@@ -181,4 +216,44 @@ public class IndexErrorDataExportDto {
     public void setTotal(int total) {
         this.total = total;
     }
+
+    public int getMusicPatrolItemSurplus() {
+        return musicPatrolItemSurplus;
+    }
+
+    public void setMusicPatrolItemSurplus(int musicPatrolItemSurplus) {
+        this.musicPatrolItemSurplus = musicPatrolItemSurplus;
+    }
+
+    public int getInspectionItemPlanSurplus() {
+        return inspectionItemPlanSurplus;
+    }
+
+    public void setInspectionItemPlanSurplus(int inspectionItemPlanSurplus) {
+        this.inspectionItemPlanSurplus = inspectionItemPlanSurplus;
+    }
+
+    public int getStudentVisitSurplus() {
+        return studentVisitSurplus;
+    }
+
+    public void setStudentVisitSurplus(int studentVisitSurplus) {
+        this.studentVisitSurplus = studentVisitSurplus;
+    }
+
+    public int getTeacherExceptionAttendanceSurplus() {
+        return teacherExceptionAttendanceSurplus;
+    }
+
+    public void setTeacherExceptionAttendanceSurplus(int teacherExceptionAttendanceSurplus) {
+        this.teacherExceptionAttendanceSurplus = teacherExceptionAttendanceSurplus;
+    }
+
+    public int getTeacherNotAClassSurplus() {
+        return teacherNotAClassSurplus;
+    }
+
+    public void setTeacherNotAClassSurplus(int teacherNotAClassSurplus) {
+        this.teacherNotAClassSurplus = teacherNotAClassSurplus;
+    }
 }

+ 105 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/IndexErrDataRecord.java

@@ -0,0 +1,105 @@
+package com.ym.mec.biz.dal.entity;
+
+import com.ym.mec.biz.dal.enums.IndexErrorType;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.util.Date;
+
+/**
+ * 对应数据库表(index_err_data_record):
+ */
+public class IndexErrDataRecord {
+
+	/**  */
+	private Long id;
+	
+	/** 分部编号 */
+	private Integer organId;
+	
+	/** 数据id */
+	private String dataId;
+	
+	/** 数据类型 */
+	private IndexErrorType dataType;
+	
+	/** 处理人编号 */
+	private Integer dealUserId = -1;
+	
+	/** 生成时间 */
+	private java.util.Date createTime;
+
+	private Date generateTime;
+	
+	/** 处理时间 */
+	private java.util.Date dealTime;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setOrganId(Integer organId){
+		this.organId = organId;
+	}
+	
+	public Integer getOrganId(){
+		return this.organId;
+	}
+			
+	public void setDataId(String dataId){
+		this.dataId = dataId;
+	}
+	
+	public String getDataId(){
+		return this.dataId;
+	}
+
+	public IndexErrorType getDataType() {
+		return dataType;
+	}
+
+	public void setDataType(IndexErrorType dataType) {
+		this.dataType = dataType;
+	}
+
+	public void setDealUserId(Integer dealUserId){
+		this.dealUserId = dealUserId;
+	}
+	
+	public Integer getDealUserId(){
+		return this.dealUserId;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+
+	public Date getGenerateTime() {
+		return generateTime;
+	}
+
+	public void setGenerateTime(Date generateTime) {
+		this.generateTime = generateTime;
+	}
+
+	public void setDealTime(java.util.Date dealTime){
+		this.dealTime = dealTime;
+	}
+	
+	public java.util.Date getDealTime(){
+		return this.dealTime;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 22 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/InspectionItem.java

@@ -88,6 +88,27 @@ public class InspectionItem {
     @ApiModelProperty(value = "主管名字")
     private String userName;
 
+    private Date generateTime;
+
+    /** 处理时间 */
+    private java.util.Date dealTime;
+
+    public Date getGenerateTime() {
+        return generateTime;
+    }
+
+    public void setGenerateTime(Date generateTime) {
+        this.generateTime = generateTime;
+    }
+
+    public Date getDealTime() {
+        return dealTime;
+    }
+
+    public void setDealTime(Date dealTime) {
+        this.dealTime = dealTime;
+    }
+
     public Long getId() {
         return id;
     }
@@ -207,4 +228,4 @@ public class InspectionItem {
     public void setUserName(String userName) {
         this.userName = userName;
     }
-}
+}

+ 22 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/InspectionItemPlan.java

@@ -136,6 +136,27 @@ public class InspectionItemPlan {
     @ApiModelProperty(value = "乐团主管名字")
     private String realName;
 
+    private Date generateTime;
+
+    /** 处理时间 */
+    private java.util.Date dealTime;
+
+    public Date getGenerateTime() {
+        return generateTime;
+    }
+
+    public void setGenerateTime(Date generateTime) {
+        this.generateTime = generateTime;
+    }
+
+    public Date getDealTime() {
+        return dealTime;
+    }
+
+    public void setDealTime(Date dealTime) {
+        this.dealTime = dealTime;
+    }
+
     public Long getId() {
         return id;
     }
@@ -327,4 +348,4 @@ public class InspectionItemPlan {
     public void setOperatorUserId(Integer operatorUserId) {
         this.operatorUserId = operatorUserId;
     }
-}
+}

+ 40 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/EndCourseScheduleQueryInfo.java

@@ -81,6 +81,14 @@ public class EndCourseScheduleQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "课程编号搜索")
     private Long courseIdSearch;
 
+    private String generateStartTime;
+
+    private String generateEndTime;
+
+    private String dealStartTime;
+
+    private String dealEndTime;
+
     public Long getCourseIdSearch() {
         return courseIdSearch;
     }
@@ -264,4 +272,36 @@ public class EndCourseScheduleQueryInfo extends QueryInfo {
     public void setTeachType(TeachTypeEnum teachType) {
         this.teachType = teachType;
     }
+
+    public String getGenerateStartTime() {
+        return generateStartTime;
+    }
+
+    public void setGenerateStartTime(String generateStartTime) {
+        this.generateStartTime = generateStartTime;
+    }
+
+    public String getGenerateEndTime() {
+        return generateEndTime;
+    }
+
+    public void setGenerateEndTime(String generateEndTime) {
+        this.generateEndTime = generateEndTime;
+    }
+
+    public String getDealStartTime() {
+        return dealStartTime;
+    }
+
+    public void setDealStartTime(String dealStartTime) {
+        this.dealStartTime = dealStartTime;
+    }
+
+    public String getDealEndTime() {
+        return dealEndTime;
+    }
+
+    public void setDealEndTime(String dealEndTime) {
+        this.dealEndTime = dealEndTime;
+    }
 }

+ 50 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/IndexErrRecordQueryInfo.java

@@ -0,0 +1,50 @@
+package com.ym.mec.biz.dal.page;
+
+import com.ym.mec.common.page.QueryInfo;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/31 0031
+ */
+public class IndexErrRecordQueryInfo extends QueryInfo {
+
+    private String organIds;
+
+    private Integer educationUserId;
+
+    private String startDate;
+
+    private String endDate;
+
+    public String getOrganIds() {
+        return organIds;
+    }
+
+    public void setOrganIds(String organIds) {
+        this.organIds = organIds;
+    }
+
+    public Integer getEducationUserId() {
+        return educationUserId;
+    }
+
+    public void setEducationUserId(Integer educationUserId) {
+        this.educationUserId = educationUserId;
+    }
+
+    public String getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(String startDate) {
+        this.startDate = startDate;
+    }
+
+    public String getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(String endDate) {
+        this.endDate = endDate;
+    }
+}

+ 40 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/InspectionItemPlanQueryInfo.java

@@ -46,6 +46,14 @@ public class InspectionItemPlanQueryInfo extends QueryInfo {
 
     private String searchStartTime;
 
+    private String generateStartTime;
+
+    private String generateEndTime;
+
+    private String dealStartTime;
+
+    private String dealEndTime;
+
     public String getSearchStartTime() {
         return searchStartTime;
     }
@@ -158,4 +166,36 @@ public class InspectionItemPlanQueryInfo extends QueryInfo {
     public void setIds(String ids) {
         this.ids = ids;
     }
+
+    public String getGenerateStartTime() {
+        return generateStartTime;
+    }
+
+    public void setGenerateStartTime(String generateStartTime) {
+        this.generateStartTime = generateStartTime;
+    }
+
+    public String getGenerateEndTime() {
+        return generateEndTime;
+    }
+
+    public void setGenerateEndTime(String generateEndTime) {
+        this.generateEndTime = generateEndTime;
+    }
+
+    public String getDealStartTime() {
+        return dealStartTime;
+    }
+
+    public void setDealStartTime(String dealStartTime) {
+        this.dealStartTime = dealStartTime;
+    }
+
+    public String getDealEndTime() {
+        return dealEndTime;
+    }
+
+    public void setDealEndTime(String dealEndTime) {
+        this.dealEndTime = dealEndTime;
+    }
 }

+ 40 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/InspectionQueryInfo.java

@@ -31,6 +31,14 @@ public class InspectionQueryInfo extends QueryInfo {
 
     private String searchStartTime;
 
+    private String generateStartTime;
+
+    private String generateEndTime;
+
+    private String dealStartTime;
+
+    private String dealEndTime;
+
     public String getSearchStartTime() {
         return searchStartTime;
     }
@@ -102,4 +110,36 @@ public class InspectionQueryInfo extends QueryInfo {
     public void setIds(String ids) {
         this.ids = ids;
     }
+
+    public String getGenerateStartTime() {
+        return generateStartTime;
+    }
+
+    public void setGenerateStartTime(String generateStartTime) {
+        this.generateStartTime = generateStartTime;
+    }
+
+    public String getGenerateEndTime() {
+        return generateEndTime;
+    }
+
+    public void setGenerateEndTime(String generateEndTime) {
+        this.generateEndTime = generateEndTime;
+    }
+
+    public String getDealStartTime() {
+        return dealStartTime;
+    }
+
+    public void setDealStartTime(String dealStartTime) {
+        this.dealStartTime = dealStartTime;
+    }
+
+    public String getDealEndTime() {
+        return dealEndTime;
+    }
+
+    public void setDealEndTime(String dealEndTime) {
+        this.dealEndTime = dealEndTime;
+    }
 }

+ 87 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/IndexErrDataRecordService.java

@@ -0,0 +1,87 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.dto.CourseScheduleEndDto;
+import com.ym.mec.biz.dal.dto.IndexErrorDataExportDto;
+import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.entity.IndexErrDataRecord;
+import com.ym.mec.biz.dal.entity.InspectionItem;
+import com.ym.mec.biz.dal.entity.InspectionItemPlan;
+import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
+import com.ym.mec.biz.dal.page.IndexErrRecordQueryInfo;
+import com.ym.mec.biz.dal.page.InspectionItemPlanQueryInfo;
+import com.ym.mec.biz.dal.page.InspectionQueryInfo;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
+import com.ym.mec.common.service.BaseService;
+
+import java.util.List;
+
+public interface IndexErrDataRecordService extends BaseService<Long, IndexErrDataRecord> {
+
+    /**
+     * @describe 历史异常数据记录
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param date:
+     * @return void
+     */
+    void indexErrDataRecordTask(String date);
+
+    /**
+     * @describe 历史异常数据记录导出
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param startDate:
+     * @param endDate:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.IndexErrDataRecord>
+     */
+    List<IndexErrorDataExportDto> errRecordExport(String organIds, String startDate, String endDate);
+
+    /**
+     * @describe 获取所有异常相关教务人员
+     * @author Joburgess
+     * @date 2021/6/2 0002
+     * @param organIds:
+     * @return java.util.List<com.ym.mec.biz.dal.dto.SimpleUserDto>
+     */
+    List<SimpleUserDto> getAllEducationUsers(String organIds);
+
+    PageInfo<IndexErrorDataExportDto> queryRecord(IndexErrRecordQueryInfo queryInfo);
+
+    /**
+     * @describe 异常数据汇总
+     * @author Joburgess
+     * @date 2021/6/2 0002
+     * @param queryInfo:
+     * @return com.ym.mec.biz.dal.dto.IndexErrorDataExportDto
+     */
+    IndexErrorDataExportDto errDataSummarizing(IndexErrRecordQueryInfo queryInfo);
+
+    /**
+     * @describe 历史异常数据-乐团巡查事项异常
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param queryInfo:
+     * @return com.ym.mec.common.page.PageInfo
+     */
+    PageInfo<InspectionItemPlan> queryErrInspectionData(InspectionItemPlanQueryInfo queryInfo);
+
+    /**
+     * @describe 历史异常数据-回访任务未完成
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param queryInfo:
+     * @return com.ym.mec.common.page.PageInfo<com.ym.mec.biz.dal.entity.InspectionItem>
+     */
+    PageInfo<InspectionItem> queryErrStudentVisit(InspectionQueryInfo queryInfo);
+
+    /**
+     * @describe 历史异常数据-课程(课程考勤异常/课程异常)
+     * @author Joburgess
+     * @date 2021/5/28 0028
+     * @param queryInfo:
+     * @return com.ym.mec.common.page.PageInfo<java.util.List<com.ym.mec.biz.dal.dto.CourseScheduleEndDto>>
+     */
+    PageInfo<CourseScheduleEndDto> queryHistoryErrCourseData(EndCourseScheduleQueryInfo queryInfo);
+
+}

+ 527 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexErrDataRecordServiceImpl.java

@@ -0,0 +1,527 @@
+package com.ym.mec.biz.service.impl;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.auth.api.entity.SysUserRole;
+import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.CourseScheduleEndDto;
+import com.ym.mec.biz.dal.dto.IndexErrorDataExportDto;
+import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.dto.TeacherVisitDto;
+import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.enums.IndexErrorType;
+import com.ym.mec.biz.dal.enums.InspectionItemEnum;
+import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
+import com.ym.mec.biz.dal.page.IndexErrRecordQueryInfo;
+import com.ym.mec.biz.dal.page.InspectionItemPlanQueryInfo;
+import com.ym.mec.biz.dal.page.InspectionQueryInfo;
+import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.common.page.QueryInfo;
+import com.ym.mec.util.collection.MapUtil;
+import com.ym.mec.util.date.DateUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.biz.service.IndexErrDataRecordService;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.time.LocalDate;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.ym.mec.biz.dal.enums.GroupType.*;
+
+@Service
+public class IndexErrDataRecordServiceImpl extends BaseServiceImpl<Long, IndexErrDataRecord>  implements IndexErrDataRecordService {
+	
+	@Autowired
+	private IndexErrDataRecordDao indexErrDataRecordDao;
+	@Autowired
+	private StudentVisitDao studentVisitDao;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+	@Autowired
+	private EmployeeDao employeeDao;
+	@Autowired
+	private ClassGroupDao classGroupDao;
+	@Autowired
+	private TeacherDao teacherDao;
+	@Autowired
+	private CourseScheduleDao courseScheduleDao;
+	@Autowired
+	private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
+	@Autowired
+	private MusicGroupDao musicGroupDao;
+	@Autowired
+	private VipGroupDao vipGroupDao;
+	@Autowired
+	private PracticeGroupDao practiceGroupDao;
+	@Autowired
+	private OrganizationDao organizationDao;
+
+	@Override
+	public BaseDAO<Long, IndexErrDataRecord> getDAO() {
+		return indexErrDataRecordDao;
+	}
+
+	@Override
+	public void indexErrDataRecordTask(String date) {
+		if(StringUtils.isBlank(date)){
+			date = LocalDate.now().plusDays(-1).toString();
+		}
+		Date dt = DateUtil.stringToDate(date, "yyyy-MM-dd");
+
+		int errDateNum = indexErrDataRecordDao.countWithGenerateTime(date);
+
+		if(errDateNum<=0){
+			//乐团巡查事项异常
+			List<IndexErrDataRecord> errInspections = indexErrDataRecordDao.queryErrInspection(date, null);
+			if(!CollectionUtils.isEmpty(errInspections)){
+				errInspections.forEach(e->{
+					e.setDataType(IndexErrorType.MUSIC_PATROL_ITEM);
+					e.setGenerateTime(dt);
+				});
+				indexErrDataRecordDao.batchInsert(errInspections);
+			}
+
+			//乐团巡查任务未提交
+			List<IndexErrDataRecord> errInspectionItemPlans = indexErrDataRecordDao.queryInspectionItemPlan(date, null);
+			if(!CollectionUtils.isEmpty(errInspectionItemPlans)) {
+				errInspectionItemPlans.forEach(e -> {
+					e.setDataType(IndexErrorType.INSPECTION_ITEM_PLAN);
+					e.setGenerateTime(dt);
+				});
+				indexErrDataRecordDao.batchInsert(errInspectionItemPlans);
+			}
+
+			//回访任务未完成
+			List<IndexErrDataRecord> errStudentVisits = indexErrDataRecordDao.queryStudentVisit(date, null);
+			if(!CollectionUtils.isEmpty(errStudentVisits)) {
+				errStudentVisits.forEach(e -> {
+					e.setDataType(IndexErrorType.STUDENT_VISIT);
+					e.setGenerateTime(dt);
+				});
+				indexErrDataRecordDao.batchInsert(errStudentVisits);
+			}
+
+			//课程考勤异常
+			List<IndexErrDataRecord> errStudentAttendances = indexErrDataRecordDao.getAttendanceError(date, null);
+			if(!CollectionUtils.isEmpty(errStudentAttendances)) {
+				errStudentAttendances.forEach(e -> {
+					e.setDataType(IndexErrorType.TEACHER_EXCEPTION_ATTENDANCE);
+					e.setGenerateTime(dt);
+				});
+				indexErrDataRecordDao.batchInsert(errStudentAttendances);
+			}
+
+			//课程异常
+			List<IndexErrDataRecord> errNoAttendances = indexErrDataRecordDao.getNoAttendance(date, null);
+			if(!CollectionUtils.isEmpty(errNoAttendances)) {
+				errNoAttendances.forEach(e -> {
+					e.setDataType(IndexErrorType.TEACHER_NOT_A_CLASS);
+					e.setGenerateTime(dt);
+				});
+				indexErrDataRecordDao.batchInsert(errNoAttendances);
+			}
+		}
+
+		//处理历史异常数据
+		checkUntreatedRecord();
+	}
+
+	private void checkUntreatedRecord(){
+		List<IndexErrDataRecord> untreatedRecord = indexErrDataRecordDao.findUntreatedRecord();
+		if(CollectionUtils.isEmpty(untreatedRecord)){
+			return;
+		}
+		Map<IndexErrorType, List<IndexErrDataRecord>> typeDataMap = untreatedRecord.stream().collect(Collectors.groupingBy(IndexErrDataRecord::getDataType));
+
+		List<IndexErrDataRecord> needUpdateRecord = new ArrayList<>();
+		Date now = new Date();
+
+		for (Map.Entry<IndexErrorType, List<IndexErrDataRecord>> typeDataMapEntry : typeDataMap.entrySet()) {
+			Set<String> dates = typeDataMapEntry.getValue().stream().map(i -> DateUtil.dateToString(i.getGenerateTime(), "yyyy-MM-dd")).collect(Collectors.toSet());
+			List<IndexErrDataRecord> newRecord = new ArrayList<>();
+			switch (typeDataMapEntry.getKey()){
+				case MUSIC_PATROL_ITEM:
+					newRecord = indexErrDataRecordDao.queryErrInspection(null, dates);
+					break;
+				case INSPECTION_ITEM_PLAN:
+					newRecord = indexErrDataRecordDao.queryInspectionItemPlan(null, dates);
+					break;
+				case STUDENT_VISIT:
+					newRecord = indexErrDataRecordDao.queryStudentVisit(null, dates);
+					break;
+				case TEACHER_EXCEPTION_ATTENDANCE:
+					newRecord = indexErrDataRecordDao.getAttendanceError(null, dates);
+					break;
+				case TEACHER_NOT_A_CLASS:
+					newRecord = indexErrDataRecordDao.getNoAttendance(null, dates);
+					break;
+			}
+			Set<String> dataIds = newRecord.stream().map(IndexErrDataRecord::getDataId).collect(Collectors.toSet());
+			for (IndexErrDataRecord record : typeDataMapEntry.getValue()) {
+				if(dataIds.contains(record.getDataId())){
+					continue;
+				}
+				record.setDealTime(now);
+				needUpdateRecord.add(record);
+			}
+		}
+		if(!CollectionUtils.isEmpty(needUpdateRecord)){
+			indexErrDataRecordDao.batchUpdate(needUpdateRecord);
+		}
+	}
+
+	@Override
+	public List<SimpleUserDto> getAllEducationUsers(String organIds) {
+		Set<Integer> queryOrganIds = null;
+		if(StringUtils.isNotBlank(organIds)){
+			queryOrganIds = Arrays.stream(organIds.split(",")).map(Integer::new).collect(Collectors.toSet());
+		}
+		List<Integer> allDealUserIds = indexErrDataRecordDao.getAllDealUserIds(queryOrganIds);
+		List<SimpleUserDto> users = teacherDao.getUsersSimpleInfo(allDealUserIds);
+		return users;
+	}
+
+	@Override
+	public List<IndexErrorDataExportDto> errRecordExport(String organIdsStr, String startDate, String endDate) {
+		List<IndexErrorDataExportDto> result = new ArrayList<>();
+		Set<Integer> queryOrganIds = null;
+		if(StringUtils.isNotBlank(organIdsStr)){
+			queryOrganIds = Arrays.stream(organIdsStr.split(",")).map(Integer::new).collect(Collectors.toSet());
+		}
+		List<IndexErrDataRecord> errRecords = indexErrDataRecordDao.getWithGenerateTime(queryOrganIds, startDate, endDate);
+		if(CollectionUtils.isEmpty(errRecords)){
+			return result;
+		}
+		List<Integer> organIds = errRecords.stream().map(IndexErrDataRecord::getOrganId).collect(Collectors.toList());
+		List<Organization> organs = organizationDao.findOrgans(organIds);
+		Map<Integer, String> idOrganNameMap = organs.stream().collect(Collectors.toMap(Organization::getId, o -> o.getName()));
+
+		List<Integer> userIds = errRecords.stream().map(IndexErrDataRecord::getDealUserId).collect(Collectors.toList());
+		Map<Integer, SimpleUserDto> idUserMap = new HashMap<>();
+		if(!CollectionUtils.isEmpty(userIds)){
+			List<SimpleUserDto> users = teacherDao.getUsersSimpleInfo(userIds);
+			idUserMap = users.stream().collect(Collectors.toMap(SimpleUserDto::getUserId, u->u, (u1, u2)->u1));
+		}
+		Map<Integer, List<IndexErrDataRecord>> organDataMap = errRecords.stream().collect(Collectors.groupingBy(IndexErrDataRecord::getOrganId));
+		for (Map.Entry<Integer, List<IndexErrDataRecord>> organDataMapEntry : organDataMap.entrySet()) {
+			Map<Date, Map<Integer, List<IndexErrDataRecord>>> dateUserRecordMap = organDataMapEntry.getValue().stream().collect(Collectors.groupingBy(IndexErrDataRecord::getGenerateTime, Collectors.groupingBy(IndexErrDataRecord::getDealUserId)));
+			for (Map.Entry<Date, Map<Integer, List<IndexErrDataRecord>>> dateUserRecordMapEntry : dateUserRecordMap.entrySet()) {
+				String generateTimeStr = DateUtil.dateToString(dateUserRecordMapEntry.getKey(), DateUtil.DATE_FORMAT_MIN);
+				for (Map.Entry<Integer, List<IndexErrDataRecord>> userRecordMapEntry : dateUserRecordMapEntry.getValue().entrySet()) {
+					IndexErrorDataExportDto record = new IndexErrorDataExportDto();
+					record.setGenerateTime(generateTimeStr);
+					record.setOrganName(idOrganNameMap.get(organDataMapEntry.getKey()));
+					if(idUserMap.containsKey(userRecordMapEntry.getKey())){
+						record.setDealUserName(idUserMap.get(userRecordMapEntry.getKey()).getUserName());
+					}
+					Map<IndexErrorType, Long> typeDataNumMap = userRecordMapEntry.getValue().stream().collect(Collectors.groupingBy(IndexErrDataRecord::getDataType, Collectors.counting()));
+					for (Map.Entry<IndexErrorType, Long> typeDataNumMapEntry : typeDataNumMap.entrySet()) {
+						switch (typeDataNumMapEntry.getKey()){
+							case MUSIC_PATROL_ITEM:
+								record.setMusicPatrolItem(typeDataNumMapEntry.getValue().intValue());
+								break;
+							case INSPECTION_ITEM_PLAN:
+								record.setInspectionItemPlan(typeDataNumMapEntry.getValue().intValue());
+								break;
+							case STUDENT_VISIT:
+								record.setStudentVisit(typeDataNumMapEntry.getValue().intValue());
+								break;
+							case TEACHER_EXCEPTION_ATTENDANCE:
+								record.setTeacherExceptionAttendance(typeDataNumMapEntry.getValue().intValue());
+								break;
+							case TEACHER_NOT_A_CLASS:
+								record.setTeacherNotAClass(typeDataNumMapEntry.getValue().intValue());
+								break;
+						}
+					}
+					result.add(record);
+				}
+			}
+		}
+
+		return result;
+	}
+
+	@Override
+	public PageInfo<IndexErrorDataExportDto> queryRecord(IndexErrRecordQueryInfo queryInfo) {
+		PageInfo<IndexErrorDataExportDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+		Set<Integer> queryOrganIds = null;
+		if(StringUtils.isNotBlank(queryInfo.getOrganIds())){
+			queryOrganIds = Arrays.stream(queryInfo.getOrganIds().split(",")).map(Integer::new).collect(Collectors.toSet());
+		}
+		params.put("queryOrganIds", queryOrganIds);
+
+		int count = indexErrDataRecordDao.queryErrStringsCount(params);
+		pageInfo.setTotal(count);
+		params.put("offset", pageInfo.getOffset());
+		List<IndexErrorDataExportDto> dataList = new ArrayList<>();
+		List<String> strings = indexErrDataRecordDao.queryErrStrings(params);
+		if (!CollectionUtils.isEmpty(strings)) {
+			List<IndexErrDataRecord> errRecords = indexErrDataRecordDao.getWithOrganMonthUserStr(strings);
+			List<Integer> organIds = errRecords.stream().map(IndexErrDataRecord::getOrganId).collect(Collectors.toList());
+			List<Organization> organs = organizationDao.findOrgans(organIds);
+			Map<Integer, String> idOrganNameMap = organs.stream().collect(Collectors.toMap(Organization::getId, o -> o.getName()));
+
+			List<Integer> userIds = errRecords.stream().map(IndexErrDataRecord::getDealUserId).collect(Collectors.toList());
+			Map<Integer, SimpleUserDto> idUserMap = new HashMap<>();
+			if(!CollectionUtils.isEmpty(userIds)){
+				List<SimpleUserDto> users = teacherDao.getUsersSimpleInfo(userIds);
+				idUserMap = users.stream().collect(Collectors.toMap(SimpleUserDto::getUserId, u->u, (u1, u2)->u1));
+			}
+			Map<Integer, List<IndexErrDataRecord>> organDataMap = errRecords.stream().collect(Collectors.groupingBy(IndexErrDataRecord::getOrganId));
+			for (Map.Entry<Integer, List<IndexErrDataRecord>> organDataMapEntry : organDataMap.entrySet()) {
+				Map<Date, Map<Integer, List<IndexErrDataRecord>>> dateUserRecordMap = organDataMapEntry.getValue().stream().collect(Collectors.groupingBy(IndexErrDataRecord::getGenerateTime, Collectors.groupingBy(IndexErrDataRecord::getDealUserId)));
+				for (Map.Entry<Date, Map<Integer, List<IndexErrDataRecord>>> dateUserRecordMapEntry : dateUserRecordMap.entrySet()) {
+					String generateTimeStr = DateUtil.dateToString(dateUserRecordMapEntry.getKey(), DateUtil.DATE_FORMAT_MIN);
+					for (Map.Entry<Integer, List<IndexErrDataRecord>> userRecordMapEntry : dateUserRecordMapEntry.getValue().entrySet()) {
+						IndexErrorDataExportDto record = new IndexErrorDataExportDto();
+						record.setGenerateTime(generateTimeStr);
+						record.setOrganName(idOrganNameMap.get(organDataMapEntry.getKey()));
+						if(idUserMap.containsKey(userRecordMapEntry.getKey())){
+							record.setDealUserName(idUserMap.get(userRecordMapEntry.getKey()).getUserName());
+						}
+						Map<IndexErrorType, Long> typeDataNumMap = userRecordMapEntry.getValue().stream().collect(Collectors.groupingBy(IndexErrDataRecord::getDataType, Collectors.counting()));
+						Map<IndexErrorType, Long> typeSurplusDataNumMap = userRecordMapEntry.getValue().stream().filter(e->Objects.isNull(e.getDealTime())).collect(Collectors.groupingBy(IndexErrDataRecord::getDataType, Collectors.counting()));
+						for (Map.Entry<IndexErrorType, Long> typeDataNumMapEntry : typeDataNumMap.entrySet()) {
+							switch (typeDataNumMapEntry.getKey()){
+								case MUSIC_PATROL_ITEM:
+									record.setMusicPatrolItem(typeDataNumMapEntry.getValue().intValue());
+									if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+										record.setMusicPatrolItemSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+									}
+									break;
+								case INSPECTION_ITEM_PLAN:
+									record.setInspectionItemPlan(typeDataNumMapEntry.getValue().intValue());
+									if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+										record.setInspectionItemPlanSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+									}
+									break;
+								case STUDENT_VISIT:
+									record.setStudentVisit(typeDataNumMapEntry.getValue().intValue());
+									if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+										record.setStudentVisitSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+									}
+									break;
+								case TEACHER_EXCEPTION_ATTENDANCE:
+									record.setTeacherExceptionAttendance(typeDataNumMapEntry.getValue().intValue());
+									if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+										record.setTeacherExceptionAttendanceSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+									}
+									break;
+								case TEACHER_NOT_A_CLASS:
+									record.setTeacherNotAClass(typeDataNumMapEntry.getValue().intValue());
+									if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+										record.setTeacherNotAClassSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+									}
+									break;
+							}
+						}
+						dataList.add(record);
+					}
+				}
+			}
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
+	@Override
+	public IndexErrorDataExportDto errDataSummarizing(IndexErrRecordQueryInfo queryInfo) {
+		PageInfo<IndexErrorDataExportDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+		Set<Integer> queryOrganIds = null;
+		if(StringUtils.isNotBlank(queryInfo.getOrganIds())){
+			queryOrganIds = Arrays.stream(queryInfo.getOrganIds().split(",")).map(Integer::new).collect(Collectors.toSet());
+		}
+		params.put("queryOrganIds", queryOrganIds);
+
+		List<IndexErrDataRecord> allErrDatas = indexErrDataRecordDao.getAllErrDatas(params);
+		IndexErrorDataExportDto record = new IndexErrorDataExportDto();
+
+		Map<IndexErrorType, Long> typeDataNumMap = allErrDatas.stream().collect(Collectors.groupingBy(IndexErrDataRecord::getDataType, Collectors.counting()));
+		Map<IndexErrorType, Long> typeSurplusDataNumMap = allErrDatas.stream().filter(e->Objects.isNull(e.getDealTime())).collect(Collectors.groupingBy(IndexErrDataRecord::getDataType, Collectors.counting()));
+		for (Map.Entry<IndexErrorType, Long> typeDataNumMapEntry : typeDataNumMap.entrySet()) {
+			switch (typeDataNumMapEntry.getKey()){
+				case MUSIC_PATROL_ITEM:
+					record.setMusicPatrolItem(typeDataNumMapEntry.getValue().intValue());
+					if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+						record.setMusicPatrolItemSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+					}
+					break;
+				case INSPECTION_ITEM_PLAN:
+					record.setInspectionItemPlan(typeDataNumMapEntry.getValue().intValue());
+					if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+						record.setInspectionItemPlanSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+					}
+					break;
+				case STUDENT_VISIT:
+					record.setStudentVisit(typeDataNumMapEntry.getValue().intValue());
+					if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+						record.setStudentVisitSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+					}
+					break;
+				case TEACHER_EXCEPTION_ATTENDANCE:
+					record.setTeacherExceptionAttendance(typeDataNumMapEntry.getValue().intValue());
+					if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+						record.setTeacherExceptionAttendanceSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+					}
+					break;
+				case TEACHER_NOT_A_CLASS:
+					record.setTeacherNotAClass(typeDataNumMapEntry.getValue().intValue());
+					if(typeSurplusDataNumMap.containsKey(typeDataNumMapEntry.getValue())) {
+						record.setTeacherNotAClassSurplus(typeSurplusDataNumMap.get(typeDataNumMapEntry.getValue()).intValue());
+					}
+					break;
+			}
+		}
+
+		return record;
+	}
+
+	@Override
+	public PageInfo<InspectionItemPlan> queryErrInspectionData(InspectionItemPlanQueryInfo queryInfo) {
+		PageInfo<InspectionItemPlan> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+
+		int count = indexErrDataRecordDao.errInspectionDataCount(params);
+		pageInfo.setTotal(count);
+		params.put("offset", pageInfo.getOffset());
+		List<InspectionItemPlan> dataList = indexErrDataRecordDao.queryErrInspectionData(params);
+
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
+	@Override
+	public PageInfo<InspectionItem> queryErrStudentVisit(InspectionQueryInfo queryInfo) {
+		if (queryInfo.getMonth() != null) {
+			queryInfo.setStartTime(DateUtil.getFirstDayOfMonth(queryInfo.getMonth()));
+			queryInfo.setEndTime(DateUtil.getLastTimeWithDay(DateUtil.getLastDayOfMonth(queryInfo.getMonth())));
+		}
+		if (queryInfo.getStartTime() != null) {
+			queryInfo.setStartTime(DateUtil.getFirstDayOfMonth(queryInfo.getStartTime()));
+		}
+		if (queryInfo.getEndTime() != null) {
+			queryInfo.setEndTime(DateUtil.getLastTimeWithDay(DateUtil.getLastDayOfMonth(queryInfo.getEndTime())));
+		}
+		PageInfo<InspectionItem> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo);
+
+		int count = indexErrDataRecordDao.studentVisitCount(params);
+		pageInfo.setTotal(count);
+		params.put("offset", pageInfo.getOffset());
+		List<InspectionItem> dataList = indexErrDataRecordDao.queryErrStudentVisit(params);
+		pageInfo.setRows(dataList);
+		if (pageInfo.getRows().size() <= 0) {
+			return pageInfo;
+		}
+		List<InspectionItem> rows = pageInfo.getRows();
+		List<Integer> teacherIds = rows.stream().filter(e -> e.getItem().equals(InspectionItemEnum.VISIT)).map(InspectionItem::getUserId).collect(Collectors.toList());
+		if (teacherIds.size() > 0) {
+			Date startTime = rows.stream().map(InspectionItem::getMonth).min(Date::compareTo).get();
+			Date EndTime = rows.stream().map(InspectionItem::getMonth).max(Date::compareTo).get();
+			startTime = DateUtil.getFirstDayOfMonth(startTime);
+			EndTime = DateUtil.getLastTimeWithDay(DateUtil.getLastDayOfMonth(EndTime));
+			List<TeacherVisitDto> teacherVisitCounts = studentVisitDao.getTeacherVisitCount(teacherIds, startTime, EndTime);
+			for (InspectionItem row : rows) {
+				if (row.getItem().equals(InspectionItemEnum.INSPECT)) continue;
+				for (TeacherVisitDto teacherVisitCount : teacherVisitCounts) {
+					if (teacherVisitCount.getTeacherId().equals(row.getUserId()) &&
+							DateUtil.dateToString(row.getMonth(), "yyyy-MM").equals(teacherVisitCount.getMonth())
+					) {
+						row.setSubmittedTimes(teacherVisitCount.getNum());
+					}
+				}
+			}
+		}
+		return pageInfo;
+	}
+
+	@Override
+	public PageInfo<CourseScheduleEndDto> queryHistoryErrCourseData(EndCourseScheduleQueryInfo queryInfo) {
+		PageInfo<CourseScheduleEndDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
+		Map<String, Object> params = new HashMap<>(16);
+		MapUtil.populateMap(params, queryInfo);
+
+		List<CourseScheduleEndDto> results;
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		List<Integer> userRole = employeeDao.queryUserRole(sysUser.getId());
+		//如果当前用户只有教务老师角色,那么只能看到他所管理的课程组的信息
+		if (!sysUser.getIsSuperAdmin() && userRole.size() == 1 && userRole.contains(SysUserRole.EDUCATIONAL_TEACHER)) {
+			List<Long> classGroupIds = classGroupDao.queryGroupClassGroupIds(sysUser.getId());
+			if(classGroupIds.size() == 0){
+				return pageInfo;
+			}
+			params.put("classGroupIds",classGroupIds);
+		}
+		int count = indexErrDataRecordDao.historyErrCourseDataCount(params);
+		if(queryInfo.getIsExport() && count > 50000){
+			throw new BizException("数据集太大,不能导出.最大数据集不能超过50000");
+		}
+		pageInfo.setTotal(count);
+		params.put("offset", pageInfo.getOffset());
+		results = indexErrDataRecordDao.queryHistoryErrCourseData(params);
+		if (!CollectionUtils.isEmpty(results)) {
+			List<Long> courseScheduleIds = results.stream().map(CourseScheduleEndDto::getId).collect(Collectors.toList());
+			List<Integer> teacherIds=results.stream().filter(t->Objects.nonNull(t.getActualTeacherId())).map(CourseSchedule::getActualTeacherId).collect(Collectors.toList());
+
+			List<Map<Integer, String>> nameIdMaps = teacherDao.queryNameByIdList(teacherIds);
+			Map<Integer, String> nameIdMap=MapUtil.convertIntegerMap(nameIdMaps);
+
+			List<Map<Long, Long>> courseMergeCourseNum = courseScheduleDao.countCourseMergeCourseNum(courseScheduleIds);
+			Map<Long, Long> courseMergeCourseNumMap = new HashMap<>();
+			if(!CollectionUtils.isEmpty(courseMergeCourseNum)){
+				courseMergeCourseNumMap = MapUtil.convertIntegerMap(courseMergeCourseNum);
+			}
+			//获取课程的预计人数
+			List<CourseSchedule> courseScheduleStudentNum = courseScheduleStudentPaymentDao.getCourseScheduleStudentNum(courseScheduleIds);
+			Map<Long, Integer> courseScheduleStudentNumMap = courseScheduleStudentNum.stream().collect(Collectors.toMap(CourseSchedule::getId, CourseSchedule::getStudentNum));
+			//获取班级声部名称
+			List<Map<Integer, String>> classGroupSubjectNameMaps = classGroupDao.findClassGroupSubjectNameMaps(courseScheduleIds);
+			Map<Integer, String> classGroupSubjectNameMap = MapUtil.convertIntegerMap(classGroupSubjectNameMaps);
+			Map<Long, String> eduName = null;
+			if(queryInfo.getIsExport()){
+				List<Long> musicCourseIds = results.stream().filter(e -> e.getGroupType() == MUSIC).map(CourseScheduleEndDto::getId).collect(Collectors.toList());
+				eduName = new HashMap<>(courseScheduleIds.size());
+				if(musicCourseIds != null && musicCourseIds.size() > 0){
+					eduName.putAll(MapUtil.convertMybatisMap(musicGroupDao.queryEduNameMapByCourseId(musicCourseIds)));
+				}
+				List<Long> vipCourseIds = results.stream().filter(e -> e.getGroupType() == VIP).map(CourseScheduleEndDto::getId).collect(Collectors.toList());
+				if(vipCourseIds != null && vipCourseIds.size() > 0){
+					eduName.putAll(MapUtil.convertMybatisMap(vipGroupDao.queryEduNameMapByCourseId(vipCourseIds)));
+				}
+				List<Long> practiceCourseIds = results.stream().filter(e -> e.getGroupType() == PRACTICE).map(CourseScheduleEndDto::getId).collect(Collectors.toList());
+				if(practiceCourseIds != null && practiceCourseIds.size() > 0){
+					eduName.putAll(MapUtil.convertMybatisMap(practiceGroupDao.queryEduNameMapByCourseId(practiceCourseIds)));
+				}
+			}
+			for (CourseScheduleEndDto result : results) {
+				if(eduName != null){
+					result.setEducationTeacherName(eduName.get(result.getId()));
+				}
+				result.setTeacher(null);
+				result.setTeacherName(nameIdMap.get(result.getActualTeacherId()));
+				result.setSubjectName(classGroupSubjectNameMap.get(result.getId()));
+				result.setIsSettlement(Objects.isNull(result.getSettlementTime())?0:1);
+				if(courseMergeCourseNumMap.containsKey(result.getId())){
+					result.setBeMerged(courseMergeCourseNumMap.get(result.getId())>0?true:false);
+				}
+				result.setStudentNum(courseScheduleStudentNumMap.getOrDefault(result.getId(), 0));
+			}
+		}
+		pageInfo.setRows(results);
+		return pageInfo;
+	}
+}

+ 622 - 0
mec-biz/src/main/resources/config/mybatis/IndexErrDataRecordMapper.xml

@@ -0,0 +1,622 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!--
+这个文件是自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<mapper namespace="com.ym.mec.biz.dal.dao.IndexErrDataRecordDao">
+
+	<resultMap type="com.ym.mec.biz.dal.entity.IndexErrDataRecord" id="IndexErrDataRecord">
+		<result column="id_" property="id" />
+		<result column="organ_id_" property="organId" />
+		<result column="data_id_" property="dataId" />
+		<result column="data_type_" property="dataType" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler" />
+		<result column="deal_user_id_" property="dealUserId" />
+		<result column="generate_time_" property="generateTime"/>
+		<result column="create_time_" property="createTime" />
+		<result column="deal_time_" property="dealTime" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="IndexErrDataRecord" >
+		SELECT * FROM index_err_data_record WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="IndexErrDataRecord">
+		SELECT * FROM index_err_data_record ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.IndexErrDataRecord" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!--
+		<selectKey resultClass="int" keyProperty="id" > 
+		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
+		</selectKey>
+		-->
+		INSERT INTO index_err_data_record (organ_id_,data_id_,data_type_,deal_user_id_,generate_time_,deal_time_,create_time_)
+		VALUES(#{organId},#{dataId},#{dataType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{dealUserId},#{generateTime},#{dealTime},NOW())
+	</insert>
+
+	<insert id="batchInsert" parameterType="com.ym.mec.biz.dal.entity.IndexErrDataRecord" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		INSERT INTO index_err_data_record (organ_id_,data_id_,data_type_,deal_user_id_,generate_time_,deal_time_,create_time_)
+		VALUE
+		<foreach collection="datas" item="data" separator=",">
+			(#{data.organId},#{data.dataId},#{data.dataType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{data.dealUserId},
+			#{data.generateTime},#{data.dealTime},NOW())
+		</foreach>
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.ym.mec.biz.dal.entity.IndexErrDataRecord">
+		UPDATE index_err_data_record
+		<set>
+			<if test="organId != null">
+				organ_id_ = #{organId},
+			</if>
+			<if test="dealUserId != null">
+				deal_user_id_ = #{dealUserId},
+			</if>
+			<if test="dataId != null">
+				data_id_ = #{dataId},
+			</if>
+			<if test="dataType != null">
+				data_type_ = #{dataType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+			</if>
+			<if test="generateTime != null">
+				generate_time_ = #{generateTime},
+			</if>
+			<if test="dealTime != null">
+				deal_time_ = #{dealTime},
+			</if>
+		</set>
+		WHERE id_ = #{id}
+	</update>
+
+	<update id="batchUpdate" parameterType="com.ym.mec.biz.dal.entity.IndexErrDataRecord">
+		<foreach collection="datas" item="data" separator=";">
+			UPDATE index_err_data_record
+			<set>
+				<if test="data.organId != null">
+					organ_id_ = #{data.organId},
+				</if>
+				<if test="data.dealUserId != null">
+					deal_user_id_ = #{data.dealUserId},
+				</if>
+				<if test="data.dataId != null">
+					data_id_ = #{data.dataId},
+				</if>
+				<if test="data.dataType != null">
+					data_type_ = #{data.dataType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
+				</if>
+				<if test="data.generateTime != null">
+					generate_time_ = #{data.generateTime},
+				</if>
+				<if test="data.dealTime != null">
+					deal_time_ = #{data.dealTime},
+				</if>
+			</set>
+			WHERE id_ = #{data.id}
+		</foreach>
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete" >
+		DELETE FROM index_err_data_record WHERE id_ = #{id}
+	</delete>
+
+	<delete id="deleteWithGenerateTimeAndType" >
+		DELETE FROM index_err_data_record
+		WHERE
+			generate_time_ = #{generateTime}
+			<if test="dataType!=null">
+				AND data_type_=#{dataType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="IndexErrDataRecord" parameterType="map">
+		SELECT * FROM index_err_data_record ORDER BY id_ <include refid="global.limit"/>
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM index_err_data_record
+	</select>
+
+	<select id="countWithGenerateTime" resultType="int">
+		SELECT COUNT(id_) FROM index_err_data_record WHERE generate_time_=#{generateTime}
+	</select>
+
+	<select id="getWithGenerateTime" resultMap="IndexErrDataRecord">
+		SELECT * FROM index_err_data_record
+		<where>
+			<if test="organIds!=null and organIds.size()>0">
+				AND organ_id_ IN
+				<foreach collection="organIds" item="organId" open="(" close=")" separator=",">
+					#{organId}
+				</foreach>
+			</if>
+			<if test="generateStartTime!=null and generateStartTime!=''">
+				AND generate_time_&gt;=#{generateStartTime}
+			</if>
+			<if test="generateEndTime!=null and generateEndTime!=''">
+				AND generate_time_&lt;=#{generateEndTime}
+			</if>
+		</where>
+	</select>
+
+	<select id="findUntreatedRecord" resultMap="IndexErrDataRecord">
+		SELECT * FROM index_err_data_record WHERE deal_time_ IS NULL
+	</select>
+
+	<select id="queryErrInspection" resultMap="IndexErrDataRecord">
+		SELECT
+			id_ data_id_,
+		    organ_id_,
+		    user_id_ deal_user_id_
+		FROM
+			inspection_item_plan
+		WHERE
+			conclusion_status_ = 1 AND memo_ = ''
+			<if test="date!=null">
+				AND DATE_FORMAT(plan_start_,'%Y-%m-%d') = #{date}
+			</if>
+			<if test="dates!=null and dates.size()>0">
+				AND DATE_FORMAT(plan_start_,'%Y-%m-%d') IN
+				<foreach collection="dates" item="dt" separator="," open="(" close=")">
+					#{dt}
+				</foreach>
+			</if>
+	</select>
+
+	<select id="queryInspectionItemPlan" resultMap="IndexErrDataRecord">
+		SELECT
+			iip.id_ data_id_,
+			iip.organ_id_,
+			iip.user_id_ deal_user_id_
+		FROM inspection_item_plan iip
+		WHERE iip.status_ = 0 AND iip.memo_ = ''
+			AND DATE_FORMAT(iip.plan_start_,'%Y-%m-%d') &lt; DATE_FORMAT(NOW(),'%Y-%m-%d')
+			AND DATE_FORMAT(iip.plan_start_,'%Y-%m-%d') &lt;= DATE_FORMAT(NOW(),'%Y-%m-%d')
+			<if test="date!=null">
+		  		AND DATE_FORMAT(iip.plan_start_,'%Y-%m-%d') = #{date}
+			</if>
+			<if test="dates!=null and dates.size()>0">
+				AND DATE_FORMAT(iip.plan_start_,'%Y-%m-%d') IN
+				<foreach collection="dates" item="dt" separator="," open="(" close=")">
+					#{dt}
+				</foreach>
+			</if>
+	</select>
+
+	<select id="queryStudentVisit" resultMap="IndexErrDataRecord">
+		SELECT
+			ii.id_ data_id_,
+		    ii.organ_id_,
+		    ii.user_id_ deal_user_id_
+		FROM inspection_item ii
+		LEFT JOIN inspection i ON ii.inspection_id_ = i.id_
+		WHERE ii.item_ = 'VISIT' AND ii.memo_ =''
+			AND ii.times_ > (SELECT COUNT(DISTINCT sv.id_) FROM student_visit sv
+			WHERE sv.teacher_id_ = ii.user_id_ AND DATE_FORMAT(i.month_,'%Y-%m') = DATE_FORMAT(sv.visit_time_,'%Y-%m'))
+			AND i.month_ &lt;= DATE_FORMAT(NOW(),'%Y-%m-%d')
+			<if test="date!=null">
+				AND i.month_ = #{date}
+			</if>
+			<if test="dates!=null and dates.size()>0">
+				AND i.month_ IN
+				<foreach collection="dates" item="dt" separator="," open="(" close=")">
+					#{dt}
+				</foreach>
+			</if>
+	</select>
+
+	<select id="getAttendanceError" resultMap="IndexErrDataRecord">
+		SELECT
+			cs.id_ data_id_,
+			cs.organ_id_,
+			CASE cs.group_type_ WHEN 'MUSIC' THEN mg.educational_teacher_id_ WHEN 'VIP' THEN vg.educational_teacher_id_ WHEN 'PRACTICE' THEN pg.educational_teacher_id_ END deal_user_id_
+		FROM course_schedule cs
+			LEFT JOIN teacher_attendance ta ON ta.course_schedule_id_ = cs.id_
+			LEFT JOIN course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+			LEFT JOIN student_attendance sa ON sa.course_schedule_id_ = cssp.course_schedule_id_ AND cssp.user_id_ = sa.user_id_
+			LEFT JOIN music_group mg ON cs.music_group_id_=mg.id_ AND cs.group_type_='MUSIC'
+			LEFT JOIN vip_group vg ON cs.music_group_id_=vg.id_ AND cs.group_type_='VIP'
+			LEFT JOIN practice_group pg ON cs.music_group_id_=pg.id_ AND cs.group_type_='PRACTICE'
+		WHERE ta.teacher_id_ = cs.actual_teacher_id_
+			AND cs.status_ = 'OVER' AND cs.del_flag_ = 0 AND cs.class_date_ >= '2021-02-01'
+			AND (((ta.sign_in_status_ = 0 OR ta.sign_in_status_ IS NULL OR ta.sign_out_status_ = 0 OR ta.sign_out_status_ IS NULL) AND ta.dispose_content_ IS NULL) OR (sa.id_ IS NULL OR (sa.status_ = 'TRUANT' AND sa.visit_flag_ = 0)))
+			AND ((ta.sign_in_status_ IS NULL AND ta.sign_out_status_ IS NOT NULL) OR (ta.sign_out_status_ IS NULL AND ta.sign_in_status_ IS NOT NULL) OR (ta.sign_out_status_ IS NOT NULL AND ta.sign_in_status_ IS NOT NULL))
+			AND (cs.new_course_id_ IS NULL OR cs.new_course_id_=cs.id_) AND cssp.id_ IS NOT NULL
+			AND EXISTS (SELECT id_ FROM course_schedule_teacher_salary WHERE cs.id_=course_schedule_id_ AND settlement_time_ IS NULL)
+			<if test="date!=null">
+				AND cs.class_date_=#{date}
+			</if>
+			<if test="dates!=null and dates.size()>0">
+				AND cs.class_date_ IN
+				<foreach collection="dates" item="dt" separator="," open="(" close=")">
+					#{dt}
+				</foreach>
+			</if>
+	</select>
+
+	<select id="getNoAttendance" resultMap="IndexErrDataRecord">
+		SELECT
+			cs.id_ data_id_,
+			cs.organ_id_,
+			CASE cs.group_type_ WHEN 'MUSIC' THEN mg.educational_teacher_id_ WHEN 'VIP' THEN vg.educational_teacher_id_ WHEN 'PRACTICE' THEN pg.educational_teacher_id_ END deal_user_id_
+		FROM course_schedule cs
+			LEFT JOIN teacher_attendance ta ON ta.course_schedule_id_ = cs.id_
+			LEFT JOIN music_group mg ON cs.music_group_id_=mg.id_ AND cs.group_type_='MUSIC'
+			LEFT JOIN vip_group vg ON cs.music_group_id_=vg.id_ AND cs.group_type_='VIP'
+			LEFT JOIN practice_group pg ON cs.music_group_id_=pg.id_ AND cs.group_type_='PRACTICE'
+		WHERE ta.teacher_id_ = cs.actual_teacher_id_
+			AND cs.status_ = 'OVER' AND cs.del_flag_ = 0 AND cs.class_date_>='2021-02-01'
+			AND ta.sign_in_time_ IS NULL AND ta.sign_out_time_ IS NULL AND ta.dispose_content_ IS NULL
+			AND (cs.new_course_id_ IS NULL OR cs.new_course_id_ = cs.id_)
+			AND EXISTS (SELECT id_ FROM course_schedule_teacher_salary WHERE cs.id_=course_schedule_id_ AND settlement_time_ IS NULL)
+			<if test="date!=null">
+		  		AND cs.class_date_=#{date}
+			</if>
+			<if test="dates!=null and dates.size()>0">
+				AND cs.class_date_ IN
+				<foreach collection="dates" item="dt" separator="," open="(" close=")">
+					#{dt}
+				</foreach>
+			</if>
+	</select>
+
+	<sql id="queryErrStringsCondition">
+		<where>
+			<if test="queryOrganIds!=null and queryOrganIds.size()>0">
+				AND organ_id_ IN
+				<foreach collection="queryOrganIds" item="organId" open="(" close=")" separator=",">
+					#{organId}
+				</foreach>
+			</if>
+			<if test="startDate!=null and startDate!=''">
+				AND generate_time_&gt;=#{startDate}
+			</if>
+			<if test="endDate!=null and endDate!=''">
+				AND generate_time_&lt;=#{endDate}
+			</if>
+			<if test="educationUserId!=null">
+				AND deal_user_id_ = #{educationUserId}
+			</if>
+		</where>
+	</sql>
+
+	<select id="queryErrStrings" resultType="string">
+		SELECT CONCAT(generate_time_, organ_id_, deal_user_id_) FROM index_err_data_record
+		<include refid="queryErrStringsCondition"></include>
+		GROUP BY generate_time_,organ_id_,deal_user_id_
+		ORDER BY generate_time_ DESC,organ_id_,deal_user_id_
+		<include refid="global.limit"></include>
+	</select>
+
+	<select id="queryErrStringsCount" resultType="int">
+		SELECT COUNT(DISTINCT CONCAT(generate_time_,organ_id_,deal_user_id_)) FROM index_err_data_record
+		<include refid="queryErrStringsCondition"></include>
+	</select>
+
+	<select id="getWithOrganMonthUserStr" resultMap="IndexErrDataRecord">
+		SELECT * FROM index_err_data_record WHERE CONCAT(generate_time_, organ_id_, deal_user_id_) IN
+		<foreach collection="omuStrings" item="omuString" open="(" close=")" separator=",">
+			#{omuString}
+		</foreach>
+	</select>
+
+	<select id="getAllErrDatas" resultMap="IndexErrDataRecord">
+		SELECT * FROM index_err_data_record
+		<include refid="queryErrStringsCondition"></include>
+	</select>
+
+	<select id="queryErrInspectionData" resultMap="com.ym.mec.biz.dal.dao.InspectionItemPlanDao.InspectionItemPlan" parameterType="map">
+		SELECT iip.*,su.real_name_ realName,o.name_ organName,co.name_ cooperationName,mg.name_ musicGroupName,
+		       irdr.generate_time_ generateTime,irdr.deal_time_ dealTime
+		FROM index_err_data_record irdr
+		LEFT JOIN inspection_item_plan iip ON irdr.data_id_=iip.id_
+		LEFT JOIN sys_user su ON su.id_ = iip.user_id_
+		LEFT JOIN organization o ON o.id_=iip.organ_id_
+		LEFT JOIN cooperation_organ co ON co.id_=iip.cooperation_organ_id_
+		LEFT JOIN music_group mg ON mg.id_ = iip.music_group_id_
+		<include refid="queryErrInspectionDataCondition"/>
+		ORDER BY iip.plan_start_ ASC
+		<include refid="global.limit"/>
+	</select>
+
+	<select id="errInspectionDataCount" resultType="int">
+		SELECT COUNT(*)
+		FROM index_err_data_record irdr
+		LEFT JOIN inspection_item_plan iip ON irdr.data_id_=iip.id_
+		LEFT JOIN music_group mg ON mg.id_ = iip.music_group_id_
+		<include refid="queryErrInspectionDataCondition"/>
+	</select>
+
+	<sql id="queryErrInspectionDataCondition">
+		<where>
+			<if test="searchType != null and searchType != ''">
+				<if test="searchType == 'MUSIC_PATROL_ITEM'">
+					irdr.data_type_ = 'MUSIC_PATROL_ITEM'
+				</if>
+				<if test="searchType == 'INSPECTION_ITEM_PLAN'">
+					irdr.data_type_ = 'INSPECTION_ITEM_PLAN'
+				</if>
+			</if>
+			<if test="itemId != null">
+				AND iip.item_id_ = #{itemId}
+			</if>
+			<if test="userId != null">
+				AND iip.user_id_ = #{userId}
+			</if>
+			<if test="organId != null">
+				AND FIND_IN_SET(iip.organ_id_,#{organId})
+			</if>
+			<if test="cooperationOrganId != null">
+				AND iip.cooperation_organ_id_ = #{cooperationOrganId}
+			</if>
+			<if test="musicGroupId != null">
+				AND iip.music_group_id_ = #{musicGroupId}
+			</if>
+			<if test="conclusionStatus != null">
+				AND iip.conclusion_status_ = #{conclusionStatus}
+			</if>
+			<if test="status !=null">
+				AND iip.status_ = #{status}
+			</if>
+			<if test='hasSubmit != null and hasSubmit.toString()=="1".toString()'>
+				AND iip.status_ > 0
+			</if>
+			<if test='hasSubmit != null and hasSubmit.toString()=="0".toString()'>
+				AND iip.status_ = 0
+			</if>
+			<if test="startTime != null">
+				AND iip.plan_start_ >= #{startTime}
+			</if>
+			<if test="endTime != null">
+				<![CDATA[AND iip.plan_start_ <= #{endTime}]]>
+			</if>
+			<if test="generateStartTime != null">
+				AND irdr.generate_time_ >= #{generateStartTime}
+			</if>
+			<if test="generateEndTime != null">
+				<![CDATA[AND irdr.generate_time_ <= #{generateEndTime}]]>
+			</if>
+			<if test="dealStartTime != null">
+				AND DATE_FORMAT(irdr.deal_time_,"%Y-%m-%d") >= #{dealStartTime}
+			</if>
+			<if test="dealEndTime != null">
+				<![CDATA[AND DATE_FORMAT(irdr.deal_time_,"%Y-%m-%d") <= #{dealEndTime}]]>
+			</if>
+			<if test="search != null">
+				AND mg.name_ LIKE CONCAT('%', #{search}, '%')
+			</if>
+			<if test="ids != null and ids != ''">
+				AND FIND_IN_SET(iip.id_,#{ids})
+			</if>
+		</where>
+	</sql>
+
+	<select id="queryErrStudentVisit" resultMap="com.ym.mec.biz.dal.dao.InspectionItemDao.InspectionItem" parameterType="map">
+		SELECT ii.*,i.month_ month,o.name_ organName,su.real_name_ userName,
+			irdr.generate_time_ generateTime,irdr.deal_time_ dealTime
+		FROM index_err_data_record irdr
+		LEFT JOIN inspection_item ii ON irdr.data_id_=ii.id_
+		LEFT JOIN inspection i ON i.id_ = ii.inspection_id_
+		LEFT JOIN organization o ON o.id_=ii.organ_id_
+		LEFT JOIN sys_user su ON su.id_ = ii.user_id_
+		<include refid="queryErrStudentVisitCondition"/>
+		ORDER BY i.month_ DESC ,ii.id_ DESC
+		<include refid="global.limit"/>
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="studentVisitCount" resultType="int">
+		SELECT COUNT(*)
+		FROM index_err_data_record irdr
+		LEFT JOIN inspection_item ii ON irdr.data_id_=ii.id_
+		LEFT JOIN inspection i ON i.id_ = ii.inspection_id_
+		<include refid="queryErrStudentVisitCondition"/>
+	</select>
+
+	<sql id="queryErrStudentVisitCondition">
+		<where>
+			irdr.data_type_ = 'STUDENT_VISIT'
+			<if test="organId != null">
+				AND FIND_IN_SET(ii.organ_id_,#{organId})
+			</if>
+			<if test="userId != null">
+				AND ii.user_id_ = #{userId}
+			</if>
+			<if test="operation != null">
+				AND ii.operation_ = #{operation}
+			</if>
+			<if test="ids != null">
+				AND FIND_IN_SET(ii.id_,#{ids})
+			</if>
+			<if test="startTime != null">
+				AND i.month_ >= #{startTime}
+			</if>
+			<if test="endTime != null">
+				<![CDATA[AND i.month_ <= #{endTime}]]>
+			</if>
+			<if test="generateStartTime != null">
+				AND irdr.generate_time_ >= #{generateStartTime}
+			</if>
+			<if test="generateEndTime != null">
+				<![CDATA[AND irdr.generate_time_ <= #{generateEndTime}]]>
+			</if>
+			<if test="dealStartTime != null">
+				AND DATE_FORMAT(irdr.deal_time_,"%Y-%m-%d") >= #{dealStartTime}
+			</if>
+			<if test="dealEndTime != null">
+				<![CDATA[AND DATE_FORMAT(irdr.deal_time_,"%Y-%m-%d") <= #{dealEndTime}]]>
+			</if>
+		</where>
+	</sql>
+
+	<select id="queryHistoryErrCourseData" resultMap="com.ym.mec.biz.dal.dao.CourseScheduleDao.CourseScheduleEndDto">
+		SELECT
+			cs.id_ id_,
+			cs.new_course_id_,
+			cs.group_type_,
+			cs.music_group_id_,
+			cs.class_group_id_,
+			cs.status_,
+			cs.name_,
+			cs.class_date_,
+			CONCAT(cs.class_date_,' ',cs.start_class_time_) course_start_time_,
+			CONCAT(cs.class_date_,' ',cs.end_class_time_) course_end_time_,
+			cs.actual_teacher_id_,
+			cs.teach_mode_,
+			cs.type_,
+			cs.schoole_id_,
+			cs.create_time_,
+			cs.is_lock_,
+			cs.organ_id_,
+			s.name_ schoole_name_,
+			o.name_ organ_name_,
+			irdr.generate_time_ generateTime,
+		    irdr.deal_time_ dealTime,
+		    eu.real_name_ educationTeacherName,
+			CASE WHEN COUNT(CASE WHEN sa.id_ IS NULL OR (sa.status_ = 'LEAVE' AND sa.remark_ IS NOT NULL) THEN NULL ELSE 1 END) > 0 THEN 1 ELSE 0 END isCallNames,
+			CASE WHEN COUNT(CASE WHEN ta.is_complaints_ = 1 THEN 1 ELSE NULL END) > 0 THEN '1' ELSE '0' END is_complaints_
+		FROM index_err_data_record irdr
+			LEFT JOIN course_schedule cs ON irdr.data_id_=cs.id_
+			LEFT JOIN school s ON cs.schoole_id_=s.id_
+			LEFT JOIN organization o ON cs.organ_id_=o.id_
+			LEFT JOIN course_schedule_teacher_salary csts ON csts.course_schedule_id_ = cs.id_
+			left join teacher_attendance ta on ta.course_schedule_id_ = cs.id_
+			<if test="searchType == 'ERR_ATTENDANCE'">
+				LEFT JOIN course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+			</if>
+			LEFT JOIN student_attendance sa ON sa.course_schedule_id_ = cs.id_
+			<if test="searchType == 'ERR_ATTENDANCE'">
+				AND cssp.user_id_ = sa.user_id_
+			</if>
+			LEFT JOIN sys_user eu ON irdr.deal_user_id_ = eu.id_
+		<include refid="endFindCourseSchedulesCondition"/>
+		GROUP BY cs.class_date_,cs.start_class_time_,cs.id_
+		ORDER BY cs.class_date_,cs.start_class_time_,cs.id_
+		<include refid="global.limit"/>
+	</select>
+
+	<select id="historyErrCourseDataCount" resultType="int">
+		SELECT
+			COUNT(DISTINCT cs.id_)
+		FROM index_err_data_record irdr
+			LEFT JOIN course_schedule cs ON irdr.data_id_=cs.id_
+			<if test="searchType == 'ERR_ATTENDANCE'">
+				LEFT JOIN course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+			</if>
+			LEFT JOIN student_attendance sa ON sa.course_schedule_id_ = cs.id_
+			<if test="searchType == 'ERR_ATTENDANCE'">
+				AND cssp.user_id_ = sa.user_id_
+			</if>
+			LEFT JOIN teacher_attendance ta on ta.course_schedule_id_ = cs.id_
+			LEFT JOIN course_schedule_teacher_salary csts ON csts.course_schedule_id_ = cs.id_
+		<include refid="endFindCourseSchedulesCondition"/>
+	</select>
+
+	<select id="getAllDealUserIds" resultType="int">
+		SELECT DISTINCT deal_user_id_ FROM index_err_data_record
+		<where>
+			<if test="organIds!=null and organIds.size()>0">
+				AND organ_id_ IN
+				<foreach collection="organIds" item="organId" open="(" close=")" separator=",">
+					#{organId}
+				</foreach>
+			</if>
+		</where>
+	</select>
+
+	<sql id="endFindCourseSchedulesCondition">
+		<where>
+			cs.del_flag_ = 0
+			<if test="searchType == 'ERR_ATTENDANCE'">
+				AND irdr.data_type_ = 'TEACHER_EXCEPTION_ATTENDANCE'
+			</if>
+			<if test="searchType == 'NO_ATTENDANCE'">
+				AND irdr.data_type_ = 'TEACHER_NOT_A_CLASS'
+			</if>
+			<if test="mergeCourseType != null and mergeCourseType != ''">
+				<if test="mergeCourseType == 'MASTER'">
+					AND cs.new_course_id_ = cs.id_
+				</if>
+				<if test="mergeCourseType == 'ASSIST'">
+					AND cs.new_course_id_ > 0 AND cs.new_course_id_ != cs.id_
+				</if>
+				<if test="mergeCourseType == 'ALL'">
+					AND cs.new_course_id_ > 0
+				</if>
+			</if>
+			<if test="isCallNames != null and isCallNames == 1">
+				AND sa.id_ IS NOT NULL
+			</if>
+			<if test="isCallNames != null and isCallNames == 0">
+				AND sa.id_ IS NULL
+			</if>
+			<if test="startTime!=null">
+				AND cs.class_date_ &gt;= DATE_FORMAT(#{startTime},"%Y-%m-%d")
+			</if>
+			<if test="endTime!=null">
+				AND cs.class_date_ &lt;= DATE_FORMAT(#{endTime},"%Y-%m-%d")
+			</if>
+			<if test="generateStartTime != null">
+				AND irdr.generate_time_ >= #{generateStartTime}
+			</if>
+			<if test="generateEndTime != null">
+				<![CDATA[AND irdr.generate_time_ <= #{generateEndTime}]]>
+			</if>
+			<if test="dealStartTime != null">
+				AND DATE_FORMAT(irdr.deal_time_,"%Y-%m-%d") >= #{dealStartTime}
+			</if>
+			<if test="dealEndTime != null">
+				<![CDATA[AND DATE_FORMAT(irdr.deal_time_,"%Y-%m-%d") <= #{dealEndTime}]]>
+			</if>
+			<if test="courseStatus!=null">
+				AND cs.status_ = #{courseStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="createStartDate!=null">
+				AND date(cs.create_time_) &gt;= date(#{createStartDate})
+			</if>
+			<if test="createEndDate!=null">
+				AND date(cs.create_time_) &lt;= date(#{createEndDate})
+			</if>
+			<if test="courseType!=null">
+				AND cs.type_ = #{courseType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="groupType!=null">
+				AND cs.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="schoolId!=null">
+				AND cs.schoole_id_ = #{schoolId}
+			</if>
+			<if test="teachMode!=null">
+				AND cs.teach_mode_ = #{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="teacherIdList != null">
+				AND csts.user_id_=#{teacherIdList}
+			</if>
+			<if test="teachType != null">
+				AND csts.teacher_role_ = #{teachType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+			</if>
+			<if test="organIdList!=null">
+				AND FIND_IN_SET(cs.organ_id_,#{organIdList})
+			</if>
+			<if test="search != null and search != ''">
+				AND (cs.music_group_id_ = #{search} OR cs.id_=#{search} OR cs.name_ LIKE CONCAT('%' ,#{search}, '%' ))
+			</if>
+			<if test="courseIdSearch != null">
+				AND cs.id_ = #{courseIdSearch}
+			</if>
+			<if test="classGroupIds != null and classGroupIds.size() > 0">
+				AND cs.class_group_id_ IN
+				<foreach collection="classGroupIds" item="classGroupId" open="(" close=")" separator=",">
+					#{classGroupId}
+				</foreach>
+			</if>
+		</where>
+	</sql>
+</mapper>

+ 4 - 0
mec-client-api/src/main/java/com/ym/mec/task/TaskRemoteService.java

@@ -191,4 +191,8 @@ public interface TaskRemoteService {
 	//乐团云教练订单
 	@GetMapping("task/checkCloudOrderStart")
 	void checkCloudOrderStart();
+
+	//历史异常数据记录
+	@GetMapping("task/indexErrDataRecordTask")
+	void indexErrDataRecord();
 }

+ 5 - 0
mec-client-api/src/main/java/com/ym/mec/task/fallback/TaskRemoteServiceFallback.java

@@ -237,4 +237,9 @@ public class TaskRemoteServiceFallback implements TaskRemoteService {
 	public void checkCloudOrderStart() {
 		logger.error("乐团云教练订单生效处理失败");
 	}
+
+	@Override
+	public void indexErrDataRecord() {
+		logger.error("历史异常数据记录失败");
+	}
 }

+ 23 - 0
mec-task/src/main/java/com/ym/mec/task/jobs/IndexErrDataRecordTask.java

@@ -0,0 +1,23 @@
+package com.ym.mec.task.jobs;
+
+import com.ym.mec.task.TaskRemoteService;
+import com.ym.mec.task.core.BaseTask;
+import com.ym.mec.task.core.TaskException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/28 0028
+ */
+@Service
+public class IndexErrDataRecordTask extends BaseTask {
+
+    @Autowired
+    private TaskRemoteService taskRemoteService;
+
+    @Override
+    public void execute() throws TaskException {
+        taskRemoteService.indexErrDataRecord();
+    }
+}

+ 56 - 0
mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java

@@ -140,6 +140,8 @@ public class ExportController extends BaseController {
     private SysUserCoursesAccountDetailDao sysUserCoursesAccountDetailDao;
     @Autowired
     private ChildrenDayReserveService childrenDayReserveService;
+    @Autowired
+    private IndexErrDataRecordService indexErrDataRecordService;
 
     @ApiOperation(value = "21年暑期考级活动统计页面详情导出")
     @PostMapping("export/statisticsDetail")
@@ -2942,4 +2944,58 @@ public class ExportController extends BaseController {
             }
         }
     }
+
+    @ApiOperation(value = "首页历史异常统计导出")
+    @RequestMapping("export/exportIndexHistoryErrData")
+    @PreAuthorize("@pcs.hasPermissions('export/exportIndexHistoryErrData')")
+    public void exportIndexHistoryErrData(IndexErrRecordQueryInfo queryInfo, HttpServletResponse response) throws IOException {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("用户信息获取失败");
+        }
+        Employee employee = employeeService.get(sysUser.getId());
+        if (StringUtils.isBlank(queryInfo.getOrganIds())) {
+            queryInfo.setOrganIds(employee.getOrganIdList());
+        }else if(StringUtils.isEmpty(employee.getOrganIdList())){
+            throw new BizException("用户所在分部异常");
+        }else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if(!list.containsAll(Arrays.asList(queryInfo.getOrganIds().split(",")))){
+                throw new BizException("非法请求");
+            }
+        }
+        List<IndexErrorDataExportDto> result = indexErrDataRecordService.queryRecord(queryInfo).getRows();
+        if (CollectionUtils.isEmpty(result)) {
+            response.setStatus(200);
+            response.setContentType("Content-Type: application/json;charset=UTF-8");
+            response.getOutputStream().write("{\"data\": null, \"code\": 500, \"status\": false, \"msg\": \"没有可导出的记录\"}".getBytes());
+            response.flushBuffer();
+            return;
+        }
+        OutputStream outputStream = response.getOutputStream();
+
+        try {
+            String[] header = {"日期", "分部", "乐团主管", "乐团巡查事项异常", "剩余乐团巡查事项异常", "乐团巡查任务未提交", "剩余乐团巡查任务未提交",
+                    "回访任务未完成", "剩余回访任务未完成", "课程考勤异常", "剩余课程考勤异常", "课程异常", "剩余课程异常"};
+            String[] body = {"generateTime", "organName", "dealUserName", "musicPatrolItem", "musicPatrolItemSurplus", "inspectionItemPlan", "inspectionItemPlanSurplus",
+                    "studentVisit", "studentVisitSurplus", "teacherExceptionAttendance", "teacherExceptionAttendanceSurplus", "teacherNotAClass", "teacherNotAClassSurplus"};
+            HSSFWorkbook workbook = POIUtil.exportExcel(header, body, result);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attachment;filename=teacherDefaultSalary-" + DateUtil.getDate(new Date()) + ".xls");
+            response.flushBuffer();
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 }

+ 190 - 0
mec-web/src/main/java/com/ym/mec/web/controller/IndexErrDataRecordController.java

@@ -0,0 +1,190 @@
+package com.ym.mec.web.controller;
+
+import com.netflix.discovery.converters.Auto;
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.auth.api.entity.SysUserRole;
+import com.ym.mec.biz.dal.dao.EmployeeDao;
+import com.ym.mec.biz.dal.dto.CourseScheduleEndDto;
+import com.ym.mec.biz.dal.dto.IndexErrorDataExportDto;
+import com.ym.mec.biz.dal.entity.Employee;
+import com.ym.mec.biz.dal.entity.InspectionItem;
+import com.ym.mec.biz.dal.entity.InspectionItemPlan;
+import com.ym.mec.biz.dal.page.EndCourseScheduleQueryInfo;
+import com.ym.mec.biz.dal.page.IndexErrRecordQueryInfo;
+import com.ym.mec.biz.dal.page.InspectionItemPlanQueryInfo;
+import com.ym.mec.biz.dal.page.InspectionQueryInfo;
+import com.ym.mec.biz.service.IndexErrDataRecordService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.page.PageInfo;
+import com.ym.mec.util.date.DateUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/5/28 0028
+ */
+@Api(tags = "异常数据")
+@RequestMapping("indexErrDataRecord")
+@RestController
+public class IndexErrDataRecordController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private EmployeeDao employeeDao;
+    @Autowired
+    private IndexErrDataRecordService indexErrDataRecordService;
+
+    @ApiOperation(value = "历史异常记录")
+    @GetMapping("/queryRecord")
+    public HttpResponseResult<PageInfo<IndexErrorDataExportDto>> queryRecord(IndexErrRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(queryInfo.getOrganIds())) {
+            queryInfo.setOrganIds(employee.getOrganIdList());
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            return failed("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(queryInfo.getOrganIds().split(",")))) {
+                return failed("非法请求");
+            }
+        }
+        return succeed(indexErrDataRecordService.queryRecord(queryInfo));
+    }
+
+    @ApiOperation(value = "异常记录汇总")
+    @GetMapping("/errDataSummarizing")
+    public HttpResponseResult errDataSummarizing(IndexErrRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(queryInfo.getOrganIds())) {
+            queryInfo.setOrganIds(employee.getOrganIdList());
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            return failed("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(queryInfo.getOrganIds().split(",")))) {
+                return failed("非法请求");
+            }
+        }
+        return succeed(indexErrDataRecordService.errDataSummarizing(queryInfo));
+    }
+
+    @ApiOperation(value = "获取所有异常相关教务人员")
+    @GetMapping("/getAllEducationUsers")
+    public HttpResponseResult getAllEducationUsers(String organIds){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(organIds)) {
+            organIds = employee.getOrganIdList();
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            return failed("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(organIds.split(",")))) {
+                return failed("非法请求");
+            }
+        }
+        return succeed(indexErrDataRecordService.getAllEducationUsers(organIds));
+    }
+
+    @ApiOperation(value = "乐团巡查事项异常/乐团巡查任务未提交")
+    @GetMapping("/queryErrInspectionData")
+    public HttpResponseResult<PageInfo<InspectionItemPlan>> queryErrInspectionData(InspectionItemPlanQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(queryInfo.getOrganId())) {
+            queryInfo.setOrganId(employee.getOrganIdList());
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            return failed("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(queryInfo.getOrganId().split(",")))) {
+                return failed("非法请求");
+            }
+        }
+        if (queryInfo.getStartTime() != null) {
+            queryInfo.setStartTime(DateUtil.trunc(queryInfo.getStartTime()));
+        }
+        if (queryInfo.getEndTime() != null) {
+            queryInfo.setEndTime(DateUtil.getLastTimeWithDay(queryInfo.getEndTime()));
+        }
+        String startTime = DateUtil.format(DateUtil.getFirstDayOfMonth(DateUtil.addMonths(new Date(), -2)), DateUtil.ISO_EXPANDED_DATE_FORMAT);
+        queryInfo.setSearchStartTime(startTime);
+
+        return succeed(indexErrDataRecordService.queryErrInspectionData(queryInfo));
+    }
+
+    @ApiOperation(value = "回访任务未完成")
+    @GetMapping("/queryErrStudentVisit")
+    public HttpResponseResult<PageInfo<InspectionItem>> queryErrStudentVisit(InspectionQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(queryInfo.getOrganId())) {
+            queryInfo.setOrganId(employee.getOrganIdList());
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            return failed("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(queryInfo.getOrganId().split(",")))) {
+                return failed("非法请求");
+            }
+        }
+        List<Integer> userRole = employeeDao.queryUserRole(sysUser.getId());
+        if (!userRole.contains(SysUserRole.SECTION_MANAGER) && !sysUser.getIsSuperAdmin()) {
+            queryInfo.setUserId(sysUser.getId());
+        }
+        String startTime = DateUtil.format(DateUtil.getFirstDayOfMonth(DateUtil.addMonths(new Date(), -2)),DateUtil.ISO_EXPANDED_DATE_FORMAT);
+        queryInfo.setSearchStartTime(startTime);
+        return succeed(indexErrDataRecordService.queryErrStudentVisit(queryInfo));
+    }
+
+    @ApiOperation(value = "课程考勤异常/课程异常")
+    @GetMapping("/queryHistoryErrCourseData")
+    public HttpResponseResult<PageInfo<CourseScheduleEndDto>> queryHistoryErrCourseData(EndCourseScheduleQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (org.apache.commons.lang3.StringUtils.isEmpty(queryInfo.getOrganIdList())) {
+            queryInfo.setOrganIdList(employee.getOrganIdList());
+        }else if(org.apache.commons.lang3.StringUtils.isEmpty(employee.getOrganIdList())){
+            return failed("用户所在分部异常");
+        }else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if(!list.containsAll(Arrays.asList(queryInfo.getOrganIdList().split(",")))){
+                return failed("非法请求");
+            }
+        }
+        return succeed(indexErrDataRecordService.queryHistoryErrCourseData(queryInfo));
+    }
+}

+ 9 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

@@ -101,6 +101,9 @@ public class TaskController extends BaseController {
 	@Autowired
 	private CloudTeacherOrderService cloudTeacherOrderService;
 
+	@Autowired
+	private IndexErrDataRecordService indexErrDataRecordService;
+
 	@GetMapping(value = "/autoAffirmReceiveTask")
 	// 自动确认收货
 	public void affirmReceive(){
@@ -393,4 +396,10 @@ public class TaskController extends BaseController {
 	public void checkCloudOrderStart(){
 		cloudTeacherOrderService.checkCloudOrderStart();
 	}
+
+	//历史异常数据记录
+	@GetMapping("/indexErrDataRecordTask")
+	public void indexErrDataRecordTask(String date){
+		indexErrDataRecordService.indexErrDataRecordTask(date);
+	}
 }