Selaa lähdekoodia

Merge branch 'zx_2022-11-22' of http://git.dayaedu.com/yonge/mec into master_saas

zouxuan 2 vuotta sitten
vanhempi
commit
d155451696
22 muutettua tiedostoa jossa 809 lisäystä ja 99 poistoa
  1. 19 3
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentStatisticsDao.java
  2. 83 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentCourseConsumerDetailDto.java
  3. 106 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentCourseConsumerDto.java
  4. 63 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentCourseConsumerSumDto.java
  5. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentStatisticsSumDto.java
  6. 2 2
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ClassGroupTypeEnum.java
  7. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportEnum.java
  8. 6 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/ExportTypeEnum.java
  9. 50 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/page/StudentCourseConsumerQueryInfo.java
  10. 26 0
      mec-biz/src/main/java/com/ym/mec/biz/service/StudentCourseConsumerService.java
  11. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java
  12. 62 4
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java
  13. 18 49
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java
  14. 72 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentCourseConsumerServiceImpl.java
  15. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentManageServiceImpl.java
  16. 6 2
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentStatisticsServiceImpl.java
  17. 7 2
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  18. 5 4
      mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml
  19. 163 17
      mec-biz/src/main/resources/config/mybatis/StudentStatisticsMapper.xml
  20. 0 13
      mec-web/src/main/java/com/ym/mec/web/controller/ExportController.java
  21. 72 0
      mec-web/src/main/java/com/ym/mec/web/controller/StudentCourseConsumerController.java
  22. 21 1
      mec-web/src/main/resources/exportColumnMapper.ini

+ 19 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentStatisticsDao.java

@@ -1,9 +1,8 @@
 package com.ym.mec.biz.dal.dao;
 
-import com.ym.mec.biz.dal.dto.StudentOrganDto;
-import com.ym.mec.biz.dal.dto.StudentStatisticsDto;
-import com.ym.mec.biz.dal.dto.StudentStatisticsSumDto;
+import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.StudentStatistics;
+import com.ym.mec.biz.dal.page.StudentCourseConsumerQueryInfo;
 import com.ym.mec.common.dal.BaseDAO;
 import org.apache.ibatis.annotations.Param;
 
@@ -68,4 +67,21 @@ public interface StudentStatisticsDao extends BaseDAO<Integer, StudentStatistics
     List<StudentOrganDto> queryNoScheduleNumStudent(@Param("organIds") List<Integer> organIds);
 
     void updateFirstOrderTime();
+
+    Integer countNormalNum(@Param("groupType") String groupType, @Param("organIdList") List<Integer> organIdList);
+
+    //获取实际课耗列表
+    List<StudentCourseConsumerDto> queryCourseConsumer(@Param("queryInfo") StudentCourseConsumerQueryInfo queryInfo);
+
+    //获取预计课耗列表
+    List<StudentCourseConsumerDto> queryPreCourseConsumer(@Param("queryInfo") StudentCourseConsumerQueryInfo queryInfo);
+
+    //获取课耗统计
+    List<StudentCourseConsumerSumDto> queryCourseConsumerSum(@Param("queryInfo") StudentCourseConsumerQueryInfo queryInfo);
+
+    //获取实际课耗学员详情列表
+    List<StudentCourseConsumerDetailDto> queryCourseConsumerDetail(@Param("queryInfo") StudentCourseConsumerQueryInfo queryInfo);
+
+    //获取预计课耗学员详情列表
+    List<StudentCourseConsumerDetailDto> queryPreCourseConsumerDetail(@Param("queryInfo") StudentCourseConsumerQueryInfo queryInfo);
 }

+ 83 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentCourseConsumerDetailDto.java

@@ -0,0 +1,83 @@
+package com.ym.mec.biz.dal.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class StudentCourseConsumerDetailDto {
+
+    @ApiModelProperty(value = "分部")
+    private String organName;
+
+    @ApiModelProperty(value = "学员姓名")
+    private String username;
+
+    @ApiModelProperty(value = "用户编号")
+    private Integer userId;
+
+    @ApiModelProperty(value = "手机号")
+    private String phone;
+
+    @ApiModelProperty(value = "应耗课时")
+    private Integer preConsumerNum;
+
+    @ApiModelProperty(value = "实际消耗")
+    private Integer consumerNum;
+
+    @ApiModelProperty(value = "已排课时")
+    private Integer courseNum;
+
+    public Integer getCourseNum() {
+        return courseNum;
+    }
+
+    public void setCourseNum(Integer courseNum) {
+        this.courseNum = courseNum;
+    }
+
+    public String getOrganName() {
+        return organName;
+    }
+
+    public void setOrganName(String organName) {
+        this.organName = organName;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public Integer getPreConsumerNum() {
+        return preConsumerNum;
+    }
+
+    public void setPreConsumerNum(Integer preConsumerNum) {
+        this.preConsumerNum = preConsumerNum;
+    }
+
+    public Integer getConsumerNum() {
+        return consumerNum;
+    }
+
+    public void setConsumerNum(Integer consumerNum) {
+        this.consumerNum = consumerNum;
+    }
+}

+ 106 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentCourseConsumerDto.java

@@ -0,0 +1,106 @@
+package com.ym.mec.biz.dal.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+
+public class StudentCourseConsumerDto{
+    @ApiModelProperty(value = "分部")
+    private String organId;
+
+    @ApiModelProperty(value = "分部")
+    private String organName;
+
+    @ApiModelProperty(value = "在读人数")
+    private BigDecimal normalNum = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "大于等于5节")
+    private Integer num5;
+
+    @ApiModelProperty(value = "4节")
+    private Integer num4;
+
+    @ApiModelProperty(value = "3节")
+    private Integer num3;
+
+    @ApiModelProperty(value = "2节")
+    private Integer num2;
+
+    @ApiModelProperty(value = "1节")
+    private Integer num1;
+
+    @ApiModelProperty(value = "0节")
+    private Integer num0;
+
+    public String getOrganId() {
+        return organId;
+    }
+
+    public void setOrganId(String organId) {
+        this.organId = organId;
+    }
+
+    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 Integer getNum5() {
+        return num5;
+    }
+
+    public void setNum5(Integer num5) {
+        this.num5 = num5;
+    }
+
+    public Integer getNum4() {
+        return num4;
+    }
+
+    public void setNum4(Integer num4) {
+        this.num4 = num4;
+    }
+
+    public Integer getNum3() {
+        return num3;
+    }
+
+    public void setNum3(Integer num3) {
+        this.num3 = num3;
+    }
+
+    public Integer getNum2() {
+        return num2;
+    }
+
+    public void setNum2(Integer num2) {
+        this.num2 = num2;
+    }
+
+    public Integer getNum1() {
+        return num1;
+    }
+
+    public void setNum1(Integer num1) {
+        this.num1 = num1;
+    }
+
+    public Integer getNum0() {
+        return num0;
+    }
+
+    public void setNum0(Integer num0) {
+        this.num0 = num0;
+    }
+}

+ 63 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentCourseConsumerSumDto.java

