Selaa lähdekoodia

管乐迷新需求一大堆

zouxuan 2 vuotta sitten
vanhempi
commit
c63b52fde9
22 muutettua tiedostoa jossa 518 lisäystä ja 134 poistoa
  1. 6 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/IndexBaseMonthDataDao.java
  2. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java
  3. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentTeacherMapperDao.java
  4. 140 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CloudTeacherSumDto.java
  5. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/EduOrganStudentListExportDto.java
  6. 8 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/IndexErrInfoDto.java
  7. 1 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportEnum.java
  8. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportTypeEnum.java
  9. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/IndexErrorType.java
  10. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/EndCourseScheduleQueryInfo.java
  11. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/StudentCourseConsumerQueryInfo.java
  12. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/service/StudentService.java
  13. 16 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java
  14. 130 126
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java
  15. 23 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentServiceImpl.java
  16. 4 1
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  17. 28 0
      mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml
  18. 31 0
      mec-biz/src/main/resources/config/mybatis/StudentMapper.xml
  19. 10 0
      mec-biz/src/main/resources/config/mybatis/StudentTeacherMapperMapper.xml
  20. 62 0
      mec-util/src/main/java/com/ym/mec/util/date/DateUtil.java
  21. 8 0
      mec-web/src/main/java/com/ym/mec/web/controller/StudentManageController.java
  22. 4 0
      mec-web/src/main/resources/exportColumnMapper.ini

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/IndexBaseMonthDataDao.java

@@ -442,4 +442,10 @@ public interface IndexBaseMonthDataDao extends BaseDAO<Long, IndexBaseMonthData>
 
     //获取网管课订单数量
     List<IndexBaseMonthData> getStudentPracticeOrderNum(@Param("dayStr") String dayStr,@Param("tenantId") Integer tenantId);
+
+    //当月排课异常
+    int getCurrentCourseError(@Param("month") String month,@Param("organIdList") Set<Integer> organIdList);
+
+    //待续费学员提醒
+    int getWaitRenewInfo(@Param("organIdList") Set<Integer> organIdList);
 }

+ 4 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentDao.java

@@ -5,6 +5,7 @@ import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.IndexBaseMonthData;
 import com.ym.mec.biz.dal.entity.Student;
 import com.ym.mec.biz.dal.entity.Subject;
+import com.ym.mec.biz.dal.page.StudentCourseConsumerQueryInfo;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
@@ -341,4 +342,7 @@ public interface StudentDao extends com.ym.mec.common.dal.BaseDAO<Integer, Stude
     List<BaseMapDto> queryStuSubjectIdByTeacherId(@Param("userId") Integer userId);
 
     void updateRepairFlag(@Param("userIdList") List<Integer> userIdList, @Param("repairFlag") boolean repairFlag);
+
+    //统计训练时长
+    List<CloudTeacherSumDto> cloudTeacherSum(@Param("queryInfo") StudentCourseConsumerQueryInfo queryInfo);
 }

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentTeacherMapperDao.java

@@ -6,6 +6,7 @@ import com.ym.mec.common.dal.BaseDAO;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 public interface StudentTeacherMapperDao extends BaseDAO<Integer, StudentTeacherMapper> {
@@ -34,4 +35,6 @@ public interface StudentTeacherMapperDao extends BaseDAO<Integer, StudentTeacher
     void create();
 
     List<StudentTeacherMapperDto> queryDtoByStudent(@Param("userIds") Set<Integer> userIds);
+
+    List<Map<Integer, String>> queryTeacherMapper(@Param("userIds") List<Integer> userIds, @Param("teacherType") String teacherType);
 }

+ 140 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CloudTeacherSumDto.java

@@ -0,0 +1,140 @@
+package com.ym.mec.biz.dal.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+
+public class CloudTeacherSumDto {
+
+    @ApiModelProperty(value = "分部")
+    private String organName;
+
+    @ApiModelProperty(value = "在读人数")
+    private BigDecimal normalNum = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "练习率")
+    private BigDecimal trainRate = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "练习总时长")
+    private BigDecimal trainTotalTime = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "平均练习时长")
+    private BigDecimal avgTrainTime = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "练习达标率")
+    private BigDecimal trainStandRate = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "练习总人数")
+    private BigDecimal trainStudentNum = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "练习时长>60分钟的人数")
+    private BigDecimal train0 = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "<60分钟")
+    private Integer train1;
+
+    @ApiModelProperty(value = "60~120分钟")
+    private Integer train2;
+
+    @ApiModelProperty(value = "120~240分钟")
+    private Integer train3;
+
+    @ApiModelProperty(value = ">240分钟")
+    private Integer train4;
+
+    public String getOrganName() {
+        return organName;
+    }
+
+    public void setOrganName(String organName) {
+        this.organName = organName;
+    }
+
+    public BigDecimal getNormalNum() {
+        return normalNum;
+    }
+
+    public void setNormalNum(BigDecimal normalNum) {
+        this.normalNum = normalNum;
+    }
+
+    public BigDecimal getTrainRate() {
+        return trainRate;
+    }
+
+    public void setTrainRate(BigDecimal trainRate) {
+        this.trainRate = trainRate;
+    }
+
+    public BigDecimal getTrainTotalTime() {
+        return trainTotalTime;
+    }
+
+    public void setTrainTotalTime(BigDecimal trainTotalTime) {
+        this.trainTotalTime = trainTotalTime;
+    }
+
+    public BigDecimal getAvgTrainTime() {
+        return avgTrainTime;
+    }
+
+    public void setAvgTrainTime(BigDecimal avgTrainTime) {
+        this.avgTrainTime = avgTrainTime;
+    }
+
+    public BigDecimal getTrainStandRate() {
+        return trainStandRate;
+    }
+
+    public void setTrainStandRate(BigDecimal trainStandRate) {
+        this.trainStandRate = trainStandRate;
+    }
+
+    public BigDecimal getTrainStudentNum() {
+        return trainStudentNum;
+    }
+
+    public void setTrainStudentNum(BigDecimal trainStudentNum) {
+        this.trainStudentNum = trainStudentNum;
+    }
+
+    public BigDecimal getTrain0() {
+        return train0;
+    }
+
+    public void setTrain0(BigDecimal train0) {
+        this.train0 = train0;
+    }
+
+    public Integer getTrain1() {
+        return train1;
+    }
+
+    public void setTrain1(Integer train1) {
+        this.train1 = train1;
+    }
+
+    public Integer getTrain2() {
+        return train2;
+    }
+
+    public void setTrain2(Integer train2) {
+        this.train2 = train2;
+    }
+
+    public Integer getTrain3() {
+        return train3;
+    }
+
+    public void setTrain3(Integer train3) {
+        this.train3 = train3;
+    }
+
+    public Integer getTrain4() {
+        return train4;
+    }
+
+    public void setTrain4(Integer train4) {
+        this.train4 = train4;
+    }
+}

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/EduOrganStudentListExportDto.java

