瀏覽代碼

学员管理新增【小课课耗统计】

zouxuan 2 年之前
父節點
當前提交
3716557002

+ 17 - 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;
 
@@ -70,4 +69,19 @@ public interface StudentStatisticsDao extends BaseDAO<Integer, StudentStatistics
     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;
+    }
+}

+ 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);
+}

+ 58 - 0
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);

+ 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;
+    }
+}

+ 5 - 0
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"/>

+ 115 - 0
mec-biz/src/main/resources/config/mybatis/StudentStatisticsMapper.xml

@@ -535,4 +535,119 @@
 			#{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"]