@@ -0,0 +1,63 @@
+package com.ym.mec.biz.dal.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+
+public class StudentCourseConsumerSumDto extends StudentCourseConsumerDto{
+
+    @ApiModelProperty(value = "实际课耗:所选时间段内所有学生课时数之和,注意:若一节1v2课程又两个学生,则统计为2节课")
+    private BigDecimal courseSum = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "课耗达标率:实际课耗/应有课耗*100%")
+    private BigDecimal courseConsumerRate = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "达标占比:4节+≥5节的人数之和/在读人数*100%")
+    private BigDecimal standRate = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "应有课耗:根据所选时间段计算,若所选时间段在一个自然月内则按在读人数*4,若超出一个月,该时间周期存在几个月就按在读人数*4*月数")
+    private BigDecimal courseConsumerNum = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "大于等于4节")
+    private BigDecimal num6 = BigDecimal.ZERO;
+
+    public BigDecimal getNum6() {
+        return num6;
+    }
+
+    public void setNum6(BigDecimal num6) {
+        this.num6 = num6;
+    }
+
+    public BigDecimal getCourseSum() {
+        return courseSum;
+    }
+
+    public void setCourseSum(BigDecimal courseSum) {
+        this.courseSum = courseSum;
+    }
+
+    public BigDecimal getCourseConsumerRate() {
+        return courseConsumerRate;
+    }
+
+    public void setCourseConsumerRate(BigDecimal courseConsumerRate) {
+        this.courseConsumerRate = courseConsumerRate;
+    }
+
+    public BigDecimal getStandRate() {
+        return standRate;
+    }
+
+    public void setStandRate(BigDecimal standRate) {
+        this.standRate = standRate;
+    }
+
+    public BigDecimal getCourseConsumerNum() {
+        return courseConsumerNum;
+    }
+
+    public void setCourseConsumerNum(BigDecimal courseConsumerNum) {
+        this.courseConsumerNum = courseConsumerNum;
+    }
+}

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