@@ -25,6 +25,9 @@ public class EduOrganStudentListExportDto {
     @ApiModelProperty("声部名称")
     private String subjectName;
 
+    @ApiModelProperty("声部老师")
+    private String subjectTeacherName;
+
     private String currentGradeNum;
 
     private String currentClass;
@@ -86,6 +89,14 @@ public class EduOrganStudentListExportDto {
     @ApiModelProperty("会员有效期")
     private String membershipEndTime;
 
+    public String getSubjectTeacherName() {
+        return subjectTeacherName;
+    }
+
+    public void setSubjectTeacherName(String subjectTeacherName) {
+        this.subjectTeacherName = subjectTeacherName;
+    }
+
     public String getCurrentClass() {
         return currentClass;
     }

+ 8 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/IndexErrInfoDto.java

@@ -24,9 +24,15 @@ public class IndexErrInfoDto<T> {
     public IndexErrInfoDto() {
     }
 
-    public IndexErrInfoDto(IndexErrorType errorType, String desc, int num, List<T> result) {
+    public IndexErrInfoDto(IndexErrorType errorType,int num) {
         this.errorType = errorType;
-        this.desc = desc;
+        this.desc = errorType.getMsg();
+        this.num = num;
+    }
+
+    public IndexErrInfoDto(IndexErrorType errorType,int num, List<T> result) {
+        this.errorType = errorType;
+        this.desc = errorType.getMsg();
         this.num = num;
         this.result = result;
     }

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportEnum.java

@@ -84,6 +84,7 @@ public enum ExportEnum implements BaseEnum<String, ExportEnum> {
     EXPORT_PRE_COURSE_CONSUMER("EXPORT_PRE_COURSE_CONSUMER", "预计课耗导出"),
     EXPORT_PRE_COURSE_CONSUMER_DETAIL("EXPORT_PRE_COURSE_CONSUMER_DETAIL", "预计课耗学员详情导出"),
     EXPORT_COURSE_CONSUMER_SUM("EXPORT_COURSE_CONSUMER_SUM", "课耗统计导出"),
+    EXPORT_CLOUD_TEACHER_SUM("EXPORT_CLOUD_TEACHER_SUM", "云教练统计导出"),
     ;
 
     private String code;

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportTypeEnum.java

@@ -22,7 +22,8 @@ public enum ExportTypeEnum implements BaseEnum<Integer, ExportTypeEnum> {
 	EXPORT_COURSE_CONSUMER_DETAIL(16, "实际课耗学员详情导出"),
 	EXPORT_PRE_COURSE_CONSUMER(17, "预计课耗导出"),
 	EXPORT_PRE_COURSE_CONSUMER_DETAIL(18, "预计课耗学员详情导出"),
-	EXPORT_COURSE_CONSUMER_SUM(19, "课耗统计导出")
+	EXPORT_COURSE_CONSUMER_SUM(19, "课耗统计导出"),
+	EXPORT_CLOUD_TEACHER_SUM(20, "云教练统计导出")
 	;
 
 	private Integer code;

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/IndexErrorType.java

@@ -42,6 +42,8 @@ public enum IndexErrorType implements BaseEnum<String, IndexErrorType> {
     ATTENDANCE_SERVE("ATTENDANCE_SERVE", "考勤及服务"),
     TEACHER_EXCEPTION_ATTENDANCE("TEACHER_EXCEPTION_ATTENDANCE", "老师考勤异常"),
     STUDENT_EXCEPTION_ATTENDANCE("STUDENT_EXCEPTION_ATTENDANCE", "学员考勤异常"),
+    CURRENT_COURSE_ERROR("CURRENT_COURSE_ERROR", "当月排课异常"),
+    WAIT_RENEW_INFO("WAIT_RENEW_INFO", "待续费学员提醒"),
     TEACHER_NOT_A_CLASS("TEACHER_NOT_A_CLASS", "课程异常"),
     TEACHER_SERVE_ERROR("TEACHER_SERVE_ERROR", "服务指标异常"),
     HAS_FREE_COURSE_TIMES("HAS_FREE_COURSE_TIMES", "学员已排课时长未消耗完"),

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

@@ -32,6 +32,9 @@ public class EndCourseScheduleQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "学生编号")
     private String studentIdList;
 
+    @ApiModelProperty(value = "学生编号")
+    private Integer studentId;
+
     @ApiModelProperty(value = "学生名称")
     private String studentName;
 
@@ -103,6 +106,14 @@ public class EndCourseScheduleQueryInfo extends QueryInfo {
     @ApiModelProperty(value = "是否云教练课程")
     private Integer memberFlag;
 
+    public Integer getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Integer studentId) {
+        this.studentId = studentId;
+    }
+
     public Integer getMemberFlag() {
         return memberFlag;
     }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/page/StudentCourseConsumerQueryInfo.java

@@ -16,6 +16,17 @@ public class StudentCourseConsumerQueryInfo{
     @ApiModelProperty(value = "结束时间")
     private String endDate;
 
+    @ApiModelProperty(value = "周数")
+    private long weekBetween;
+
+    public long getWeekBetween() {
+        return weekBetween;
+    }
+
+    public void setWeekBetween(long weekBetween) {
+        this.weekBetween = weekBetween;
+    }
+
     public String getOrganId() {
         return organId;
     }

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/StudentService.java

@@ -191,4 +191,7 @@ public interface StudentService extends BaseService<Integer, Student> {
     * @date 2022/10/11 11:03
     */
     void updateRepairFlag(Integer userId, boolean repairFlag);
+
+    //统计训练时长
+    List<CloudTeacherSumDto> cloudTeacherSum(StudentCourseConsumerQueryInfo queryInfo);
 }

+ 16 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java

@@ -183,6 +183,8 @@ public class ExportServiceImpl implements ExportService {
     private OperatingReportNewService operatingReportNewService;
     @Autowired
     private StudentCourseConsumerService studentCourseConsumerService;
+    @Autowired
+    private StudentTeacherMapperDao studentTeacherMapperDao;
 
     private static final ExecutorService exportExecutorService = Executors.newFixedThreadPool(10);
     @Autowired
@@ -371,6 +373,7 @@ public class ExportServiceImpl implements ExportService {
         exportManageFuncMap.put(ExportEnum.EXPORT_PRE_COURSE_CONSUMER, (info) -> exportPreCourseConsumer(info));
         exportManageFuncMap.put(ExportEnum.EXPORT_PRE_COURSE_CONSUMER_DETAIL, (info) -> exportPreCourseConsumerDetail(info));
         exportManageFuncMap.put(ExportEnum.EXPORT_COURSE_CONSUMER_SUM, (info) -> exportCourseConsumerSum(info));
+        exportManageFuncMap.put(ExportEnum.EXPORT_CLOUD_TEACHER_SUM, (info) -> exportCloudTeacherSum(info));
     }
 
     private List<StudentServeExportDto> exportStudentServeInfo(Map<String, Object> info) {
@@ -1093,9 +1096,12 @@ public class ExportServiceImpl implements ExportService {
         if (CollectionUtils.isEmpty(rows)) {
             throw new BizException("没有可导出的记录");
         }
+        List<Integer> userIds = rows.stream().map(e -> e.getStudentId()).collect(Collectors.toList());
+        Map<Integer,String> teacherMapper = MapUtil.convertMybatisMap(studentTeacherMapperDao.queryTeacherMapper(userIds,"NORMAL"));
         for (EduOrganStudentListExportDto row : rows) {
             row.setCloudStudyUseTime(Math.round(row.getCloudStudyUseTime()));
             row.setCloudStudyUseAvgTime(Math.round(row.getCloudStudyUseAvgTime()));
+            row.setSubjectTeacherName(teacherMapper.get(row.getStudentId()));
         }
         return rows;
     }
@@ -1541,6 +1547,16 @@ public class ExportServiceImpl implements ExportService {
         return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_COURSE_CONSUMER_SUM),
                 managerDownload.getName());
     }
+    private HttpResponseResult exportCloudTeacherSum(Map<String, Object> info){
+        StudentCourseConsumerQueryInfo queryInfo = JSONObject.parseObject(JSONObject.toJSONString(info), StudentCourseConsumerQueryInfo.class);
+        SysUser user = sysUserService.getUser();
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(user.getId(), queryInfo.getOrganId(), user.getIsSuperAdmin()));
+        List<CloudTeacherSumDto> dtos = studentService.cloudTeacherSum(queryInfo);
+        checkRows(dtos);
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.EXPORT_CLOUD_TEACHER_SUM,user.getId());
+        return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_CLOUD_TEACHER_SUM),
+                managerDownload.getName());
+    }
 
     //导出训练统计
     private HttpResponseResult exportCompareRecord(Map<String, Object> info){

+ 130 - 126
mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java

@@ -1,12 +1,14 @@
 package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.extension.api.R;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.*;
-import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.entity.IndexBaseMonthData;
+import com.ym.mec.biz.dal.entity.IndexErrInfoDto;
+import com.ym.mec.biz.dal.entity.Organization;
+import com.ym.mec.biz.dal.entity.StudentRegistration;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.IndexDataQueryInfo;
 import com.ym.mec.biz.dal.page.OrganCloudStudyStudentDataQueryInfo;
@@ -35,6 +37,8 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 import static com.ym.mec.biz.dal.enums.IndexDataType.*;
@@ -58,8 +62,6 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 	@Autowired
 	private SysUserFeignService sysUserFeignService;
 	@Autowired
-	private StudentExtracurricularExercisesSituationDao studentExtracurricularExercisesSituationDao;
-	@Autowired
 	private ClassGroupDao classGroupDao;
 	@Autowired
 	private StudentRegistrationDao studentRegistrationDao;
@@ -363,43 +365,33 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 	//异步处理经营数据查询
 	public void syncOperation(String startDate1,String endDate1,List<Integer> arrayList,Integer tenantId,List<IndexBaseDto> indexBaseDtoList,Map<IndexDataType, List<IndexBaseMonthData>> typeDateMap){
 		CompletableFuture future1 = CompletableFuture.supplyAsync(() -> {
-//			List<IndexBaseDto> indexBaseDtoList = new ArrayList<>();
 			indexBaseDtoList.add(this.getIndexBaseDto(ORGAN_RENEW_AMOUNT,indexBaseMonthDataDao.getOrganTotalAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,"RENEW",null,tenantId)));
 			indexBaseDtoList.add(this.getIndexBaseDto(ORGAN_VIP_AMOUNT,indexBaseMonthDataDao.getOrganVipAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,tenantId)));
-//			return indexBaseDtoList;
 			return true;
 		},exportExecutorService);
 		CompletableFuture future2 = CompletableFuture.supplyAsync(() -> {
-//			List<IndexBaseDto> indexBaseDtoList = new ArrayList<>();
 			indexBaseDtoList.add(this.getIndexBaseDto(ORGAN_PRACTICE_AMOUNT,indexBaseMonthDataDao.getOrganTotalAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,"PRACTICE_GROUP_BUY,PRACTICE_GROUP_RENEW",null,tenantId)));
 			indexBaseDtoList.add(this.getIndexBaseDto(ORGAN_OTHER_AMOUNT,indexBaseMonthDataDao.getOrganOtherAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,tenantId)));
-//			return indexBaseDtoList;
 			return true;
 		},exportExecutorService);
 		CompletableFuture future3 = CompletableFuture.supplyAsync(() -> {
-//			List<IndexBaseDto> indexBaseDtoList = new ArrayList<>();
 			indexBaseDtoList.add(this.getIndexBaseDto(IndexDataType.ORGAN_TOTAL_AMOUNT,indexBaseMonthDataDao.getOrganTotalAmountDataWithTimely(startDate1, endDate1, arrayList,tenantId)));
 			//经营报表细化
 			indexBaseDtoList.add(this.getIndexBaseDto(ORGAN_APPLY_AMOUNT,indexBaseMonthDataDao.getOrganTotalAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,"APPLY,ADD_STUDENT",null,tenantId)));
-//			return indexBaseDtoList;
 			return true;
 		},exportExecutorService);
 		CompletableFuture future4 = CompletableFuture.supplyAsync(() -> {
-//			List<IndexBaseDto> indexBaseDtoList = new ArrayList<>();
 			indexBaseDtoList.add(this.getIndexBaseDto(IndexDataType.ORGAN_FINANCE_BALANCE_AMOUNT,indexBaseMonthDataDao.getOrganFinanceBalanceDataWithTimely(startDate1, endDate1, arrayList,tenantId)));
 			indexBaseDtoList.add(this.getIndexBaseDto(ORGAN_FINANCE_AMOUNT,indexBaseMonthDataDao.getOrganFinanceActualDataWithTimely(startDate1, endDate1, arrayList,tenantId)));
-//			return indexBaseDtoList;
 			return true;
 		},exportExecutorService);
 
 		CompletableFuture future5 = CompletableFuture.supplyAsync(()->{
-//			Map<IndexDataType, List<IndexBaseMonthData>> typeDateMap = new HashMap<>(2);
 			typeDateMap.put(IndexDataType.FINANCE_BALANCE_AMOUNT,indexBaseMonthDataDao.getFinanceBalanceDataWithTimely(startDate1, endDate1, arrayList,tenantId));
 			typeDateMap.put(FINANCE_AMOUNT,indexBaseMonthDataDao.getFinanceActualDataWithTimely(startDate1, endDate1, arrayList,tenantId));
 			return true;
 		},exportExecutorService);
 		CompletableFuture future6 = CompletableFuture.supplyAsync(()->{
-//			Map<IndexDataType, List<IndexBaseMonthData>> typeDateMap = new HashMap<>(2);
 			List<IndexBaseMonthData> renewAmount = indexBaseMonthDataDao.getTotalAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,"RENEW",null,tenantId);
 			typeDateMap.put(RENEW_AMOUNT,renewAmount);
 			List<IndexBaseMonthData> vipAmount = indexBaseMonthDataDao.getVipAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,tenantId);
