zouxuan %!s(int64=3) %!d(string=hai) anos
pai
achega
95700b04a4
Modificáronse 20 ficheiros con 470 adicións e 61 borrados
  1. 18 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CooperationOrganDao.java
  2. 20 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleStudentPaymentDao.java
  3. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupDao.java
  4. 9 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupPaymentCalenderDao.java
  5. 18 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentRegistrationDao.java
  6. 65 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentPaymentOrderExportDto.java
  7. 60 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentVipPracticeExportDto.java
  8. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/IndexDataType.java
  9. 6 4
      mec-biz/src/main/java/com/ym/mec/biz/event/listener/GroupEventListener.java
  10. 9 0
      mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupPaymentCalenderService.java
  11. 112 32
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java
  12. 9 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/IndexBaseMonthDataServiceImpl.java
  13. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderServiceImpl.java
  14. 14 0
      mec-biz/src/main/resources/config/mybatis/CooperationOrganMapper.xml
  15. 62 15
      mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml
  16. 2 1
      mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml
  17. 14 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml
  18. 8 0
      mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderMapper.xml
  19. 22 1
      mec-biz/src/main/resources/config/mybatis/StudentRegistrationMapper.xml
  20. 6 6
      mec-web/src/main/resources/exportColumnMapper.ini

+ 18 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CooperationOrganDao.java

@@ -70,4 +70,22 @@ public interface CooperationOrganDao extends BaseDAO<Integer, CooperationOrgan>
      * @return
      */
     List<CooperationOrgan> getCooperationOrganByEduTeacherId(@Param("userId") Integer userId);
+
+    /**
+    * @description: 获取合作单位创建的第一个进行中乐团
+     * @param cooperationOrganId
+    * @return java.lang.String
+    * @author zx
+    * @date 2022/3/16 13:46
+    */
+    String getFirstGroup(Integer cooperationOrganId);
+
+    /**
+    * @description: 获取合作单位第一个乐团
+     * @param
+    * @return java.util.List<java.util.Map<java.lang.Integer,java.lang.String>>
+    * @author zx
+    * @date 2022/3/17 11:36
+    */
+    List<Map<Integer, String>> findFirstMusic();
 }

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleStudentPaymentDao.java

@@ -577,4 +577,24 @@ public interface CourseScheduleStudentPaymentDao extends BaseDAO<Long, CourseSch
 	Boolean hasStudentMusicTheoryCourseInfo(@Param("organId") String organId, @Param("tenantId") Integer tenantId, @Param("groupType") String groupType);
 
     List<ExportStudentCourseInfoDto> queryStudentCourseInfo(@Param("organId") String organId, @Param("tenantId") Integer tenantId, @Param("groupType") String groupType);
+
+    /**
+    * @description: 获取学员第一个课程组编号
+     * @param groupType
+    * @return int
+    * @author zx
+    * @date 2022/3/16 10:32
+    */
+    List<Map<Integer,Integer>> findUserFirstVipMap(@Param("groupType") String groupType, @Param("studentIds") List<Integer> studentIds);
+
+    /**
+    * @description: 获取学员声部班老师
+     * @param studentIds
+    * @return java.util.List<com.ym.mec.biz.dal.dto.BaseNameDto>
+    * @author zx
+    * @date 2022/3/16 18:57
+    */
+    List<BaseNameDto> queryClassTeacher(@Param("studentIds") List<Integer> studentIds);
+
+    List<BaseNameDto> queryFirstNotStartTeacher(@Param("studentIds") List<Integer> studentIds, @Param("groupType") String groupType);
 }

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupDao.java

@@ -9,6 +9,7 @@ import com.ym.mec.biz.dal.entity.School;
 import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
 import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
 import com.ym.mec.biz.dal.enums.StudentMusicGroupStatusEnum;
+import com.ym.mec.biz.dal.page.IndexDataQueryInfo;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImGroupModel;
 import org.apache.ibatis.annotations.Param;
@@ -495,4 +496,13 @@ public interface MusicGroupDao extends BaseDAO<String, MusicGroup> {
     * @date 2022/3/4 11:40
     */
     List<HasFreeCourseTimesDto> queryHasFreeCourseTimes(Map<String, Object> params);
+
+    /**
+    * @description: 获取首页退学学员数量
+     * @param queryInfo
+    * @return java.lang.Integer
+    * @author zx
+    * @date 2022/3/17 16:20
+    */
+    Integer countQuitNum(@Param("queryInfo") IndexDataQueryInfo queryInfo);
 }

+ 9 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/MusicGroupPaymentCalenderDao.java

@@ -326,4 +326,13 @@ public interface MusicGroupPaymentCalenderDao extends BaseDAO<Long, MusicGroupPa
     List<MusicGroupPaymentCalenderResultDto> queryCalenderPage(Map<String, Object> params);
     
     List<Map<String, BigDecimal>> queryChargeStandard(String musicGroupIdList);
+
+    /**
+    * @description: 获取缴费项目关联的合作单为编号
+     * @param calenderIds
+    * @return java.util.List<java.util.Map<java.lang.Long,java.lang.Integer>>
+    * @author zx
+    * @date 2022/3/17 11:18
+    */
+    List<Map<Long, Integer>> findCooperationByIds(@Param("calenderIds") List<Long> calenderIds);
 }

+ 18 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentRegistrationDao.java

@@ -720,4 +720,22 @@ public interface StudentRegistrationDao extends BaseDAO<Long, StudentRegistratio
     * @date 2021/11/16 10:26
     */
     List<Map<Long,BigDecimal>> querySubjectAmount(String musicGroupId);
+
+    /**
+    * @description: 获取学员最近加入的一个乐团编号
+     * @param userIds
+    * @return java.lang.String
+    * @author zx
+    * @date 2022/3/16 14:10
+    */
+    List<Map<Integer,String>> getLastMusicGroupId(@Param("userIds") List<Integer> userIds);
+
+    /**
+    * @description: 获取学员最近加入的一个乐团编号
+     * @param userIds
+    * @return java.lang.String
+    * @author zx
+    * @date 2022/3/16 14:10
+    */
+    List<Map<Integer,String>> getLastMusicGroupName(@Param("userIds") List<Integer> userIds);
 }

+ 65 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentPaymentOrderExportDto.java

@@ -1,8 +1,11 @@
 package com.ym.mec.biz.dal.dto;
 
+import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.Goods;
 import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
 import com.ym.mec.biz.dal.entity.StudentPaymentOrderDetail;