@@ -34,6 +34,17 @@ public class StudentStatisticsSumDto {
     @ApiModelProperty(value = "未排课课时:活动资格【未排课】课程总数(1v多不去重)",required = false)
     private Integer noScheduleNum;
 
+    @ApiModelProperty(value = "在册:有课程或排课资格的",required = false)
+    private Integer registerNum;
+
+    public Integer getRegisterNum() {
+        return registerNum;
+    }
+
+    public void setRegisterNum(Integer registerNum) {
+        this.registerNum = registerNum;
+    }
+
     public Integer getSleepStudentNum() {
         return sleepStudentNum;
     }

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

@@ -6,9 +6,9 @@ import com.ym.mec.common.enums.BaseEnum;
  * 班级类型
  */
 public enum ClassGroupTypeEnum implements BaseEnum<String, ClassGroupTypeEnum> {
-	NORMAL("NORMAL", "普通班级"), MIX("MIX", "合奏班级"), HIGH("HIGH", "提高班"),
+	NORMAL("NORMAL", "声部班"), MIX("MIX", "合奏班"), HIGH("HIGH", "基础技能班"),
 	VIP("VIP", "vip课"), DEMO("DEMO", "试听课"), PRACTICE("PRACTICE", "网管课"), SNAP("SNAP",
-			"临时班"), COMM("COMM", "对外课程"), HIGH_ONLINE("HIGH_ONLINE", "网络基础训练课"),
+			"临时班"), COMM("COMM", "对外课程"), HIGH_ONLINE("HIGH_ONLINE", "网络基础技能班"),
 	MUSIC_NETWORK("MUSIC_NETWORK","乐团网管课");
 
 	private String code;

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

@@ -79,6 +79,11 @@ public enum ExportEnum implements BaseEnum<String, ExportEnum> {
     EXPORT_TRAINING_STATISTICS("EXPORT_TRAINING_STATISTICS", "训练统计导出"),
     EXPORT_OPERATING_VISIT_STATISTICS("EXPORT_OPERATING_VISIT_STATISTICS", "回访统计导出"),
     EXPORT_OPERATING_REPORT_NEW("EXPORT_OPERATING_REPORT_NEW", "经营报表导出"),
+    EXPORT_COURSE_CONSUMER("EXPORT_COURSE_CONSUMER", "实际课耗导出"),
+    EXPORT_COURSE_CONSUMER_DETAIL("EXPORT_COURSE_CONSUMER_DETAIL", "实际课耗学员详情导出"),
+    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", "课耗统计导出"),
     ;
 
     private String code;

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

@@ -17,7 +17,12 @@ public enum ExportTypeEnum implements BaseEnum<Integer, ExportTypeEnum> {
 	EXPORT_STUDENT_SUBCOURSE(11, "活动资格导出"),
 	EXPORT_TRAINING_STATISTICS(12, "训练统计导出"),
 	MALL_ORDER(13, "商城订单列表"),
-	MALL_ROUTE_ORDER(14, "商城财务管理");
+	MALL_ROUTE_ORDER(14, "商城财务管理"),
+	EXPORT_COURSE_CONSUMER(15, "实际课耗导出"),
+	EXPORT_COURSE_CONSUMER_DETAIL(16, "实际课耗学员详情导出"),
+	EXPORT_PRE_COURSE_CONSUMER(17, "预计课耗导出"),
+	EXPORT_PRE_COURSE_CONSUMER_DETAIL(18, "预计课耗学员详情导出"),
+	EXPORT_COURSE_CONSUMER_SUM(19, "课耗统计导出")
 	;
 
 	private Integer code;

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

@@ -0,0 +1,50 @@
+package com.ym.mec.biz.dal.page;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class StudentCourseConsumerQueryInfo{
+
+    @ApiModelProperty(value = "分部")
+    private String organId;
+
+    @ApiModelProperty(value = "月份")
+    private String month;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startDate;
+
+    @ApiModelProperty(value = "结束时间")
+    private String endDate;
+
+    public String getOrganId() {
+        return organId;
+    }
+
+    public void setOrganId(String organId) {
+        this.organId = organId;
+    }
+
+    public String getMonth() {
+        return month;
+    }
+
+    public void setMonth(String month) {
+        this.month = month;
+    }
+
+    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;
+    }
+}

+ 26 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/StudentCourseConsumerService.java

@@ -0,0 +1,26 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerDetailDto;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerDto;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerSumDto;
+import com.ym.mec.biz.dal.page.StudentCourseConsumerQueryInfo;
+
+import java.util.List;
+
+public interface StudentCourseConsumerService{
+
+    //实际课耗列表
+    List<StudentCourseConsumerDto> queryCourseConsumer(StudentCourseConsumerQueryInfo queryInfo);
+
+    //实际课耗学员详情列表
+    List<StudentCourseConsumerDetailDto> queryCourseConsumerDetail(StudentCourseConsumerQueryInfo queryInfo);
+
+    //预计课耗列表
+    List<StudentCourseConsumerDto> queryPreCourseConsumer(StudentCourseConsumerQueryInfo queryInfo);
+
+    //预计课耗学员详情列表
+    List<StudentCourseConsumerDetailDto> queryPreCourseConsumerDetail(StudentCourseConsumerQueryInfo queryInfo);
+
+    //课耗统计
+    List<StudentCourseConsumerSumDto> queryCourseConsumerSum(StudentCourseConsumerQueryInfo queryInfo);
+}

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java

@@ -3668,6 +3668,17 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
                     if (!classGroup.getId().equals(classGroupTeacher.getClassGroupId())) continue;
                     classGroupTeacherMappers.add(classGroupTeacher);
                 }
+                List<ClassGroupTeacherMapper> classGroupTeacherMapperList = classGroup.getClassGroupTeacherMapperList();
+                if (classGroupTeacherMapperList.size() > 0) {
+                    List<ClassGroupTeacherMapper> teachingTeachers = classGroupTeacherMapperList.stream().filter(e -> e.getTeacherRole() == TeachTypeEnum.TEACHING).collect(Collectors.toList());
+                    if (teachingTeachers.size() > 0) {
+                        classGroup.setTeachingTeacherName(StringUtils.join(teachingTeachers.stream().map(e -> e.getUserName()).collect(Collectors.toList()), ","));
+                    }
+                    List<ClassGroupTeacherMapper> bishopTeachers = classGroupTeacherMapperList.stream().filter(e -> e.getTeacherRole() == TeachTypeEnum.BISHOP).collect(Collectors.toList());
+                    if (bishopTeachers.size() > 0) {
+                        classGroup.setBishopTeacherName(StringUtils.join(bishopTeachers.stream().map(e -> e.getUserName()).collect(Collectors.toList()), ","));
+                    }
+                }
                 classGroup.setClassGroupTeacherMapperList(classGroupTeacherMappers);
                 classGroup.setStudentNum(studyNums.get(classGroup.getId()));
                 int totalClassTimes = 0;

+ 62 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java

@@ -181,6 +181,8 @@ public class ExportServiceImpl implements ExportService {
     private StudentOperatingVisitDao studentOperatingVisitDao;
     @Autowired
     private OperatingReportNewService operatingReportNewService;
+    @Autowired
+    private StudentCourseConsumerService studentCourseConsumerService;
 
     private static final ExecutorService exportExecutorService = Executors.newFixedThreadPool(10);
     @Autowired
@@ -364,6 +366,11 @@ public class ExportServiceImpl implements ExportService {
         exportManageFuncMap.put(ExportEnum.VIP_STUDENT_COURSE_MANAGE, (info) -> exportVipStudentCourseManage(info));
         exportManageFuncMap.put(ExportEnum.EXPORT_STUDENT_SUBCOURSE, (info) -> exportStudentSubCourse(info));
         exportManageFuncMap.put(ExportEnum.EXPORT_TRAINING_STATISTICS, (info) -> exportCompareRecord(info));
+        exportManageFuncMap.put(ExportEnum.EXPORT_COURSE_CONSUMER, (info) -> exportCourseConsumer(info));
+        exportManageFuncMap.put(ExportEnum.EXPORT_COURSE_CONSUMER_DETAIL, (info) -> exportCourseConsumerDetail(info));
+        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));
     }
 
     private List<StudentServeExportDto> exportStudentServeInfo(Map<String, Object> info) {
@@ -1484,6 +1491,57 @@ public class ExportServiceImpl implements ExportService {
     }
 
 
+    private HttpResponseResult exportCourseConsumer(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<StudentCourseConsumerDto> dtos = studentCourseConsumerService.queryCourseConsumer(queryInfo);
+        checkRows(dtos);
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.EXPORT_COURSE_CONSUMER,user.getId());
+        return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_COURSE_CONSUMER),
+                managerDownload.getName());
+    }
+    private HttpResponseResult exportCourseConsumerDetail(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<StudentCourseConsumerDetailDto> dtos = studentCourseConsumerService.queryCourseConsumerDetail(queryInfo);
+        checkRows(dtos);
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.EXPORT_COURSE_CONSUMER_DETAIL,user.getId());
+        return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_COURSE_CONSUMER_DETAIL),
+                managerDownload.getName());
+    }
+    private HttpResponseResult exportPreCourseConsumer(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<StudentCourseConsumerDto> dtos = studentCourseConsumerService.queryPreCourseConsumer(queryInfo);
+        checkRows(dtos);
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.EXPORT_PRE_COURSE_CONSUMER,user.getId());
+        return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_PRE_COURSE_CONSUMER),
+                managerDownload.getName());
+    }
+    private HttpResponseResult exportPreCourseConsumerDetail(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<StudentCourseConsumerDetailDto> dtos = studentCourseConsumerService.queryPreCourseConsumerDetail(queryInfo);
+        checkRows(dtos);
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.EXPORT_PRE_COURSE_CONSUMER_DETAIL,user.getId());
+        return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_PRE_COURSE_CONSUMER_DETAIL),
+                managerDownload.getName());
+    }
+    private HttpResponseResult exportCourseConsumerSum(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<StudentCourseConsumerSumDto> dtos = studentCourseConsumerService.queryCourseConsumerSum(queryInfo);
+        checkRows(dtos);
+        ManagerDownload managerDownload = saveManagerDownload(ExportTypeEnum.EXPORT_COURSE_CONSUMER_SUM,user.getId());
+        return this.asyncExport(() -> this.initExportInfo(dtos, managerDownload,ExportEnum.EXPORT_COURSE_CONSUMER_SUM),
+                managerDownload.getName());
+    }
+
     //导出训练统计
     private HttpResponseResult exportCompareRecord(Map<String, Object> info){
         ExportCompareQueryInfo queryInfo = JSONObject.parseObject(JSONObject.toJSONString(info), ExportCompareQueryInfo.class);
@@ -2764,15 +2822,15 @@ public class ExportServiceImpl implements ExportService {
         List<StudentStatisticsDto> rows = studentStatisticsService.queryStatisticsPage(queryInfo).getRows();
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"分部", "学生姓名", "学员编号", "联系电话", "声部", "学校", "年级", "学员状态", "未排课时", "总课时", "已完成课时",
-                            "剩余未开始课时","剩余课时(未开始+未排课资格)", "预收金额", "第一次课时间", "最近上课时间", "指导老师编号", "指导老师", "乐团主管编号", "乐团主管", "声部课老师编号", "声部课老师", "近30天课耗", "回访次数",
+                            "剩余未开始课时","剩余课时(未开始+未排课资格)", "预收金额", "第一次课时间", "最近上课时间", "乐团主管编号", "乐团主管", "管理老师编号", "管理老师", "近30天课耗", "回访次数",
                             "回访状态", "原因", "回访日期"},
                     new String[]{"studentBasicInfo.organName", "studentBasicInfo.userName", "studentBasicInfo.userId",
                             "studentBasicInfo.phone", "studentBasicInfo.subjectName", "studentBasicInfo.cooperationOrganName", "studentBasicInfo.grade",
                             "studentBasicInfo.studentStatus",
-                            "noScheduleNum", "totalCourseNum", "overCourseNum", "subCourseNum",  "subTotalCourse", "preCourseFee", "firstCourseTime", "lastCourseTime", "teacherId", "teacherName", "musicDirectorId", "musicDirectorName",
+                            "noScheduleNum", "totalCourseNum", "overCourseNum", "subCourseNum",  "subTotalCourse", "preCourseFee", "firstCourseTime", "lastCourseTime","musicDirectorId", "musicDirectorName",
                             "studentBasicInfo.subjectTeacherId", "studentBasicInfo.subjectTeacherName", "latelyCourseConsumer", "visitNum",
-                            "lastVisitStatus == null?'':lastVisitStatus == 'LOST' ? '流失':lastVisitStatus == 'THINKING' ? '考虑中':" +
-                                    "lastVisitStatus == 'PENDING_PAYMENT' ? '确认缴费待缴费':lastVisitStatus == 'PAUSE' ? '暂停':lastVisitStatus == 'OTHER' ? '其他':''"
+                            "lastVisitStatus == null?'':lastVisitStatus == 'LOST' ? '流失':lastVisitStatus == 'NORMAL' ? '在读':" +
+                                    "lastVisitStatus == 'SLEEPY' ? '沉睡':lastVisitStatus == 'PAUSE' ? '暂停':'其他'"
                             , "visitReason", "lastVisitTime"}, rows);
             exportManagerDownload(workbook, managerDownload);
         } catch (Exception e) {

+ 18 - 49
mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java

@@ -850,20 +850,11 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			int teacherAttendanceError = 0;
 			int studentAttendanceError = 0;
 			int noAttendance = 0;
-			//课程时间安排异常
-//			int courseTimeError = 0;
 			if(classGroupIds == null || classGroupIds.size() > 0){
 				teacherAttendanceError = indexBaseMonthDataDao.getTeacherAttendanceError(organIds,startTime,classGroupIds,tenantId);
 				studentAttendanceError = indexBaseMonthDataDao.getStudentAttendanceError(organIds,startTime,classGroupIds,tenantId);
 				noAttendance = indexBaseMonthDataDao.getNoAttendance(organIds,startTime,classGroupIds,tenantId);
-//				String courseStartTimeError = sysTenantConfigService.getTenantConfigValue(SysConfigService.COURSE_START_TIME_ERROR, tenantId);
-//				String courseEndTimeError = sysTenantConfigService.getTenantConfigValue(SysConfigService.COURSE_END_TIME_ERROR, tenantId);
-//				if(StringUtils.isNotEmpty(courseStartTimeError) && StringUtils.isNotEmpty(courseEndTimeError)){
-//					courseTimeError = indexBaseMonthDataDao.getCourseTimeError(organIds,classGroupIds,courseStartTimeError,courseEndTimeError,tenantId);
-//				}
 			}
-//			fourChild.add(new IndexErrInfoDto(IndexErrorType.COURSE_TIME_ERROR, IndexErrorType.COURSE_TIME_ERROR.getMsg(), courseTimeError, null));
-
 			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));
 