@@ -407,7 +399,6 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			return true;
 		},exportExecutorService);
 		CompletableFuture future7 = CompletableFuture.supplyAsync(()->{
-//			Map<IndexDataType, List<IndexBaseMonthData>> typeDateMap = new HashMap<>(2);
 			List<IndexBaseMonthData> totalAmountDataWithTimely = indexBaseMonthDataDao.getTotalAmountDataWithTimely(startDate1, endDate1, arrayList,tenantId);
 			typeDateMap.put(IndexDataType.TOTAL_AMOUNT,totalAmountDataWithTimely);
 			//经营报表细化
@@ -416,7 +407,6 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			return true;
 		},exportExecutorService);
 		CompletableFuture future8 = CompletableFuture.supplyAsync(()->{
-//			Map<IndexDataType, List<IndexBaseMonthData>> typeDateMap = new HashMap<>(2);
 			List<IndexBaseMonthData> practiceAmount = indexBaseMonthDataDao.getTotalAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,"PRACTICE_GROUP_BUY,PRACTICE_GROUP_RENEW",null,tenantId);
 			typeDateMap.put(PRACTICE_AMOUNT,practiceAmount);
 			List<IndexBaseMonthData> otherAmount = indexBaseMonthDataDao.getOtherAmountDataWithTimelyDetails(startDate1, endDate1, arrayList,tenantId);
@@ -726,15 +716,23 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 		}
 	}
 