+import com.ym.mec.common.enums.BaseEnum;
+import io.swagger.annotations.ApiModelProperty;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -100,6 +103,68 @@ public class StudentPaymentOrderExportDto extends StudentPaymentOrder {
     //订单金额
     private BigDecimal orderAmount = BigDecimal.ZERO;
 
+    public enum TypeDesc implements BaseEnum<String, StudentPaymentOrderExportDto.TypeDesc> {
+
+        NEW_VIP("NEW_VIP", "VIP课新增"),
+        RENEW_VIP("RENEW_VIP", "VIP课续费"),
+        NEW_MUSIC("NEW_MUSIC", "乐团新开"),
+        ADD_MUSIC("ADD_MUSIC", "乐团扩招"),
+        RENEW_MUSIC("RENEW_MUSIC", "乐团续费");
+
+        private String code;
+
+        private String msg;
+
+        TypeDesc(String code, String msg) {
+            this.code = code;
+            this.msg = msg;
+        }
+
+        @Override
+        public String getCode() {
+            return code;
+        }
+
+        public String getMsg() {
+            return msg;
+        }
+    }
+
+    //课程形态描述
+    //学员没有历史VIP课程则导出为【VIP课新增】
+    //学员有历史VIP课程到导出为【VIP课续费】……
+    private TypeDesc typeDesc;
+
+    //该笔订单为乐团订单则导出该乐团的【乐团名称】
+    //该笔订单非乐团订单时,查询学员是否有在读乐团,无则导出为空,有则导出该学员【进行中】【暂停】乐团名称,进行中>暂停,多个进行中则导出加入乐团时间最近的乐团名称
+    private String feeMusicGroupId;
+
+    private String feeMusicGroupName;
+
+    public String getFeeMusicGroupName() {
+        return feeMusicGroupName;
+    }
+
+    public void setFeeMusicGroupName(String feeMusicGroupName) {
+        this.feeMusicGroupName = feeMusicGroupName;
+    }
+
+    public String getFeeMusicGroupId() {
+        return feeMusicGroupId;
+    }
+
+    public void setFeeMusicGroupId(String feeMusicGroupId) {
+        this.feeMusicGroupId = feeMusicGroupId;
+    }
+
+    public TypeDesc getTypeDesc() {
+        return typeDesc;
+    }
+
+    public void setTypeDesc(TypeDesc typeDesc) {
+        this.typeDesc = typeDesc;
+    }
+
     public BigDecimal getOrderAmount() {
         return orderAmount;
     }

+ 60 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/StudentVipPracticeExportDto.java

@@ -11,6 +11,14 @@ public class StudentVipPracticeExportDto{
 
     private Integer vipNotStartNum;
 
+    private Integer vipNotStartTeacherId;
+
+    private String vipNotStartTeacherName;
+
+    private Integer normalClassTeacherId;
+
+    private String normalClassTeacherName;
+
     private Integer vipOverTeacherId;
 
     private String vipOverTeacherName;
@@ -27,6 +35,10 @@ public class StudentVipPracticeExportDto{
 
     private String practiceOverTeacherName;
 
+    private Integer practiceNotStartTeacherId;
+
+    private String practiceNotStartTeacherName;
+
     private String practiceNotStartTeacherIds;
 
     private String practiceNotStartTeacherNames;
@@ -41,6 +53,54 @@ public class StudentVipPracticeExportDto{
 
     private String subjectName;
 
+    public Integer getNormalClassTeacherId() {
+        return normalClassTeacherId;
+    }
+
+    public void setNormalClassTeacherId(Integer normalClassTeacherId) {
+        this.normalClassTeacherId = normalClassTeacherId;
+    }
+
+    public String getNormalClassTeacherName() {
+        return normalClassTeacherName;
+    }
+
+    public void setNormalClassTeacherName(String normalClassTeacherName) {
+        this.normalClassTeacherName = normalClassTeacherName;
+    }
+
+    public Integer getVipNotStartTeacherId() {
+        return vipNotStartTeacherId;
+    }
+
+    public void setVipNotStartTeacherId(Integer vipNotStartTeacherId) {
+        this.vipNotStartTeacherId = vipNotStartTeacherId;
+    }
+
+    public String getVipNotStartTeacherName() {
+        return vipNotStartTeacherName;
+    }
+
+    public void setVipNotStartTeacherName(String vipNotStartTeacherName) {
+        this.vipNotStartTeacherName = vipNotStartTeacherName;
+    }
+
+    public Integer getPracticeNotStartTeacherId() {
+        return practiceNotStartTeacherId;
+    }
+
+    public void setPracticeNotStartTeacherId(Integer practiceNotStartTeacherId) {
+        this.practiceNotStartTeacherId = practiceNotStartTeacherId;
+    }
+
+    public String getPracticeNotStartTeacherName() {
+        return practiceNotStartTeacherName;
+    }
+
+    public void setPracticeNotStartTeacherName(String practiceNotStartTeacherName) {
+        this.practiceNotStartTeacherName = practiceNotStartTeacherName;
+    }
+
     public BigDecimal getCourseBalance() {
         return courseBalance;
     }

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

@@ -67,7 +67,7 @@ public enum IndexDataType implements BaseEnum<String, IndexDataType> {
     ADD_STUDENT_REGISTRATION_NUM("ADD_STUDENT_REGISTRATION_NUM", "新增注册学员", false, true),
     MUSIC_GROUP_STUDENT("MUSIC_GROUP_STUDENT","乐团在读学员", false, false),
     NEWLY_STUDENT_NUM("NEWLY_STUDENT_NUM","乐团新增学员", false, true),
-    QUIT_MUSIC_GROUP_STUDENT_NUM("QUIT_MUSIC_GROUP_STUDENT_NUM","退学员", false, true),
+    QUIT_MUSIC_GROUP_STUDENT_NUM("QUIT_MUSIC_GROUP_STUDENT_NUM","退学员", false, true),
     VIP_PRACTICE_STUDENT_NUM("VIP_PRACTICE_STUDENT_NUM", "VIP/网管在读", false, false),
     VIP_PRACTICE_ADD_STUDENT_NUM("VIP_PRACTICE_ADD_STUDENT_NUM", "VIP/网管新增", false, true),
 

+ 6 - 4
mec-biz/src/main/java/com/ym/mec/biz/event/listener/GroupEventListener.java

@@ -54,16 +54,18 @@ public class GroupEventListener {
             return;
         }
         List<StudentRegistration> studentNormalRegistration = studentRegistrationDao.getStudentNormalRegistration(new HashSet<>(studentIds));
-        Map<Integer, Set<String>> userGroupIdMap = studentNormalRegistration.stream().collect(Collectors.groupingBy(StudentRegistration::getUserId, Collectors.mapping(StudentRegistration::getMusicGroupId, Collectors.toSet())));
+        Map<Integer, Set<String>> userGroupIdMap = studentNormalRegistration.stream().
+                collect(Collectors.groupingBy(StudentRegistration::getUserId,
+                        Collectors.mapping(StudentRegistration::getMusicGroupId, Collectors.toSet())));
         int updateNum = 0;
         for (Integer studentId : studentIds) {
-            if(userGroupIdMap.containsKey(studentId)&&userGroupIdMap.get(studentId).size()>1){
+            if(userGroupIdMap.containsKey(studentId) && userGroupIdMap.get(studentId).size() > 1){
                 continue;
             }
-            if(userGroupIdMap.containsKey(studentId)&&!userGroupIdMap.get(studentId).contains(musicGroupStatusChangeEvent.getMusicGroupId())){
+            if(userGroupIdMap.containsKey(studentId) && !userGroupIdMap.get(studentId).contains(musicGroupStatusChangeEvent.getMusicGroupId())){
                 continue;
             }
-            updateNum+=1;
+            updateNum += 1;
         }
         LocalDate nowDate = LocalDate.now();
         String dayStr = nowDate.toString();

+ 9 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/MusicGroupPaymentCalenderService.java

@@ -221,4 +221,13 @@ public interface MusicGroupPaymentCalenderService extends BaseService<Long, Musi
 	* @date 2022/3/4 11:35
 	*/
 	PageInfo<HasFreeCourseTimesDto> queryHasFreeCourseTimesStudent(BaseOrganQueryInfo queryInfo);
+
+	/**
+	* @description: 获取缴费项目关联的合作单为编号
+	 * @param calenderIds
+	* @return java.util.List<java.util.Map<java.lang.Long,java.lang.Integer>>
+	* @author zx
+	* @date 2022/3/17 11:16
+	*/
+	Map<Long, Integer>  findCooperationByIds(List<Long> calenderIds);
 }

+ 112 - 32
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ExportServiceImpl.java

@@ -1,15 +1,5 @@
 package com.ym.mec.biz.service.impl;
 
-import java.io.*;
-import java.math.BigDecimal;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.client.SysUserFeignService;
@@ -26,11 +16,16 @@ import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.IdGeneratorService;
+import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.thirdparty.adapay.ConfigInit;
 import com.ym.mec.thirdparty.adapay.Payment;
+import com.ym.mec.thirdparty.storage.StoragePluginContext;
+import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
 import com.ym.mec.util.collection.MapUtil;
+import com.ym.mec.util.date.DateUtil;
+import com.ym.mec.util.excel.POIUtil;
 import com.ym.mec.util.ini.IniFileUtil;
-import io.swagger.annotations.ApiOperation;
+import com.ym.mec.util.upload.UploadUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -38,23 +33,20 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.system.ApplicationHome;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.http.HttpStatus;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
-
-import com.ym.mec.common.tenant.TenantContextHolder;
-import com.ym.mec.thirdparty.storage.StoragePluginContext;
-import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
-import com.ym.mec.util.date.DateUtil;
-import com.ym.mec.util.excel.POIUtil;
-import com.ym.mec.util.upload.UploadUtil;
 import org.springframework.util.CollectionUtils;
-import org.springframework.web.bind.annotation.GetMapping;
 
 import javax.annotation.PostConstruct;
 import javax.servlet.http.HttpServletResponse;
-
-import static com.ym.mec.biz.dal.enums.QuestionnaireActiveTypeEnum.CLOUD_TEACHER_FEEDBACK;
+import java.io.*;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 @Service
 public class ExportServiceImpl implements ExportService {
@@ -1419,7 +1411,7 @@ public class ExportServiceImpl implements ExportService {
         CompletableFuture.runAsync(()->{
             try {
                 this.studentVipPractice(organId, managerDownload, tenantId,headColumns);
-            } catch (FileNotFoundException e) {
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         },executor);
@@ -1443,7 +1435,7 @@ public class ExportServiceImpl implements ExportService {
         CompletableFuture.runAsync(()->{
             try {
                 this.queryStudentCourseInfo(organId, tenantId,"VIP", managerDownload,headColumns,ExportEnum.STUDENT_VIP_COURSE_INFO);
-            } catch (FileNotFoundException e) {
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         },executor);
@@ -1467,7 +1459,7 @@ public class ExportServiceImpl implements ExportService {
         CompletableFuture.runAsync(()->{
             try {
                 this.queryStudentCourseInfo(organId, tenantId,"THEORY", managerDownload,headColumns,ExportEnum.STUDENT_MUSIC_THEORY_COURSE_INFO);
-            } catch (FileNotFoundException e) {
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         },executor);
@@ -1507,7 +1499,7 @@ public class ExportServiceImpl implements ExportService {
         CompletableFuture.runAsync(()->{
             try {
                 this.orderList(params, managerDownload, headColumns);
-            } catch (FileNotFoundException e) {
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         },executor);
@@ -1539,7 +1531,7 @@ public class ExportServiceImpl implements ExportService {
         CompletableFuture.runAsync(()->{
             try {
                 this.superFindCourseSchedules(queryInfo, managerDownload);
-            } catch (FileNotFoundException e) {
+            } catch (Exception e) {
                 e.printStackTrace();
             }
         },executor);
@@ -1589,7 +1581,28 @@ public class ExportServiceImpl implements ExportService {
         //获取机构费率
         Integer tenantId = (Integer) params.get("tenantId");
         TenantConfig tenantConfig = tenantConfigService.queryByTenantId(tenantId);
-        
+        //获取缴费项目编号
+        List<Long> calenderIds = studentPaymentOrderExportDtos.stream().map(e -> e.getCalenderId()).filter(e -> e != null).distinct().collect(Collectors.toList());
+        Map<Long, Integer> calenderCooperationMap = new HashMap<>();
+        Map<Integer, String> firstMusicMap = new HashMap<>();
+        if(calenderIds != null && calenderIds.size() > 0){
+            //获取缴费项目关联的合作单位
+            calenderCooperationMap = musicGroupPaymentCalenderService.findCooperationByIds(calenderIds);
+            //获取合作单位第一个乐团
+            firstMusicMap = MapUtil.convertMybatisMap(cooperationOrganDao.findFirstMusic());
+        }
+        List<Integer> studentIds = studentPaymentOrderExportDtos.stream().map(e -> e.getUserId()).distinct().collect(Collectors.toList());
+        //获取学员第一个课程组编号
+        Map<Integer, String> userFirstVipMap = MapUtil.convertMybatisMap(courseScheduleStudentPaymentDao.findUserFirstVipMap("VIP",studentIds));
+        //获取学员最近加入的一个乐团编号
+        Map<Integer, String> userLastMusicIdMap = MapUtil.convertMybatisMap(studentRegistrationDao.getLastMusicGroupId(studentIds));
+        Map<Integer, String> userLastMusicNameMap = MapUtil.convertMybatisMap(studentRegistrationDao.getLastMusicGroupName(studentIds));
+        Set<String> musicGroupIds = studentPaymentOrderExportDtos.stream().map(e -> e.getMusicGroupId()).collect(Collectors.toSet());
+        Map<String, String> musicGroupNameMap = new HashMap<>();
+        if(musicGroupIds != null && musicGroupIds.size() > 0){
+            musicGroupNameMap = MapUtil.convertIntegerMap(musicGroupDao.queryMusicGroupNameMap(musicGroupIds));
+        }
+
         for (StudentPaymentOrderExportDto row : studentPaymentOrderExportDtos) {
             if (row.getActualAmount() == null) {
                 row.setActualAmount(BigDecimal.ZERO);
@@ -1607,6 +1620,28 @@ public class ExportServiceImpl implements ExportService {
             row.setTransferFee(transferFee);
             row.setPlatformFee(row.getActualAmount().multiply(tenantConfig.getChargeRate()).divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP));
 
+            Long calenderId = row.getCalenderId();
+            if(calenderId != null){
+                row.setFeeMusicGroupId(row.getMusicGroupId());
+                row.setFeeMusicGroupName(musicGroupNameMap.get(row.getMusicGroupId()));
+                OrderTypeEnum orderTypeEnum = row.getType();
+                if(orderTypeEnum == OrderTypeEnum.APPLY || orderTypeEnum == OrderTypeEnum.ADD_STUDENT){
+                    Integer cooperationId = calenderCooperationMap.get(calenderId);
+                    if(cooperationId != null){
+                        String firstMusicId = firstMusicMap.get(cooperationId);
+                        if(Objects.equals(firstMusicId,row.getMusicGroupId())){
+                            row.setTypeDesc(StudentPaymentOrderExportDto.TypeDesc.NEW_MUSIC);
+                        }else {
+                            row.setTypeDesc(StudentPaymentOrderExportDto.TypeDesc.ADD_MUSIC);
+                        }
+                    }
+                }else {
+                    row.setTypeDesc(StudentPaymentOrderExportDto.TypeDesc.RENEW_MUSIC);
+                }
+            }else {
+                row.setFeeMusicGroupId(userLastMusicIdMap.get(row.getUserId()));
+                row.setFeeMusicGroupName(userLastMusicNameMap.get(row.getUserId()));
+            }
             String goodsName = "";
             if (row.getOrderDetailList() != null) {
                 for (StudentPaymentOrderDetail orderDetail : row.getOrderDetailList()) {
@@ -1671,6 +1706,15 @@ public class ExportServiceImpl implements ExportService {
                                 vipCourseFee = orderDetail.getPrice().multiply(row.getActualAmount()).divide(row.getExpectAmount(), 2, BigDecimal.ROUND_DOWN);
                             }
                             row.setVipCourseFee(vipCourseFee);
+                            if(row.getTypeDesc() == null){
+                                //学员没有历史VIP课程则导出为【VIP课新增】
+                                //学员有历史VIP课程到导出为【VIP课续费]
+                                if(Objects.equals(userFirstVipMap.get(row.getUserId()),row.getMusicGroupId())){
+                                    row.setTypeDesc(StudentPaymentOrderExportDto.TypeDesc.NEW_VIP);
+                                }else {
+                                    row.setTypeDesc(StudentPaymentOrderExportDto.TypeDesc.RENEW_VIP);
+                                }
+                            }
                             break;
                         case THEORY_COURSE:
                             BigDecimal theoryCourseFee = BigDecimal.ZERO;
@@ -2419,14 +2463,32 @@ public class ExportServiceImpl implements ExportService {
     public void studentVipPractice(String organId, ManagerDownload managerDownload, Integer tenantId,List<String> headColumns) throws FileNotFoundException {
         List<StudentVipPracticeExportDto> studentVipPracticeExportDtos = courseScheduleStudentPaymentDao.exportStudentVipPractice(organId, tenantId);
         if(studentVipPracticeExportDtos != null && studentVipPracticeExportDtos.size() > 0){
-            List<Integer> studentIds = studentVipPracticeExportDtos.stream().map(e -> e.getUserId()).collect(Collectors.toList());
-            //获取学员最后一节已结束的vip课的老师以及编号
+            List<Integer> studentIds = studentVipPracticeExportDtos.stream().map(e -> e.getUserId()).distinct().collect(Collectors.toList());
+            //新增声部课老师,学员有在读乐团,导出该学员所在声部班班级老师,无声部班则为空
+            List<BaseNameDto> normalClassTeacher = courseScheduleStudentPaymentDao.queryClassTeacher(studentIds);
+            Map<Integer, List<BaseNameDto>> normalClassTeacherMap = new HashMap<>();
+            if(normalClassTeacher != null && normalClassTeacher.size() > 0){
+                normalClassTeacherMap = normalClassTeacher.stream().collect(Collectors.groupingBy(BaseNameDto::getUserId));
+            }
+            //获取最近一节未开始vip课课程组老师编号
+            List<BaseNameDto> vipFirstNotStartTeacher = courseScheduleStudentPaymentDao.queryFirstNotStartTeacher(studentIds,"VIP");
+            Map<Integer, List<BaseNameDto>> vipFirstNotStartTeacherMap = new HashMap<>();
+            if(vipFirstNotStartTeacher != null && vipFirstNotStartTeacher.size() > 0){
+                vipFirstNotStartTeacherMap = vipFirstNotStartTeacher.stream().collect(Collectors.groupingBy(BaseNameDto::getUserId));
+            }
+            //获取最近一节未开始网管课课课程组老师编号
+            List<BaseNameDto> practiceFirstNotStartTeacher = courseScheduleStudentPaymentDao.queryFirstNotStartTeacher(studentIds,"PRACTICE");
+            Map<Integer, List<BaseNameDto>> practiceFirstNotStartTeacherMap = new HashMap<>();
+            if(practiceFirstNotStartTeacher != null && practiceFirstNotStartTeacher.size() > 0){
+                practiceFirstNotStartTeacherMap = practiceFirstNotStartTeacher.stream().collect(Collectors.groupingBy(BaseNameDto::getUserId));
+            }
+            //获取学员最后一节已结束的vip课课程组的老师以及编号
             List<BaseNameDto> vipBaseNameDtos = courseScheduleStudentPaymentDao.queryLastOverTeacher(studentIds,"VIP");
             Map<Integer, List<BaseNameDto>> vipBaseNameMap = new HashMap<>();
             if(vipBaseNameDtos != null && vipBaseNameDtos.size() > 0){
                 vipBaseNameMap = vipBaseNameDtos.stream().collect(Collectors.groupingBy(BaseNameDto::getUserId));
             }
-            //获取学员最后一节已结束的网管课的老师以及编号
+            //获取学员最后一节已结束的网管课课程组的老师以及编号
             List<BaseNameDto> practiceBaseNameDtos = courseScheduleStudentPaymentDao.queryLastOverTeacher(studentIds,"PRACTICE");
             Map<Integer, List<BaseNameDto>> practiceBaseNameMap = new HashMap<>();
             if(practiceBaseNameDtos != null && practiceBaseNameDtos.size() > 0){
@@ -2445,6 +2507,24 @@ public class ExportServiceImpl implements ExportService {
                     studentVipPracticeExportDto.setPracticeOverTeacherId(baseNameDto.getTeacherId());
                     studentVipPracticeExportDto.setPracticeOverTeacherName(baseNameDto.getTeacherName());
                 }
+                List<BaseNameDto> baseNameDtos2 = normalClassTeacherMap.get(studentVipPracticeExportDto.getUserId());
+                if(baseNameDtos2 != null && baseNameDtos2.size() > 0){
+                    BaseNameDto baseNameDto = baseNameDtos2.get(0);
+                    studentVipPracticeExportDto.setNormalClassTeacherId(baseNameDto.getTeacherId());
+                    studentVipPracticeExportDto.setNormalClassTeacherName(baseNameDto.getTeacherName());
+                }
+                List<BaseNameDto> baseNameDtos3 = vipFirstNotStartTeacherMap.get(studentVipPracticeExportDto.getUserId());
+                if(baseNameDtos3 != null && baseNameDtos3.size() > 0){
+                    BaseNameDto baseNameDto = baseNameDtos3.get(0);
+                    studentVipPracticeExportDto.setVipNotStartTeacherId(baseNameDto.getTeacherId());
+                    studentVipPracticeExportDto.setVipNotStartTeacherName(baseNameDto.getTeacherName());
+                }
+                List<BaseNameDto> baseNameDtos4 = practiceFirstNotStartTeacherMap.get(studentVipPracticeExportDto.getUserId());
+                if(baseNameDtos4 != null && baseNameDtos4.size() > 0){
+                    BaseNameDto baseNameDto = baseNameDtos4.get(0);
+                    studentVipPracticeExportDto.setPracticeNotStartTeacherId(baseNameDto.getTeacherId());
+                    studentVipPracticeExportDto.setPracticeNotStartTeacherName(baseNameDto.getTeacherName());
+                }
             }
         }
         String basePath = new ApplicationHome(this.getClass()).getSource().getParentFile().getPath();

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

@@ -310,6 +310,14 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 					}
 				}
 			}
+			if(QUIT_MUSIC_GROUP_STUDENT_NUM.equals(typeDateMapEntry.getKey())){
+				//查询时间段内学员成功退团申请的数量
+				Integer quitNum = musicGroupDao.countQuitNum(queryInfo);
+				indexBaseData.setIndexMonthDataDetail(new ArrayList<>());
+				indexBaseData.setDataType(QUIT_MUSIC_GROUP_STUDENT_NUM);
+				indexBaseData.setPercent(new BigDecimal(quitNum));
+				indexBaseData.setTitle(QUIT_MUSIC_GROUP_STUDENT_NUM.getMsg());
+			}
 			result.add(indexBaseData);
 		}
 		return result;
@@ -593,7 +601,7 @@ public class IndexBaseMonthDataServiceImpl extends BaseServiceImpl<Long, IndexBa
 			}
 			dataList.add(new IndexBaseMonthData(date, organId, tenantId));
 		}
-		if(!IndexDataType.NEWLY_STUDENT_NUM.equals(indexDataType)&&!IndexDataType.QUIT_MUSIC_GROUP_STUDENT_NUM.equals(indexDataType)){
+		if(!IndexDataType.NEWLY_STUDENT_NUM.equals(indexDataType) && !IndexDataType.QUIT_MUSIC_GROUP_STUDENT_NUM.equals(indexDataType)){
 			indexBaseMonthDataDao.deleteWithMonthAndType(Arrays.asList(dayStr), indexDataType, tenantId);
 		}
 		if(!CollectionUtils.isEmpty(dataList)){

+ 5 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupPaymentCalenderServiceImpl.java

@@ -1207,6 +1207,11 @@ public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long,
     }
 
     @Override
+    public Map<Long, Integer> findCooperationByIds(List<Long> calenderIds) {
+        return (Map<Long, Integer>)MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.findCooperationByIds(calenderIds));
+    }
+
+    @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     public boolean autoUpdateMusicGroupPaymentCalenderStatus() {
         Date date = new Date();

+ 14 - 0
mec-biz/src/main/resources/config/mybatis/CooperationOrganMapper.xml

@@ -200,4 +200,18 @@
     <select id="getCooperationOrganByEduTeacherId" resultMap="CooperationOrgan">
         SELECT * FROM cooperation_organ WHERE education_user_id_ = #{userId} and is_enable_ =1 and del_flag_ =0
     </select>
+    <select id="getFirstGroup" resultType="java.lang.String">
+        SELECT mg.id_ FROM cooperation_organ co
+        LEFT JOIN music_group mg ON mg.cooperation_organ_id_ = co.id_
+        WHERE mg.status_ IN ('PROGRESS','PAUSE') AND co.id_ = #{cooperationOrganId} ORDER BY mg.create_time_ LIMIT 1
+    </select>
+    <select id="findFirstMusic" resultType="java.util.Map">
+        SELECT mg.cooperation_organ_id_ 'key',mg.name_ 'value' FROM music_group mg
+        LEFT JOIN (SELECT co.id_,MAX(mg.create_time_) create_time_ FROM cooperation_organ co
+        LEFT JOIN music_group mg ON mg.cooperation_organ_id_ = co.id_
+        WHERE co.del_flag_ = 0 AND mg.status_ IN ('PROGRESS','PAUSE')
+        GROUP BY mg.cooperation_organ_id_) co ON co.id_ = mg.cooperation_organ_id_
+        WHERE mg.create_time_ = co.create_time_
+        ORDER BY mg.cooperation_organ_id_
+    </select>
 </mapper>

+ 62 - 15
mec-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

@@ -843,8 +843,8 @@
 		COUNT(CASE WHEN cssp.group_type_ = 'VIP' AND cs.status_ != 'NOT_START' THEN 1 ELSE NULL END) vip_over_num_,
 		COUNT(CASE WHEN cssp.group_type_ = 'VIP' AND cs.status_ = 'NOT_START' THEN 1 ELSE NULL END) vip_not_start_num_,
 		COUNT(CASE WHEN cssp.group_type_ = 'PRACTICE' AND cs.status_ != 'NOT_START' THEN 1 ELSE NULL END) practice_over_num_,
-		COUNT(CASE WHEN cssp.group_type_ = 'PRACTICE' AND cs.status_ = 'NOT_START' THEN 1 ELSE NULL END) practice_not_start_num_,
-		s.teacher_id_,ste.real_name_
+		COUNT(CASE WHEN cssp.group_type_ = 'PRACTICE' AND cs.status_ = 'NOT_START' THEN 1 ELSE NULL END) practice_not_start_num_
+		,s.teacher_id_,ste.real_name_
 		FROM student s
 		LEFT JOIN course_schedule_student_payment cssp FORCE INDEX(group_type_) ON cssp.user_id_ = s.user_id_
 		LEFT JOIN course_schedule cs ON cs.id_ = cssp.course_schedule_id_
@@ -865,19 +865,24 @@
 		<result property="userId" column="user_id_"/>
 	</resultMap>
 	<select id="queryLastOverTeacher" resultMap="BaseNameDto">
-		SELECT cssp.user_id_,su.real_name_,su.id_ teacher_id_ FROM course_schedule_student_payment cssp
-		LEFT JOIN course_schedule cs ON cs.id_ = cssp.course_schedule_id_
-		LEFT JOIN (
-		SELECT cssp.user_id_,MAX(CONCAT(cs.class_date_,' ',start_class_time_)) class_date_
-		FROM course_schedule_student_payment cssp
-		LEFT JOIN course_schedule cs ON cs.id_ = cssp.course_schedule_id_
-		WHERE cssp.group_type_ = #{groupType} AND cs.status_ != 'NOT_START' AND cssp.user_id_ IN
+		SELECT cssp.user_id_,vg.user_id_ teacher_id_,su.real_name_ FROM course_schedule_student_payment cssp
+		LEFT JOIN (SELECT cs.id_,cs.music_group_id_ FROM course_schedule cs
+		LEFT JOIN (SELECT music_group_id_,MIN(class_date_) class_date_,MIN(start_class_time_) start_class_time_ FROM course_schedule cs
+		WHERE del_flag_ = 0 AND is_lock_ = 0 AND status_ = 'OVER' AND group_type_ = #{groupType}
+		GROUP BY music_group_id_) cs1 ON cs.music_group_id_ = cs1.music_group_id_
+		WHERE cs.class_date_ = cs1.class_date_ AND cs.start_class_time_ = cs1.start_class_time_) cs ON cs.id_ = cssp.course_schedule_id_
+		<if test="groupType == 'VIP'">
+			LEFT JOIN vip_group vg ON vg.id_ = cssp.music_group_id_
+		</if>
+		<if test="groupType == 'PRACTICE'">
+			LEFT JOIN practice_group vg ON vg.id_ = cssp.music_group_id_
+		</if>
+		LEFT JOIN sys_user su ON su.id_ = vg.user_id_
+		WHERE cssp.group_type_ = #{groupType} AND cs.id_ = cssp.course_schedule_id_ AND cssp.user_id_ IN
 		<foreach collection="studentIds" open="(" close=")" item="userId" separator=",">
 			#{userId}
 		</foreach>
-		GROUP BY cssp.user_id_) c ON 1=1
-		LEFT JOIN sys_user su ON su.id_ = cs.actual_teacher_id_
-		WHERE cssp.user_id_ = c.user_id_ AND CONCAT(cs.class_date_,' ',cs.start_class_time_) = c.class_date_ AND cssp.group_type_ = #{groupType}
+		GROUP BY cssp.user_id_
 	</select>
     <select id="hasStudentMusicTheoryCourseInfo" resultType="java.lang.Boolean">
 		SELECT CASE WHEN cssp.user_id_ = NULL THEN 0 ELSE 1 END hasCourse
@@ -940,10 +945,52 @@
 		select cssp.music_group_id_ key_,count(cssp.id_) value_ from course_schedule_student_payment cssp left join course_schedule cs on cssp.course_schedule_id_ = cs.id_
 		where cssp.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} and 
 		cssp.music_group_id_ IN
-                <foreach collection="musicGroupIds" separator="," item="musicGroupId" open="(" close=")">
-                    #{musicGroupId}
-                </foreach>
+		<foreach collection="musicGroupIds" separator="," item="musicGroupId" open="(" close=")">
+			#{musicGroupId}
+		</foreach>
 		and cssp.user_id_ = #{userId} and cs.class_date_ between #{startDate} and #{endDate}
 		group by cssp.music_group_id_
 	</select>
+	<select id="findUserFirstVipMap" resultType="java.util.Map">
+		SELECT user_id_ 'key',music_group_id_ 'value' FROM course_schedule_student_payment cssp
+		RIGHT JOIN (SELECT MIN(id_) id_ FROM course_schedule_student_payment
+		WHERE group_type_ = #{groupType} AND user_id_ IN
+		<foreach collection="studentIds" separator="," item="userId" open="(" close=")">
+			#{userId}
+		</foreach>
+		GROUP BY user_id_) csp ON csp.id_ = cssp.id_
+	</select>
+	<select id="queryClassTeacher" resultMap="BaseNameDto">
+		SELECT cgsm.user_id_,cgtm.user_id_ teacher_id_,su.real_name_ FROM class_group_student_mapper cgsm
+		LEFT JOIN class_group cg ON cgsm.class_group_id_ = cg.id_
+		LEFT JOIN student_registration sr ON sr.music_group_id_ = cgsm.music_group_id_
+		LEFT JOIN class_group_teacher_mapper cgtm ON cgtm.class_group_id_ = cgsm.class_group_id_
+		LEFT JOIN sys_user su ON cgtm.user_id_ = su.id_
+		WHERE cg.del_flag_ = 0 AND cg.lock_flag_ = 0 AND cg.type_ = 'NORMAL' AND cgsm.status_ = 'NORMAL'
+		AND sr.music_group_status_ = 'NORMAL' AND cgsm.user_id_ IN
+		<foreach collection="studentIds" open="(" close=")" item="userId" separator=",">
+			#{userId}
+		</foreach>
+		GROUP BY cgsm.user_id_
+	</select>
+	<select id="queryFirstNotStartTeacher" resultMap="BaseNameDto">
+		SELECT cssp.user_id_,vg.user_id_ teacher_id_,su.real_name_ FROM course_schedule_student_payment cssp
+		LEFT JOIN (SELECT cs.id_,cs.music_group_id_ FROM course_schedule cs
+		LEFT JOIN (SELECT music_group_id_,MAX(class_date_) class_date_,MAX(start_class_time_) start_class_time_ FROM course_schedule cs
+		WHERE del_flag_ = 0 AND is_lock_ = 0 AND status_ = 'NOT_START' AND group_type_ = #{groupType}
+		GROUP BY music_group_id_) cs1 ON cs.music_group_id_ = cs1.music_group_id_
+		WHERE cs.class_date_ = cs1.class_date_ AND cs.start_class_time_ = cs1.start_class_time_) cs ON cs.id_ = cssp.course_schedule_id_
+		<if test="groupType == 'VIP'">
+			LEFT JOIN vip_group vg ON vg.id_ = cssp.music_group_id_
+		</if>
+		<if test="groupType == 'PRACTICE'">
+			LEFT JOIN practice_group vg ON vg.id_ = cssp.music_group_id_
+		</if>
+		LEFT JOIN sys_user su ON su.id_ = vg.user_id_
+		WHERE cssp.group_type_ = #{groupType} AND cs.id_ = cssp.course_schedule_id_ AND cssp.user_id_ IN
+		<foreach collection="studentIds" open="(" close=")" item="userId" separator=",">
+			#{userId}
+		</foreach>
+		GROUP BY cssp.user_id_
+	</select>
 </mapper>

+ 2 - 1
mec-biz/src/main/resources/config/mybatis/IndexBaseMonthDataMapper.xml

@@ -33,7 +33,8 @@
 	</select>
 
 	<select id="getOrganDataWithDayAndDataType" resultMap="IndexBaseMonthData">
-		SELECT * FROM index_base_month_data WHERE organ_id_=#{organId} AND month_ = #{day} AND data_type_=#{dataType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} ORDER BY month_ DESC LIMIT 1;
+		SELECT * FROM index_base_month_data WHERE organ_id_=#{organId} AND month_ = #{day}
+		AND data_type_=#{dataType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} ORDER BY month_ DESC LIMIT 1;
 	</select>
 
 	<!-- 向数据库增加一条记录 -->

+ 14 - 0
mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml

@@ -1061,4 +1061,18 @@
         ORDER BY mgpscd.update_time_ DESC
         <include refid="global.limit"/>
     </select>
+    <select id="countQuitNum" resultType="java.lang.Integer">
+        SELECT COUNT(DISTINCT mgq.user_id_) FROM music_group_quit mgq
+        LEFT JOIN music_group mg ON mg.id_ = mgq.music_group_id_
+        WHERE mgq.status_ = 'APPROVED' AND mgq.tenant_id_ = #{queryInfo.tenantId}
+        <if test="queryInfo.organId != null and queryInfo.organId != ''">
+            AND FIND_IN_SET(mg.organ_id_,#{queryInfo.organId})
+        </if>
+        <if test="queryInfo.startDate != null">
+            AND mgq.create_time_ >= #{queryInfo.startDate}
+        </if>
+        <if test="queryInfo.endDate != null">
+            AND mgq.create_time_ &lt;= #{queryInfo.endDate}
+        </if>
+    </select>
 </mapper>

+ 8 - 0
mec-biz/src/main/resources/config/mybatis/MusicGroupPaymentCalenderMapper.xml

@@ -696,4 +696,12 @@
 		GROUP BY pc.`music_group_id_` 
 		    )
     </select>
+    <select id="findCooperationByIds" resultType="java.util.Map">
+        SELECT mgpc.id_ 'key',mg.cooperation_organ_id_ 'value' FROM music_group_payment_calender mgpc
+        LEFT JOIN music_group mg ON mg.id_ = mgpc.music_group_id_
+        WHERE mgpc.id_ IN
+        <foreach collection="calenderIds" item="id" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+    </select>
 </mapper>

+ 22 - 1
mec-biz/src/main/resources/config/mybatis/StudentRegistrationMapper.xml

@@ -1194,7 +1194,7 @@
         SELECT sr.*
         FROM student_registration sr
         LEFT JOIN music_group mg ON sr.music_group_id_ = mg.id_
-        WHERE mg.status_ = 'PROGRESS'
+        WHERE mg.status_ IN ('PROGRESS','PAUSE')
         AND mg.del_flag_ = 0
         AND sr.music_group_status_ = 'NORMAL'
         AND sr.user_id_ IN
@@ -1787,4 +1787,25 @@
         AND spo.type_ = 'APPLY' AND spo.status_ = 'SUCCESS'
         GROUP BY sr.actual_subject_id_
     </select>
+    <select id="getLastMusicGroupId" resultType="java.util.Map">
+        SELECT sr.user_id_ 'key',sr.music_group_id_ 'value' FROM student_registration sr
+        WHERE sr.id_ IN (SELECT MAX(sr.id_) FROM student_registration sr
+        LEFT JOIN music_group mg ON mg.id_ = sr.music_group_id_
+        WHERE sr.music_group_status_ = 'NORMAL' AND mg.status_ IN ('PROGRESS','PAUSE') AND sr.user_id_ IN
+        <foreach collection="userIds" separator="," item="id" open="(" close=")">
+            #{id}
+        </foreach>
+        GROUP BY sr.user_id_)
+    </select>
+    <select id="getLastMusicGroupName" resultType="java.util.Map">
+        SELECT sr.user_id_ 'key',mg.name_ 'value' FROM student_registration sr
+        LEFT JOIN music_group mg ON mg.id_ = sr.music_group_id_
+        WHERE sr.id_ IN (SELECT MAX(sr.id_) FROM student_registration sr
+        LEFT JOIN music_group mg ON mg.id_ = sr.music_group_id_
+        WHERE sr.music_group_status_ = 'NORMAL' AND mg.status_ IN ('PROGRESS','PAUSE') AND sr.user_id_ IN
+        <foreach collection="userIds" separator="," item="id" open="(" close=")">
+            #{id}
+        </foreach>
+        GROUP BY sr.user_id_)
+    </select>
 </mapper>

+ 6 - 6
mec-web/src/main/resources/exportColumnMapper.ini

@@ -111,16 +111,16 @@ headColumns = ["用户编号", "用户名", "手机号", "课程类型", "实际
 fieldColumns = ["userId", "username", "phone", "type.msg", "name", "actualSalary", "subsidy", "settlementTime", "teacherRole.msg"]
 
 [订单列表导出1]
-headColumns = ["序号", "学生编号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额", "现金支付", "余额支付", "优惠金额",    "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "乐保费用", "团练宝", "押金", "乐器", "教辅费用", "上门费",    "账户充值", "其它", "汇付手续费","平台手续费", "到账时间",    "关联乐团ID/VIP课ID", "课程形态", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"]
-fieldColumns = ["id", "userId", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount", "expectAmount", "actualAmount", "balancePaymentAmount",  "couponRemitFee",     "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "maintenanceFee", "cloudTeacherFee",     "leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "transferFee", "platformFee", "payTime", "musicGroupId",     "groupType.desc", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"]
+headColumns = ["序号", "学生编号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额", "现金支付", "余额支付", "优惠金额", "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "乐保费用", "团练宝", "押金", "乐器", "教辅费用", "上门费","账户充值", "其它", "汇付手续费","平台手续费", "到账时间","关联乐团ID/VIP课ID","课程形态","课程形态描述","收费乐团编号","收费乐团","零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"]
+fieldColumns = ["id", "userId", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount", "expectAmount", "actualAmount","balancePaymentAmount","couponRemitFee","musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "maintenanceFee", "cloudTeacherFee","leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "transferFee", "platformFee", "payTime", "musicGroupId","groupType.desc","typeDesc.msg","feeMusicGroupId","feeMusicGroupName", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"]
 
 [订单列表导出2]
-headColumns = ["序号", "学生编号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额", "现金支付", "余额支付", "优惠金额",    "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "乐保费用", "团练宝", "押金", "乐器", "教辅费用", "上门费",    "账户充值", "其它","平台手续费", "到账时间",    "关联乐团ID/VIP课ID", "课程形态", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"]
-fieldColumns = ["id", "userId", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount", "expectAmount", "actualAmount", "balancePaymentAmount",  "couponRemitFee",     "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "maintenanceFee", "cloudTeacherFee",     "leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "platformFee", "payTime", "musicGroupId",     "groupType.desc", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"]
+headColumns = ["序号", "学生编号", "学生姓名", "交易流水号", "订单编号", "收款渠道", "收款账户", "订单金额", "应付金额", "现金支付", "余额支付", "优惠金额",    "乐团课", "VIP课", "网管课", "乐理课", "考级", "维修费用", "乐保费用", "团练宝", "押金", "乐器", "教辅费用", "上门费",    "账户充值", "其它","平台手续费", "到账时间",    "关联乐团ID/VIP课ID", "课程形态","课程形态描述","收费乐团编号","收费乐团", "零星收款类别", "专业", "分部", "教学点", "合作单位", "乐团主管", "备注"]
+fieldColumns = ["id", "userId", "user.username", "transNo", "orderNo", "paymentChannel", "merNos", "orderAmount", "expectAmount", "actualAmount", "balancePaymentAmount",  "couponRemitFee",     "musicGroupCourseFee", "vipCourseFee", "practiceCourseFee", "theoryCourseFee", "degreeFee", "repairFee", "maintenanceFee", "cloudTeacherFee",     "leaseFee", "musicalFee", "teachingFee", "visitFee", "rechargeFee", "otherFee", "platformFee", "payTime", "musicGroupId", "groupType.desc","typeDesc.msg","feeMusicGroupId","feeMusicGroupName", "sporadicType", "subjectName", "organName", "schoolName", "cooperationOrganName", "eduTeacher", "memo"]
 
 [学员小课记录导出]
-headColumns = ["分部", "学员编号", "学生姓名", "课程余额", "声部", "VIP已结束课时数", "VIP未开始课时数", "已结束VIP课老师编号", "已结束VIP课老师","网管课已结束课时数", "网管课未开始课时数", "已结束网管课上课老师编号", "已结束网管课上课老师", "指导老师编号", "指导老师"]
-fieldColumns = ["organName","userId", "username","courseBalance", "subjectName", "vipOverNum", "vipNotStartNum", "vipOverTeacherId", "vipOverTeacherName" , "practiceOverNum", "practiceNotStartNum", "practiceOverTeacherId", "practiceOverTeacherName","teacherId","teacherName"]
+headColumns = ["分部", "学员编号", "学生姓名", "课程余额", "声部" ,"声部班老师编号" ,"声部班老师", "VIP已结束课时数", "VIP未开始课时数", "已结束VIP课程组老师编号", "已结束VIP课程组老师", "未开始VIP课程组老师编号", "未开始VIP课程组老师","网管课已结束课时数", "网管课未开始课时数", "已结束网管课上课老师编号", "已结束网管课上课老师", "未开始网管课上课老师编号", "未开始网管课上课老师", "指导老师编号", "指导老师"]
+fieldColumns = ["organName","userId", "username","courseBalance", "subjectName", "normalClassTeacherId", "normalClassTeacherName", "vipOverNum", "vipNotStartNum", "vipOverTeacherId", "vipOverTeacherName", "vipNotStartTeacherId", "vipNotStartTeacherName" , "practiceOverNum", "practiceNotStartNum", "practiceOverTeacherId", "practiceOverTeacherName", "practiceNotStartTeacherId", "practiceNotStartTeacherName","teacherId","teacherName"]
 
 [乐团导出学员列表]
 headColumns = ["学员编号", "学员姓名", "性别", "联系电话","入团时间", "年级", "班级", "入团专业", "学员状态", "报名缴费", "缴费金额", "是否激活","VIP/网管是否有课","关心包","加油包", "欠费金额(元)", "退团原因", "会员截止时间", "会员剩余天数"]