@@ -871,22 +862,22 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			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));
-			}
+//			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));
+//			}
 			four.setNum(fourChild.stream().mapToInt(IndexErrInfoDto::getNum).sum());
 			four.setResult(fourChild);
 			all.add(four);
@@ -1288,15 +1279,6 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 				flag2 = true;
 			}
 		}
-//		if(!flag2){
-//			Map<String, Object> params = new HashMap<String, Object>(2);
-//			params.put("organId",organIdsStr);
-//			params.put("tenantId",tenantId);
-//			Integer hasFreeCourseTimes = musicGroupDao.countHasFreeCourseTimes(params);
-//			if(hasFreeCourseTimes != null && hasFreeCourseTimes > 0){
-//				flag2 = true;
-//			}
-//		}
 		resultMap.put("studentInfo",flag2);
 		boolean flag3 = false;
 
@@ -1326,19 +1308,6 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 		resultMap.put("teacherInfo",flag3);
 
 		boolean flag4 = false;
-/*		if(!flag4){
-			int courseTimeError = 0;
-			if(classGroupIds == null || classGroupIds.size() > 0){
-				String courseStartTimeError = sysTenantConfigService.getTenantConfigValue(SysConfigService.COURSE_START_TIME_ERROR, tenantId);
-				String courseEndTimeError = sysTenantConfigService.getTenantConfigValue(SysConfigService.COURSE_END_TIME_ERROR, tenantId);
-				if(StringUtils.isNotEmpty(courseStartTimeError) && StringUtils.isNotEmpty(courseEndTimeError)){
-					courseTimeError = indexBaseMonthDataDao.getCourseTimeError(organIds,classGroupIds,courseStartTimeError,courseEndTimeError, tenantId);
-				}
-			}
-			if(courseTimeError > 0){
-				flag4 = true;
-			}
-		}*/
 		if(!flag4){
 			int attendanceError = 0;
 			if(classGroupIds == null || classGroupIds.size() > 0){
@@ -1367,7 +1336,7 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			}
 		}
 		//服务指标只用于大雅
-		if(tenantId == 1 && !flag4){
+		/*if(tenantId == 1 && !flag4){
 			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);
@@ -1382,7 +1351,7 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			if(serveErrTeacherNum > 0){
 				flag4 = true;
 			}
-		}
+		}*/
 		resultMap.put("attendanceServe",flag4);
 
 		boolean flag5 = false;

+ 72 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentCourseConsumerServiceImpl.java

@@ -0,0 +1,72 @@
+package com.ym.mec.biz.service.impl;
+
+import com.ym.mec.biz.dal.dao.StudentStatisticsDao;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerDetailDto;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerDto;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerSumDto;
+import com.ym.mec.biz.dal.page.StudentCourseConsumerQueryInfo;
+import com.ym.mec.biz.service.StudentCourseConsumerService;
+import com.ym.mec.common.constant.CommonConstants;
+import com.ym.mec.util.date.DateUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class StudentCourseConsumerServiceImpl implements StudentCourseConsumerService {
+
+    @Autowired
+    private StudentStatisticsDao studentStatisticsDao;
+
+
+    @Override
+    public List<StudentCourseConsumerDto> queryCourseConsumer(StudentCourseConsumerQueryInfo queryInfo) {
+        return studentStatisticsDao.queryCourseConsumer(queryInfo);
+    }
+
+    @Override
+    public List<StudentCourseConsumerDetailDto> queryCourseConsumerDetail(StudentCourseConsumerQueryInfo queryInfo) {
+        return studentStatisticsDao.queryCourseConsumerDetail(queryInfo);
+    }
+
+    @Override
+    public List<StudentCourseConsumerDto> queryPreCourseConsumer(StudentCourseConsumerQueryInfo queryInfo) {
+        return studentStatisticsDao.queryPreCourseConsumer(queryInfo);
+    }
+
+    @Override
+    public List<StudentCourseConsumerDetailDto> queryPreCourseConsumerDetail(StudentCourseConsumerQueryInfo queryInfo) {
+        return studentStatisticsDao.queryPreCourseConsumerDetail(queryInfo);
+    }
+
+    @Override
+    public List<StudentCourseConsumerSumDto> queryCourseConsumerSum(StudentCourseConsumerQueryInfo queryInfo) {
+        List<StudentCourseConsumerSumDto> consumerDtos = studentStatisticsDao.queryCourseConsumerSum(queryInfo);
+        if(CollectionUtils.isEmpty(consumerDtos)){
+            return consumerDtos;
+        }
+        Date date = DateUtil.stringToDate(queryInfo.getStartDate(), DateUtil.ISO_YEAR_MONTH_FORMAT);
+        Date date2 = DateUtil.stringToDate(queryInfo.getEndDate(), DateUtil.ISO_YEAR_MONTH_FORMAT);
+        BigDecimal monthsBetween = new BigDecimal(DateUtil.monthsBetween(date, date2) * 4);
+//#    (2)应有课耗:根据所选时间段计算,若所选时间段在一个自然月内则按在读人数*4,若超出一个月,该时间周期存在几个月就按在读人数*4*月数
+//#    (3)实际课耗:所选时间段内所有学生课时数之和,注意:若一节1v2课程又两个学生,则统计为2节课
+//#    (4)课耗达标率:实际课耗/应有课耗*100%
+//#    (5)达标占比:4节+≥5节的人数之和/在读人数*100%
+        BigDecimal bigDecimal = new BigDecimal(100);
+        for (StudentCourseConsumerSumDto consumerDto : consumerDtos) {
+            BigDecimal courseConsumerNum = consumerDto.getNormalNum().multiply(monthsBetween);
+            if(courseConsumerNum.compareTo(BigDecimal.ZERO) != 0){
+                consumerDto.setCourseConsumerRate(consumerDto.getCourseSum().divide(courseConsumerNum,BigDecimal.ROUND_HALF_UP).multiply(bigDecimal).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN));
+            }
+            if(consumerDto.getNormalNum().compareTo(BigDecimal.ZERO) != 0){
+                consumerDto.setStandRate(consumerDto.getNum6().divide(consumerDto.getNormalNum(),BigDecimal.ROUND_HALF_UP).setScale(CommonConstants.DECIMAL_FINAL_PLACE, BigDecimal.ROUND_DOWN));
+            }
+            consumerDto.setCourseConsumerNum(courseConsumerNum);
+        }
+        return consumerDtos;
+    }
+}

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentManageServiceImpl.java

@@ -965,7 +965,7 @@ public class StudentManageServiceImpl implements StudentManageService {
         if (StringUtils.isEmpty(studentErrorLeaveNum)) {
             return pageInfo;
         }
-        Map<String, Object> params = new HashMap<>();
+        Map<String, Object> params = new HashMap<>(5);
         MapUtil.populateMap(params, queryInfo);
         params.put("offset", pageInfo.getOffset());
         String totalMonth = DateUtil.format(DateUtil.addMonths(date, -1), DateUtil.ISO_YEAR_MONTH_FORMAT);

+ 6 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentStatisticsServiceImpl.java

@@ -101,6 +101,7 @@ public class StudentStatisticsServiceImpl extends BaseServiceImpl<Integer, Stude
 			pageInfo.setTotal(count);
 			params.put("offset", pageInfo.getOffset());
 			dataList = studentStatisticsDao.queryStatistics(params);
+
 		}
 		if (count == 0) {
 			dataList = new ArrayList<>();
@@ -115,7 +116,10 @@ public class StudentStatisticsServiceImpl extends BaseServiceImpl<Integer, Stude
 		if(StringUtils.isNotEmpty(organId)){
 			organIdList = Arrays.stream(organId.split(",")).map(id -> Integer.valueOf(id)).collect(Collectors.toList());
 		}
-		return studentStatisticsDao.studentSmallClassStatisticsSum(groupType,organIdList);
+		StudentStatisticsSumDto dto = studentStatisticsDao.studentSmallClassStatisticsSum(groupType, organIdList);
+		//获取进行中的学员数量
+		dto.setNormalStudentHasNormalGroupNum(studentStatisticsDao.countNormalNum(groupType, organIdList));
+		return dto;
     }
 
     @Override