+	private CompletableFuture async(Runnable runnable){
+		return CompletableFuture.runAsync(() -> {
+			runnable.run();
+		},exportExecutorService);
+	}
+
 	@Override
 	public Map<String, Object> getIndexErrData(String organIdsStr, IndexErrorType errorType) {
 		//只筛选指定时间之后的数据
-		String startTime = DateUtil.format(DateUtil.getFirstDayOfMonth(DateUtil.addMonths(new Date(), -1)),DateUtil.ISO_EXPANDED_DATE_FORMAT);
+		Date date = new Date();
+		String startTime = DateUtil.format(DateUtil.getFirstDayOfMonth(DateUtil.addMonths(date, -1)),DateUtil.ISO_EXPANDED_DATE_FORMAT);
 
 		Set<Integer> organIds = null;
 		if(StringUtils.isNotBlank(organIdsStr)){
 			organIds = Arrays.stream(organIdsStr.split(",")).map(Integer::new).collect(Collectors.toSet());
 		}
+		Set<Integer> organIdList = organIds;
 		List<IndexErrInfoDto> all = new ArrayList<>();
 		SysUser sysUser = sysUserFeignService.queryUserInfo();
 		//如果当前用户只有教务老师角色,那么只能看到他所管理的课程组的信息
@@ -746,26 +744,35 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			classGroupIds = classGroupDao.queryGroupClassGroupIds(sysUser.getId());
 			educationUserId = sysUser.getId();
 		}
+		Integer educationId = educationUserId;
+		List<Long> classGroupIdList = classGroupIds;
 		Integer tenantId = TenantContextHolder.getTenantId();
 		if(IndexErrorType.MUSIC_PATROL.equals(errorType)){
 			IndexErrInfoDto<IndexErrInfoDto> one = new IndexErrInfoDto<>();
 			one.setErrorType(IndexErrorType.MUSIC_PATROL);
 			one.setDesc(IndexErrorType.MUSIC_PATROL.getMsg());
 			List<IndexErrInfoDto> oneChild = new ArrayList<>();
-
 			//基础技能班学员数量异常
-			oneChild.add(new IndexErrInfoDto(IndexErrorType.HIGH_CLASS_STUDENT_LESS_THAN_THREE, IndexErrorType.HIGH_CLASS_STUDENT_LESS_THAN_THREE.getMsg(), indexBaseMonthDataDao.countLessThenThreeClassGroupNum(organIds,educationUserId,tenantId,false), null));
-
+			CompletableFuture future1 = this.async(()->{
+					oneChild.add(new IndexErrInfoDto(IndexErrorType.HIGH_CLASS_STUDENT_LESS_THAN_THREE,
+						indexBaseMonthDataDao.countLessThenThreeClassGroupNum(organIdList,educationId,tenantId,false)));
+			});
 			//乐团巡查事项异常
-			int errInspection = indexBaseMonthDataDao.queryErrInspection(organIds,startTime,tenantId);
-			oneChild.add(new IndexErrInfoDto(IndexErrorType.MUSIC_PATROL_ITEM, IndexErrorType.MUSIC_PATROL_ITEM.getMsg(),errInspection, null));
-
+			CompletableFuture future2 = this.async(()->{
+					oneChild.add(new IndexErrInfoDto(IndexErrorType.MUSIC_PATROL_ITEM,
+						indexBaseMonthDataDao.queryErrInspection(organIdList,startTime,tenantId)));
+			});
 			//未加入任何班级学员
-			IndexErrInfoDto noClassMusicGroupStudentInfo = indexBaseMonthDataDao.getNoClassMusicGroupStudentInfo(organIds,educationUserId,tenantId,true);
-			noClassMusicGroupStudentInfo.setErrorType(IndexErrorType.NO_CLASS_MUSIC_GROUP_STUDENT_ERROR);
-			noClassMusicGroupStudentInfo.setDesc(IndexErrorType.NO_CLASS_MUSIC_GROUP_STUDENT_ERROR.getMsg());
-			oneChild.add(noClassMusicGroupStudentInfo);
-
+			CompletableFuture future3 = this.async(()-> {
+					oneChild.add(new IndexErrInfoDto(IndexErrorType.MUSIC_PATROL_ITEM,
+						indexBaseMonthDataDao.queryErrInspection(organIdList,startTime,tenantId)));
+
+				IndexErrInfoDto noClassMusicGroupStudentInfo = indexBaseMonthDataDao.getNoClassMusicGroupStudentInfo(organIdList,educationId,tenantId,true);
+				noClassMusicGroupStudentInfo.setErrorType(IndexErrorType.NO_CLASS_MUSIC_GROUP_STUDENT_ERROR);
+				noClassMusicGroupStudentInfo.setDesc(IndexErrorType.NO_CLASS_MUSIC_GROUP_STUDENT_ERROR.getMsg());
+				oneChild.add(noClassMusicGroupStudentInfo);
+			});
+			future1.join();future2.join();future3.join();
 			one.setNum(oneChild.stream().mapToInt(IndexErrInfoDto::getNum).sum());
 			one.setResult(oneChild);
 			all.add(one);
@@ -778,35 +785,35 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			two.setDesc(IndexErrorType.STUDENT_INFO.getMsg());
 			List<IndexErrInfoDto> twoChild = new ArrayList<>();
 			//学员请假异常提醒(只提醒本月的异常)
-			int studentErrorLeave = 0;
-			String studentErrorLeaveNum = sysTenantConfigService.getTenantConfigValue(SysConfigService.STUDENT_ERROR_LEAVE_NUM, tenantId);
-			if(StringUtils.isNotEmpty(studentErrorLeaveNum)){
-				String format1 = DateUtil.format(new Date(), DateUtil.ISO_YEAR_MONTH_FORMAT);
-				studentErrorLeave = indexBaseMonthDataDao.countStudentErrorLeave(organIds, format1, classGroupIds,Integer.parseInt(studentErrorLeaveNum),tenantId);
-			}
-
-			twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_ERROR_LEAVE, IndexErrorType.STUDENT_ERROR_LEAVE.getMsg(),studentErrorLeave , null));
-
-			//未缴费学员数
-			twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_ARREARAGE, IndexErrorType.STUDENT_ARREARAGE.getMsg(),
-					indexBaseMonthDataDao.countNoPaymentStudentNum(organIds,educationUserId,tenantId,true), Arrays.asList(educationUserId)));
-
-			//申请退团学员数
-			List<Long> quitGroupNum = indexBaseMonthDataDao.queryApplyForQuitGroupNum(organIds,educationUserId,tenantId);
-			twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_APPLY_FOR_QUIT_MUSIC_GROUP, IndexErrorType.STUDENT_APPLY_FOR_QUIT_MUSIC_GROUP.getMsg(), quitGroupNum.size(),  quitGroupNum));
-
-			//学员已排课时长未消耗完
-//			Map<String, Object> params = new HashMap<>();
-//			params.put("organId", organIdsStr);
-//			params.put("tenantId", tenantId);
-//			twoChild.add(new IndexErrInfoDto(IndexErrorType.HAS_FREE_COURSE_TIMES, IndexErrorType.HAS_FREE_COURSE_TIMES.getMsg(), musicGroupDao.countHasFreeCourseTimes(params), null));
+			CompletableFuture future1 = this.async(() -> {
+				int studentErrorLeave = 0;
+				String studentErrorLeaveNum = sysTenantConfigService.getTenantConfigValue(SysConfigService.STUDENT_ERROR_LEAVE_NUM, tenantId);
+				if (StringUtils.isNotEmpty(studentErrorLeaveNum)) {
+					String format1 = DateUtil.format(new Date(), DateUtil.ISO_YEAR_MONTH_FORMAT);
+					studentErrorLeave = indexBaseMonthDataDao.countStudentErrorLeave(organIdList, format1, classGroupIdList, Integer.parseInt(studentErrorLeaveNum), tenantId);
+				}
+				twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_ERROR_LEAVE,studentErrorLeave));
+			});
+			CompletableFuture future2 = this.async(() -> {
+				//未缴费学员数
+				twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_ARREARAGE,
+						indexBaseMonthDataDao.countNoPaymentStudentNum(organIdList,educationId,tenantId,true), Arrays.asList(educationId)));
+
+				//申请退团学员数
+				List<Long> quitGroupNum = indexBaseMonthDataDao.queryApplyForQuitGroupNum(organIdList,educationId,tenantId);
+				twoChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_APPLY_FOR_QUIT_MUSIC_GROUP
+						, quitGroupNum.size(),  quitGroupNum));
+			});
 
 			//合作单位回款异常