@@ -129,7 +133,7 @@ public class StudentStatisticsServiceImpl extends BaseServiceImpl<Integer, Stude
 			organIdList = Arrays.stream(organId.split(",")).map(id -> Integer.valueOf(id)).collect(Collectors.toList());
 		}
 		//获取流失人数
-		sumForDateDto.setLostNum(studentStatisticsDao.countLostStudentNum(groupType,startDate,endDate,organIdList));
+//		sumForDateDto.setLostNum(studentStatisticsDao.countLostStudentNum(groupType,startDate,endDate,organIdList));
 		//获取新增人数
 		sumForDateDto.setAddNum(studentStatisticsDao.countAddStudentNum(groupType,startDate,endDate,organIdList));
 		//获取续费人数

+ 7 - 2
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -176,6 +176,11 @@
         cs.evaluate_flag_
     </sql>
 
+    <sql id="courseIgnore">
+        AND cs.del_flag_ = 0 AND cs.is_lock_ = 0 and cs.pre_course_flag_ = 0
+        AND (cs.new_course_id_ IS NULL OR cs.new_course_id_ = cs.id_)
+    </sql>
+
     <!-- 根据主键查询一条记录 -->
     <select id="get" resultMap="CourseSchedule">
         SELECT <include refid="resultSql"/>
@@ -2565,7 +2570,7 @@
         <if test="searchType == 'TEACHER_ERR_ATTENDANCE'">
             AND ta.teacher_id_ = cs.actual_teacher_id_
             AND cs.status_ = 'OVER'
-            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)
+            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.complaints_content_ IS NULL)
             AND (ta.sign_out_status_ IS NOT NULL OR ta.sign_in_status_ IS NOT NULL)
             AND EXISTS (SELECT id_ FROM course_schedule_teacher_salary WHERE cs.id_=course_schedule_id_ AND settlement_time_ IS NULL)
             AND (cs.new_course_id_ IS NULL OR cs.new_course_id_=cs.id_) AND cssp.id_ IS NOT NULL
@@ -2579,7 +2584,7 @@
         </if>
         <if test="searchType == 'NO_ATTENDANCE'">
             AND ta.teacher_id_ = cs.actual_teacher_id_
-            AND cs.status_ = 'OVER' AND ta.sign_in_time_ IS NULL AND ta.sign_out_time_ IS NULL AND ta.dispose_content_ IS NULL
+            AND cs.status_ = 'OVER' AND ta.sign_in_time_ IS NULL AND ta.sign_out_time_ IS NULL AND ta.complaints_content_ IS NULL
             AND EXISTS (SELECT id_ FROM course_schedule_teacher_salary WHERE cs.id_=course_schedule_id_ AND settlement_time_ IS NULL)
             AND (cs.new_course_id_ IS NULL OR cs.new_course_id_ = cs.id_)
         </if>

+ 5 - 4
mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml

@@ -1015,7 +1015,7 @@
 		LEFT JOIN course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
 		WHERE ta.teacher_id_ = cs.actual_teacher_id_ AND cs.pre_course_flag_ = 0 and cs.tenant_id_ = #{tenantId}
 		AND cs.status_ = 'OVER' AND cs.del_flag_ = 0 AND cs.class_date_ >= #{startTime}
-		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)
+		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.complaints_content_ IS NULL)
 		AND (ta.sign_out_status_ IS NOT NULL OR 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)
@@ -1093,7 +1093,7 @@
 		LEFT JOIN teacher_attendance ta ON ta.course_schedule_id_ = cs.id_
 		WHERE ta.teacher_id_ = cs.actual_teacher_id_ and cs.tenant_id_ = #{tenantId}
 		AND cs.status_ = 'OVER' AND cs.del_flag_ = 0 AND cs.class_date_>=#{startTime} AND cs.pre_course_flag_ = 0
-		AND ta.sign_in_time_ IS NULL AND ta.sign_out_time_ IS NULL AND ta.dispose_content_ IS NULL
+		AND ta.sign_in_time_ IS NULL AND ta.sign_out_time_ IS NULL AND ta.complaints_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="classGroupIds != null and classGroupIds.size() > 0">
@@ -1762,7 +1762,8 @@
 			</foreach>
 		</if>
 		GROUP BY sa.user_id_,DATE_FORMAT(cs.class_date_,'%Y-%m')