-			Map<String, Object> params1 = new HashMap<>();
-			params1.put("organId", organIdsStr);
-			params1.put("errorType", "COOPERATION_PAYMENT_ERROR");
-			twoChild.add(new IndexErrInfoDto(IndexErrorType.COOPERATION_PAYMENT_ERROR, IndexErrorType.COOPERATION_PAYMENT_ERROR.getMsg(), musicGroupCalenderRefundPeriodDao.countCoopRefund(params1), null));
-
+			CompletableFuture future3 = this.async(() -> {
+				Map<String, Object> params1 = new HashMap<>();
+				params1.put("organId", organIdsStr);
+				params1.put("errorType", "COOPERATION_PAYMENT_ERROR");
+				twoChild.add(new IndexErrInfoDto(IndexErrorType.COOPERATION_PAYMENT_ERROR
+						, musicGroupCalenderRefundPeriodDao.countCoopRefund(params1)));
+			});
+			future1.join();future2.join();future3.join();
 			two.setNum(twoChild.stream().mapToInt(IndexErrInfoDto::getNum).sum());
 			two.setResult(twoChild);
 			all.add(two);
@@ -822,18 +829,24 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			if (onlyForRole) {
 				userId = sysUser.getId();
 			}
-
-			//乐团巡查任务未计划
-			int inspectionItem = indexBaseMonthDataDao.queryInspectionItem(organIdsStr,startTime,userId,tenantId);
-			threeChild.add(new IndexErrInfoDto(IndexErrorType.INSPECTION_ITEM, IndexErrorType.INSPECTION_ITEM.getMsg(),inspectionItem, null));
-
-			//乐团巡查任务未提交
-			int inspectionItemPlan = indexBaseMonthDataDao.queryInspectionItemPlan(organIdsStr,startTime,tenantId);
-			threeChild.add(new IndexErrInfoDto(IndexErrorType.INSPECTION_ITEM_PLAN, IndexErrorType.INSPECTION_ITEM_PLAN.getMsg(),inspectionItemPlan, null));
-
-			//回访任务未完成
-			int studentVisit = indexBaseMonthDataDao.queryStudentVisit(organIdsStr,startTime,userId,tenantId);
-			threeChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_VISIT, IndexErrorType.STUDENT_VISIT.getMsg(),studentVisit, null));
+			Integer userId1 = userId;
+			CompletableFuture future1 = this.async(() -> {
+				//乐团巡查任务未计划
+				int inspectionItem = indexBaseMonthDataDao.queryInspectionItem(organIdsStr,startTime,userId1,tenantId);
+				threeChild.add(new IndexErrInfoDto(IndexErrorType.INSPECTION_ITEM,inspectionItem));
+			});
+			CompletableFuture future2 = this.async(() -> {
+				//乐团巡查任务未提交
+				int inspectionItemPlan = indexBaseMonthDataDao.queryInspectionItemPlan(organIdsStr,startTime,tenantId);
+				threeChild.add(new IndexErrInfoDto(IndexErrorType.INSPECTION_ITEM_PLAN,inspectionItemPlan));
+
+			});
+			CompletableFuture future3 = this.async(() -> {
+				//回访任务未完成
+				int studentVisit = indexBaseMonthDataDao.queryStudentVisit(organIdsStr,startTime,userId1,tenantId);
+				threeChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_VISIT,studentVisit));
+			});
+			future1.join();future2.join();future3.join();
 
 			three.setNum(threeChild.stream().mapToInt(IndexErrInfoDto::getNum).sum());
 			three.setResult(threeChild);
@@ -846,6 +859,13 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			four.setDesc(IndexErrorType.ATTENDANCE_SERVE.getMsg());
 			List<IndexErrInfoDto> fourChild = new ArrayList<>();
 
+			CompletableFuture future1 = this.async(() -> {
+				String month = DateUtil.format(date,DateUtil.ISO_YEAR_MONTH_FORMAT);
+				//当月排课异常: (1)剩余课时(未开始+排课资格)4的学员,本月排课节数少于4节
+				int currentCourseError = indexBaseMonthDataDao.getCurrentCourseError(month,organIdList);
+				fourChild.add(new IndexErrInfoDto(IndexErrorType.CURRENT_COURSE_ERROR, currentCourseError));
+			});
+
 			//课程考勤异常
 			int teacherAttendanceError = 0;
 			int studentAttendanceError = 0;
@@ -855,29 +875,11 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 				studentAttendanceError = indexBaseMonthDataDao.getStudentAttendanceError(organIds,startTime,classGroupIds,tenantId);
 				noAttendance = indexBaseMonthDataDao.getNoAttendance(organIds,startTime,classGroupIds,tenantId);
 			}
-			fourChild.add(new IndexErrInfoDto(IndexErrorType.TEACHER_EXCEPTION_ATTENDANCE, IndexErrorType.TEACHER_EXCEPTION_ATTENDANCE.getMsg(), teacherAttendanceError, null));
-			fourChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_EXCEPTION_ATTENDANCE, IndexErrorType.STUDENT_EXCEPTION_ATTENDANCE.getMsg(), studentAttendanceError, null));
-
+			fourChild.add(new IndexErrInfoDto(IndexErrorType.TEACHER_EXCEPTION_ATTENDANCE, teacherAttendanceError));
+			fourChild.add(new IndexErrInfoDto(IndexErrorType.STUDENT_EXCEPTION_ATTENDANCE, studentAttendanceError));
 			//课程异常
-			fourChild.add(new IndexErrInfoDto(IndexErrorType.TEACHER_NOT_A_CLASS, IndexErrorType.TEACHER_NOT_A_CLASS.getMsg(), noAttendance, null));
-
-			//只适用大雅
-//			if(tenantId == 1){
-//				//服务指标异常
-//				Map<String, Object> params = new HashMap<>();
-//				LocalDate nowDate = LocalDateTime.now(DateUtil.zoneId).toLocalDate();
-//				LocalDate monDayDate = nowDate.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue()).plusDays(-7);
-//				LocalDate sunDayDate = nowDate.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.SUNDAY.getValue()).plusDays(-7);
-//				params.put("organIds", organIds);
-//				params.put("monday",monDayDate.toString());
-//				params.put("sunday",sunDayDate.toString());
-//				params.put("jobNature", JobNatureEnum.FULL_TIME);
-//				params.put("unDone",1);
-//				params.put("reminded",0);
-//				params.put("tenantId",tenantId);
-//				int serveErrTeacherNum = studentExtracurricularExercisesSituationDao.countTeacherServeInfo(params);
-//				fourChild.add(new IndexErrInfoDto(IndexErrorType.TEACHER_SERVE_ERROR, IndexErrorType.TEACHER_SERVE_ERROR.getMsg(), serveErrTeacherNum, null));
-//			}
+			fourChild.add(new IndexErrInfoDto(IndexErrorType.TEACHER_NOT_A_CLASS,noAttendance));
+			future1.join();
 			four.setNum(fourChild.stream().mapToInt(IndexErrInfoDto::getNum).sum());
 			four.setResult(fourChild);
 			all.add(four);
@@ -1153,6 +1155,7 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 		if(StringUtils.isNotBlank(organIds)){
 			organIdSet = Arrays.stream(organIds.split(",")).map(Integer::new).collect(Collectors.toSet());
 		}
+		Set<Integer> organIdList = organIdSet;
 		//当前用户是否是分部经理
 		Boolean onlyForRole = employeePositionService.onlyForRole(SysUserRoleEnum.EDUCATION,sysUser.getId(),sysUser.getIsSuperAdmin());
 		Integer educationUserId = null;
@@ -1161,46 +1164,47 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			educationUserId = sysUser.getId();
 		}
 		Date date = new Date();
-
+		Integer educationId = educationUserId;
 		List<IndexErrInfoDto> result = new ArrayList<>();
+		CompletableFuture future1 = this.async(() -> {
+//				待续费学员提醒:剩余课时(未开始+排课资格)≤3
+			int waitRenewInfo = indexBaseMonthDataDao.getWaitRenewInfo(organIdList);
+			result.add(new IndexErrInfoDto(IndexErrorType.WAIT_RENEW_INFO,waitRenewInfo));
+		});
+		CompletableFuture future2 = this.async(() -> {
+			//未缴费学员数
+			result.add(new IndexErrInfoDto(IndexErrorType.STUDENT_NOT_PAYMENT,
+					indexBaseMonthDataDao.countNoPaymentStudentNum(organIdList,educationId,tenantId,false), Arrays.asList(educationId)));
+			String monthStr = DateUtil.format(date, DateUtil.ISO_YEAR_MONTH_FORMAT);
+			//全职未离职老师
+			//预计课酬较低
+			int lowTeacherSalary = indexBaseMonthDataDao.queryLowTeacherSalary(organIds,monthStr, tenantId);
+			result.add(new IndexErrInfoDto(IndexErrorType.TEACHER_EXPECT_SALARY_BE_LOW,lowTeacherSalary));
+		});
 
-		//未缴费学员数
-		result.add(new IndexErrInfoDto(IndexErrorType.STUDENT_NOT_PAYMENT, IndexErrorType.STUDENT_NOT_PAYMENT.getMsg(),
-				indexBaseMonthDataDao.countNoPaymentStudentNum(organIdSet,educationUserId,tenantId,false), Arrays.asList(educationUserId)));
-
-		String monthStr = DateUtil.format(date, DateUtil.ISO_YEAR_MONTH_FORMAT);
-		//全职未离职老师
-		//预计课酬较低
-		int lowTeacherSalary = indexBaseMonthDataDao.queryLowTeacherSalary(organIds,monthStr, tenantId);
-		result.add(new IndexErrInfoDto(IndexErrorType.TEACHER_EXPECT_SALARY_BE_LOW, IndexErrorType.TEACHER_EXPECT_SALARY_BE_LOW.getMsg(),lowTeacherSalary, null));
-
-		//乐团展演计划提醒
-//		List<MusicGroupPerformance> musicGroupPerformances = musicGroupPerformanceDao.findNoStart(educationUserId,organIds);
-//		IndexErrInfoDto infoDto1 = new IndexErrInfoDto();
-//		infoDto1.setErrorType(IndexErrorType.MUSIC_GROUP_PERFORMANCE);
-//		infoDto1.setNum(musicGroupPerformances.stream().map(e -> e.getMusicGroupId()).collect(Collectors.toSet()).size());
-//		infoDto1.setNum2(musicGroupPerformances.stream().map(e -> e.getId()).collect(Collectors.toSet()).size());
-//		infoDto1.setDesc(IndexErrorType.MUSIC_GROUP_PERFORMANCE.getMsg());
-//		result.add(infoDto1);
-
-		//乐团剩余时长未排课
-		List<String> musicGroupIds = musicGroupDao.queryHasSubCourseTimes(organIds,tenantId);
-		result.add(new IndexErrInfoDto(IndexErrorType.MUSIC_GROUP_HAS_COURSE_TIMES, IndexErrorType.MUSIC_GROUP_HAS_COURSE_TIMES.getMsg(),musicGroupIds.size(), null));
-
-		//基础技能班学员数量异常提醒
-		result.add(new IndexErrInfoDto(IndexErrorType.HIGH_CLASS_STUDENT_LESS_THAN_THREE_INFO, IndexErrorType.HIGH_CLASS_STUDENT_LESS_THAN_THREE_INFO.getMsg(), indexBaseMonthDataDao.countLessThenThreeClassGroupNum(organIdSet,educationUserId,tenantId,true), null));
-
-		//未加入任何班级学员
-		IndexErrInfoDto noClassMusicGroupStudentInfo = indexBaseMonthDataDao.getNoClassMusicGroupStudentInfo(organIdSet,educationUserId,tenantId,false);
-		noClassMusicGroupStudentInfo.setDesc(IndexErrorType.NO_CLASS_MUSIC_GROUP_STUDENT_INFO.getMsg());
-		result.add(noClassMusicGroupStudentInfo);
-
-		//合作单位回款提醒
-		Map<String, Object> params = new HashMap<>();
-		params.put("organId", organIds);
-		params.put("errorType", "COOPERATION_PAYMENT_ALERT");
-		result.add(new IndexErrInfoDto(IndexErrorType.COOPERATION_PAYMENT_ALERT, IndexErrorType.COOPERATION_PAYMENT_ALERT.getMsg(), musicGroupCalenderRefundPeriodDao.countCoopRefund(params), null));
+		CompletableFuture future3 = this.async(() -> {
+			//乐团剩余时长未排课
+			List<String> musicGroupIds = musicGroupDao.queryHasSubCourseTimes(organIds,tenantId);
+			result.add(new IndexErrInfoDto(IndexErrorType.MUSIC_GROUP_HAS_COURSE_TIMES,musicGroupIds.size()));
 
+			//基础技能班学员数量异常提醒
+			result.add(new IndexErrInfoDto(IndexErrorType.HIGH_CLASS_STUDENT_LESS_THAN_THREE_INFO
+					, indexBaseMonthDataDao.countLessThenThreeClassGroupNum(organIdList,educationId,tenantId,true)));
+		});
+		CompletableFuture future4 = this.async(() -> {
+			//未加入任何班级学员
+			IndexErrInfoDto noClassMusicGroupStudentInfo = indexBaseMonthDataDao.getNoClassMusicGroupStudentInfo(organIdList,educationId,tenantId,false);
+			noClassMusicGroupStudentInfo.setDesc(IndexErrorType.NO_CLASS_MUSIC_GROUP_STUDENT_INFO.getMsg());
+			result.add(noClassMusicGroupStudentInfo);
+
+			//合作单位回款提醒
+			Map<String, Object> params = new HashMap<>(2);
+			params.put("organId", organIds);
+			params.put("errorType", "COOPERATION_PAYMENT_ALERT");
+			result.add(new IndexErrInfoDto(IndexErrorType.COOPERATION_PAYMENT_ALERT
+					, musicGroupCalenderRefundPeriodDao.countCoopRefund(params)));
+		});
+		future1.join();future2.join();future3.join();future4.join();
 		return result;
 	}
 