-		HAVING COUNT(sa.id_) >= #{studentErrorLeaveNum} AND COUNT(sa.id_) > SUM(sa.leave_visit_flag_)) c
+		HAVING COUNT(distinct DATE_FORMAT(cs.class_date_,'%Y-%m-%d')) >= #{studentErrorLeaveNum}
+		   AND COUNT(distinct DATE_FORMAT(cs.class_date_,'%Y-%m-%d')) > SUM(sa.leave_visit_flag_)) c
 	</select>
 	<select id="countOrganStudentErrorLeave" resultType="map">
 		SELECT c.organ_id_ 'key',COUNT(c.user_id_) 'value' FROM (
@@ -1804,7 +1805,7 @@
 			AND (sa.user_id_ = #{search} OR su.username_ LIKE CONCAT('%',#{search},'%') OR su.phone_ LIKE CONCAT('%',#{search},'%'))
 		</if>
 		GROUP BY sa.user_id_,DATE_FORMAT(cs.class_date_,'%Y-%m')
-		HAVING COUNT(sa.id_) >= #{studentErrorLeaveNum} AND COUNT(sa.id_) > SUM(sa.leave_visit_flag_)) c
+		HAVING COUNT(distinct DATE_FORMAT(cs.class_date_,'%Y-%m-%d')) >= #{studentErrorLeaveNum} AND COUNT(distinct DATE_FORMAT(cs.class_date_,'%Y-%m-%d')) > SUM(sa.leave_visit_flag_)) c
 	</select>
 	<resultMap id="StudentErrorLeaveDto" type="com.ym.mec.biz.dal.dto.StudentErrorLeaveDto">
 		<result property="currentNum" column="current_num_"/>

+ 163 - 17
mec-biz/src/main/resources/config/mybatis/StudentStatisticsMapper.xml

@@ -233,8 +233,8 @@
 			<result column="organ_name_" property="organName" />
 			<result column="cooperation_organ_id_" property="cooperationOrganId" />
 			<result column="cooperation_organ_name_" property="cooperationOrganName" />
-			<result column="subject_teacher_id_" property="subjectTeacherId" />
-			<result column="subject_teacher_name_" property="subjectTeacherName" />
+			<result column="teacher_id_" property="subjectTeacherId" />
+			<result column="real_name_" property="subjectTeacherName" />
 			<result column="course_balance_" property="courseBalance" />
 			<result column="student_status_" property="studentStatus" />
 		</association>
@@ -249,24 +249,21 @@
 			</if>
 			<if test="studentStatus != null and studentStatus != ''">
 				<if test="studentStatus == 'NORMAL'">
-					AND (ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND (ss.lately_year_course_consumer_ > 0 OR ss.over_course_num_ &lt;= 0)
+					AND (ss.last_visit_status_ = #{feedbackType} OR ((ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND ss.lately_year_course_consumer_ > 0))
 				</if>
 				<if test="studentStatus == 'SLEEPY'">
-					AND ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0
+					AND (ss.last_visit_status_ = #{feedbackType} OR (ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0))
 				</if>
 				<if test="studentStatus == 'LOST'">
-					AND ss.over_course_num_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 AND suca.course_balance_ &lt;= 0
+					AND (ss.last_visit_status_ = #{feedbackType} OR (ss.over_course_num_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 AND suca.course_balance_ &lt;= 0))
 				</if>
 				<if test="studentStatus == 'PAUSE'">
-					AND suca.course_balance_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0
+					AND (ss.last_visit_status_ = #{feedbackType} OR (suca.course_balance_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0))
 				</if>
 			</if>
 			<if test="studentStatus == null or studentStatus == ''">
 				AND (ss.over_course_num_ > 0 OR ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0 OR suca.course_balance_ > 0)
 			</if>
-			<if test="feedbackType != null and feedbackType != ''">
-				AND ss.last_visit_status_ = #{feedbackType}
-			</if>
 			<if test="latelyCourseConsumer != null">
 				AND ss.lately_course_consumer_ = #{latelyCourseConsumer}
 			</if>
@@ -335,15 +332,27 @@
 	<select id="queryStatistics" resultMap="StudentStatisticsDto">
 		SELECT *,ss.not_start_course_fee_ + ss.no_course_fee_ preCourseFee,
 		ss.no_schedule_num_ + ss.sub_course_num_ subTotalCourse,
-			CASE WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND (ss.lately_year_course_consumer_ > 0 OR ss.over_course_num_ &lt;= 0) THEN '在读'
-			WHEN ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0 THEN '沉睡'
-			WHEN ss.over_course_num_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 AND suca.course_balance_ &lt;= 0 THEN '流失'
-			WHEN suca.course_balance_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 THEN '暂停' ELSE '其他' END student_status_
+			CASE WHEN ss.last_visit_status_ IN ('NORMAL','PAUSE','SLEEPY','LOST') THEN ss.last_visit_status_
+			WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND (ss.lately_year_course_consumer_ > 0 OR ss.over_course_num_ &lt;= 0) THEN 'NORMAL'
+			WHEN ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0 THEN 'SLEEPY'
+			WHEN ss.over_course_num_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 AND suca.course_balance_ &lt;= 0 THEN 'LOST'
+			WHEN suca.course_balance_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 THEN 'PAUSE' ELSE 'OTHER' END student_status_
 			,suca.course_balance_,
-			ss.last_visit_time_
+			ss.last_visit_time_,stm.teacher_id_,stm.real_name_
 		FROM student_basic_info sbi
 		LEFT JOIN student_statistics ss ON ss.user_id_ = sbi.user_id_
 		LEFT JOIN sys_user_cash_account suca ON sbi.user_id_ = suca.user_id_
+		left join (select student_id_,group_concat(stm.teacher_id_) teacher_id_,group_concat(su.real_name_)real_name_ from student_teacher_mapper stm
+		left join sys_user su ON su.id_ = stm.teacher_id_
+		<if test="groupType != null and groupType != ''">
+			<if test="groupType == 'VIP' or groupType == 'THEORY'">
+				where stm.teacher_type_ = 'VIP'
+			</if>
+			<if test="groupType == 'PRACTICE'">
+				where stm.teacher_type_ = 'PRACTICE'
+			</if>
+		</if>
+		group by stm.student_id_) stm ON sbi.user_id_ = stm.student_id_
 		<include refid="queryStatisticsSql"/>
 		<include refid="global.limit"/>
 	</select>
@@ -358,17 +367,18 @@
 		<result property="waitRenewNum" column="waitRenewNum"/>
 		<result property="subCourseNum" column="subCourseNum"/>
 		<result property="noScheduleNum" column="noScheduleNum"/>
+		<result property="registerNum" column="registerNum"/>
 	</resultMap>
 	<select id="studentSmallClassStatisticsSum" resultMap="StudentStatisticsSumDto">
 		SELECT
-		COUNT(CASE WHEN ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0 THEN 1 ELSE NULL END) 'sleepStudentNum',
+		COUNT(CASE WHEN (ss.no_schedule_num_ > 0 OR suca.course_balance_ > 0) AND (ss.over_course_num_ &lt;= 0 OR ss.lately_year_course_consumer_ &lt;= 0) THEN 1 ELSE NULL END) 'sleepStudentNum',
 		COUNT(CASE WHEN ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0 AND ss.no_schedule_num_ > 0 THEN 1 ELSE NULL END) 'sleepStudentHasNotSchedule',
 		COUNT(CASE WHEN ss.over_course_num_ > 0 AND (ss.sub_course_num_ > 0 OR ss.no_schedule_num_ > 0) AND ss.lately_year_course_consumer_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 THEN 1 ELSE NULL END) 'sleepStudentNoNotSchedule',
-		COUNT(CASE WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND (ss.lately_year_course_consumer_ > 0 OR ss.over_course_num_ &lt;= 0) THEN 1 ELSE NULL END) 'normalStudentNum',
-		COUNT(CASE WHEN ((ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND (ss.lately_year_course_consumer_ > 0 OR ss.over_course_num_ &lt;= 0)) AND ss.normal_group_num_ > 0 THEN 1 ELSE NULL END) 'normalStudentHasNormalGroupNum',
+		COUNT(CASE WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND ss.lately_year_course_consumer_ > 0 THEN 1 ELSE NULL END) 'normalStudentNum',
 		COUNT(CASE WHEN suca.course_balance_ > 0 AND ss.sub_course_num_ &lt;= 0 AND ss.no_schedule_num_ &lt;= 0 THEN 1 ELSE NULL END) 'hasCourseBalanceAndNotSubCourseNum',
 		COUNT(CASE WHEN ((ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0) AND (ss.lately_year_course_consumer_ > 0 OR ss.over_course_num_ &lt;= 0)) AND ss.no_schedule_num_ > 0 THEN 1 ELSE NULL END) 'normalStudentHasNoScheduleNum',
 		COUNT(CASE WHEN (ss.no_schedule_num_ + ss.sub_course_num_) &lt; 4 THEN 1 ELSE NULL END) 'waitRenewNum',
+		COUNT(CASE WHEN ss.no_schedule_num_ > 0 OR ss.sub_course_num_ > 0 OR ss.over_course_num_ > 0 THEN 1 ELSE NULL END) 'registerNum',
 		SUM(ss.sub_course_num_) 'subCourseNum',
 		SUM(ss.no_schedule_num_) 'noScheduleNum'
 		FROM student_statistics ss
@@ -504,4 +514,140 @@
         </foreach>
         group by ss.user_id_ , u.organ_id_
 	</select>
+	<select id="countNormalNum" resultType="java.lang.Integer">
+		<if test="groupType == 'VIP'">
+			select count(distinct cssp.user_id_) from vip_group vg
+			left join course_schedule_student_payment cssp ON cssp.music_group_id_ = vg.id_
+			where cssp.group_type_ = 'VIP' and vg.group_status_ = 2 AND vg.vip_group_category_id_ != 16
+		</if>
+		<if test="groupType == 'THEORY'">
+			select count(distinct cssp.user_id_) from vip_group vg
+			left join course_schedule_student_payment cssp ON cssp.music_group_id_ = vg.id_
+			where cssp.group_type_ = 'VIP' and vg.group_status_ = 2 AND vg.vip_group_category_id_ = 16
+		</if>
+		<if test="groupType == 'PRACTICE'">
+			select count(distinct cssp.user_id_) from practice_group vg
+			left join course_schedule_student_payment cssp ON cssp.music_group_id_ = vg.id_
+			where cssp.group_type_ = 'PRACTICE' and vg.group_status_ = 'NORMAL'
+		</if>
+		AND vg.organ_id_ IN
+		<foreach collection="organIdList" item="organId" open="(" close=")" separator=",">
+			#{organId}
+		</foreach>
+	</select>
+	<resultMap id="StudentCourseConsumerDto" type="com.ym.mec.biz.dal.dto.StudentCourseConsumerDto">
+		<result property="organId" column="organ_id_"/>
+		<result property="organName" column="organName"/>
+		<result property="normalNum" column="normalNum"/>
+		<result property="num5" column="num5"/>
+		<result property="num4" column="num4"/>
+		<result property="num3" column="num3"/>
+		<result property="num2" column="num2"/>
+		<result property="num1" column="num1"/>
+		<result property="num0" column="num0"/>
+		<result property="num0" column="course_sum_"/>
+	</resultMap>
+	<select id="queryCourseConsumer" resultMap="StudentCourseConsumerDto">
+		select o.id_ organ_id_,o.name_ organName,count(CASE WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_) AND ss.lately_year_course_consumer_ > 0 THEN 1 END) normalNum,
+		COUNT(CASE WHEN cs.course_num_ > 4 THEN 1 END) num5
+		,COUNT(CASE WHEN cs.course_num_ = 4 THEN 1 END) num4,COUNT(CASE WHEN cs.course_num_ = 3 THEN 1 END) num3
+		,COUNT(CASE WHEN cs.course_num_ = 2 THEN 1 END) num2,COUNT(CASE WHEN cs.course_num_ = 1 THEN 1 END) num1,
+		COUNT(CASE WHEN cs.course_num_ = 0 THEN 1 END) num0
+		from student_statistics ss
+		left join (select cs.organ_id_,cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
+		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{queryInfo.month}
+		<if test="queryInfo.organId != null and queryInfo.organId != ''">
+			AND FIND_IN_SET(cs.organ_id_,#{queryInfo.organId})
+		</if>
+		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
+		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
+		left join organization o ON o.id_ = cs.organ_id_
+		where ss.group_type_ = 'VIP' AND cs.organ_id_ IS NOT NULL
+		group by cs.organ_id_
+	</select>
+	<select id="queryPreCourseConsumer" resultMap="StudentCourseConsumerDto">
+		select o.id_ organ_id_,o.name_ organName,count(CASE WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_) AND ss.lately_year_course_consumer_ > 0 THEN 1 END) normalNum,
+		COUNT(CASE WHEN cs.course_num_ > 4 THEN 1 END) num5
+		,COUNT(CASE WHEN cs.course_num_ = 4 THEN 1 END) num4,COUNT(CASE WHEN cs.course_num_ = 3 THEN 1 END) num3
+		,COUNT(CASE WHEN cs.course_num_ = 2 THEN 1 END) num2,COUNT(CASE WHEN cs.course_num_ = 1 THEN 1 END) num1,
+		COUNT(CASE WHEN cs.course_num_ = 0 THEN 1 END) num0
+		from student_statistics ss
+		left join (select cs.organ_id_,cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
+		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate}
+		<if test="queryInfo.organId != null and queryInfo.organId != ''">
+			AND FIND_IN_SET(cs.organ_id_,#{queryInfo.organId})
+		</if>
+		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
+		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
+		left join organization o ON o.id_ = cs.organ_id_
+		where ss.group_type_ = 'VIP' AND cs.organ_id_ IS NOT NULL
+		group by cs.organ_id_
+	</select>
+
+	<resultMap id="StudentCourseConsumerSumDto" type="com.ym.mec.biz.dal.dto.StudentCourseConsumerSumDto" extends="StudentCourseConsumerDto">
+		<result property="courseSum" column="course_sum_"/>
+		<result property="num6" column="num6"/>
+	</resultMap>
+	<select id="queryCourseConsumerSum" resultMap="StudentCourseConsumerSumDto">
+		select o.id_ organ_id_,o.name_ organName,SUM(cs.course_sum_) course_sum_,count(CASE WHEN (ss.no_schedule_num_ > 0 OR ss.sub_course_num_) AND ss.lately_year_course_consumer_ > 0 THEN 1 END) normalNum,
+		COUNT(CASE WHEN cs.course_num_ > 4 THEN 1 END) num5,
+		COUNT(CASE WHEN cs.course_num_ > 3 THEN 1 END) num6
+		,COUNT(CASE WHEN cs.course_num_ = 4 THEN 1 END) num4,COUNT(CASE WHEN cs.course_num_ = 3 THEN 1 END) num3
+		,COUNT(CASE WHEN cs.course_num_ = 2 THEN 1 END) num2,COUNT(CASE WHEN cs.course_num_ = 1 THEN 1 END) num1,
+		COUNT(CASE WHEN cs.course_num_ = 0 THEN 1 END) num0
+		from student_statistics ss
+		left join (select cs.organ_id_,COUNT(cssp.id_) course_sum_,cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
+		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+		where DATE_FORMAT(cs.class_date_,'%Y-%m-%d') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate} AND cs.status_ = 'OVER'
+		<if test="queryInfo.organId != null and queryInfo.organId != ''">
+			AND FIND_IN_SET(cs.organ_id_,#{queryInfo.organId})
+		</if>
+		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
+		group by cssp.user_id_) cs ON cs.user_id_ = ss.user_id_
+		left join organization o ON o.id_ = cs.organ_id_
+		where ss.group_type_ = 'VIP' AND cs.organ_id_ IS NOT NULL
+		group by cs.organ_id_
+	</select>
+	<resultMap id="StudentCourseConsumerDetailDto" type="com.ym.mec.biz.dal.dto.StudentCourseConsumerDetailDto">
+		<result property="organName" column="organName"/>
+		<result property="username" column="username_"/>
+		<result property="userId" column="user_id_"/>
+		<result property="phone" column="phone_"/>
+		<result property="preConsumerNum" column="preConsumerNum"/>
+		<result property="consumerNum" column="consumerNum"/>
+		<result property="courseNum" column="course_num_"/>
+	</resultMap>
+	<select id="queryCourseConsumerDetail" resultMap="StudentCourseConsumerDetailDto">
+		select o.name_ organName,su.username_,su.phone_,cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) consumerNum,4 preConsumerNum
+		from course_schedule cs
+		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+		left join organization o ON o.id_ = cs.organ_id_
+		left join sys_user su ON su.id_ = cssp.user_id_
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') = #{queryInfo.month} AND cs.status_ = 'OVER'
+		<if test="queryInfo.organId != null and queryInfo.organId != ''">
+			AND FIND_IN_SET(cs.organ_id_,#{queryInfo.organId})
+		</if>
+		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
+		group by cssp.user_id_ order by cs.organ_id_;
+	</select>
+	<select id="queryPreCourseConsumerDetail" resultMap="StudentCourseConsumerDetailDto">
+		select cs.name_ organName,cs.username_,cs.user_id_,cs.phone_,
+		       CASE WHEN ss.no_schedule_num_ + cs.course_num_ > 3 THEN 4 ELSE ss.no_schedule_num_ + cs.course_num_ END preConsumerNum,
+			   cs.course_num_
+		from student_statistics ss
+		left join (
+		select cs.organ_id_,o.name_,su.username_,su.phone_,cssp.user_id_,COUNT(distinct cssp.course_schedule_id_) course_num_ from course_schedule cs
+		left join course_schedule_student_payment cssp ON cssp.course_schedule_id_ = cs.id_
+		left join organization o ON o.id_ = cs.organ_id_
+		left join sys_user su ON su.id_ = cssp.user_id_
+		where DATE_FORMAT(cs.class_date_,'%Y-%m') BETWEEN #{queryInfo.startDate} AND #{queryInfo.endDate}
+		<if test="queryInfo.organId != null and queryInfo.organId != ''">
+			AND FIND_IN_SET(cs.organ_id_,#{queryInfo.organId})
+		</if>
+		<include refid="com.ym.mec.biz.dal.dao.CourseScheduleDao.courseIgnore"/>
+		group by cssp.user_id_) cs ON ss.user_id_ = cs.user_id_
+		where ss.group_type_ = 'VIP' AND ss.user_id_ = cs.user_id_
+	</select>
 </mapper>

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

@@ -486,19 +486,6 @@ public class ExportController extends BaseController {
         queryInfo.setRows(49999);
         queryInfo.setOrganIds(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
         List<ClassGroupTeachersDto> rows = classGroupService.queryClassGroupPage(queryInfo).getRows();
-        for (ClassGroupTeachersDto row : rows) {
-            List<ClassGroupTeacherMapper> classGroupTeacherMapperList = row.getClassGroupTeacherMapperList();
-            if (classGroupTeacherMapperList.size() > 0) {
-                List<ClassGroupTeacherMapper> teachingTeachers = classGroupTeacherMapperList.stream().filter(e -> e.getTeacherRole() == TeachTypeEnum.TEACHING).collect(Collectors.toList());
-                if (teachingTeachers.size() > 0) {
-                    row.setTeachingTeacherName(StringUtils.join(teachingTeachers.stream().map(e -> e.getUserName()).collect(Collectors.toList()), ","));
-                }
-                List<ClassGroupTeacherMapper> bishopTeachers = classGroupTeacherMapperList.stream().filter(e -> e.getTeacherRole() == TeachTypeEnum.BISHOP).collect(Collectors.toList());
-                if (bishopTeachers.size() > 0) {
-                    row.setBishopTeacherName(StringUtils.join(bishopTeachers.stream().map(e -> e.getUserName()).collect(Collectors.toList()), ","));
-                }
-            }
-        }
         OutputStream outputStream = response.getOutputStream();
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"课程组编号", "课程组名称", "分部名称", "班级名称",

+ 72 - 0
mec-web/src/main/java/com/ym/mec/web/controller/StudentCourseConsumerController.java

@@ -0,0 +1,72 @@
+package com.ym.mec.web.controller;
+
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerDetailDto;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerDto;
+import com.ym.mec.biz.dal.dto.StudentCourseConsumerSumDto;
+import com.ym.mec.biz.dal.page.StudentCourseConsumerQueryInfo;
+import com.ym.mec.biz.service.OrganizationService;
+import com.ym.mec.biz.service.StudentCourseConsumerService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Api(tags = "学员课耗统计")
+@RequestMapping("studentCourseConsumer")
+@RestController
+public class StudentCourseConsumerController extends BaseController {
+
+    @Autowired
+    private StudentCourseConsumerService studentCourseConsumerService;
+	@Autowired
+	private OrganizationService organizationService;
+
+    @ApiOperation(value = "实际课耗列表")
+    @PostMapping("/queryCourseConsumer")
+    @PreAuthorize("@pcs.hasPermissions('studentCourseConsumer/queryCourseConsumer')")
+    public HttpResponseResult<List<StudentCourseConsumerDto>> queryCourseConsumer(@RequestBody StudentCourseConsumerQueryInfo queryInfo){
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
+        return succeed(studentCourseConsumerService.queryCourseConsumer(queryInfo));
+    }
+
+    @ApiOperation(value = "实际课耗学员详情列表")
+    @PostMapping("/queryCourseConsumerDetail")
+    @PreAuthorize("@pcs.hasPermissions('studentCourseConsumer/queryCourseConsumerDetail')")
+    public HttpResponseResult<List<StudentCourseConsumerDetailDto>> queryCourseConsumerDetail(@RequestBody StudentCourseConsumerQueryInfo queryInfo){
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
+        return succeed(studentCourseConsumerService.queryCourseConsumerDetail(queryInfo));
+    }
+
+    @ApiOperation(value = "预计课耗列表")
+    @PostMapping("/queryPreCourseConsumer")
+    @PreAuthorize("@pcs.hasPermissions('studentCourseConsumer/queryPreCourseConsumer')")
+    public HttpResponseResult<List<StudentCourseConsumerDto>> queryPreCourseConsumer(@RequestBody StudentCourseConsumerQueryInfo queryInfo){
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
+        return succeed(studentCourseConsumerService.queryPreCourseConsumer(queryInfo));
+    }
+
+    @ApiOperation(value = "预计课耗学员详情列表")
+    @PostMapping("/queryPreCourseConsumerDetail")
+    @PreAuthorize("@pcs.hasPermissions('studentCourseConsumer/queryPreCourseConsumerDetail')")
+    public HttpResponseResult<List<StudentCourseConsumerDetailDto>> queryPreCourseConsumerDetail(@RequestBody StudentCourseConsumerQueryInfo queryInfo){
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
+        return succeed(studentCourseConsumerService.queryPreCourseConsumerDetail(queryInfo));
+    }
+
+
+    @ApiOperation(value = "课耗统计列表")
+    @PostMapping("/queryCourseConsumerSum")
+    @PreAuthorize("@pcs.hasPermissions('studentCourseConsumer/queryCourseConsumerSum')")
+    public HttpResponseResult<List<StudentCourseConsumerSumDto>> queryCourseConsumerSum(@RequestBody StudentCourseConsumerQueryInfo queryInfo){
+        queryInfo.setOrganId(organizationService.getEmployeeOrgan(queryInfo.getOrganId()));
+        return succeed(studentCourseConsumerService.queryCourseConsumerSum(queryInfo));
+    }
+}

+ 21 - 1
mec-web/src/main/resources/exportColumnMapper.ini

@@ -300,4 +300,24 @@ fieldColumns = ["organName","expectVisitNum","visitNum","coverRate"]
 
 [经营报表导出]
 headColumns = ["月份","分部", "销售收入", "服务收入", "课程收入", "云教练收入","乐保收入", "业务退费", "收入合计", "销售成本", "固定费用", "变动费用", "内部结算", "成本费用合计", "准可自由支配利润", "预收账款", "云教练预收", "课程预收", "商品预收", "其他预收", "预付账款", "应收账款", "应付账款"]
-fieldColumns = ["month","organName","saleAmount","serviceAmount","courseAmount","cloudAmount","maintenanceAmount","businessRefund","totalIncome","saleCost","fixedCosts","variableCosts","internalSettlement","totalCost","quasiDiscretionaryProfit","prepaidFee","cloudPrepaidFee","coursePrepaidFee","salePrepaidFee","otherPrepaidFee","prepayments","receivables","payable"]
+fieldColumns = ["month","organName","saleAmount","serviceAmount","courseAmount","cloudAmount","maintenanceAmount","businessRefund","totalIncome","saleCost","fixedCosts","variableCosts","internalSettlement","totalCost","quasiDiscretionaryProfit","prepaidFee","cloudPrepaidFee","coursePrepaidFee","salePrepaidFee","otherPrepaidFee","prepayments","receivables","payable"]
+
+[实际课耗导出]
+headColumns = ["分部", "在读人数", "大于等于5节", "4节","3节","2节","1节","0节"]
+fieldColumns = ["organName","normalNum","num5","num4","num3","num2","num1","num0"]
+
+[实际课耗学员详情导出]
+headColumns = ["分部", "学生姓名", "学生编号", "学生手机号","应耗课时","实耗课时"]
+fieldColumns = ["organName","username","userId","phone","preConsumerNum","consumerNum"]
+
+[预计课耗导出]
+headColumns = ["分部", "在读人数", "大于等于5节", "4节","3节","2节","1节","0节"]
+fieldColumns = ["organName","normalNum","num5","num4","num3","num2","num1","num0"]
+
+[预计课耗学员详情导出]
+headColumns = ["分部", "学生姓名", "学生编号", "学生手机号","应耗课时","已排课时"]
+fieldColumns = ["organName","username","userId","phone","preConsumerNum","courseNum"]
+
+[课耗统计导出]
+headColumns = ["分部", "在读人数", "应有课耗", "实际课耗","课耗达标率","实际课耗大于等于5节", "4节","3节","2节","1节","0节","达标占比"]
+fieldColumns = ["organName","normalNum","courseConsumerNum","courseSum","courseConsumerRate","num5","num4","num3","num2","num1","num0","standRate"]