+ 23 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentServiceImpl.java

@@ -6,10 +6,7 @@ import com.ym.mec.biz.dal.dao.*;
 import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.*;
-import com.ym.mec.biz.dal.page.CloudTeacherActiveQueryInfo;
-import com.ym.mec.biz.dal.page.OrganCloudStudyStudentDataQueryInfo;
-import com.ym.mec.biz.dal.page.StudentQueryInfo;
-import com.ym.mec.biz.dal.page.UserBasicQueryInfo;
+import com.ym.mec.biz.dal.page.*;
 import com.ym.mec.biz.service.*;
 import com.ym.mec.common.constant.CommonConstants;
 import com.ym.mec.common.dal.BaseDAO;
@@ -1315,6 +1312,28 @@ public class StudentServiceImpl extends BaseServiceImpl<Integer, Student> implem
         studentDao.updateRepairFlag(userIdList,repairFlag);
     }
 
+    @Override
+    public List<CloudTeacherSumDto> cloudTeacherSum(StudentCourseConsumerQueryInfo queryInfo) {
+        Date date = DateUtil.stringToDate(queryInfo.getStartDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT);
+        Date date2 = DateUtil.stringToDate(queryInfo.getEndDate(), DateUtil.ISO_EXPANDED_DATE_FORMAT);
+        long weekBetween = DateUtil.weekBetween(date, date2);
+        queryInfo.setWeekBetween(weekBetween);
+        List<CloudTeacherSumDto> cloudTeacherSumDtos = studentDao.cloudTeacherSum(queryInfo);
+        if(CollectionUtils.isEmpty(cloudTeacherSumDtos)){
+            return cloudTeacherSumDtos;
+        }
+        BigDecimal decimal = new BigDecimal(100);
+        for (CloudTeacherSumDto dto : cloudTeacherSumDtos) {
+            if(dto.getNormalNum().compareTo(BigDecimal.ZERO) == 0){
+                continue;
+            }
+            dto.setAvgTrainTime(dto.getTrainTotalTime().divide(dto.getNormalNum(),2, BigDecimal.ROUND_DOWN));
+            dto.setTrainRate(dto.getTrainStudentNum().divide(dto.getNormalNum(),2, BigDecimal.ROUND_DOWN).multiply(decimal));
+            dto.setTrainStandRate(dto.getTrain0().divide(dto.getNormalNum(),2, BigDecimal.ROUND_DOWN));
+        }
+        return cloudTeacherSumDtos;
+    }
+
     @Transactional(rollbackFor = Exception.class)
     public  <T extends BaseStudentDto> void insertStudent(T baseStudent){
         Student student = new Student();

+ 4 - 1
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -2432,7 +2432,7 @@
             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 == 'TEACHER_ERR_ATTENDANCE' or searchType == 'STUDENT_ERR_ATTENDANCE'">
+            <if test="studentId != null or searchType == 'TEACHER_ERR_ATTENDANCE' or searchType == 'STUDENT_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_
@@ -2507,6 +2507,9 @@
                 AND cs.new_course_id_ > 0
             </if>
         </if>
+        <if test="studentId != null">
+            AND cssp.user_id_ = #{studentId}
+        </if>
         <if test="memberFlag != null">
             AND cs.member_flag_ = #{memberFlag}
         </if>

+ 28 - 0
mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml

@@ -2136,4 +2136,32 @@
 		WHERE spo.type_ = 'PRACTICE_GROUP_BUY' OR spo.type_ = 'PRACTICE_GROUP_RENEW' OR (spo.group_type_ = 'MUSIC' AND spod.type_ = 'PRACTICE')
 		GROUP BY spo.user_id_,spo.create_time_,spo.organ_id_;
 	</select>
+    <select id="getCurrentCourseError" resultType="java.lang.Integer">
+		select COUNT(ss.user_id_) from student_statistics ss
+		left join (select cssp.user_id_ from mec_pro.course_schedule cs
+		left join mec_pro.course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{month} AND cs.type_ = 'VIP' AND cssp.group_type_ = 'VIP' and cssp.user_id_ IS NOT NULL
+		<if test="organIdList != null and organIdList.size > 0">
+			AND cs.organ_id_ IN
+			<foreach collection="organIdList" open="(" close=")" item="item" separator=",">
+				#{item}
+			</foreach>
+		</if>
+		group by cssp.user_id_ having COUNT(distinct cssp.course_schedule_id_) &lt; 4) cs ON cs.user_id_ = ss.user_id_
+		where ss.no_schedule_num_ + ss.sub_course_num_ > 4 and ss.group_type_ = 'VIP' AND cs.user_id_ = ss.user_id_;
+	</select>
+	<select id="getWaitRenewInfo" resultType="java.lang.Integer">
+		select COUNT(ss.user_id_) from student_statistics ss
+		<if test="organIdList != null and organIdList.size > 0">
+			left join sys_user su ON su.id_ = ss.user_id_
+		</if>
+		where ss.group_type_ = 'VIP' AND ss.no_schedule_num_ + ss.sub_course_num_ &lt; 4
+		AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ > 0
+		<if test="organIdList != null and organIdList.size > 0">
+			AND su.organ_id_ IN
+			<foreach collection="organIdList" open="(" close=")" item="item" separator=",">
+				#{item}
+			</foreach>
+		</if>
+	</select>
 </mapper>

+ 31 - 0
mec-biz/src/main/resources/config/mybatis/StudentMapper.xml

@@ -1160,6 +1160,37 @@
     <select id="queryByOperatingTag" resultType="java.lang.Integer">
         SELECT user_id_ FROM student WHERE operating_tag_ = #{operatingTag}
     </select>
+    <resultMap id="CloudTeacherSumDto" type="com.ym.mec.biz.dal.dto.CloudTeacherSumDto">
+        <result property="organName" column="organ_name_"/>
+        <result property="normalNum" column="normal_num_"/>
+        <result property="train0" column="train0"/>
+        <result property="train1" column="train1"/>
+        <result property="train2" column="train2"/>
+        <result property="train3" column="train3"/>
+        <result property="train4" column="train4"/>
+        <result property="trainTotalTime" column="train_total_time_"/>
+        <result property="trainStudentNum" column="train_student_num_"/>
+    </resultMap>
+    <select id="cloudTeacherSum" resultMap="CloudTeacherSumDto">
+        select o.name_ organ_name_,COUNT(s.user_id_) normal_num_,COUNT(smcr.user_id_) train_student_num_,
+        COUNT(CASE WHEN smcr.train_time_ &lt; 60 THEN 1 END) 'train1',
+        COUNT(CASE WHEN smcr.train_time_ >= 60 AND smcr.train_time_ &lt; 120 THEN 1 END) 'train2',
+        COUNT(CASE WHEN smcr.train_time_ >= 120 AND smcr.train_time_ &lt; 240 THEN 1 END) 'train3',
+        COUNT(CASE WHEN smcr.train_time_ >= 240 THEN 1 END) 'train4',
+        SUM(smcr.train_time_) train_total_time_,COUNT(CASE WHEN smcr.train_time_ > 60 THEN 1 END) 'train0'
+        from music_group mg
+        left join student_registration sr ON mg.id_ = sr.music_group_id_
+        left join student s ON sr.user_id_ = s.user_id_
+        left join (select smcr.user_id_,ROUND(SUM(smcr.play_time_)/60/#{queryInfo.weekBetween}) train_time_ from sys_music_compare_record smcr
+        where smcr.create_time_ between #{queryInfo.startDate} AND #{queryInfo.endDate}
+        group by smcr.user_id_) smcr ON s.user_id_ = smcr.user_id_
+        left join organization o ON o.id_ = mg.organ_id_
+        where mg.status_ = 'PROGRESS' AND sr.music_group_status_ = 'NORMAL' AND s.membership_end_time_ >= NOW()
+        <if test="queryInfo.organId != null and queryInfo.organId != ''">
+            AND FIND_IN_SET(mg.organ_id_,#{queryInfo.organId})
+        </if>
+        group by mg.organ_id_
+    </select>
     <sql id="queryStudentBasicInfoSql">
         <where>
             AND su.lock_flag_ = 0 AND su.del_flag_ = 0

+ 10 - 0
mec-biz/src/main/resources/config/mybatis/StudentTeacherMapperMapper.xml

@@ -49,4 +49,14 @@
 			#{id}
 		</foreach>
 	</select>
+	<select id="queryTeacherMapper" resultType="java.util.Map">
+		select stm.student_id_ 'key',GROUP_CONCAT(su.real_name_) 'value' from student_teacher_mapper stm
+		LEFT JOIN sys_user su ON su.id_ = stm.teacher_id_
+		where stm.student_id_ IN
+		<foreach collection="userIds" separator="," open="(" close=")" item="id">
+			#{id}
+		</foreach>
+		AND stm.teacher_type_ = #{teacherType}
+		GROUP BY stm.student_id_
+	</select>
 </mapper>

+ 62 - 0
mec-util/src/main/java/com/ym/mec/util/date/DateUtil.java

@@ -984,6 +984,68 @@ public class DateUtil {
 		return dates;
 	}
 
+	static int calculate(Calendar c){
+		int dayForWeek;
+		if(c.get(Calendar.DAY_OF_WEEK) == 1){
+			dayForWeek = 7;
+		}else{
+			dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;}
+		return dayForWeek;
+	}
+
+	static Calendar From(Calendar c){
+		switch(calculate(c)){
+			case 1:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-0);
+				break;
+			case 2:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-1);
+				break;
+			case 3:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-2);
+				break;
+			case 4:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-3);
+				break;
+			case 5:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-4);
+				break;
+			case 6:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-5);
+				break;
+			case 7:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)-6);
+		}
+		return c;
+
+	}
+
+	static Calendar To(Calendar c){
+		switch(calculate(c)){
+			case 1:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+6);
+				break;
+			case 2:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+5);
+				break;
+			case 3:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+4);
+				break;
+			case 4:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+3);
+				break;
+			case 5:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+2);
+				break;
+			case 6:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+1);
+				break;
+			case 7:c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR)+0);
+		}
+		return c;
+
+	}
+
+
+	public static long weekBetween(Date startDate, Date endDate) {
+		Calendar c1 = Calendar.getInstance();
+		Calendar c2 = Calendar.getInstance();
+
+		c1.setTime(startDate);
+		c2.setTime(endDate);
+
+		long cc1=From(c1).getTimeInMillis()/(1000*3600*24);
+		long cc2=To(c2).getTimeInMillis()/(1000*3600*24);
+		return (cc2-cc1+1)/7;
+	}
+
 	/**
 	 * @describe 获取指定时间再当天最后一秒的时间
 	 * @author Joburgess

+ 8 - 0
mec-web/src/main/java/com/ym/mec/web/controller/StudentManageController.java

@@ -429,4 +429,12 @@ public class StudentManageController extends BaseController {
     public Object countCloudTeacherActiveDetail(CloudTeacherActiveQueryInfo queryInfo) throws Exception {
         return succeed(studentService.countCloudTeacherActiveDetail(queryInfo));
     }
+
+    @ApiOperation(value = "新云教练统计")
+    @PostMapping("/cloudTeacherSum")
+    @PreAuthorize("@pcs.hasPermissions('studentManage/cloudTeacherSum')")
+    public Object cloudTeacherSum(@RequestBody StudentCourseConsumerQueryInfo queryInfo) throws Exception {
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
+        return succeed(studentService.cloudTeacherSum(queryInfo));
+    }
 }

+ 4 - 0
mec-web/src/main/resources/exportColumnMapper.ini

@@ -321,3 +321,7 @@ fieldColumns = ["organName","username","userId","phone","preConsumerNum","course
 [课耗统计导出]
 headColumns = ["分部", "在读人数", "应有课耗", "实际课耗","课耗达标率","实际课耗大于等于5节", "4节","3节","2节","1节","0节","达标占比"]
 fieldColumns = ["organName","normalNum","courseConsumerNum","courseSum","courseConsumerRate","num5","num4","num3","num2","num1","num0","standRate"]
+
+[云教练统计导出]
+headColumns = ["分部", "在读人数","练习人数","练习率","<60分钟", "60~120分钟","120~240分钟",">240分钟","平均练习时长","练习达标占比"]
+fieldColumns = ["organName","normalNum","trainStudentNum","trainRate","train1","train2","train3","train4","avgTrainTime","trainStandRate"]