浏览代码

Merge branch 'master' of http://git.dayaedu.com/yonge/mec

yonge 5 年之前
父节点
当前提交
ae12f155c6
共有 41 个文件被更改,包括 1998 次插入162 次删除
  1. 12 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ClassGroupDao.java
  2. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ClassGroupStudentMapperDao.java
  3. 13 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java
  4. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/GroupDao.java
  5. 19 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/PracticeGroupDao.java
  6. 14 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/PracticeGroupSellPriceDao.java
  7. 12 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentAttendanceDao.java
  8. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentRegistrationDao.java
  9. 20 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java
  10. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ExtendTeacherBasicDto.java
  11. 40 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PracticeCourseDto.java
  12. 28 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PracticeDrillTimeDto.java
  13. 35 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PracticeGroupBuyDto.java
  14. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SimpleUserDto.java
  15. 10 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java
  16. 30 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/PracticeGroup.java
  17. 81 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/PracticeGroupSellPrice.java
  18. 20 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentAttendance.java
  19. 31 0
      mec-biz/src/main/java/com/ym/mec/biz/service/GroupClassService.java
  20. 78 3
      mec-biz/src/main/java/com/ym/mec/biz/service/PracticeGroupService.java
  21. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/StudentAttendanceService.java
  22. 15 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SysConfigService.java
  23. 13 3
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  24. 55 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupClassServiceImpl.java
  25. 19 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/MusicGroupServiceImpl.java
  26. 1006 96
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/PracticeGroupServiceImpl.java
  27. 42 32
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentAttendanceServiceImpl.java
  28. 9 4
      mec-biz/src/main/resources/config/mybatis/ClassGroupMapper.xml
  29. 3 0
      mec-biz/src/main/resources/config/mybatis/ClassGroupStudentMapperMapper.xml
  30. 14 5
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  31. 1 1
      mec-biz/src/main/resources/config/mybatis/CourseScheduleTeacherSalaryMapper.xml
  32. 14 0
      mec-biz/src/main/resources/config/mybatis/GroupMapper.xml
  33. 3 2
      mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml
  34. 32 1
      mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml
  35. 74 0
      mec-biz/src/main/resources/config/mybatis/PracticeGroupSellPriceMapper.xml
  36. 25 4
      mec-biz/src/main/resources/config/mybatis/StudentAttendanceMapper.xml
  37. 5 0
      mec-biz/src/main/resources/config/mybatis/StudentRegistrationMapper.xml
  38. 44 0
      mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  39. 5 2
      mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java
  40. 64 4
      mec-student/src/main/java/com/ym/mec/student/controller/PracticeGroupController.java
  41. 28 0
      mec-util/src/main/java/com/ym/mec/util/date/DateUtil.java

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ClassGroupDao.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.dal.dao;
 import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.ClassGroup;
 import com.ym.mec.biz.dal.enums.ClassGroupTypeEnum;
+import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImGroupModel;
@@ -616,4 +617,15 @@ public interface ClassGroupDao extends BaseDAO<Integer, ClassGroup> {
      * @return
      */
     List<Map<Integer, String>> findClassGroupSubjectNameMaps(@Param("courseScheduleIds") List<Long> courseScheduleIds);
+
+    /**
+     * @describe 根据团体删除班级
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param groupId:
+     * @param groupType:
+     * @return int
+     */
+    int deleteByGroup(@Param("groupId") String groupId,
+                      @Param("groupType")GroupType groupType);
 }

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/ClassGroupStudentMapperDao.java

@@ -60,6 +60,17 @@ public interface ClassGroupStudentMapperDao extends BaseDAO<Long, ClassGroupStud
     void deleteByClassId(Integer classGroupId);
 
     /**
+     * @describe 根据团体删除班上的学生
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param groupId:
+     * @param groupType:
+     * @return int
+     */
+    int deleteByGroup(@Param("groupId") String groupId,
+                      @Param("groupType") GroupType groupType);
+
+    /**
      * @return int
      * @Author: Joburgess
      * @Date: 2019/10/17

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/CourseScheduleDao.java

@@ -1150,4 +1150,17 @@ public interface CourseScheduleDao extends BaseDAO<Long, CourseSchedule> {
      */
     List<Map<Long, String>> queryTeacherName(@Param("courseScheduleIds") List<Long> courseScheduleIds);
 
+    /**
+     * @describe 更改团体下课程的冻结状态
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param groupId:
+     * @param groupType:
+     * @param isLock: 冻结状态:1、冻结,0、正常
+     * @return int
+     */
+    int updateGroupCourseLock(@Param("groupId") String groupId,
+                              @Param("groupType") GroupType groupType,
+                              @Param("isLock") Integer isLock);
+
 }

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

@@ -12,6 +12,10 @@ import java.util.Map;
  */
 public interface GroupDao {
 
+
+    int deleteGroup(@Param("groupId") String groupId,
+                    @Param("groupType") String groupType);
+
     /**
      * @describe 搜索团体
      * @author Joburgess

+ 19 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/PracticeGroupDao.java

@@ -1,8 +1,8 @@
 package com.ym.mec.biz.dal.dao;
 
+import com.ym.mec.biz.dal.dto.PracticeCourseDto;
 import com.ym.mec.biz.dal.dto.PracticeGroupDto;
 import com.ym.mec.biz.dal.entity.PracticeGroup;
-import com.ym.mec.biz.dal.entity.VipGroup;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
@@ -60,4 +60,22 @@ public interface PracticeGroupDao extends com.ym.mec.common.dal.BaseDAO<Long, Pr
      * @param teacherId
      */
     void updateUserId(@Param("practiceGroupId") String practiceGroupId, @Param("teacherId") Integer teacherId);
+
+    /**
+     * @describe 获取学生最后一次购买的陪练课组
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param userId: 学生编号
+     * @return com.ym.mec.biz.dal.entity.PracticeGroup
+     */
+    PracticeGroup findUserLatestPracticeGroup(@Param("userId") Integer userId);
+
+    /**
+     * @describe 获取用户购买的陪练课
+     * @author Joburgess
+     * @date 2020/2/18
+     * @param userId: 用户编号
+     * @return java.util.List<com.ym.mec.biz.dal.dto.PracticeCourseDto>
+     */
+    List<PracticeCourseDto> findUserBuyPracticeGroups(@Param("userId") Integer userId);
 }

+ 14 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/PracticeGroupSellPriceDao.java

@@ -0,0 +1,14 @@
+package com.ym.mec.biz.dal.dao;
+
+import com.ym.mec.biz.dal.entity.PracticeGroupSellPrice;
+import com.ym.mec.common.dal.BaseDAO;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/18
+ */
+public interface PracticeGroupSellPriceDao extends BaseDAO<Integer, PracticeGroupSellPrice> {
+
+
+
+}

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/StudentAttendanceDao.java

@@ -5,6 +5,7 @@ import com.ym.mec.biz.dal.dto.StudentAttendanceStatusCountDto;
 import com.ym.mec.biz.dal.dto.StudentPersonalAttendanceDto;
 import com.ym.mec.biz.dal.dto.StudentStatusCountUtilEntity;
 import com.ym.mec.biz.dal.entity.StudentAttendance;
+import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.common.dal.BaseDAO;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Param;
@@ -236,4 +237,15 @@ public interface StudentAttendanceDao extends BaseDAO<Long, StudentAttendance> {
      * @return
      */
     int countStudentAttendance(Map<String, Object> params);
+
+    /**
+     * @describe 根据团体删除数据
+     * @author Joburgess
+     * 020/2/17
+     * @param groupId:
+     * @param groupType:
+     * @return int
+     */
+    int deleteByGroup(@Param("groupId") String groupId,
+                      @Param("groupType")GroupType groupType);
 }

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

@@ -311,4 +311,11 @@ public interface StudentRegistrationDao extends BaseDAO<Long, StudentRegistratio
      * @return
      */
     StudentRegistration findStudentByMusicGroupIdAndUserId(@Param("musicGroupId") String musicGroupId, @Param("userId") Integer userId);
+
+    /**
+     * 获取学员所在乐团
+     * @param studentId
+     * @return
+     */
+    List<String> queryStudentMusicGroup(Integer studentId);
 }

+ 20 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TeacherDao.java

@@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.Param;
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 public interface TeacherDao extends BaseDAO<Integer, Teacher> {
 
@@ -104,7 +105,18 @@ public interface TeacherDao extends BaseDAO<Integer, Teacher> {
      * @return java.util.List<com.ym.mec.biz.dal.dto.TeacherBasicDto>
      */
     List<ExtendTeacherBasicDto> findTeaTeachersByOrganAndSubject1(@Param("organId") Integer organId,
-                                                                 @Param("subjectId") Integer subjectId);
+                                                                  @Param("subjectId") Integer subjectId);
+
+    /**
+     * @describe 获取指定声部和分部下的全职老师--付费
+     * @author Joburgess
+     * @date 2020/2/2
+     * @param organId: 分部编号
+     * @param subjectId: 声部编号列表
+     * @return java.util.List<com.ym.mec.biz.dal.dto.TeacherBasicDto>
+     */
+    List<ExtendTeacherBasicDto> findTeaTeachersByOrganAndSubject2(@Param("organId") Integer organId,
+                                                                  @Param("subjectId") Integer subjectId);
 
     /**
      * @describe 根据部门和声部获取教师列表
@@ -289,4 +301,11 @@ public interface TeacherDao extends BaseDAO<Integer, Teacher> {
      * @return
      */
     SysUser getUser(int userId);
+
+    /**
+     * 获取教师基本信息
+     * @param teacherId
+     * @return
+     */
+    List<BasicUserDto> queryTeacherBaseInfo(@Param("teacherId")Set<Integer> teacherId);
 }

+ 30 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/ExtendTeacherBasicDto.java

@@ -6,8 +6,22 @@ package com.ym.mec.biz.dal.dto;
  */
 public class ExtendTeacherBasicDto extends TeacherBasicDto {
 
+    private String avatar;
+
+    private String subjectNames;
+
+    private String introduction;
+
     int isSupportExtraPracticeLesson = 0;
 
+    public String getIntroduction() {
+        return introduction;
+    }
+
+    public void setIntroduction(String introduction) {
+        this.introduction = introduction;
+    }
+
     public int getIsSupportExtraPracticeLesson() {
         return isSupportExtraPracticeLesson;
     }
@@ -15,4 +29,20 @@ public class ExtendTeacherBasicDto extends TeacherBasicDto {
     public void setIsSupportExtraPracticeLesson(int isSupportExtraPracticeLesson) {
         this.isSupportExtraPracticeLesson = isSupportExtraPracticeLesson;
     }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getSubjectNames() {
+        return subjectNames;
+    }
+
+    public void setSubjectNames(String subjectNames) {
+        this.subjectNames = subjectNames;
+    }
 }

+ 40 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PracticeCourseDto.java

@@ -0,0 +1,40 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.PracticeGroup;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/18
+ */
+public class PracticeCourseDto extends PracticeGroup {
+
+    private String teacherName;
+
+    private String avatar;
+
+    private String subjectName;
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+}

+ 28 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PracticeDrillTimeDto.java

@@ -0,0 +1,28 @@
+package com.ym.mec.biz.dal.dto;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/17
+ */
+public class PracticeDrillTimeDto {
+
+    private Integer weekNum;
+
+    private String timeStr;
+
+    public Integer getWeekNum() {
+        return weekNum;
+    }
+
+    public void setWeekNum(Integer weekNum) {
+        this.weekNum = weekNum;
+    }
+
+    public String getTimeStr() {
+        return timeStr;
+    }
+
+    public void setTimeStr(String timeStr) {
+        this.timeStr = timeStr;
+    }
+}

+ 35 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/PracticeGroupBuyDto.java

@@ -0,0 +1,35 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.PracticeGroup;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/17
+ */
+public class PracticeGroupBuyDto extends PracticeGroup {
+
+    @ApiModelProperty(value = "是否使用账户余额支付")
+    private boolean useBalancePayment;
+
+    private List<PracticeDrillTimeDto> drillTimes;
+
+    public boolean isUseBalancePayment() {
+        return useBalancePayment;
+    }
+
+    public void setUseBalancePayment(boolean useBalancePayment) {
+        this.useBalancePayment = useBalancePayment;
+    }
+
+    public List<PracticeDrillTimeDto> getDrillTimes() {
+        return drillTimes;
+    }
+
+    public void setDrillTimes(List<PracticeDrillTimeDto> drillTimes) {
+        this.drillTimes = drillTimes;
+    }
+
+}

+ 30 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SimpleUserDto.java

@@ -10,11 +10,41 @@ public class SimpleUserDto {
 
     private String userName;
 
+    private String avatar;
+
+    private String subjectNames;
+
+    private String introduction;
+
     public SimpleUserDto(Integer userId, String userName) {
         this.userId = userId;
         this.userName = userName;
     }
 
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getSubjectNames() {
+        return subjectNames;
+    }
+
+    public void setSubjectNames(String subjectNames) {
+        this.subjectNames = subjectNames;
+    }
+
+    public String getIntroduction() {
+        return introduction;
+    }
+
+    public void setIntroduction(String introduction) {
+        this.introduction = introduction;
+    }
+
     public Integer getUserId() {
         return userId;
     }

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/CourseSchedule.java

@@ -140,6 +140,16 @@ public class CourseSchedule {
 
 	private java.util.Date coursesExpireDate;
 
+	private Integer isLock;
+
+	public Integer getIsLock() {
+		return isLock;
+	}
+
+	public void setIsLock(Integer isLock) {
+		this.isLock = isLock;
+	}
+
 	public Date getCoursesExpireDate() {
 		return coursesExpireDate;
 	}

+ 30 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/PracticeGroup.java

@@ -48,6 +48,36 @@ public class PracticeGroup {
 	/**  */
 	private String memo;
 
+	private Integer buyMonths;
+
+	private Integer drillTimesOnWeek;
+
+	private String drillTimesJson;
+
+	public Integer getBuyMonths() {
+		return buyMonths;
+	}
+
+	public void setBuyMonths(Integer buyMonths) {
+		this.buyMonths = buyMonths;
+	}
+
+	public Integer getDrillTimesOnWeek() {
+		return drillTimesOnWeek;
+	}
+
+	public void setDrillTimesOnWeek(Integer drillTimesOnWeek) {
+		this.drillTimesOnWeek = drillTimesOnWeek;
+	}
+
+	public String getDrillTimesJson() {
+		return drillTimesJson;
+	}
+
+	public void setDrillTimesJson(String drillTimesJson) {
+		this.drillTimesJson = drillTimesJson;
+	}
+
 	public Integer getStudentId() {
 		return studentId;
 	}

+ 81 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/PracticeGroupSellPrice.java

@@ -0,0 +1,81 @@
+package com.ym.mec.biz.dal.entity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/18
+ */
+public class PracticeGroupSellPrice {
+
+    private Integer organId;
+
+    private BigDecimal onceOriginalPrice;
+
+    private BigDecimal onceActivityPrice;
+
+    private BigDecimal twiceOriginalPrice;
+
+    private BigDecimal twiceActivityPrice;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    public Integer getOrganId() {
+        return organId;
+    }
+
+    public void setOrganId(Integer organId) {
+        this.organId = organId;
+    }
+
+    public BigDecimal getOnceOriginalPrice() {
+        return onceOriginalPrice;
+    }
+
+    public void setOnceOriginalPrice(BigDecimal onceOriginalPrice) {
+        this.onceOriginalPrice = onceOriginalPrice;
+    }
+
+    public BigDecimal getOnceActivityPrice() {
+        return onceActivityPrice;
+    }
+
+    public void setOnceActivityPrice(BigDecimal onceActivityPrice) {
+        this.onceActivityPrice = onceActivityPrice;
+    }
+
+    public BigDecimal getTwiceOriginalPrice() {
+        return twiceOriginalPrice;
+    }
+
+    public void setTwiceOriginalPrice(BigDecimal twiceOriginalPrice) {
+        this.twiceOriginalPrice = twiceOriginalPrice;
+    }
+
+    public BigDecimal getTwiceActivityPrice() {
+        return twiceActivityPrice;
+    }
+
+    public void setTwiceActivityPrice(BigDecimal twiceActivityPrice) {
+        this.twiceActivityPrice = twiceActivityPrice;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 20 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentAttendance.java

@@ -54,7 +54,10 @@ public class StudentAttendance {
 	/** 状态(正常、旷课、请假) */
 	@ApiModelProperty(value = "状态(正常、旷课、请假、休学)",required = false)
 	private StudentAttendanceStatusEnum status;
-	
+
+	private Date signInTime;
+
+	private Date signOutTime;
 	/**  */
 	private java.util.Date createTime;
 	/**  */
@@ -67,6 +70,22 @@ public class StudentAttendance {
 	@ApiModelProperty(value = "当前课时")
 	private Integer currentClassTimes;
 
+	public Date getSignInTime() {
+		return signInTime;
+	}
+
+	public void setSignInTime(Date signInTime) {
+		this.signInTime = signInTime;
+	}
+
+	public Date getSignOutTime() {
+		return signOutTime;
+	}
+
+	public void setSignOutTime(Date signOutTime) {
+		this.signOutTime = signOutTime;
+	}
+
 	public String getSubjectName() {
 		return subjectName;
 	}

+ 31 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/GroupClassService.java

@@ -0,0 +1,31 @@
+package com.ym.mec.biz.service;
+
+import com.ym.mec.biz.dal.enums.GroupType;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/17
+ **/
+public interface GroupClassService {
+
+    /**
+     * @describe 删除团体信息
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param groupId: 团体编号
+     * @param groupType: 团体类型
+     * @return boolean
+     */
+    boolean deleteGroupInfo(String groupId, GroupType groupType);
+
+    /**
+     * @describe 清理团新相关信息
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param groupId: 团体编号
+     * @param groupType: 团体类型
+     * @return boolean
+     */
+    boolean cleanGroupInfo(String groupId, GroupType groupType);
+
+}

+ 78 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/PracticeGroupService.java

@@ -1,10 +1,10 @@
 package com.ym.mec.biz.service;
 
-import com.ym.mec.biz.dal.dto.CourseScheduleDto;
-import com.ym.mec.biz.dal.dto.PracticeGroupDto;
-import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.PracticeGroup;
+import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
 import com.ym.mec.biz.dal.page.PracticeGroupQueryInfo;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.BaseService;
 
@@ -112,4 +112,79 @@ public interface PracticeGroupService extends BaseService<Long, PracticeGroup> {
 	 * @return
 	 */
 	Object findPracticeGroupCourseSchedules(PracticeGroupQueryInfo queryInfo);
+
+	/**
+	 * @describe 获取学生上一次购买的记录
+	 * @author Joburgess
+	 * @date 2020/2/18
+	 * @param userId:
+	 * @return com.ym.mec.biz.dal.entity.PracticeGroup
+	 */
+	PracticeGroup findUserLatestPracticeGroup(Integer userId);
+
+    /**
+     * @describe 获取陪练课预约参数——付费
+     * @author Joburgess
+     * @date 2020/1/31
+     * @param userId: 用户编号
+     * @return java.util.Map
+     */
+    Map getPayPracticeApplyParams(Integer userId, Integer organId);
+
+	/**
+	 * @describe 获取可以预约的教师——付费
+	 * @author Joburgess
+	 * @date 2020/2/9
+	 * @param userId: 用户编号
+	 * @param subjectId: 声部编号
+	 * @return java.util.List<com.ym.mec.biz.dal.dto.SimpleUserDto>
+	 */
+	List<SimpleUserDto> getEnableApplyTeachersWithPay(Integer userId, Integer subjectId);
+
+    /**
+     * @describe 获取指定教师的空闲时间——付费
+     * @author Joburgess
+     * @date 2020/2/10
+     * @param userId: 用户编号
+     * @param teacherId: 教师编号
+     * @param firstClassTime: 第一节课开始时间
+     * @param buyMonths: 购买月数
+     * @return java.util.Map
+     */
+    Map getPayPracticeTeacherFreeTimes(Integer userId, Integer teacherId, Integer buyMonths, Date firstClassTime);
+
+    /**
+     * @describe 获取一周内可以预约课程的时间——付费
+     * @author Joburgess
+     * @date 2020/2/2
+     * @return java.util.Map
+     */
+    Map<Integer, List<String>> getEnableApplyDatesWithWeek();
+
+    /**
+     * @describe 陪练课购买
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param practiceGroupBuyParams: 购买参数
+     * @return void
+     */
+    HttpResponseResult buyPracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams);
+
+    /**
+     * @describe 支付订单回调
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param order: 支付订单
+     * @return void
+     */
+	void orderCallback(StudentPaymentOrder order);
+
+	/**
+	 * @describe 获取用户历史购买的陪练课
+	 * @author Joburgess
+	 * @date 2020/2/18
+	 * @param userId:
+	 * @return java.util.List<com.ym.mec.biz.dal.dto.PracticeCourseDto>
+	 */
+	List<PracticeCourseDto> findUserHistoryBuyPracticeGroups(Integer userId);
 }

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/StudentAttendanceService.java

@@ -4,6 +4,7 @@ import com.ym.mec.biz.dal.dto.CourseScheduleResponse;
 import com.ym.mec.biz.dal.dto.StudentAttendanceDto;
 import com.ym.mec.biz.dal.dto.StudentPersonalAttendanceDto;
 import com.ym.mec.biz.dal.entity.StudentAttendance;
+import com.ym.mec.biz.dal.enums.SignStatusEnum;
 import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
 import com.ym.mec.biz.dal.page.CourseHomeworkQueryInfo;
 import com.ym.mec.common.page.PageInfo;
@@ -79,7 +80,7 @@ public interface StudentAttendanceService extends BaseService<Long, StudentAtten
 	 * @param userId
 	 * @param statusEnum
 	 */
-	void addStudentAttendanceRecord(Integer courseScheduleId, Integer userId, StudentAttendanceStatusEnum statusEnum);
+	void addStudentAttendanceRecord(Integer courseScheduleId, Integer userId, StudentAttendanceStatusEnum statusEnum,SignStatusEnum signStatusEnum);
 
 	/**
 	 * 某节课所有学员签到状态

+ 15 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SysConfigService.java

@@ -138,6 +138,21 @@ public interface SysConfigService extends BaseService<Long, SysConfig> {
     String ONLINE_CONTINUE_COURSE_TIME = "online_continue_course_time";
 
     /**
+     * @describe 付费陪练课可购买最大月数
+     */
+    String PRACTICE_PAY_MAX_MONTH = "practice_pay_max_month";
+
+    /**
+     * @describe 付费陪练课单月上课数量
+     */
+    String PRACTICE_PAY_DRILL_TIMES_ON_ONE_WEEK = "practice_pay_drill_times_on_one_week";
+
+    /**
+     * @describe 付费陪练课活动截至日期
+     */
+    String PRACTICE_BUY_ACTIVITY_EXPIRE_DATE = "practice_buy_activity_expire_date";
+
+    /**
      * @return com.ym.mec.biz.dal.entity.SysConfig
      * @params paramName
      * @describe 根据配置名称获取配置信息

+ 13 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -1324,6 +1324,7 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                 .stream().map(Long::parseLong).collect(Collectors.toList());
         //所有的课程
         List<CourseSchedule> courseSchedules = courseScheduleDao.findByCourseScheduleIds(courseScheduleIds);
+        courseSchedules.sort(Comparator.comparing(CourseSchedule::getStartClassTime));
         //保存修改记录
         List<CourseScheduleModifyLog> scheduleModifyLogs = new ArrayList<>(courseSchedules.size());
         Date date = new Date();
@@ -1335,7 +1336,6 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             scheduleModifyLog.setOperatorId(user.getId());
             scheduleModifyLogs.add(scheduleModifyLog);
         });
-        courseSchedules.sort(Comparator.comparing(CourseSchedule::getStartClassTime));
 
         if (courseScheduleIds.size() != courseScheduleIds.size()) {
             throw new BizException("部分课程不存在");
@@ -1385,6 +1385,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
                     dateYmdStr = dateYmdStr + " " + courseTime.getStartClassTime();
                     Date courseStartTime = DateUtil.stringToDate(dateYmdStr, "yyyy-MM-dd HH:mm");
                     Date courseEndTime = DateUtil.addMinutes(courseStartTime, vipGroup.getSingleClassMinutes());
+                    if(DateUtil.daysBetween(DateUtil.stringToDate(DateUtil.format(courseStartTime,DateUtil.DEFAULT_PATTERN),DateUtil.DEFAULT_PATTERN),
+                            DateUtil.stringToDate(DateUtil.format(courseEndTime,DateUtil.DEFAULT_PATTERN),DateUtil.DEFAULT_PATTERN)) > 0){
+                        throw new BizException("单节课时不允许跨天");
+                    }
                     courseStartDates.add(DateUtil.stringToDate(dateYmdStr, DateUtil.EXPANDED_DATE_TIME_FORMAT));
                     int settlementNum = courseScheduleTeacherSalaryDao.checkCourseIsSettlement(courseSchedules.get(courseStartDates.size() - 1).getId().intValue());
                     if (settlementNum > 0) {
@@ -2056,7 +2060,6 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             boolean courseTimeIsChange = false;
             int newCourseTime = DateUtil.minutesBetween(newCourseSchedule.getStartClassTime(), newCourseSchedule.getEndClassTime());
             int oldCourseTime = DateUtil.minutesBetween(oldCourseSchedule.getStartClassTime(), oldCourseSchedule.getEndClassTime());
-
             if (newCourseTime != oldCourseTime) {
                 courseTimeIsChange = true;
             }
@@ -2069,7 +2072,6 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             oldCourseSchedule.setStartClassTime(newCourseSchedule.getStartClassTime());
             oldCourseSchedule.setEndClassTime(newCourseSchedule.getEndClassTime());
             oldCourseSchedule.setStatus(newCourseSchedule.getStatus());
-
             //被修改的教师编号列表,需要将预计薪水置零
             List<Integer> beReplaceTeacherIds = new ArrayList<>();
 
@@ -2188,6 +2190,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
             }
 
             oldCourseSchedule.setActualTeacherId(newCourseSchedule.getActualTeacherId());
+            if(DateUtil.daysBetween(DateUtil.stringToDate(DateUtil.format(oldCourseSchedule.getStartClassTime(),DateUtil.DEFAULT_PATTERN),DateUtil.DEFAULT_PATTERN),
+                    DateUtil.stringToDate(DateUtil.format(oldCourseSchedule.getEndClassTime(),DateUtil.DEFAULT_PATTERN),DateUtil.DEFAULT_PATTERN)) > 0){
+                throw new BizException("单节课时不允许跨天");
+            }
             courseScheduleDao.update(oldCourseSchedule);
             scheduleModifyLog.setCurrentCourseSchedule(JSONObject.toJSONString(oldCourseSchedule));
             courseScheduleModifyLogs.add(scheduleModifyLog);
@@ -2944,6 +2950,10 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
         if(DateUtil.minutesBetween(practiceGroup.getCoursesExpireDate(),endDateTime) > 0){
             throw new BizException("调整失败: 截止时间超过课程有效期");
         }
+        if(DateUtil.daysBetween(DateUtil.stringToDate(DateUtil.format(startDateTime,DateUtil.DEFAULT_PATTERN),DateUtil.DEFAULT_PATTERN),
+                DateUtil.stringToDate(DateUtil.format(endDateTime,DateUtil.DEFAULT_PATTERN),DateUtil.DEFAULT_PATTERN)) > 0){
+            throw new BizException("单节课时不允许跨天");
+        }
         //保存修改记录
         Date date = new Date();
         CourseScheduleModifyLog scheduleModifyLog = new CourseScheduleModifyLog();

+ 55 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/GroupClassServiceImpl.java

@@ -0,0 +1,55 @@
+package com.ym.mec.biz.service.impl;
+
+import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.enums.GroupType;
+import com.ym.mec.biz.service.GroupClassService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Author Joburgess
+ * @Date 2020/2/17
+ */
+@Service
+public class GroupClassServiceImpl implements GroupClassService {
+
+    @Autowired
+    private GroupDao groupDao;
+    @Autowired
+    private ClassGroupDao classGroupDao;
+    @Autowired
+    private ClassGroupTeacherMapperDao classGroupTeacherMapperDao;
+    @Autowired
+    private ClassGroupTeacherSalaryDao classGroupTeacherSalaryDao;
+    @Autowired
+    private ClassGroupStudentMapperDao classGroupStudentMapperDao;
+    @Autowired
+    private CourseScheduleDao courseScheduleDao;
+    @Autowired
+    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
+    @Autowired
+    private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
+    @Autowired
+    private TeacherAttendanceDao teacherAttendanceDao;
+    @Autowired
+    private StudentAttendanceDao studentAttendanceDao;
+
+    @Override
+    public boolean deleteGroupInfo(String groupId, GroupType groupType) {
+        groupDao.deleteGroup(groupId,groupType.getCode());
+        classGroupDao.deleteByGroup(groupId,groupType);
+        classGroupStudentMapperDao.deleteByGroup(groupId,groupType);
+        courseScheduleDao.deleteCourseSchedulesByMusicGroupID(groupId,groupType);
+        courseScheduleTeacherSalaryDao.deleteByMusicGroupId(groupId,groupType);
+        courseScheduleStudentPaymentDao.deleteByMusicGroupId(groupId,groupType);
+        teacherAttendanceDao.deleteByMusicGroupId(groupId,groupType);
+        studentAttendanceDao.deleteByGroup(groupId,groupType);
+        return true;
+    }
+
+    @Override
+    public boolean cleanGroupInfo(String groupId, GroupType groupType) {
+
+        return false;
+    }
+}

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

@@ -1083,7 +1083,25 @@ public class MusicGroupServiceImpl extends BaseServiceImpl<String, MusicGroup> i
 
     @Override
     public List<BasicUserDto> findTeachersByStuId(Integer studentId) {
-        return musicGroupDao.findTeachersByStuId(studentId);
+        List<BasicUserDto> teachersByStuId = musicGroupDao.findTeachersByStuId(studentId);
+        //获取学员所在乐团列表
+        List<String> musicGroupIds = studentRegistrationDao.queryStudentMusicGroup(studentId);
+        Set<Integer> teacherId = new HashSet<>();
+        if(musicGroupIds != null && musicGroupIds.size() > 0){
+            List<MusicGroup> musicGroups = musicGroupDao.queryListByIds(StringUtils.join(musicGroupIds, ","));
+            musicGroups.forEach(e->{
+                teacherId.add(e.getDirectorUserId());
+                teacherId.add(e.getOperatorUserId());
+                teacherId.add(e.getEducationalTeacherId());
+                teacherId.add(e.getTeamTeacherId());
+            });
+        }
+        Set<Integer> collect = teachersByStuId.stream().map(e -> e.getUserId()).collect(Collectors.toSet());
+        if(collect == null){
+            collect = new HashSet<>();
+        }
+        collect.addAll(teacherId);
+        return teacherDao.queryTeacherBaseInfo(collect);
     }
 
     @Override

+ 1006 - 96
mec-biz/src/main/java/com/ym/mec/biz/service/impl/PracticeGroupServiceImpl.java

@@ -1,5 +1,7 @@
 package com.ym.mec.biz.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
@@ -8,15 +10,15 @@ import com.ym.mec.biz.dal.dto.*;
 import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.dal.page.PracticeGroupQueryInfo;
-import com.ym.mec.biz.service.PracticeGroupService;
-import com.ym.mec.biz.service.SysConfigService;
-import com.ym.mec.biz.service.SysMessageService;
-import com.ym.mec.biz.service.TeacherService;
+import com.ym.mec.biz.service.*;
+import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.dal.BaseDAO;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.entity.ImGroupMember;
 import com.ym.mec.common.entity.ImGroupModel;
 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.service.impl.BaseServiceImpl;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
@@ -24,6 +26,7 @@ import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
@@ -31,6 +34,9 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.WeekFields;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -79,6 +85,26 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
     private ImFeignService imFeignService;
     @Autowired
     private TeacherFreeTimeDao teacherFreeTimeDao;
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+    @Autowired
+    private IdGeneratorService idGeneratorService;
+    @Autowired
+    private PayService payService;
+    @Autowired
+    private StudentPaymentOrderService studentPaymentOrderService;
+    @Autowired
+    private SysUserCashAccountService sysUserCashAccountService;
+    @Autowired
+    private SysUserCashAccountDetailService sysUserCashAccountDetailService;
+    @Autowired
+    private SysConfigDao sysConfigDao;
+    @Autowired
+    private StudentPaymentOrderDao studentPaymentOrderDao;
+    @Autowired
+    private GroupClassService groupService;
+    @Autowired
+    private PracticeGroupSellPriceDao practiceGroupSellPriceDao;
 
     private static Map<Integer, Map<Integer, List<Integer>>> schoolSubjectTeachersMap;
 
@@ -92,7 +118,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
 
     private static Date activityStartDate, activityEndDate, applyStartDay, courseExpireDate;
 
-    private static List<String> applyDayTimes=new ArrayList<>();
+    private static List<String> applyDayTimes = new ArrayList<>();
 
     static {
         applyStartDay = DateUtil.stringToDate("2020-02-08 00:00:00");
@@ -735,28 +761,28 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
 
         List<CourseSchedule> userCourses = courseScheduleDao.findUserCourses(userId, allTeacherIds);
 
-        if(!CollectionUtils.isEmpty(userCourses)){
+        if (!CollectionUtils.isEmpty(userCourses)) {
             Map<CourseSchedule.CourseScheduleType, List<CourseSchedule>> courseTypeCourseMap = userCourses.stream().collect(Collectors.groupingBy(CourseSchedule::getType));
-            List<CourseSchedule> vipCourses=courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.VIP);
-            if(!CollectionUtils.isEmpty(vipCourses)){
+            List<CourseSchedule> vipCourses = courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.VIP);
+            if (!CollectionUtils.isEmpty(vipCourses)) {
                 for (CourseSchedule vipCourse : vipCourses) {
-                    if(!includeTeacherIds.contains(vipCourse.getTeacherId())){
+                    if (!includeTeacherIds.contains(vipCourse.getTeacherId())) {
                         includeTeacherIds.add(vipCourse.getTeacherId());
                     }
                 }
             }
-            List<CourseSchedule> singleCourses=courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.SINGLE);
-            if(!CollectionUtils.isEmpty(singleCourses)){
+            List<CourseSchedule> singleCourses = courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.SINGLE);
+            if (!CollectionUtils.isEmpty(singleCourses)) {
                 for (CourseSchedule singleCourse : singleCourses) {
-                    if(!includeTeacherIds.contains(singleCourse.getTeacherId())){
+                    if (!includeTeacherIds.contains(singleCourse.getTeacherId())) {
                         includeTeacherIds.add(singleCourse.getTeacherId());
                     }
                 }
             }
-            List<CourseSchedule> highCourses=courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.HIGH);
-            if(!CollectionUtils.isEmpty(highCourses)){
+            List<CourseSchedule> highCourses = courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.HIGH);
+            if (!CollectionUtils.isEmpty(highCourses)) {
                 for (CourseSchedule highCourse : highCourses) {
-                    if(!includeTeacherIds.contains(highCourse.getTeacherId())){
+                    if (!includeTeacherIds.contains(highCourse.getTeacherId())) {
                         includeTeacherIds.add(highCourse.getTeacherId());
                     }
                 }
@@ -765,7 +791,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
 
         for (ExtendTeacherBasicDto organAndSubjectTeacher : organAndSubjectTeachers) {
             if (!includeTeacherIds.contains(organAndSubjectTeacher.getId())
-                &&1 == organAndSubjectTeacher.getIsSupportExtraPracticeLesson()) {
+                    && 1 == organAndSubjectTeacher.getIsSupportExtraPracticeLesson()) {
                 includeTeacherIds.add(organAndSubjectTeacher.getId());
             }
         }
@@ -774,11 +800,11 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             return new ArrayList<>();
         }
 
-        List<SimpleUserDto> userInfos=new ArrayList<>();
-        Map<Integer, ExtendTeacherBasicDto> idTeacherMap = organAndSubjectTeachers.stream().collect(Collectors.toMap(ExtendTeacherBasicDto::getId,teacher->teacher));
+        List<SimpleUserDto> userInfos = new ArrayList<>();
+        Map<Integer, ExtendTeacherBasicDto> idTeacherMap = organAndSubjectTeachers.stream().collect(Collectors.toMap(ExtendTeacherBasicDto::getId, teacher -> teacher));
         for (Integer includeTeacherId : includeTeacherIds) {
             ExtendTeacherBasicDto teacher = idTeacherMap.get(includeTeacherId);
-            userInfos.add(new SimpleUserDto(includeTeacherId,teacher.getRealName()));
+            userInfos.add(new SimpleUserDto(includeTeacherId, teacher.getRealName()));
         }
 
         return userInfos;
@@ -814,17 +840,57 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         }
 
         Set<Integer> disableApplyWeekNum = new HashSet<>();
-
-        TeacherFreeTime teacherFreeTime=teacherFreeTimeDao.findTeacherFreeTime(teacherId);
-        Integer maxTeacherCourses=null;
-        int holiday=0;
-        if(Objects.nonNull(teacherFreeTime)){
-            if(Objects.nonNull(teacherFreeTime.getTotalTimes())){
-                maxTeacherCourses=teacherFreeTime.getTotalTimes();
+        Set<Integer> disableApplyWeekDay = new HashSet<>();
+
+        TeacherFreeTime teacherFreeTime = teacherFreeTimeDao.findTeacherFreeTime(teacherId);
+        JSONObject teacherFreeTimes=new JSONObject();
+        Integer maxTeacherCourses = null;
+        int holiday = 0;
+        if (Objects.nonNull(teacherFreeTime)) {
+            if (Objects.nonNull(teacherFreeTime.getTotalTimes())) {
+                maxTeacherCourses = teacherFreeTime.getTotalTimes();
+            }
+            if (Objects.nonNull(teacherFreeTime.getHoliday())) {
+                holiday = DateUtil.normalWeekNumCalendarWeekNumMap.get(teacherFreeTime.getHoliday());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getMonday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.MONDAY), JSON.parseArray(teacherFreeTime.getMonday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.MONDAY);
             }
-            if(Objects.nonNull(teacherFreeTime.getHoliday())){
-                holiday=DateUtil.normalWeekNumCalendarWeekNumMap.get(teacherFreeTime.getHoliday());
+            if(StringUtils.isNotBlank(teacherFreeTime.getTuesday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.TUESDAY), JSON.parseArray(teacherFreeTime.getTuesday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.TUESDAY);
             }
+            if(StringUtils.isNotBlank(teacherFreeTime.getWednesday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.WEDNESDAY), JSON.parseArray(teacherFreeTime.getWednesday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.WEDNESDAY);
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getThursday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.THURSDAY), JSON.parseArray(teacherFreeTime.getThursday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.THURSDAY);
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getFriday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.FRIDAY), JSON.parseArray(teacherFreeTime.getFriday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.FRIDAY);
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getSaturday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.SATURDAY), JSON.parseArray(teacherFreeTime.getSaturday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.SATURDAY);
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getSunday())){
+                teacherFreeTimes.put(String.valueOf(Calendar.SUNDAY), JSON.parseArray(teacherFreeTime.getSunday()));
+            }else{
+                disableApplyWeekDay.add(Calendar.SUNDAY);
+            }
+        }else{
+            result.put("teacherFreeDays", new ArrayList<>());
+            return result;
         }
 
         Date now = new Date();
@@ -841,15 +907,15 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         Date firstMonday = DateUtil.getWeekDayWithDate(applyStartDate, Calendar.MONDAY);
         Date secondSunday = DateUtil.getWeekDayWithDate(applyEndDate, Calendar.SUNDAY);
 
-        Date yesterday=null;
-        Date tomorrow=null;
-        if(Objects.nonNull(firstClassTime)){
-            Calendar tempCalendar=Calendar.getInstance();
+        Date yesterday = null;
+        Date tomorrow = null;
+        if (Objects.nonNull(firstClassTime)) {
+            Calendar tempCalendar = Calendar.getInstance();
             tempCalendar.setTime(firstClassTime);
-            tempCalendar.add(Calendar.DATE,-1);
-            yesterday=tempCalendar.getTime();
-            tempCalendar.add(Calendar.DATE,2);
-            tomorrow=tempCalendar.getTime();
+            tempCalendar.add(Calendar.DATE, -1);
+            yesterday = tempCalendar.getTime();
+            tempCalendar.add(Calendar.DATE, 2);
+            tomorrow = tempCalendar.getTime();
         }
 
         List<Date> enableApplyDates = getEnableApplyDates(applyStartDate, applyEndDate);
@@ -868,11 +934,11 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
                 applyDateRangeCourses.add(teacherCourse);
             }
             courseCalendar.setTime(teacherCourse.getClassDate());
-            if (i==0&&teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
-                practiceCourseNum+=1;
+            if (i == 0 && teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
+                practiceCourseNum += 1;
                 courseWeekNum = courseCalendar.get(Calendar.WEEK_OF_YEAR);
             }
-            if(Objects.nonNull(maxTeacherCourses)&&practiceCourseNum>=maxTeacherCourses){
+            if (Objects.nonNull(maxTeacherCourses) && practiceCourseNum >= maxTeacherCourses) {
                 disableApplyWeekNum.add(courseWeekNum);
             }
             if (courseCalendar.get(Calendar.WEEK_OF_YEAR) != courseWeekNum) {
@@ -880,7 +946,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
                 practiceCourseNum = 0;
             }
             if (teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
-                practiceCourseNum+=1;
+                practiceCourseNum += 1;
             }
         }
 
@@ -896,13 +962,13 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         if (CollectionUtils.isEmpty(applyDateRangeCourses)) {
             for (Date enableApplyDate : enableApplyDates) {
                 if (Objects.nonNull(firstClassTime)) {
-                    if(DateUtil.isSameDay(enableApplyDate, firstClassTime)){
+                    if (DateUtil.isSameDay(enableApplyDate, firstClassTime)) {
                         continue;
                     }
-                    if(DateUtil.isSameDay(enableApplyDate, tomorrow)){
+                    if (DateUtil.isSameDay(enableApplyDate, tomorrow)) {
                         continue;
                     }
-                    if(DateUtil.isSameDay(enableApplyDate, yesterday)){
+                    if (DateUtil.isSameDay(enableApplyDate, yesterday)) {
                         continue;
                     }
                 }
@@ -943,43 +1009,66 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
                     }
                 }
                 calendar.setTime(enableApplyDate);
-                if (calendar.get(Calendar.DAY_OF_WEEK)!=holiday) {
+                int dayOfWeek=calendar.get(Calendar.DAY_OF_WEEK);
+                if(disableApplyWeekDay.contains(dayOfWeek)){
+                    continue;
+                }
+                JSONArray teacherWeekDayFreeTimes = teacherFreeTimes.getJSONArray(String.valueOf(dayOfWeek));
+                if(Objects.nonNull(teacherWeekDayFreeTimes)){
+                    LocalTime enableApplyStartTime=LocalDateTime.ofInstant(enableApplyDate.toInstant(),DateUtil.zoneId).toLocalTime();
+                    LocalTime enableApplyEndTime=LocalDateTime.ofInstant(enableApplyDateCourseEndTime.toInstant(),DateUtil.zoneId).toLocalTime();
+                    boolean isInclude=false;
+                    for (Object teacherWeekDayFreeTimeObject : teacherWeekDayFreeTimes) {
+                        JSONObject teacherWeekDayFreeTime=JSONObject.parseObject(teacherWeekDayFreeTimeObject.toString());
+                        LocalTime teacherFreeStartTime=LocalTime.parse(teacherWeekDayFreeTime.getString("startTime"),DateUtil.timeFormatter);
+                        LocalTime teacherFreeEndTime=LocalTime.parse(teacherWeekDayFreeTime.getString("endTime"),DateUtil.timeFormatter);
+                        if(enableApplyEndTime.compareTo(teacherFreeEndTime)<=0
+                            &&enableApplyStartTime.compareTo(teacherFreeStartTime)>=0){
+                            isInclude=true;
+                            break;
+                        }
+                    }
+                    if(!isInclude){
+                        continue;
+                    }
+                }
+                if (dayOfWeek != holiday) {
                     allTeacherFreeDates.add(enableApplyDate);
                 }
             }
             if (!CollectionUtils.isEmpty(allTeacherFreeDates)) {
-                List<Date> tempDates=new ArrayList<>();
-                if(Objects.nonNull(firstClassTime)){
+                List<Date> tempDates = new ArrayList<>();
+                if (Objects.nonNull(firstClassTime)) {
                     calendar.setTime(firstClassTime);
                     calendar.add(Calendar.DATE, -6);
                     calendar.set(Calendar.HOUR_OF_DAY, 0);
                     calendar.set(Calendar.MINUTE, 0);
                     calendar.set(Calendar.SECOND, 0);
                     calendar.set(Calendar.MILLISECOND, 0);
-                    applyStartDate=calendar.getTime();
+                    applyStartDate = calendar.getTime();
                     calendar.setTime(firstClassTime);
                     calendar.add(Calendar.DATE, 7);
                     calendar.set(Calendar.HOUR_OF_DAY, 0);
                     calendar.set(Calendar.MINUTE, 0);
                     calendar.set(Calendar.SECOND, 0);
                     calendar.set(Calendar.MILLISECOND, 0);
-                    applyEndDate=calendar.getTime();
+                    applyEndDate = calendar.getTime();
                     for (Date teacherFreeDate : allTeacherFreeDates) {
-                        if(!teacherFreeDate.before(applyStartDate)
-                            &&!teacherFreeDate.after(applyEndDate)){
+                        if (!teacherFreeDate.before(applyStartDate)
+                                && !teacherFreeDate.after(applyEndDate)) {
                             tempDates.add(teacherFreeDate);
                         }
                     }
                 }
-                if(CollectionUtils.isEmpty(tempDates)){
-                    tempDates=new ArrayList<>(allTeacherFreeDates);
+                if (CollectionUtils.isEmpty(tempDates)) {
+                    tempDates = new ArrayList<>(allTeacherFreeDates);
                 }
                 tempDates.sort(Comparator.comparing(Date::getTime));
                 Set<String> days = tempDates.stream()
                         .map(date -> DateUtil.dateToString(date, "yyyy-MM-dd")).collect(Collectors.toSet());
-                List<Date> tempDays=days.stream().map(dateStr -> DateUtil.stringToDate(dateStr,"yyyy-MM-dd")).collect(Collectors.toList());
+                List<Date> tempDays = days.stream().map(dateStr -> DateUtil.stringToDate(dateStr, "yyyy-MM-dd")).collect(Collectors.toList());
                 tempDays.sort(Comparator.comparing(Date::getTime));
-                result.put("teacherFreeDays", tempDays.stream().map(day->DateUtil.dateToString(day, "yyyy-MM-dd")).collect(Collectors.toList()));
+                result.put("teacherFreeDays", tempDays.stream().map(day -> DateUtil.dateToString(day, "yyyy-MM-dd")).collect(Collectors.toList()));
                 result.put("teacherFreeDates", tempDates);
             } else {
                 result.put("teacherFreeDays", new ArrayList<>());
@@ -991,13 +1080,13 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         for (Date enableApplyDate : enableApplyDates) {
             Date enableApplyDateCourseEndTime = DateUtil.addMinutes(enableApplyDate, practiceCourseMinutes);
             if (Objects.nonNull(firstClassTime)) {
-                if(DateUtil.isSameDay(enableApplyDate, firstClassTime)){
+                if (DateUtil.isSameDay(enableApplyDate, firstClassTime)) {
                     continue;
                 }
-                if(DateUtil.isSameDay(enableApplyDate, tomorrow)){
+                if (DateUtil.isSameDay(enableApplyDate, tomorrow)) {
                     continue;
                 }
-                if(DateUtil.isSameDay(enableApplyDate, yesterday)){
+                if (DateUtil.isSameDay(enableApplyDate, yesterday)) {
                     continue;
                 }
             }
@@ -1039,7 +1128,31 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             }
             calendar.setTime(enableApplyDate);
 
-            if (calendar.get(Calendar.DAY_OF_WEEK)==holiday) {
+            int dayOfWeek=calendar.get(Calendar.DAY_OF_WEEK);
+            if(disableApplyWeekDay.contains(dayOfWeek)){
+                continue;
+            }
+            JSONArray teacherWeekDayFreeTimes = teacherFreeTimes.getJSONArray(String.valueOf(dayOfWeek));
+            if(Objects.nonNull(teacherWeekDayFreeTimes)){
+                LocalTime enableApplyStartTime=LocalDateTime.ofInstant(enableApplyDate.toInstant(),DateUtil.zoneId).toLocalTime();
+                LocalTime enableApplyEndTime=LocalDateTime.ofInstant(enableApplyDateCourseEndTime.toInstant(),DateUtil.zoneId).toLocalTime();
+                boolean isInclude=false;
+                for (Object teacherWeekDayFreeTimeObject : teacherWeekDayFreeTimes) {
+                    JSONObject teacherWeekDayFreeTime=JSONObject.parseObject(teacherWeekDayFreeTimeObject.toString());
+                    LocalTime teacherFreeStartTime=LocalTime.parse(teacherWeekDayFreeTime.getString("startTime"),DateUtil.timeFormatter);
+                    LocalTime teacherFreeEndTime=LocalTime.parse(teacherWeekDayFreeTime.getString("endTime"),DateUtil.timeFormatter);
+                    if(enableApplyEndTime.compareTo(teacherFreeEndTime)<=0
+                            &&enableApplyStartTime.compareTo(teacherFreeStartTime)>=0){
+                        isInclude=true;
+                        break;
+                    }
+                }
+                if(!isInclude){
+                    continue;
+                }
+            }
+
+            if (dayOfWeek == holiday) {
                 continue;
             }
 
@@ -1091,38 +1204,38 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             }
         }
         if (!CollectionUtils.isEmpty(allTeacherFreeDates)) {
-            List<Date> tempDates=new ArrayList<>();
-            if(Objects.nonNull(firstClassTime)){
+            List<Date> tempDates = new ArrayList<>();
+            if (Objects.nonNull(firstClassTime)) {
                 calendar.setTime(firstClassTime);
                 calendar.add(Calendar.DATE, -6);
                 calendar.set(Calendar.HOUR_OF_DAY, 0);
                 calendar.set(Calendar.MINUTE, 0);
                 calendar.set(Calendar.SECOND, 0);
                 calendar.set(Calendar.MILLISECOND, 0);
-                applyStartDate=calendar.getTime();
+                applyStartDate = calendar.getTime();
                 calendar.setTime(firstClassTime);
                 calendar.add(Calendar.DATE, 7);
                 calendar.set(Calendar.HOUR_OF_DAY, 0);
                 calendar.set(Calendar.MINUTE, 0);
                 calendar.set(Calendar.SECOND, 0);
                 calendar.set(Calendar.MILLISECOND, 0);
-                applyEndDate=calendar.getTime();
+                applyEndDate = calendar.getTime();
                 for (Date teacherFreeDate : allTeacherFreeDates) {
-                    if(!teacherFreeDate.before(applyStartDate)
-                            &&!teacherFreeDate.after(applyEndDate)){
+                    if (!teacherFreeDate.before(applyStartDate)
+                            && !teacherFreeDate.after(applyEndDate)) {
                         tempDates.add(teacherFreeDate);
                     }
                 }
             }
-            if(CollectionUtils.isEmpty(tempDates)){
-                tempDates=new ArrayList<>(allTeacherFreeDates);
+            if (CollectionUtils.isEmpty(tempDates)) {
+                tempDates = new ArrayList<>(allTeacherFreeDates);
             }
             tempDates.sort(Comparator.comparing(Date::getTime));
             Set<String> days = tempDates.stream()
                     .map(date -> DateUtil.dateToString(date, "yyyy-MM-dd")).collect(Collectors.toSet());
-            List<Date> tempDays=days.stream().map(dateStr -> DateUtil.stringToDate(dateStr,"yyyy-MM-dd")).collect(Collectors.toList());
+            List<Date> tempDays = days.stream().map(dateStr -> DateUtil.stringToDate(dateStr, "yyyy-MM-dd")).collect(Collectors.toList());
             tempDays.sort(Comparator.comparing(Date::getTime));
-            result.put("teacherFreeDays", tempDays.stream().map(day->DateUtil.dateToString(day, "yyyy-MM-dd")).collect(Collectors.toList()));
+            result.put("teacherFreeDays", tempDays.stream().map(day -> DateUtil.dateToString(day, "yyyy-MM-dd")).collect(Collectors.toList()));
             result.put("teacherFreeDates", tempDates);
         }
         return result;
@@ -1455,9 +1568,9 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             Calendar applyStartCalendar = Calendar.getInstance();
             applyStartCalendar.setTime(enableApplyDayStartTime);
             for (String applyDayTime : applyDayTimes) {
-                String temp=DateUtil.dateToString(applyStartCalendar.getTime(),"yyyy-MM-dd");
-                temp=temp+" "+applyDayTime;
-                result.add(DateUtil.stringToDate(temp,"yyyy-MM-dd HH:mm:ss"));
+                String temp = DateUtil.dateToString(applyStartCalendar.getTime(), "yyyy-MM-dd");
+                temp = temp + " " + applyDayTime;
+                result.add(DateUtil.stringToDate(temp, "yyyy-MM-dd HH:mm:ss"));
             }
         }
         return result;
@@ -1466,13 +1579,13 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
     @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     public Map practiceApply(PracticeGroup practiceGroup) {
-        if(Objects.isNull(practiceGroup.getUserId())){
+        if (Objects.isNull(practiceGroup.getUserId())) {
             throw new BizException("请选择老师");
         }
         Map result = new HashMap();
         SysConfig practiceSubjectIdListConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_SUBJECT_ID_LIST);
         if (Objects.isNull(practiceGroup.getSubjectId())
-                ||!Arrays.asList(practiceSubjectIdListConfig.getParanValue().split(",")).contains(practiceGroup.getSubjectId().toString())) {
+                || !Arrays.asList(practiceSubjectIdListConfig.getParanValue().split(",")).contains(practiceGroup.getSubjectId().toString())) {
             result.put("status", "DISABLE_SUBJECT");
             result.put("info", "预约失败,声部选择错误,请重试。");
             return result;
@@ -1548,13 +1661,13 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         practiceGroup.setCoursesStartDate(allCourseDates.get(0));
         practiceGroup.setCoursesExpireDate(courseExpireDate);
         Teacher teacher = teacherService.getDetail(practiceGroup.getUserId());
-        if(Objects.isNull(teacher)){
+        if (Objects.isNull(teacher)) {
             throw new BizException("老师不存在");
         }
 
         List<SimpleUserDto> enableApplyTeachers = getEnableApplyTeachers(practiceGroup.getStudentId(), practiceGroup.getSubjectId());
         Set<Integer> enableApplyTeacherIds = enableApplyTeachers.stream().map(SimpleUserDto::getUserId).collect(Collectors.toSet());
-        if(!enableApplyTeacherIds.contains(practiceGroup.getUserId())){
+        if (!enableApplyTeacherIds.contains(practiceGroup.getUserId())) {
             throw new BizException("预约失败,老师选择错误,请重试");
         }
 
@@ -1567,51 +1680,56 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
             return result;
         }
 
-        TeacherFreeTime teacherFreeTime=teacherFreeTimeDao.findTeacherFreeTime(practiceGroup.getUserId());
-        Integer maxTeacherCourses=null;
-        if(Objects.nonNull(teacherFreeTime)){
-            if(Objects.nonNull(teacherFreeTime.getTotalTimes())){
-                maxTeacherCourses=teacherFreeTime.getTotalTimes();
+        TeacherFreeTime teacherFreeTime = teacherFreeTimeDao.findTeacherFreeTime(practiceGroup.getUserId());
+        Integer maxTeacherCourses = null;
+        if (Objects.nonNull(teacherFreeTime)) {
+            if (Objects.nonNull(teacherFreeTime.getTotalTimes())) {
+                maxTeacherCourses = teacherFreeTime.getTotalTimes();
             }
+        }else{
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            result.put("status", "TEACHER_PRACTICE_REPEAT");
+            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
+            return result;
         }
 
         Date monday1 = DateUtil.getWeekDayWithDate(allCourseDates.get(0), Calendar.MONDAY);
         Date sunday1 = DateUtil.getWeekDayWithDate(allCourseDates.get(0), Calendar.SUNDAY);
         int tp1 = courseScheduleDao.countTeacherPracticeCourse(practiceGroup.getUserId(), monday1, sunday1);
-        if(Objects.nonNull(maxTeacherCourses)&&tp1>=maxTeacherCourses){
+        if (Objects.nonNull(maxTeacherCourses) && tp1 >= maxTeacherCourses) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "TEACHER_PRACTICE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() +"」老师已被预约,请重新选择时段或更换老师后重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
             return result;
         }
 
         Date monday2 = DateUtil.getWeekDayWithDate(allCourseDates.get(1), Calendar.MONDAY);
         Date sunday2 = DateUtil.getWeekDayWithDate(allCourseDates.get(1), Calendar.SUNDAY);
         int tp2 = courseScheduleDao.countTeacherPracticeCourse(practiceGroup.getUserId(), monday2, sunday2);
-        if(Objects.nonNull(maxTeacherCourses)&&tp2>=maxTeacherCourses){
+        if (Objects.nonNull(maxTeacherCourses) && tp2 >= maxTeacherCourses) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "TEACHER_PRACTICE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() +"」老师已被预约,请重新选择时段或更换老师后重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
             return result;
         }
 
         Date monday3 = DateUtil.getWeekDayWithDate(allCourseDates.get(2), Calendar.MONDAY);
         Date sunday3 = DateUtil.getWeekDayWithDate(allCourseDates.get(2), Calendar.SUNDAY);
         int tp3 = courseScheduleDao.countTeacherPracticeCourse(practiceGroup.getUserId(), monday3, sunday3);
-        if(Objects.nonNull(maxTeacherCourses)&&tp3>=maxTeacherCourses){
+        if (Objects.nonNull(maxTeacherCourses) && tp3 >= maxTeacherCourses) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "TEACHER_PRACTICE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() +"」老师已被预约,请重新选择时段或更换老师后重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
             return result;
         }
 
         Date monday4 = DateUtil.getWeekDayWithDate(allCourseDates.get(3), Calendar.MONDAY);
         Date sunday4 = DateUtil.getWeekDayWithDate(allCourseDates.get(3), Calendar.SUNDAY);
         int tp4 = courseScheduleDao.countTeacherPracticeCourse(practiceGroup.getUserId(), monday4, sunday4);
-        if(Objects.nonNull(maxTeacherCourses)&&tp4>=maxTeacherCourses){
+        if (Objects.nonNull(maxTeacherCourses) && tp4 >= maxTeacherCourses) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "TEACHER_PRACTICE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() +"」老师已被预约,请重新选择时段或更换老师后重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
             return result;
         }
 
@@ -1621,7 +1739,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         List<CourseSchedule> courseSchedules9 = courseScheduleDao.findTeacherCoursesWithIncludeDateRange(practiceGroup.getUserId(), allCourseDates.get(3), DateUtil.addMinutes(allCourseDates.get(3), practiceCourseMinutes));
 
         if (!CollectionUtils.isEmpty(courseSchedules6) || !CollectionUtils.isEmpty(courseSchedules7)
-                ||!CollectionUtils.isEmpty(courseSchedules8) || !CollectionUtils.isEmpty(courseSchedules9)) {
+                || !CollectionUtils.isEmpty(courseSchedules8) || !CollectionUtils.isEmpty(courseSchedules9)) {
             if (courseSchedules6 == null) {
                 courseSchedules6 = new ArrayList<>();
             }
@@ -1641,7 +1759,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
                 if (courseSchedules6.get(i).getGroupType().equals(GroupType.PRACTICE)) {
                     TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                     result.put("status", "TEACHER_PRACTICE_REPEAT");
-                    result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() +"」老师已被预约,请选择其他时段或更换老师后重试。");
+                    result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请选择其他时段或更换老师后重试。");
                     return result;
                 }
             }
@@ -1785,28 +1903,28 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         if (!CollectionUtils.isEmpty(studentRepeatCourse1)) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "STUDENT_COURSE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「"+studentRepeatCourse1.get(0).getName()+"」时段冲突,请选择其他时段重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「" + studentRepeatCourse1.get(0).getName() + "」时段冲突,请选择其他时段重试。");
             return result;
         }
         List<CourseSchedule> studentRepeatCourse2 = courseScheduleDao.findStudentCoursesWithIncludeDateRange(practiceGroup.getStudentId(), allCourseDates.get(1), DateUtil.addMinutes(allCourseDates.get(1), practiceCourseMinutes));
         if (!CollectionUtils.isEmpty(studentRepeatCourse2)) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "STUDENT_COURSE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「"+studentRepeatCourse2.get(0).getName()+"」时段冲突,请选择其他时段重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「" + studentRepeatCourse2.get(0).getName() + "」时段冲突,请选择其他时段重试。");
             return result;
         }
         List<CourseSchedule> studentRepeatCourse3 = courseScheduleDao.findStudentCoursesWithIncludeDateRange(practiceGroup.getStudentId(), allCourseDates.get(2), DateUtil.addMinutes(allCourseDates.get(2), practiceCourseMinutes));
         if (!CollectionUtils.isEmpty(studentRepeatCourse3)) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "STUDENT_COURSE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「"+studentRepeatCourse3.get(0).getName()+"」时段冲突,请选择其他时段重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「" + studentRepeatCourse3.get(0).getName() + "」时段冲突,请选择其他时段重试。");
             return result;
         }
         List<CourseSchedule> studentRepeatCourse4 = courseScheduleDao.findStudentCoursesWithIncludeDateRange(practiceGroup.getStudentId(), allCourseDates.get(3), DateUtil.addMinutes(allCourseDates.get(3), practiceCourseMinutes));
         if (!CollectionUtils.isEmpty(studentRepeatCourse4)) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             result.put("status", "STUDENT_COURSE_REPEAT");
-            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「"+studentRepeatCourse4.get(0).getName()+"」时段冲突,请选择其他时段重试。");
+            result.put("info", "抱歉啦,当前所选时段组合,与您现有课程「" + studentRepeatCourse4.get(0).getName() + "」时段冲突,请选择其他时段重试。");
             return result;
         }
         courseScheduleStudentPaymentDao.batchInsert(courseScheduleStudentPayments);
@@ -1817,7 +1935,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         List<CourseSchedule> courseSchedules3 = courseScheduleDao.findTeacherCoursesWithIncludeDateRange(practiceGroup.getUserId(), allCourseDates.get(2), DateUtil.addMinutes(allCourseDates.get(2), practiceCourseMinutes));
         List<CourseSchedule> courseSchedules5 = courseScheduleDao.findTeacherCoursesWithIncludeDateRange(practiceGroup.getUserId(), allCourseDates.get(3), DateUtil.addMinutes(allCourseDates.get(3), practiceCourseMinutes));
         if (!CollectionUtils.isEmpty(courseSchedules1) || !CollectionUtils.isEmpty(courseSchedules2)
-                ||!CollectionUtils.isEmpty(courseSchedules3) || !CollectionUtils.isEmpty(courseSchedules5)) {
+                || !CollectionUtils.isEmpty(courseSchedules3) || !CollectionUtils.isEmpty(courseSchedules5)) {
             if (courseSchedules1 == null) {
                 courseSchedules1 = new ArrayList<>();
             }
@@ -1842,7 +1960,7 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
                     } else {
                         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                         result.put("status", "TEACHER_PRACTICE_REPEAT");
-                        result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() +"」老师已被预约,请选择其他时段或更换老师后重试。");
+                        result.put("info", "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请选择其他时段或更换老师后重试。");
                         return result;
                     }
                 }
@@ -1963,4 +2081,796 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         return result;
     }
 
+    @Override
+    public PracticeGroup findUserLatestPracticeGroup(Integer userId) {
+        return practiceGroupDao.findUserLatestPracticeGroup(userId);
+    }
+
+    @Override
+    public Map getPayPracticeApplyParams(Integer userId, Integer organId) {
+        Map result = new HashMap();
+        SysConfig practiceSubjectIdListConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_SUBJECT_ID_LIST);
+        SysConfig practiceApplyStartTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_START_TIME);
+        SysConfig practiceApplyEndTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_END_TIME);
+        SysConfig practiceApplyIntervalTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_INTERVAL_TIME);
+        SysConfig practiceCourseMinutesConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_COURSE_MINUTES);
+        SysConfig practicePayMaxMonthConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_PAY_MAX_MONTH);
+        SysConfig practicePayDrillTimesOnOneWeekConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_PAY_DRILL_TIMES_ON_ONE_WEEK);
+        Student student = studentDao.get(userId);
+        List<Subject> subjects = subjectDao.findBySubjectByIdList(practiceSubjectIdListConfig.getParanValue());
+        List<Integer> subjectIds = Arrays.asList(practiceSubjectIdListConfig.getParanValue().split(",")).stream().mapToInt(idStr -> Integer.valueOf(idStr)).boxed().collect(Collectors.toList());
+        List<Integer> userDefaultSubjectIds = Objects.isNull(student) || Objects.isNull(student.getSubjectIdList()) ? null : Arrays.asList(student.getSubjectIdList().split(",")).stream().mapToInt(idStr -> Integer.valueOf(idStr)).boxed().collect(Collectors.toList());
+        if (!CollectionUtils.isEmpty(userDefaultSubjectIds)) {
+            userDefaultSubjectIds = userDefaultSubjectIds.stream().filter(userDefaultSubjectId -> subjectIds.contains(userDefaultSubjectId)).collect(Collectors.toList());
+        } else {
+            userDefaultSubjectIds = new ArrayList<>();
+        }
+        PracticeGroupSellPrice practiceGroupSellPrice = practiceGroupSellPriceDao.get(organId);
+        result.put("subjects", subjects);
+        result.put("practiceApplyStartTime", practiceApplyStartTimeConfig.getParanValue());
+        result.put("practiceApplyEndTime", practiceApplyEndTimeConfig.getParanValue());
+        result.put("userDefaultSubjectIds", StringUtils.join(userDefaultSubjectIds.toArray(), ","));
+        result.put("practiceApplyIntervalMinutes", practiceApplyIntervalTimeConfig.getParanValue(Integer.class));
+        result.put("practiceCourseMinutes", practiceCourseMinutesConfig.getParanValue(Integer.class));
+        result.put("practicePayMaxMonth", practicePayMaxMonthConfig.getParanValue(Integer.class));
+        result.put("practicePayDrillTimesOnOneWeek", practicePayDrillTimesOnOneWeekConfig.getParanValue(Integer.class));
+        result.put("practiceGroupSellPrice", practiceGroupSellPrice);
+        return result;
+    }
+
+    @Override
+    public List<SimpleUserDto> getEnableApplyTeachersWithPay(Integer userId, Integer subjectId) {
+        if (Objects.isNull(subjectId)) {
+            throw new BizException("请选择声部");
+        }
+        SysUser sysUser = sysUserFeignService.queryUserById(userId);
+        if (Objects.isNull(sysUser)) {
+            throw new BizException("用户不存在");
+        }
+        if (Objects.isNull(sysUser.getOrganId())) {
+            throw new BizException("未找到用户分部属性");
+        }
+
+        if (sysUser.getOrganId().equals(DALIAN_ORGAN_ID)) {
+            sysUser.setOrganId(SHENYANG_ORGAN_ID);
+        }
+
+        List<Integer> includeTeacherIds = new ArrayList<>();
+        List<ExtendTeacherBasicDto> organAndSubjectTeachers = teacherDao.findTeaTeachersByOrganAndSubject2(sysUser.getOrganId(), subjectId);
+        if (CollectionUtils.isEmpty(organAndSubjectTeachers)) {
+            return new ArrayList<>();
+        }
+
+        List<Integer> allTeacherIds = organAndSubjectTeachers.stream().map(TeacherBasicDto::getId).collect(Collectors.toList());
+
+        List<CourseSchedule> userCourses = courseScheduleDao.findUserCourses(userId, allTeacherIds);
+
+        if (!CollectionUtils.isEmpty(userCourses)) {
+            Map<CourseSchedule.CourseScheduleType, List<CourseSchedule>> courseTypeCourseMap = userCourses.stream().collect(Collectors.groupingBy(CourseSchedule::getType));
+            List<CourseSchedule> vipCourses = courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.VIP);
+            if (!CollectionUtils.isEmpty(vipCourses)) {
+                for (CourseSchedule vipCourse : vipCourses) {
+                    if (!includeTeacherIds.contains(vipCourse.getTeacherId())) {
+                        includeTeacherIds.add(vipCourse.getTeacherId());
+                    }
+                }
+            }
+            List<CourseSchedule> singleCourses = courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.SINGLE);
+            if (!CollectionUtils.isEmpty(singleCourses)) {
+                for (CourseSchedule singleCourse : singleCourses) {
+                    if (!includeTeacherIds.contains(singleCourse.getTeacherId())) {
+                        includeTeacherIds.add(singleCourse.getTeacherId());
+                    }
+                }
+            }
+            List<CourseSchedule> highCourses = courseTypeCourseMap.get(CourseSchedule.CourseScheduleType.HIGH);
+            if (!CollectionUtils.isEmpty(highCourses)) {
+                for (CourseSchedule highCourse : highCourses) {
+                    if (!includeTeacherIds.contains(highCourse.getTeacherId())) {
+                        includeTeacherIds.add(highCourse.getTeacherId());
+                    }
+                }
+            }
+        }
+
+        for (ExtendTeacherBasicDto organAndSubjectTeacher : organAndSubjectTeachers) {
+            if (!includeTeacherIds.contains(organAndSubjectTeacher.getId())
+                    && 1 == organAndSubjectTeacher.getIsSupportExtraPracticeLesson()) {
+                includeTeacherIds.add(organAndSubjectTeacher.getId());
+            }
+        }
+
+        if (CollectionUtils.isEmpty(new ArrayList<>(includeTeacherIds))) {
+            return new ArrayList<>();
+        }
+
+        List<SimpleUserDto> userInfos = new ArrayList<>();
+        Map<Integer, ExtendTeacherBasicDto> idTeacherMap = organAndSubjectTeachers.stream().collect(Collectors.toMap(ExtendTeacherBasicDto::getId, teacher -> teacher));
+        for (Integer includeTeacherId : includeTeacherIds) {
+            ExtendTeacherBasicDto teacher = idTeacherMap.get(includeTeacherId);
+            SimpleUserDto simpleUserDto=new SimpleUserDto(includeTeacherId, teacher.getRealName());
+            simpleUserDto.setAvatar(teacher.getAvatar());
+            simpleUserDto.setIntroduction(teacher.getIntroduction());
+            simpleUserDto.setSubjectNames(teacher.getSubjectNames());
+            userInfos.add(simpleUserDto);
+        }
+
+        return userInfos;
+    }
+
+    @Override
+    public Map<Integer, List<String>> getEnableApplyDatesWithWeek() {
+        Map<Integer, List<String>> result = new HashMap<>();
+        SysConfig practiceApplyStartTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_START_TIME);
+        SysConfig practiceApplyEndTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_END_TIME);
+        SysConfig practiceApplyIntervalTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_INTERVAL_TIME);
+        Integer practiceApplyIntervalMinutes = practiceApplyIntervalTimeConfig.getParanValue(Integer.class);
+        LocalTime dayStartTime=LocalTime.parse(practiceApplyStartTimeConfig.getParanValue(),DateUtil.timeFormatter);
+        LocalTime dayEndTime=LocalTime.parse(practiceApplyEndTimeConfig.getParanValue(),DateUtil.timeFormatter);
+        List<String> dayApplyTimes=new ArrayList<>();
+        while (dayEndTime.isAfter(dayStartTime)){
+            dayApplyTimes.add(dayStartTime.format(DateUtil.timeFormatter));
+            dayStartTime=dayStartTime.plusMinutes(practiceApplyIntervalMinutes);
+        }
+        for (int i = 1; i <= 7; i++) {
+            List<String> tempTimes = new ArrayList<>();
+            for (String applyDayTime : dayApplyTimes) {
+                tempTimes.add(applyDayTime);
+            }
+            result.put(i, tempTimes);
+        }
+        return result;
+    }
+
+    @Override
+    public Map getPayPracticeTeacherFreeTimes(Integer userId, Integer teacherId, Integer buyMonths, Date firstClassTime) {
+        if (Objects.isNull(teacherId)) {
+            throw new BizException("请选择教师");
+        }
+        SysUser student = sysUserFeignService.queryUserById(userId);
+        if (Objects.isNull(student)) {
+            throw new BizException("用户不存在");
+        }
+        if (Objects.isNull(student.getOrganId())) {
+            throw new BizException("未找到用户分部属性");
+        }
+        Teacher teacher = teacherDao.get(teacherId);
+        if (Objects.isNull(teacher)) {
+            throw new BizException("教师不存在");
+        }
+        Map result = new HashMap();
+        Set<Integer> disableApplyWeekDay = new HashSet<>();
+
+        SysConfig practiceCourseMinutesConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_COURSE_MINUTES);
+        Integer practiceCourseMinutes = practiceCourseMinutesConfig.getParanValue(Integer.class);
+
+        boolean checkTeacherLeaveDate = true;
+        SysConfig allTeacherLeaveDataConfig = sysConfigService.findByParamName(SysConfigService.TEACHER_LEAVE_DATA);
+        JSONObject allTeacherLeaveData = JSONObject.parseObject(allTeacherLeaveDataConfig.getParanValue());
+        if (Objects.isNull(allTeacherLeaveData)) {
+            checkTeacherLeaveDate = false;
+        }
+
+        TeacherFreeTime teacherFreeTime = teacherFreeTimeDao.findTeacherFreeTime(teacherId);
+        JSONObject teacherFreeTimes=new JSONObject();
+        Integer maxTeacherCourses = null;
+        int holiday = 0;
+        if (Objects.nonNull(teacherFreeTime)) {
+            if (Objects.nonNull(teacherFreeTime.getTotalTimes())) {
+                maxTeacherCourses = teacherFreeTime.getTotalTimes();
+            }
+            if (Objects.nonNull(teacherFreeTime.getHoliday())) {
+                holiday = teacherFreeTime.getHoliday();
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getMonday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.MONDAY.getValue()), JSON.parseArray(teacherFreeTime.getMonday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.MONDAY.getValue());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getTuesday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.TUESDAY.getValue()), JSON.parseArray(teacherFreeTime.getTuesday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.TUESDAY.getValue());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getWednesday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.WEDNESDAY.getValue()), JSON.parseArray(teacherFreeTime.getWednesday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.WEDNESDAY.getValue());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getThursday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.THURSDAY.getValue()), JSON.parseArray(teacherFreeTime.getThursday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.THURSDAY.getValue());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getFriday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.FRIDAY.getValue()), JSON.parseArray(teacherFreeTime.getFriday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.FRIDAY.getValue());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getSaturday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.SATURDAY.getValue()), JSON.parseArray(teacherFreeTime.getSaturday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.SATURDAY.getValue());
+            }
+            if(StringUtils.isNotBlank(teacherFreeTime.getSunday())){
+                teacherFreeTimes.put(String.valueOf(DayOfWeek.SUNDAY.getValue()), JSON.parseArray(teacherFreeTime.getSunday()));
+            }else{
+                disableApplyWeekDay.add(DayOfWeek.SUNDAY.getValue());
+            }
+        }
+
+        DateTimeFormatter ddtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        DateTimeFormatter ddf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
+        WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 1);
+        ZoneId zoneId = ZoneId.systemDefault();
+
+        LocalDateTime now = LocalDateTime.now();
+        now.plusDays(1);
+        Date applyStartDate = Date.from(now.atZone(zoneId).toInstant());
+        now.plusMonths(buyMonths);
+        Date applyEndDate = Date.from(now.atZone(zoneId).toInstant());
+        Date firstMonday = DateUtil.getWeekDayWithDate(applyStartDate, Calendar.MONDAY);
+        Date secondSunday = DateUtil.getWeekDayWithDate(applyEndDate, Calendar.SUNDAY);
+
+        Map<Integer, List<String>> weekNumApplyTimesMap = getEnableApplyDatesWithWeek();
+        List<CourseSchedule> allTeacherCourses = courseScheduleDao.findTeacherCoursesWithDateRange(teacherId, firstMonday, secondSunday);
+        allTeacherCourses.sort(Comparator.comparing(CourseSchedule::getStartClassTime));
+
+        JSONObject teacherLeaveData = null;
+        if (checkTeacherLeaveDate) {
+            teacherLeaveData = allTeacherLeaveData.getJSONObject(teacherId.toString());
+        }
+
+        if (Objects.isNull(teacherLeaveData)) {
+            checkTeacherLeaveDate = false;
+        }
+
+        if (Objects.nonNull(firstClassTime)) {
+            LocalDateTime localFirstClassTime = LocalDateTime.ofInstant(firstClassTime.toInstant(), zoneId);
+            weekNumApplyTimesMap.remove(localFirstClassTime.getDayOfWeek().getValue());
+        }
+        weekNumApplyTimesMap.remove(holiday);
+
+        if (teacherId == 100473) {
+            List<String> timeStrs = weekNumApplyTimesMap.get(DateUtil.calendarWeekNumNormalWeekNumMap.get(Calendar.MONDAY));
+            LocalTime noonStartTime = LocalTime.parse("11:30:00", dtf);
+            LocalTime noonEndTime = LocalTime.parse("14:30:00", dtf);
+            LocalTime nightStartTime = LocalTime.parse("20:30:00", dtf);
+            LocalTime defaultApplyTime;
+            Iterator<String> iterator = timeStrs.iterator();
+            while (iterator.hasNext()) {
+                defaultApplyTime = LocalTime.parse(iterator.next(), dtf);
+                LocalTime defaultApplyEndTime = defaultApplyTime.plusMinutes(practiceCourseMinutes);
+                if (defaultApplyTime.compareTo(noonStartTime) <= 0
+                        && defaultApplyEndTime.compareTo(noonEndTime) >= 0) {
+                    iterator.remove();
+                    continue;
+                }
+                if (defaultApplyEndTime.compareTo(nightStartTime) < 0) {
+                    iterator.remove();
+                    continue;
+                }
+            }
+            weekNumApplyTimesMap.remove(DateUtil.calendarWeekNumNormalWeekNumMap.get(Calendar.SATURDAY));
+            weekNumApplyTimesMap.put(DateUtil.calendarWeekNumNormalWeekNumMap.get(Calendar.MONDAY), timeStrs);
+            weekNumApplyTimesMap.put(DateUtil.calendarWeekNumNormalWeekNumMap.get(Calendar.SUNDAY), timeStrs);
+        } else if (checkTeacherLeaveDate) {
+            for (String dateStr : teacherLeaveData.keySet()) {
+                LocalDate parse = LocalDate.parse(dateStr, ddf);
+                List<String> applyTimeStrs = weekNumApplyTimesMap.get(parse.getDayOfWeek().getValue());
+                Iterator<String> iterator = applyTimeStrs.iterator();
+                JSONObject leaveDateData = teacherLeaveData.getJSONObject(dateStr);
+                LocalTime leaveStartTime = LocalDateTime.parse(leaveDateData.getString("leave_start_time"), ddtf).toLocalTime();
+                LocalTime leaveEndTime = LocalDateTime.parse(leaveDateData.getString("leave_end_time"), ddtf).toLocalTime();
+                LocalTime defaultApplyTime;
+                while (iterator.hasNext()) {
+                    defaultApplyTime = LocalTime.parse(iterator.next(), dtf);
+                    LocalTime defaultApplyEndTime = defaultApplyTime.plusMinutes(practiceCourseMinutes);
+                    if (defaultApplyTime.compareTo(leaveStartTime) <= 0
+                            && defaultApplyEndTime.compareTo(leaveEndTime) >= 0) {
+                        iterator.remove();
+                        continue;
+                    }
+                }
+                weekNumApplyTimesMap.put(parse.getDayOfWeek().getValue(), applyTimeStrs);
+            }
+        }
+
+        Iterator<Integer> weekNumApplyTimeIterator = weekNumApplyTimesMap.keySet().iterator();
+        while (weekNumApplyTimeIterator.hasNext()) {
+            Integer weekNum=weekNumApplyTimeIterator.next();
+            JSONArray teacherWeekDayFreeTimes = teacherFreeTimes.getJSONArray(String.valueOf(weekNum));
+            if(Objects.nonNull(teacherWeekDayFreeTimes)){
+                List<String> applyTimeStrs = weekNumApplyTimesMap.get(weekNum);
+                Iterator<String> iterator = applyTimeStrs.iterator();
+                while (iterator.hasNext()) {
+                    LocalTime enableApplyStartTime=LocalTime.parse(iterator.next(), dtf);
+                    LocalTime enableApplyEndTime=enableApplyStartTime.plusMinutes(practiceCourseMinutes);
+                    boolean isInclude=false;
+                    for (Object teacherWeekDayFreeTimeObject : teacherWeekDayFreeTimes) {
+                        JSONObject teacherWeekDayFreeTime=JSONObject.parseObject(teacherWeekDayFreeTimeObject.toString());
+                        LocalTime teacherFreeStartTime=LocalTime.parse(teacherWeekDayFreeTime.getString("startTime"),DateUtil.timeFormatter);
+                        LocalTime teacherFreeEndTime=LocalTime.parse(teacherWeekDayFreeTime.getString("endTime"),DateUtil.timeFormatter);
+                        if(enableApplyEndTime.compareTo(teacherFreeEndTime)<=0
+                                &&enableApplyStartTime.compareTo(teacherFreeStartTime)>=0){
+                            isInclude=true;
+                            break;
+                        }
+                    }
+                    if(!isInclude){
+                        iterator.remove();
+                    }
+                }
+                weekNumApplyTimesMap.put(weekNum,applyTimeStrs);
+            }else{
+                weekNumApplyTimeIterator.remove();
+            }
+        }
+
+        if (CollectionUtils.isEmpty(allTeacherCourses)) {
+            result.put("teacherFreeDays", weekNumApplyTimesMap);
+            return result;
+        }
+
+        int courseWeekNum = 0;
+        int practiceCourseNum = 0;
+        boolean hasDisableWeek = false;
+        LocalDateTime tempClassDateTime;
+        for (int i = 0; i < allTeacherCourses.size(); i++) {
+            CourseSchedule teacherCourse = allTeacherCourses.get(i);
+            tempClassDateTime = LocalDateTime.ofInstant(teacherCourse.getClassDate().toInstant(), zoneId);
+            if (i == 0 && teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
+                practiceCourseNum += 1;
+                courseWeekNum = tempClassDateTime.get(weekFields.weekOfYear());
+            }
+            if (Objects.nonNull(maxTeacherCourses) && practiceCourseNum >= maxTeacherCourses) {
+                hasDisableWeek = true;
+                break;
+            }
+            if (tempClassDateTime.get(weekFields.weekOfYear()) != courseWeekNum) {
+                courseWeekNum = tempClassDateTime.get(weekFields.weekOfYear());
+                practiceCourseNum = 0;
+            }
+            if (teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
+                practiceCourseNum += 1;
+            }
+        }
+
+        if (hasDisableWeek) {
+            result.put("teacherFreeDays", new HashMap<>());
+            return result;
+        }
+
+        for (CourseSchedule teacherCourse : allTeacherCourses) {
+            LocalDateTime courseStartTime = LocalDateTime.ofInstant(teacherCourse.getStartClassTime().toInstant(), zoneId);
+            LocalDateTime courseEndTime = LocalDateTime.ofInstant(teacherCourse.getEndClassTime().toInstant(), zoneId);
+            List<String> applyTimeStrs = weekNumApplyTimesMap.get(courseStartTime.getDayOfWeek().getValue());
+            if (CollectionUtils.isEmpty(applyTimeStrs)) {
+                continue;
+            }
+            Iterator<String> iterator = applyTimeStrs.iterator();
+            LocalTime defaultApplyTime;
+            while (iterator.hasNext()) {
+                defaultApplyTime = LocalTime.parse(iterator.next(), dtf);
+                LocalTime defaultApplyEndTime = defaultApplyTime.plusMinutes(practiceCourseMinutes);
+                if (defaultApplyTime.compareTo(courseEndTime.toLocalTime()) <= 0
+                        && defaultApplyEndTime.compareTo(courseStartTime.toLocalTime()) >= 0) {
+                    iterator.remove();
+                    continue;
+                }
+            }
+            weekNumApplyTimesMap.put(courseStartTime.getDayOfWeek().getValue(), applyTimeStrs);
+        }
+        result.put("teacherFreeDays", weekNumApplyTimesMap);
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public HttpResponseResult buyPracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams) {
+        if (Objects.isNull(practiceGroupBuyParams.getUserId())) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "请选择教师");
+        }
+        if (Objects.isNull(practiceGroupBuyParams.getSubjectId())) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "请选择声部");
+        }
+        if (Objects.isNull(practiceGroupBuyParams.getBuyMonths())) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "请选择需要购买的月数");
+        }
+        if (Objects.isNull(practiceGroupBuyParams.getDrillTimesOnWeek())) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "请选择单周陪练次数");
+        }
+        if (CollectionUtils.isEmpty(practiceGroupBuyParams.getDrillTimes())) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "请选择训练时间");
+        }
+        if (practiceGroupBuyParams.getDrillTimesOnWeek() != practiceGroupBuyParams.getDrillTimes().size()) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED,"训练时间与陪练次数不匹配");
+        }
+
+        SysUser sysUser = sysUserFeignService.queryUserById(practiceGroupBuyParams.getStudentId());
+
+        Subject subject = subjectDao.get(practiceGroupBuyParams.getSubjectId());
+        if (Objects.isNull(subject)) {
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "预约失败,声部选择错误,请重试。");
+        }
+
+        Teacher teacher = teacherService.getDetail(practiceGroupBuyParams.getUserId());
+        if (Objects.isNull(teacher)) {
+            throw new BizException("老师不存在");
+        }
+
+        SysConfig practiceCourseMinutesConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_COURSE_MINUTES);
+        Integer practiceCourseMinutes = practiceCourseMinutesConfig.getParanValue(Integer.class);
+        SysConfig practiceCourseSalaryConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_COURSE_SALARY);
+        SysConfig practiceBuyActivityExpireDateConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_BUY_ACTIVITY_EXPIRE_DATE);
+        Date practiceBuyActivityExpireDate=DateUtil.stringToDate(practiceBuyActivityExpireDateConfig.getParanValue(),"yyyy-MM-dd HH:mm:ss");
+
+        Date now=new Date();
+        PracticeGroup userLatestPracticeGroup = practiceGroupDao.findUserLatestPracticeGroup(practiceGroupBuyParams.getUserId());
+        LocalDate courseStartDay=LocalDate.now();
+        if(Objects.nonNull(userLatestPracticeGroup)){
+            LocalDate lastExpiredDay=LocalDateTime.ofInstant(userLatestPracticeGroup.getCoursesExpireDate().toInstant(),DateUtil.zoneId).toLocalDate();
+            if(Objects.nonNull(lastExpiredDay)&&lastExpiredDay.compareTo(courseStartDay)>=0){
+                courseStartDay=lastExpiredDay;
+            }
+        }
+        courseStartDay=courseStartDay.plusDays(1);
+        Date courseStartDate=Date.from(courseStartDay.atStartOfDay(DateUtil.zoneId).toInstant());
+        practiceGroupBuyParams.setCoursesStartDate(courseStartDate);
+        LocalDate currentExpiredDay = courseStartDay.plusMonths(practiceGroupBuyParams.getBuyMonths());
+        Date courseExpiredDate=Date.from(currentExpiredDay.atStartOfDay(DateUtil.zoneId).toInstant());
+        practiceGroupBuyParams.setCoursesStartDate(courseExpiredDate);
+
+        LocalDate courseStartMonday=courseStartDay.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue());
+        LocalDate courseExpiredSunday=currentExpiredDay.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.SUNDAY.getValue());
+        Date courseStartMondayDate = Date.from(courseStartMonday.atStartOfDay(DateUtil.zoneId).toInstant());
+        Date courseExpiredSundayDate = Date.from(courseExpiredSunday.atStartOfDay(DateUtil.zoneId).toInstant());
+
+        List<CourseSchedule> allTeacherCourses = courseScheduleDao.findTeacherCoursesWithDateRange(practiceGroupBuyParams.getUserId(), courseStartMondayDate, courseExpiredSundayDate);
+
+        TeacherFreeTime teacherFreeTime = teacherFreeTimeDao.findTeacherFreeTime(practiceGroupBuyParams.getUserId());
+        Integer maxTeacherCourses = null;
+        if (Objects.nonNull(teacherFreeTime)) {
+            if (Objects.nonNull(teacherFreeTime.getTotalTimes())) {
+                maxTeacherCourses = teacherFreeTime.getTotalTimes();
+            }
+        }
+        int courseWeekNum = 0;
+        int practiceCourseNum = 0;
+        LocalDateTime tempClassDateTime;
+        for (int i = 0; i < allTeacherCourses.size(); i++) {
+            CourseSchedule teacherCourse = allTeacherCourses.get(i);
+            tempClassDateTime = LocalDateTime.ofInstant(teacherCourse.getClassDate().toInstant(), DateUtil.zoneId);
+            if (i == 0 && teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
+                practiceCourseNum += 1;
+                courseWeekNum = tempClassDateTime.get(DateUtil.weekFields.weekOfYear());
+            }
+            if (Objects.nonNull(maxTeacherCourses) && practiceCourseNum >= maxTeacherCourses) {
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                return BaseController.failed(HttpStatus.MULTIPLE_CHOICES,"抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
+            }
+            if (tempClassDateTime.get(DateUtil.weekFields.weekOfYear()) != courseWeekNum) {
+                courseWeekNum = tempClassDateTime.get(DateUtil.weekFields.weekOfYear());
+                practiceCourseNum = 0;
+            }
+            if (teacherCourse.getGroupType().equals(GroupType.PRACTICE)) {
+                practiceCourseNum += 1;
+            }
+        }
+        allTeacherCourses=new ArrayList<>();
+
+        practiceGroupBuyParams.setName(subject.getName() + "•" + sysUser.getUsername());
+
+        List<CourseSchedule> practiceCourses = createPracticeCourses(practiceGroupBuyParams, practiceCourseMinutes);
+
+        JSONObject drillTimesObject=new JSONObject();
+        for (PracticeDrillTimeDto drillTime : practiceGroupBuyParams.getDrillTimes()) {
+            drillTimesObject.put(String.valueOf(drillTime.getWeekNum()),drillTime.getTimeStr());
+        }
+
+        PracticeGroupSellPrice practiceGroupSellPrice = practiceGroupSellPriceDao.get(sysUser.getOrganId());
+        BigDecimal oneMonthPrice;
+        if(practiceBuyActivityExpireDate.after(now)){
+            oneMonthPrice=practiceGroupBuyParams.getDrillTimesOnWeek()==1?practiceGroupSellPrice.getOnceActivityPrice():practiceGroupSellPrice.getTwiceActivityPrice();
+        }else{
+            oneMonthPrice=practiceGroupBuyParams.getDrillTimesOnWeek()==1?practiceGroupSellPrice.getOnceOriginalPrice():practiceGroupSellPrice.getTwiceOriginalPrice();
+        }
+        BigDecimal amount= oneMonthPrice.multiply(new BigDecimal(practiceGroupBuyParams.getBuyMonths()));
+
+        practiceGroupBuyParams.setDrillTimesJson(drillTimesObject.toJSONString());
+        practiceGroupBuyParams.setOrganId(sysUser.getOrganId());
+        practiceGroupBuyParams.setSingleClassMinutes(practiceCourseMinutes);
+        practiceGroupDao.insert(practiceGroupBuyParams);
+
+        //创建班级信息
+        ClassGroup classGroup = new ClassGroup();
+        classGroup.setSubjectIdList(practiceGroupBuyParams.getSubjectId().toString());
+        classGroup.setExpectStudentNum(1);
+        classGroup.setStudentNum(1);
+        classGroup.setName(practiceGroupBuyParams.getName());
+        classGroup.setTotalClassTimes(practiceCourses.size());
+        classGroup.setType(ClassGroupTypeEnum.PRACTICE);
+        classGroup.setDelFlag(0);
+        classGroup.setGroupType(GroupType.PRACTICE);
+        classGroup.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+        classGroup.setCreateTime(now);
+        classGroup.setUpdateTime(now);
+        classGroupDao.insert(classGroup);
+
+        //创建班级老师关联记录
+        ClassGroupTeacherMapper classGroupTeacherMapper = new ClassGroupTeacherMapper();
+        classGroupTeacherMapper.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+        classGroupTeacherMapper.setClassGroupId(classGroup.getId());
+        classGroupTeacherMapper.setTeacherRole(TeachTypeEnum.BISHOP);
+        classGroupTeacherMapper.setUserId(practiceGroupBuyParams.getUserId());
+        classGroupTeacherMapper.setGroupType(GroupType.PRACTICE);
+        classGroupTeacherMapper.setCreateTime(now);
+        classGroupTeacherMapper.setUpdateTime(now);
+        classGroupTeacherMapperDao.insert(classGroupTeacherMapper);
+
+        //创建班级与老师课酬记录
+        ClassGroupTeacherSalary classGroupTeacherSalary = new ClassGroupTeacherSalary();
+        classGroupTeacherSalary.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+        classGroupTeacherSalary.setClassGroupId(classGroup.getId());
+        classGroupTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
+        classGroupTeacherSalary.setUserId(practiceGroupBuyParams.getUserId());
+        classGroupTeacherSalary.setSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue(Integer.class)));
+        classGroupTeacherSalary.setOnlineClassesSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue(Integer.class)));
+        classGroupTeacherSalary.setGroupType(GroupType.PRACTICE);
+        classGroupTeacherSalary.setCreateTime(now);
+        classGroupTeacherSalary.setUpdateTime(now);
+        classGroupTeacherSalaryDao.insert(classGroupTeacherSalary);
+
+        //班级学生关联表
+        ClassGroupStudentMapper classGroupStudentMapper = new ClassGroupStudentMapper();
+        classGroupStudentMapper.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+        classGroupStudentMapper.setClassGroupId(classGroup.getId());
+        classGroupStudentMapper.setUserId(practiceGroupBuyParams.getStudentId());
+        classGroupStudentMapper.setCreateTime(now);
+        classGroupStudentMapper.setStatus(ClassGroupStudentStatusEnum.NORMAL);
+        classGroupStudentMapper.setGroupType(GroupType.PRACTICE);
+        classGroupStudentMapperDao.insert(classGroupStudentMapper);
+
+        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = new ArrayList<>();
+        List<CourseScheduleStudentPayment> courseScheduleStudentPayments = new ArrayList<>();
+        List<TeacherAttendance> teacherAttendances = new ArrayList<>();
+
+        for (CourseSchedule courseSchedule : practiceCourses) {
+            //课表
+            courseSchedule.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+            courseSchedule.setClassGroupId(classGroup.getId());
+            courseSchedule.setStatus(CourseStatusEnum.NOT_START);
+            courseSchedule.setCreateTime(now);
+            courseSchedule.setUpdateTime(now);
+            courseSchedule.setTeachMode(TeachModeEnum.ONLINE);
+            courseSchedule.setType(CourseSchedule.CourseScheduleType.PRACTICE);
+            courseSchedule.setGroupType(GroupType.PRACTICE);
+            courseSchedule.setIsLock(1);
+        }
+        courseScheduleDao.batchAddCourseSchedules(practiceCourses);
+        for (CourseSchedule courseSchedule : practiceCourses) {
+            //课程与老师薪水表
+            CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
+            courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());
+            courseScheduleTeacherSalary.setGroupType(GroupType.PRACTICE);
+            courseScheduleTeacherSalary.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+            courseScheduleTeacherSalary.setTeacherRole(classGroupTeacherMapper.getTeacherRole());
+            courseScheduleTeacherSalary.setUserId(practiceGroupBuyParams.getUserId());
+            courseScheduleTeacherSalary.setExpectSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue()));
+            courseScheduleTeacherSalary.setCreateTime(now);
+            courseScheduleTeacherSalary.setUpdateTime(now);
+            courseScheduleTeacherSalary.setClassGroupId(classGroup.getId());
+            courseScheduleTeacherSalaries.add(courseScheduleTeacherSalary);
+
+            //学生缴费记录
+            CourseScheduleStudentPayment courseScheduleStudentPayment = new CourseScheduleStudentPayment();
+            courseScheduleStudentPayment.setGroupType(GroupType.PRACTICE);
+            courseScheduleStudentPayment.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+            courseScheduleStudentPayment.setCourseScheduleId(courseSchedule.getId());
+            courseScheduleStudentPayment.setUserId(practiceGroupBuyParams.getStudentId());
+            courseScheduleStudentPayment.setExpectPrice(BigDecimal.ZERO);
+            courseScheduleStudentPayment.setClassGroupId(classGroup.getId());
+            courseScheduleStudentPayment.setCreateTime(now);
+            courseScheduleStudentPayment.setUpdateTime(now);
+            courseScheduleStudentPayments.add(courseScheduleStudentPayment);
+
+            //教师签到记录
+            TeacherAttendance teacherAttendance = new TeacherAttendance();
+            teacherAttendance.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+            teacherAttendance.setTeacherId(practiceGroupBuyParams.getUserId());
+            teacherAttendance.setClassGroupId(classGroup.getId());
+            teacherAttendance.setGroupType(GroupType.PRACTICE);
+            teacherAttendance.setCourseScheduleId(courseSchedule.getId());
+            teacherAttendance.setCreateTime(now);
+            teacherAttendances.add(teacherAttendance);
+        }
+        courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaries);
+        teacherAttendanceDao.batchInsert(teacherAttendances);
+
+        try {
+            courseScheduleService.checkNewCourseSchedules(practiceCourses,false);
+        } catch (Exception e) {
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return BaseController.failed(HttpStatus.FOUND, "课程冲突");
+        }
+
+        StudentPaymentOrder studentPaymentOrder=new StudentPaymentOrder();
+        studentPaymentOrder.setUserId(practiceGroupBuyParams.getStudentId());
+        studentPaymentOrder.setGroupType(GroupType.PRACTICE);
+        String orderNo=idGeneratorService.generatorId("payment") + "";
+        studentPaymentOrder.setOrderNo(orderNo);
+        studentPaymentOrder.setStatus(DealStatusEnum.ING);
+        studentPaymentOrder.setType(OrderTypeEnum.SMALL_CLASS_TO_BUY);
+        studentPaymentOrder.setExpectAmount(amount);
+        studentPaymentOrder.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+        studentPaymentOrder.setActualAmount(studentPaymentOrder.getExpectAmount());
+        studentPaymentOrder.setClassGroupId(classGroup.getId());
+        studentPaymentOrder.setVersion(0);
+        studentPaymentOrderService.insert(studentPaymentOrder);
+
+        if(practiceGroupBuyParams.isUseBalancePayment() || studentPaymentOrder.getExpectAmount().doubleValue() == 0){
+            SysUserCashAccount userCashAccount = sysUserCashAccountService.getLocked(practiceGroupBuyParams.getStudentId());
+            if(userCashAccount == null){
+                throw new BizException("用户账户找不到");
+            }
+            studentPaymentOrder.setPaymentChannel("BALANCE");
+            if(userCashAccount.getBalance().subtract(studentPaymentOrder.getExpectAmount()).doubleValue() >= 0){
+                // 更新订单信息
+                studentPaymentOrder.setActualAmount(new BigDecimal(0));
+                studentPaymentOrder.setBalancePaymentAmount(studentPaymentOrder.getExpectAmount());
+                studentPaymentOrder.setStatus(DealStatusEnum.SUCCESS);
+                studentPaymentOrder.setUpdateTime(now);
+                studentPaymentOrder.setOrganId(practiceGroupBuyParams.getOrganId());
+
+                sysUserCashAccountService.updateBalance(practiceGroupBuyParams.getStudentId(), studentPaymentOrder.getExpectAmount().negate(),PlatformCashAccountDetailTypeEnum.PAY_FEE,"陪练课购买");
+
+                Map<String,Object> result=new HashMap<>();
+                result.put("orderNo",studentPaymentOrder.getOrderNo());
+
+                return BaseController.succeed();
+            }else{
+                if (userCashAccount.getBalance().doubleValue() > 0) {
+                    sysUserCashAccountService.updateBalance(practiceGroupBuyParams.getStudentId(), userCashAccount.getBalance().negate(), PlatformCashAccountDetailTypeEnum.PAY_FEE, "陪练课购买");
+                    amount = studentPaymentOrder.getExpectAmount().subtract(userCashAccount.getBalance());
+                    studentPaymentOrder.setActualAmount(amount);
+                    studentPaymentOrder.setBalancePaymentAmount(userCashAccount.getBalance());
+                } else {
+                    studentPaymentOrder.setBalancePaymentAmount(new BigDecimal(0));
+                }
+            }
+        }
+
+        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");
+        Map<String, BigDecimal> classFee = new HashMap<>();
+        classFee.put("course",amount);
+        classFee.put("instrument",BigDecimal.ZERO);
+        classFee.put("accessories",BigDecimal.ZERO);
+        classFee.put("other",BigDecimal.ZERO);
+        try {
+            Map<String,Object> payMap = payService.getPayMap(
+                    amount,
+                    orderNo,
+                    baseApiUrl+"/api-student/studentOrder/notify",
+                    baseApiUrl+"/api-student/studentOrder/paymentResult?orderNo=" + orderNo,
+                    "vip课购买",
+                    practiceGroupBuyParams.getName(),
+                    practiceGroupBuyParams.getStudentId(),
+                    classFee,
+                    practiceGroupBuyParams.getOrganId()
+            );
+
+            Map<String,BigDecimal> routingFee = (Map<String,BigDecimal>)payMap.get("routingFee");
+            studentPaymentOrder.setOrganId(practiceGroupBuyParams.getOrganId());
+            studentPaymentOrder.setComAmount(routingFee.get("COM"));
+            studentPaymentOrder.setPerAmount(routingFee.get("PER"));
+            studentPaymentOrder.setMerNos((String) payMap.get("routingMerNos"));
+            studentPaymentOrder.setPaymentChannel((String) payMap.get("type"));
+            studentPaymentOrder.setUpdateTime(now);
+            studentPaymentOrderService.update(studentPaymentOrder);
+
+            return BaseController.succeed(payMap);
+        } catch (Exception e) {
+            throw new BizException("调用支付接口出错", e);
+        }
+    }
+
+    private List<CourseSchedule> createPracticeCourses(PracticeGroupBuyDto practiceGroupBuyParams, Integer practiceCourseMinutes){
+        List<CourseSchedule> courseSchedules=new ArrayList<>();
+        LocalDate courseStartDay=LocalDateTime.ofInstant(practiceGroupBuyParams.getCoursesStartDate().toInstant(),DateUtil.zoneId).toLocalDate();
+        LocalDate courseEndDay=LocalDateTime.ofInstant(practiceGroupBuyParams.getCoursesExpireDate().toInstant(),DateUtil.zoneId).toLocalDate();
+        while (courseStartDay.compareTo(courseEndDay)<0){
+            int dayOfWeek = courseStartDay.get(DateUtil.weekFields.dayOfWeek());
+            for (PracticeDrillTimeDto drillTime : practiceGroupBuyParams.getDrillTimes()) {
+                if(dayOfWeek==drillTime.getWeekNum()){
+                    CourseSchedule courseSchedule=new CourseSchedule();
+                    String courseStartDayStr = DateUtil.dateFormatter.format(courseStartDay);
+                    String courseStartDateTimeStr = courseStartDayStr+" "+drillTime.getTimeStr();
+                    LocalDateTime courseStartDateTime = LocalDateTime.parse(courseStartDateTimeStr,DateUtil.dateTimeFormatter);
+                    LocalDateTime courseEndDateTime = courseStartDateTime.plusMinutes(practiceCourseMinutes);
+                    courseSchedule.setClassDate(Date.from(courseStartDay.atStartOfDay(DateUtil.zoneId).toInstant()));
+                    courseSchedule.setStartClassTime(Date.from(courseStartDateTime.atZone(DateUtil.zoneId).toInstant()));
+                    courseSchedule.setEndClassTime(Date.from(courseEndDateTime.atZone(DateUtil.zoneId).toInstant()));
+                    courseSchedule.setName(practiceGroupBuyParams.getName());
+                    courseSchedule.setTeacherId(practiceGroupBuyParams.getUserId());
+                    courseSchedule.setActualTeacherId(practiceGroupBuyParams.getUserId());
+                    courseSchedule.setTeachMode(TeachModeEnum.ONLINE);
+                    courseSchedule.setType(CourseSchedule.CourseScheduleType.PRACTICE);
+                    courseSchedule.setStatus(CourseStatusEnum.NOT_START);
+                    courseSchedules.add(courseSchedule);
+                }
+            }
+        }
+        return courseSchedules;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
+    public void orderCallback(StudentPaymentOrder order) {
+        StudentPaymentOrder studentPaymentOrder = studentPaymentOrderDao.get(order.getId());
+        if(studentPaymentOrder.getStatus().equals(DealStatusEnum.SUCCESS)){
+            return;
+        }
+        if(order.getStatus().equals(DealStatusEnum.SUCCESS)){
+            courseScheduleDao.updateGroupCourseLock(order.getMusicGroupId(),GroupType.PRACTICE,0);
+        }else{
+            groupService.deleteGroupInfo(order.getMusicGroupId(),GroupType.PRACTICE);
+        }
+        studentPaymentOrderDao.update(order);
+        SysUserCashAccount sysUserCashAccount = sysUserCashAccountService.get(order.getUserId());
+
+        //插入缴费明细
+        //收入
+        SysUserCashAccountDetail sysUserIncomeCashAccountDetail = new SysUserCashAccountDetail();
+        sysUserIncomeCashAccountDetail.setUserId(order.getUserId());
+        sysUserIncomeCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.RECHARGE);
+        sysUserIncomeCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
+        sysUserIncomeCashAccountDetail.setAmount(order.getActualAmount());
+        sysUserIncomeCashAccountDetail.setBalance(sysUserCashAccount.getBalance().add(order.getActualAmount()));
+        sysUserIncomeCashAccountDetail.setAttribute(order.getTransNo());
+        sysUserIncomeCashAccountDetail.setChannel(studentPaymentOrder.getPaymentChannel());
+        sysUserIncomeCashAccountDetail.setComAmount(studentPaymentOrder.getComAmount());
+        sysUserIncomeCashAccountDetail.setPerAmount(studentPaymentOrder.getPerAmount());
+
+        //支出
+        SysUserCashAccountDetail sysUserExpendCashAccountDetail = new SysUserCashAccountDetail();
+        sysUserExpendCashAccountDetail.setUserId(order.getUserId());
+        sysUserExpendCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.PAY_FEE);
+        sysUserExpendCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
+        sysUserExpendCashAccountDetail.setAmount(order.getActualAmount().negate());
+        sysUserExpendCashAccountDetail.setBalance(sysUserCashAccount.getBalance());
+        sysUserExpendCashAccountDetail.setAttribute(order.getTransNo());
+        sysUserExpendCashAccountDetail.setChannel(studentPaymentOrder.getPaymentChannel());
+        if(studentPaymentOrder.getComAmount() != null){
+            sysUserExpendCashAccountDetail.setComAmount(studentPaymentOrder.getComAmount().negate());
+        }
+        if(studentPaymentOrder.getPerAmount() != null){
+            sysUserExpendCashAccountDetail.setPerAmount(studentPaymentOrder.getPerAmount().negate());
+        }
+
+        sysUserCashAccountDetailService.insert(sysUserIncomeCashAccountDetail);
+        sysUserCashAccountDetailService.insert(sysUserExpendCashAccountDetail);
+    }
+
+    @Override
+    public List<PracticeCourseDto> findUserHistoryBuyPracticeGroups(Integer userId) {
+        List<PracticeCourseDto> userPracticeGroups = practiceGroupDao.findUserBuyPracticeGroups(userId);
+        SysConfig practiceCourseMinutesConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_COURSE_MINUTES);
+        Integer practiceCourseMinutes = practiceCourseMinutesConfig.getParanValue(Integer.class);
+        for (PracticeCourseDto userPracticeGroup : userPracticeGroups) {
+            JSONArray coursesArry=new JSONArray();
+            JSONObject courseJson=JSON.parseObject(userPracticeGroup.getDrillTimesJson());
+            for (String weekNumStr : courseJson.keySet()) {
+                JSONObject newCourseJson=new JSONObject();
+                newCourseJson.put("weekName",DateUtil.weekNumNormalWeekNameMap.get(Integer.parseInt(weekNumStr)));
+                LocalTime courseStartTime=LocalTime.parse(courseJson.getString(weekNumStr),DateUtil.timeFormatter);
+                LocalTime courseEndTime=courseStartTime.plusMinutes(practiceCourseMinutes);
+                newCourseJson.put("startTime",courseStartTime.format(DateUtil.timeFormatter));
+                newCourseJson.put("endTime",courseEndTime.format(DateUtil.timeFormatter));
+                coursesArry.add(newCourseJson);
+            }
+            userPracticeGroup.setDrillTimesJson(coursesArry.toJSONString());
+        }
+        return userPracticeGroups;
+    }
 }

+ 42 - 32
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentAttendanceServiceImpl.java

@@ -131,6 +131,9 @@ public class StudentAttendanceServiceImpl extends BaseServiceImpl<Long, StudentA
 							studentAttendanceInfo.getMusicGroupId(),
 							YesOrNoEnum.NO.getCode());
 				}
+				if(studentAttendanceInfo.getStatus() == StudentAttendanceStatusEnum.NORMAL){
+					studentAttendanceInfo.setSignInTime(date);
+				}
 				studentAttendanceDao.insert(studentAttendanceInfo);
 			}else{
 				studentFeeDao.updateStudentAbsenteeismTimes(studentAttendanceInfo.getUserId(),
@@ -439,43 +442,50 @@ public class StudentAttendanceServiceImpl extends BaseServiceImpl<Long, StudentA
 	}
 
 	@Override
-	public void addStudentAttendanceRecord(Integer courseScheduleId, Integer userId, StudentAttendanceStatusEnum statusEnum) {
+	public void addStudentAttendanceRecord(Integer courseScheduleId, Integer userId, StudentAttendanceStatusEnum statusEnum,SignStatusEnum signStatusEnum) {
+		CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
+		ClassGroup classGroup = classGroupDao.findByCourseSchedule(courseScheduleId);
 		StudentAttendance studentAttendance = studentAttendanceDao.findByStatusAndCourseScheduleId(userId,courseScheduleId);
+		Date date = new Date();
 		if(studentAttendance == null){
+			studentAttendance = new StudentAttendance();
+			studentAttendance.setClassGroupId(classGroup.getId());
+			studentAttendance.setCourseScheduleId(courseScheduleId.longValue());
+			studentAttendance.setCurrentClassTimes(classGroup.getCurrentClassTimes() + 1);
+			studentAttendance.setGroupType(classGroup.getGroupType());
+			studentAttendance.setMusicGroupId(classGroup.getMusicGroupId());
+			studentAttendance.setUserId(userId);
+			studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
+			studentAttendanceDao.insert(studentAttendance);
+		}else {
+			studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
+			studentAttendance.setUpdateTime(date);
+		}
+		//没有签到信息才会生成
+		if(signStatusEnum == SignStatusEnum.SIGN_IN && studentAttendance.getSignInTime() == null){
 			//判断是否在签到时间段内(课程开始前20~结束前)
-			CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId.longValue());
-			ClassGroup classGroup = classGroupDao.findByCourseSchedule(courseScheduleId);
-			if(classGroup != null && courseSchedule != null){
-//				int advanceSignMinutes = Integer.parseInt(sysConfigDao.findConfigValue(SysConfigService.ADVANCE_SIGN_IN_MINUTES));
-				Date date = new Date();
-				String classDate = DateUtil.format(courseSchedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
-				String startClassTime = DateUtil.format(courseSchedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-				String endClassTime = DateUtil.format(courseSchedule.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
-				//上课时间
-				Date classStartDateTime = DateUtil.stringToDate(classDate + " " + startClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-				Date classEndDateTime = DateUtil.stringToDate(classDate + " " + endClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
-				Date addMinutes = DateUtil.addMinutes(classStartDateTime, -60);
-				//课程结束前进入,算正常
-				if(DateUtil.minutesBetween(addMinutes,date) >= 0 && DateUtil.minutesBetween(date,classEndDateTime) > 0){
-					studentAttendance = new StudentAttendance();
-					studentAttendance.setClassGroupId(classGroup.getId());
-					studentAttendance.setCourseScheduleId(courseScheduleId.longValue());
-					studentAttendance.setCurrentClassTimes(classGroup.getCurrentClassTimes() + 1);
-					studentAttendance.setGroupType(classGroup.getGroupType());
-					studentAttendance.setMusicGroupId(classGroup.getMusicGroupId());
-					studentAttendance.setStatus(statusEnum);
-					studentAttendance.setUserId(userId);
-					studentAttendance.setTeacherId(courseSchedule.getActualTeacherId());
-
-					courseSchedule.setUpdateTime(date);
-					courseSchedule.setStudentNum((courseSchedule.getStudentNum() == null?0:courseSchedule.getStudentNum()) + 1);
-					courseScheduleDao.update(courseSchedule);
-					studentAttendanceDao.insert(studentAttendance);
-				}
-			}else {
-				throw new BizException("学员班级或课程信息异常");
+//			int advanceSignMinutes = Integer.parseInt(sysConfigDao.findConfigValue(SysConfigService.ADVANCE_SIGN_IN_MINUTES));
+			String classDate = DateUtil.format(courseSchedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
+			String startClassTime = DateUtil.format(courseSchedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+			String endClassTime = DateUtil.format(courseSchedule.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+			//上课时间
+			Date classStartDateTime = DateUtil.stringToDate(classDate + " " + startClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+			Date classEndDateTime = DateUtil.stringToDate(classDate + " " + endClassTime, DateUtil.EXPANDED_DATE_TIME_FORMAT);
+			Date addMinutes = DateUtil.addMinutes(classStartDateTime, -60);
+			//课程结束前进入,算正常
+			if(DateUtil.minutesBetween(addMinutes,date) >= 0 && DateUtil.minutesBetween(date,classEndDateTime) > 0){
+				studentAttendance.setStatus(statusEnum);
+				studentAttendance.setSignInTime(date);
+
+				courseSchedule.setUpdateTime(date);
+				courseSchedule.setStudentNum((courseSchedule.getStudentNum() == null?0:courseSchedule.getStudentNum()) + 1);
+				courseScheduleDao.update(courseSchedule);
 			}
+		}else if(signStatusEnum == SignStatusEnum.SIGN_OUT){
+			studentAttendance.setStatus(statusEnum);
+			studentAttendance.setSignOutTime(date);
 		}
+		studentAttendanceDao.update(studentAttendance);
 	}
 
 	@Override

+ 9 - 4
mec-biz/src/main/resources/config/mybatis/ClassGroupMapper.xml

@@ -79,6 +79,10 @@
         </trim>
     </insert>
 
+    <update id="deleteByGroup">
+        UPDATE class_group SET del_flag_ = 1,update_time_=NOW() WHERE music_group_id_=#{groupId} AND group_type_=#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+    </update>
+
     <!-- 根据主键查询一条记录 -->
     <select id="get" resultMap="ClassGroup">
         SELECT * FROM class_group WHERE id_ = #{id}
@@ -262,9 +266,9 @@
     <select id="queryUserGroups" resultMap="imGroupModel">
         SELECT cg.id_,cg.name_,cg.student_num_,cg.img_,mg.name_ group_name_ FROM class_group_student_mapper cgsm
         LEFT JOIN class_group cg ON cgsm.class_group_id_ = cg.id_
-        LEFT JOIN music_group mg ON mg.id_ = cg.music_group_id_ AND cg.group_type_ = 'MUSIC'
+        LEFT JOIN music_group mg ON mg.id_ = cg.music_group_id_
         <where>
-            cg.del_flag_ = 0 AND cgsm.status_ != 'QUIT'
+            cg.del_flag_ = 0 AND cgsm.status_ != 'QUIT' AND (mg.status_ = 'PROGRESS' OR mg.id_ IS NULL)
             <if test="userId != null">
                 AND cgsm.user_id_ = #{userId}
             </if>
@@ -354,8 +358,9 @@
     <select id="queryTeacherGroups" resultMap="imGroupModel">
         SELECT cg.id_,cg.name_,cg.student_num_,cg.img_,mg.name_ group_name_ FROM class_group_teacher_mapper cgtm
         LEFT JOIN class_group cg ON cgtm.class_group_id_ = cg.id_
-        LEFT JOIN music_group mg ON mg.id_ = cg.music_group_id_ AND cg.group_type_ = 'MUSIC'
-        WHERE (cgtm.user_id_ = #{userId} OR mg.team_teacher_id_ = #{userId} OR mg.educational_teacher_id_ = #{userId} OR mg.director_user_id_ = #{userId}) AND cg.del_flag_ = 0
+        LEFT JOIN music_group mg ON mg.id_ = cg.music_group_id_
+        WHERE (cgtm.user_id_ = #{userId} OR mg.team_teacher_id_ = #{userId} OR mg.educational_teacher_id_ = #{userId} OR mg.director_user_id_ = #{userId})
+         AND cg.del_flag_ = 0 AND (mg.status_ = 'PROGRESS' OR mg.id_ IS NULL)
         <if test="search != null">
             AND cg.name_ LIKE CONCAT('%',#{search},'%')
         </if>

+ 3 - 0
mec-biz/src/main/resources/config/mybatis/ClassGroupStudentMapperMapper.xml

@@ -63,6 +63,9 @@
     <delete id="deleteByClassId">
         UPDATE class_group_student_mapper SET status_='QUIT' WHERE class_group_id_ = #{classGroupId} AND status_='NORMAL'
     </delete>
+    <delete id="deleteByGroup">
+        UPDATE class_group_student_mapper SET status_='QUIT' WHERE music_group_id_=#{groupId} AND group_type_=#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+    </delete>
 
     <!-- 分页查询 -->
     <select id="queryPage" resultMap="ClassGroupStudentMapper" parameterType="map">

+ 14 - 5
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -141,17 +141,17 @@
         </selectKey>
         -->
         INSERT INTO course_schedule
-        (id_,group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_)
-        VALUES(#{id},#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{classGroupId},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{subsidy},#{classDate},#{startClassTime},#{endClassTime},#{teacherId},#{teacherId},now(),now(),#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{name},#{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{studentNum},#{leaveStudentNum},#{schoolId})
+        (id_,group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_,is_lock_)
+        VALUES(#{id},#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{classGroupId},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{subsidy},#{classDate},#{startClassTime},#{endClassTime},#{teacherId},#{teacherId},now(),now(),#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{name},#{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{studentNum},#{leaveStudentNum},#{schoolId},#{isLock})
     </insert>
 
     <insert id="batchAddCourseSchedules" parameterType="java.util.List" useGeneratedKeys="true" keyColumn="id"
             keyProperty="id">
         INSERT INTO course_schedule
-        (group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_)
+        (group_type_,music_group_id_,class_group_id_,status_,subsidy_,class_date_,start_class_time_,end_class_time_,teacher_id_,actual_teacher_id_,create_time_,update_time_,type_,name_,teach_mode_,student_num_,leave_student_num_,schoole_id_,is_lock_)
         VALUE
         <foreach collection="list" item="course" separator=",">
-            (#{course.groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.musicGroupId},#{course.classGroupId},#{course.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.subsidy},#{course.classDate},#{course.startClassTime},#{course.endClassTime},#{course.teacherId},#{course.teacherId},now(),now(),#{course.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.name},#{course.teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.studentNum},#{course.leaveStudentNum},#{course.schoolId})
+            (#{course.groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.musicGroupId},#{course.classGroupId},#{course.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.subsidy},#{course.classDate},#{course.startClassTime},#{course.endClassTime},#{course.teacherId},#{course.teacherId},now(),now(),#{course.type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.name},#{course.teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{course.studentNum},#{course.leaveStudentNum},#{course.schoolId},#{isLock})
         </foreach>
     </insert>
 
@@ -207,6 +207,9 @@
             <if test="teachMode != null">
                 teach_mode_ = #{teachMode,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>
+            <if test="isLock != null">
+                is_lock_ = #{isLock},
+            </if>
             update_time_ = NOW()
         </set>
         WHERE id_ = #{id}
@@ -1100,7 +1103,13 @@
     <update id="updateCourseSchoolByGroup">
         UPDATE course_schedule cs SET cs.schoole_id_ = #{schoolId},update_time_ = NOW()
         WHERE cs.music_group_id_ = #{groupId}
-        AND cs.group_type_ = #{groupType} AND NOW() &lt; CONCAT(cs.class_date_," ",cs.start_class_time_);
+        AND cs.group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} AND NOW() &lt; CONCAT(cs.class_date_," ",cs.start_class_time_);
+    </update>
+
+    <update id="updateGroupCourseLock">
+        UPDATE course_schedule SET is_lock_ = #{isLock},update_time_ = NOW()
+        WHERE music_group_id_ = #{groupId}
+        AND group_type_ = #{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} AND NOW() &lt; CONCAT(class_date_," ",start_class_time_);
     </update>
 
     <select id="queryNoSignInListByBeforeMinutes" resultMap="CourseSchedule">

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

@@ -431,7 +431,7 @@
 		DELETE cssp FROM course_schedule_teacher_salary cssp left join course_schedule cs on cssp.course_schedule_id_ = cs.id_ WHERE cssp.music_group_id_=#{musicGroupId} AND cssp.group_type_=#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} and cs.status_ = 'NOT_START'
 	</delete>
 
-	<select id="queryUserNoSettlementListByTypeAndStartClassDate" resultMap="CourseScheduleTeacherSalary">
+    <select id="queryUserNoSettlementListByTypeAndStartClassDate" resultMap="CourseScheduleTeacherSalary">
 		SELECT ts.*,cs.type_,cs.teach_mode_,cs.class_date_,cs.start_class_time_,cs.end_class_time_ FROM course_schedule_teacher_salary ts LEFT JOIN course_schedule cs ON ts.course_schedule_id_ = cs.id_
 		WHERE FIND_IN_SET(cs.type_, #{typeList}) AND ts.user_id_ = #{userId} AND ts.settlement_time_ IS NULL AND cs.class_date_ &gt;= #{startClassDate}
 	</select>

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

@@ -42,6 +42,20 @@
         </where>
     </sql>
 
+    <delete id="deleteGroup">
+        DELETE FROM
+        <if test="groupType!=null and groupType='MUSIC'">
+            music_group
+        </if>
+        <if test="groupType!=null and groupType='VIP'">
+            vip_group
+        </if>
+        <if test="groupType!=null and groupType='PRACTICE'">
+            practice_group
+        </if>
+        WHERE id_=#{groupId}
+    </delete>
+
     <select id="searchGroups" resultMap="Group">
         ( SELECT o.id_ organ_id_,o.name_ organ_name_,g.id_, g.name_ group_name_, 'MUSIC' group_type_
         FROM music_group g

+ 3 - 2
mec-biz/src/main/resources/config/mybatis/MusicGroupMapper.xml

@@ -257,8 +257,9 @@
 			LEFT JOIN sys_user su ON cgtm.user_id_ = su.id_
 			LEFT JOIN teacher t ON su.id_ = t.id_
 			LEFT JOIN `subject` s ON FIND_IN_SET(s.id_,t.subject_id_)
+			LEFT JOIN music_group mg ON cgsp.music_group_id_ = mg.id_
 		  WHERE
-			cgsp.user_id_ = #{studentId} AND cgsp.status_ != 'QUIT'
+			cgsp.user_id_ = #{studentId} AND cgsp.status_ != 'QUIT' AND cg.del_flag_ = 0 AND ((cgsp.group_type_ = 'MUSIC' AND mg.status_ = 'PROGRESS') OR cgsp.group_type_ != 'MUSIC')
 		  GROUP BY su.id_
 	</select>
 
@@ -300,7 +301,7 @@
 		LEFT JOIN class_group cg ON mg.id_ = cg.music_group_id_
 		LEFT JOIN class_group_teacher_mapper cgtm ON cg.id_ = cgtm.class_group_id_
 		WHERE (cgtm.user_id_ = #{userId} OR mg.team_teacher_id_ = #{userId} OR mg.educational_teacher_id_ = #{userId}
-		 OR director_user_id_ = #{userId})
+		 OR director_user_id_ = #{userId}) AND mg.status_ = 'PROGRESS'
 		<if test="search != null and search != ''">
 			AND mg.name_ LIKE CONCAT('%',#{search},'%')
 		</if>

+ 32 - 1
mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml

@@ -11,6 +11,7 @@
 		<result column="name_" property="name" />
 		<result column="subject_id_" property="subjectId" />
 		<result column="user_id_" property="userId" />
+		<result column="student_id_" property="studentId" />
 		<result column="single_class_minutes_" property="singleClassMinutes" />
 		<result column="organ_id_" property="organId" />
 		<result column="courses_start_date_" property="coursesStartDate" />
@@ -18,6 +19,15 @@
 		<result column="create_time_" property="createTime" />
 		<result column="update_time_" property="updateTime" />
 		<result column="memo_" property="memo" />
+		<result column="buy_months_" property="buyMonths" />
+		<result column="drill_times_on_week_" property="drillTimesOnWeek" />
+		<result column="drill_times_json_" property="drillTimesJson" />
+	</resultMap>
+
+	<resultMap id="PracticeCourseDto" type="com.ym.mec.biz.dal.dto.PracticeCourseDto" extends="PracticeGroup">
+		<result property="teacherName" column="real_name_"/>
+		<result property="avatar" column="avatar_"/>
+		<result property="subjectName" column="subject_name_"/>
 	</resultMap>
 
 	<resultMap type="com.ym.mec.biz.dal.dto.PracticeGroupDto" id="PracticeGroupDto">
@@ -57,7 +67,9 @@
 		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
 		</selectKey>
 		-->
-		INSERT INTO practice_group (id_,name_,subject_id_,user_id_,single_class_minutes_,organ_id_,courses_start_date_,courses_expire_date_,create_time_,update_time_,memo_) VALUES(#{id},#{name},#{subjectId},#{userId},#{singleClassMinutes},#{organId},#{coursesStartDate},#{coursesExpireDate},NOW(),NOW(),#{memo})
+		INSERT INTO practice_group
+		(id_,name_,subject_id_,user_id_,student_id_,single_class_minutes_,organ_id_,courses_start_date_,courses_expire_date_,create_time_,update_time_,memo_,buy_months_,drill_times_on_week_,drill_times_json_)
+		VALUES(#{id},#{name},#{subjectId},#{userId},#{studentId},#{singleClassMinutes},#{organId},#{coursesStartDate},#{coursesExpireDate},NOW(),NOW(),#{memo},#{buyMonths},#{drillTimesOnWeek},#{drillTimesJson})
 	</insert>
 	
 	
@@ -94,6 +106,25 @@
 	<select id="countPracticeGroupOverCourse" resultType="java.util.Map">
 
 	</select>
+
+    <select id="findUserLatestPracticeGroup" resultMap="PracticeGroup">
+		SELECT * FROM practice_group WHERE student_id_=#{userId} AND buy_months_ IS NOT NULL ORDER BY create_time_ DESC LIMIT 1;
+	</select>
+
+	<select id="findUserBuyPracticeGroups" resultMap="PracticeCourseDto">
+		SELECT
+			pg.*,
+			su.real_name_,
+			su.avatar_,
+			s.name_ subject_name_
+		FROM
+			practice_group pg
+			LEFT JOIN sys_user su ON pg.user_id_ = su.id_
+			LEFT JOIN `subject` s ON pg.subject_id_ = s.id_
+		WHERE
+			student_id_=#{userId}
+	</select>
+
 	<sql id="practiceGroupQueryCondition">
 		<where>
 			<if test="search!=null and search!=''">

+ 74 - 0
mec-biz/src/main/resources/config/mybatis/PracticeGroupSellPriceMapper.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<!-- 这个文件是自动生成的。 不要修改此文件。所有改动将在下次重新自动生成时丢失。 -->
+<mapper namespace="com.ym.mec.biz.dal.dao.PracticeGroupSellPriceDao">
+
+	<resultMap type="com.ym.mec.biz.dal.entity.PracticeGroupSellPrice" id="PracticeGroupSellPrice">
+		<result column="organ_id_" property="organId" />
+		<result column="once_original_price" property="onceOriginalPrice" />
+		<result column="once_activity_price" property="onceActivityPrice" />
+		<result column="twice_original_price" property="twiceOriginalPrice" />
+		<result column="twice_activity_price" property="twiceActivityPrice" />
+		<result column="create_time_" property="createTime" />
+		<result column="update_time_" property="updateTime" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="PracticeGroupSellPrice">
+		SELECT * FROM
+		practice_group_sell_price WHERE organ_id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="PracticeGroupSellPrice">
+		SELECT * FROM practice_group_sell_price
+		ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.ym.mec.biz.dal.entity.PracticeGroupSellPrice"
+		useGeneratedKeys="true" keyColumn="organ_id_" keyProperty="organId">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO practice_group_sell_price
+		(`organ_id_`, `once_original_price`, `once_activity_price`, `twice_original_price`, `twice_activity_price`, `create_time_`, `update_time_`)
+		VALUES(#{organId},#{onceOriginalPrice},#{onceActivityPrice},#{twiceOriginalPrice},#{twiceActivityPrice},#{createTime},#{updateTime})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.ym.mec.biz.dal.entity.PracticeGroupSellPrice">
+		UPDATE practice_group_sell_price
+		<set>
+			<if test="onceOriginalPrice != null">
+				once_original_price = #{onceOriginalPrice},
+			</if>
+			<if test="onceActivityPrice != null">
+				once_activity_price = #{onceActivityPrice},
+			</if>
+			<if test="twiceOriginalPrice != null">
+				twice_original_price = #{twiceOriginalPrice},
+			</if>
+			<if test="twiceActivityPrice != null">
+				twice_activity_price = #{twiceActivityPrice},
+			</if>
+			update_time_=NOW
+		</set>
+		WHERE organ_id_ = #{organId}
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM practice_group_sell_price WHERE organ_id_ = #{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="PracticeGroupSellPrice" parameterType="map">
+		SELECT * FROM practice_group_sell_price ORDER BY id_
+		<include refid="global.limit" />
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM practice_group_sell_price
+	</select>
+</mapper>

+ 25 - 4
mec-biz/src/main/resources/config/mybatis/StudentAttendanceMapper.xml

@@ -17,6 +17,8 @@
         <result column="subject_name_" property="subjectName"/>
         <result column="phone_" property="phone"/>
         <result column="teacher_id_" property="teacherId"/>
+        <result column="sign_in_time_" property="signInTime"/>
+        <result column="sign_out_time_" property="signOutTime"/>
         <result column="status_" property="status" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
         <result column="create_time_" property="createTime"/>
         <result column="update_time_" property="updateTime"/>
@@ -38,20 +40,23 @@
     <insert id="insert" parameterType="com.ym.mec.biz.dal.entity.StudentAttendance" useGeneratedKeys="true"
             keyColumn="id" keyProperty="id">
         INSERT INTO student_attendance
-        (group_type_,music_group_id_,class_group_id_,course_schedule_id_,user_id_,teacher_id_,status_,create_time_,remark_,current_class_times_)
-        VALUES(#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{classGroupId},#{courseScheduleId},#{userId},#{teacherId},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},now(),#{remark},#{currentClassTimes})
+        (group_type_,music_group_id_,class_group_id_,course_schedule_id_,user_id_,teacher_id_,status_,create_time_,update_time_,remark_,current_class_times_,sign_in_time_,sign_out_time_)
+        VALUES(#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},#{musicGroupId},#{classGroupId},
+        #{courseScheduleId},#{userId},#{teacherId},#{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},now(),now(),
+        #{remark},#{currentClassTimes},#{signInTime},#{signOutTime})
     </insert>
 
     <insert id="addStudentAttendances" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id_">
       INSERT INTO student_attendance (group_type_, music_group_id_, class_group_id_, course_schedule_id_,
-      user_id_, teacher_id_, status_, create_time_,update_time_, remark_ ,current_class_times_)
+      user_id_, teacher_id_, status_, create_time_,update_time_, remark_ ,current_class_times_,sign_in_time_,sign_out_time_)
       VALUES
 	  <foreach collection="list" item="studentAttendance" separator=",">
           (#{studentAttendance.groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
           #{studentAttendance.musicGroupId},#{studentAttendance.classGroupId},#{studentAttendance.courseScheduleId},
           #{studentAttendance.userId},#{studentAttendance.teacherId},
           #{studentAttendance.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},now(),#{studentAttendance.updateTime},
-          #{studentAttendance.remark},#{studentAttendance.currentClassTimes})
+          #{studentAttendance.remark},#{studentAttendance.currentClassTimes}),
+          #{studentAttendance.signInTime},#{studentAttendance.signOutTime})
       </foreach>
     </insert>
 
@@ -62,6 +67,12 @@
             <if test="status != null">
                 status_ = #{status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
             </if>
+            <if test="signOutTime != null">
+                sign_out_time_ = #{signOutTime},
+            </if>
+            <if test="signInTime != null">
+                sign_in_time_ = #{signInTime},
+            </if>
             <if test="userId != null">
                 user_id_ = #{userId},
             </if>
@@ -98,6 +109,12 @@
 	            <if test="item.status != null">
 	                status_ = #{item.status,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler},
 	            </if>
+                <if test="item.signOutTime != null">
+                    sign_out_time_ = #{item.signOutTime},
+                </if>
+                <if test="item.signInTime != null">
+                    sign_in_time_ = #{item.signInTime},
+                </if>
 	            <if test="item.userId != null">
 	                user_id_ = #{item.userId},
 	            </if>
@@ -152,6 +169,10 @@
             #{userId}
         </foreach>
     </delete>
+    <delete id="deleteByGroup">
+        DELETE sa FROM student_attendance sa LEFT JOIN course_schedule cs ON sa.course_schedule_id_ = cs.id_
+		WHERE sa.music_group_id_=#{musicGroupId} AND sa.group_type_=#{groupType,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler} and cs.status_ = 'NOT_START'
+    </delete>
 
     <resultMap id="studentAttendanceViewUtilEntity" type="com.ym.mec.biz.dal.dto.StudentAttendanceViewDto">
         <result property="classGroupId" column="class_group_id_"/>

+ 5 - 0
mec-biz/src/main/resources/config/mybatis/StudentRegistrationMapper.xml

@@ -599,4 +599,9 @@
         LEFT JOIN cooperation_organ co ON mg.cooperation_organ_id_ = co.id_
         WHERE sr.music_group_id_ = #{musicGroupId} AND sr.user_id_ = #{userId} AND sr.music_group_status_ != 'QUIT' LIMIT 1
     </select>
+    <select id="queryStudentMusicGroup" resultType="java.lang.String">
+        SELECT DISTINCT sr.music_group_id_ FROM student_registration sr
+        LEFT JOIN music_group mg ON sr.music_group_id_ = mg.id_
+        WHERE sr.user_id_ = #{studentId} AND sr.music_group_status_ != 'QUIT' AND mg.status_ = 'PROGRESS'
+    </select>
 </mapper>

+ 44 - 0
mec-biz/src/main/resources/config/mybatis/TeacherMapper.xml

@@ -266,6 +266,7 @@
         LEFT JOIN music_group mg ON mg.id_ = cgtm.music_group_id_
         WHERE (cgtm.user_id_ = #{teacherId} OR mg.team_teacher_id_ = #{teacherId} OR mg.educational_teacher_id_ = #{teacherId}
         OR director_user_id_ = #{teacherId}) AND su.id_ IS NOT NULL AND cgtm.music_group_id_ = sr.music_group_id_
+        AND (mg.status_ = 'PROGRESS' OR mg.status_ IS NULL)
         <if test="search != null">
             AND su.username_ LIKE CONCAT('%',#{search},'%')
         </if>
@@ -288,6 +289,9 @@
 
     <resultMap id="ExtendTeacherBasicDto" type="com.ym.mec.biz.dal.dto.ExtendTeacherBasicDto" extends="TeacherBasicDto">
         <result property="isSupportExtraPracticeLesson" column="is_support_extra_practice_lesson_"/>
+        <result property="avatar" column="avatar_"/>
+        <result property="subjectNames" column="subject_names_"/>
+        <result property="introduction" column="introduction_"/>
     </resultMap>
     <select id="findTeachers" resultMap="TeacherBasicDto">
         SELECT su.id_,su.username_,su.real_name_,t.organ_id_ FROM sys_user su
@@ -346,6 +350,30 @@
             AND su.del_flag_=0 AND su.lock_flag_=0
             AND t.organ_id_!=36 AND t.organ_id_!=38
     </select>
+
+    <select id="findTeaTeachersByOrganAndSubject2" resultMap="ExtendTeacherBasicDto">
+        SELECT
+            su.id_,
+            su.username_,
+            su.real_name_,
+            su.avatar_,
+            t.introduction_,
+            t.organ_id_,
+            t.is_support_extra_practice_lesson_,
+            GROUP_CONCAT(s.name_) subject_names_
+        FROM
+            teacher t
+            LEFT JOIN sys_user su ON t.id_ = su.id_
+            LEFT JOIN subject s ON FIND_IN_SET(s.id_,t.subject_id_)
+        WHERE
+            FIND_IN_SET(#{subjectId},t.subject_id_)
+            AND (t.organ_id_=#{organId} OR FIND_IN_SET(#{organId},t.flow_organ_range_))
+            AND t.job_nature_='FULL_TIME'
+            AND su.del_flag_=0 AND su.lock_flag_=0
+            AND t.organ_id_!=36 AND t.organ_id_!=38
+        GROUP BY su.id_
+    </select>
+
     <select id="findTeacherByOrganAndSubject" resultMap="TeacherBasicDto">
         SELECT
             su.id_,
@@ -752,4 +780,20 @@
         FROM sys_user su
         WHERE su.id_ = #{id} LIMIT 1
     </select>
+    <select id="queryTeacherBaseInfo"  resultMap="com.ym.mec.biz.dal.dao.MusicGroupDao.BasicUserDto">
+        SELECT
+        su.real_name_ username_,
+        su.id_ user_id_,
+        su.avatar_ head_url_,
+        gender_,
+        GROUP_CONCAT(s.name_) subject_name_
+        FROM sys_user su
+        LEFT JOIN teacher t ON su.id_ = t.id_
+        LEFT JOIN `subject` s ON FIND_IN_SET(s.id_,t.subject_id_)
+        WHERE su.id_ IN
+        <foreach collection="teacherId" item="userId" open="(" close=")" separator=",">
+            #{userId}
+        </foreach>
+        GROUP BY su.id_
+    </select>
 </mapper>

+ 5 - 2
mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java

@@ -21,7 +21,6 @@ import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
 import com.ym.mec.biz.service.StudentAttendanceService;
 import com.ym.mec.biz.service.TeacherAttendanceService;
 import com.ym.mec.common.exception.BizException;
-import com.ym.mec.common.security.SecurityUtils;
 import com.ym.mec.im.IMHelper;
 import com.ym.mec.im.message.*;
 import com.ym.pojo.*;
@@ -103,7 +102,7 @@ public class RoomServiceImpl implements RoomService {
             if(teacher != null && teacher.getId().equals(courseSchedule.getActualTeacherId())){
                 teacherAttendanceService.addTeacherAttendanceRecord(Integer.parseInt(roomId),courseSchedule.getActualTeacherId(), SignStatusEnum.SIGN_IN,true);
             }else {
-                studentAttendanceService.addStudentAttendanceRecord(Integer.parseInt(roomId),Integer.parseInt(userId), StudentAttendanceStatusEnum.NORMAL);
+                studentAttendanceService.addStudentAttendanceRecord(Integer.parseInt(roomId),Integer.parseInt(userId), StudentAttendanceStatusEnum.NORMAL,SignStatusEnum.SIGN_IN);
             }
         }catch (Exception e){
             e.printStackTrace();
@@ -253,6 +252,8 @@ public class RoomServiceImpl implements RoomService {
         try {
             if(teacher != null && teacher.getId().equals(courseSchedule.getActualTeacherId())){
                 teacherAttendanceService.addTeacherAttendanceRecord(Integer.parseInt(roomId.substring(4)),user.getId(), SignStatusEnum.SIGN_OUT,true);
+            }else {
+                studentAttendanceService.addStudentAttendanceRecord(Integer.parseInt(roomId.substring(4)),user.getId(), StudentAttendanceStatusEnum.NORMAL,SignStatusEnum.SIGN_OUT);
             }
         }catch (Exception e){
             e.printStackTrace();
@@ -1139,6 +1140,8 @@ public class RoomServiceImpl implements RoomService {
             try {
                 if(teacher != null && teacher.getId().equals(courseSchedule.getActualTeacherId())){
                     teacherAttendanceService.addTeacherAttendanceRecord(Integer.parseInt(roomId.substring(4)),Integer.parseInt(userId), SignStatusEnum.SIGN_OUT,true);
+                }else {
+                    studentAttendanceService.addStudentAttendanceRecord(Integer.parseInt(roomId.substring(4)),Integer.parseInt(userId), StudentAttendanceStatusEnum.NORMAL,SignStatusEnum.SIGN_OUT);
                 }
             }catch (Exception e){
                 e.printStackTrace();

+ 64 - 4
mec-student/src/main/java/com/ym/mec/student/controller/PracticeGroupController.java

@@ -2,18 +2,17 @@ package com.ym.mec.student.controller;
 
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.biz.dal.dto.PracticeGroupBuyDto;
 import com.ym.mec.biz.dal.entity.PracticeGroup;
 import com.ym.mec.biz.service.PracticeGroupService;
 import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -65,6 +64,16 @@ public class PracticeGroupController extends BaseController {
         return succeed(practiceGroupService.getEnableApplyTeachers(sysUser.getId(), subjectId));
     }
 
+    @ApiOperation("获取可以预约的教师--付费")
+    @GetMapping(value = "/getEnableApplyTeachersWithPay")
+    public Object getEnableApplyTeachersWithPay(Integer subjectId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(practiceGroupService.getEnableApplyTeachersWithPay(sysUser.getId(), subjectId));
+    }
+
     @ApiOperation("获取指定学员所在分部下的教师空闲时间")
     @GetMapping(value = "/getTeacherFreeTimes")
     public Object getTeacherFreeTimes(Integer teacherId, Date firstClassTime){
@@ -99,4 +108,55 @@ public class PracticeGroupController extends BaseController {
         return succeed(practiceGroupService.practiceApply(practiceGroup));
     }
 
+    @ApiOperation("获取陪练课预约参数——付费")
+    @GetMapping(value = "/getPayPracticeApplyParams")
+    public Object getPayPracticeApplyParams(){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(practiceGroupService.getPayPracticeApplyParams(sysUser.getId(), sysUser.getOrganId()));
+    }
+
+    @ApiOperation("获取指定教师的空闲时间——付费")
+    @GetMapping(value = "/getPayPracticeTeacherFreeTimes")
+    public Object getPayPracticeTeacherFreeTimes(Integer teacherId,Integer buyMonths, Date firstClassTime){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(practiceGroupService.getPayPracticeTeacherFreeTimes(sysUser.getId(),teacherId, buyMonths,firstClassTime));
+    }
+
+    @ApiOperation("获取学生上一次的购买信息--付费")
+    @GetMapping(value = "/findUserLatestPracticeGroup")
+    public HttpResponseResult findUserLatestPracticeGroup(){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(practiceGroupService.findUserLatestPracticeGroup(sysUser.getId()));
+    }
+
+    @ApiOperation("陪练课购买")
+    @GetMapping(value = "/buyPracticeGroup")
+    public HttpResponseResult buyPracticeGroup(@RequestBody PracticeGroupBuyDto practiceGroupBuyParams){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        practiceGroupBuyParams.setStudentId(sysUser.getId());
+        return succeed(practiceGroupService.buyPracticeGroup(practiceGroupBuyParams));
+    }
+
+    @ApiOperation("获取用户历史购买的陪练课")
+    @GetMapping(value = "/findUserHistoryBuyPracticeGroups")
+    public HttpResponseResult findUserHistoryBuyPracticeGroups(){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(practiceGroupService.findUserHistoryBuyPracticeGroups(sysUser.getId()));
+    }
+
 }

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

@@ -5,6 +5,10 @@ import org.apache.commons.lang3.StringUtils;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.DayOfWeek;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.WeekFields;
 import java.util.*;
 
 /**
@@ -129,7 +133,15 @@ public class DateUtil {
 
 	public static final long ONE_WEEK = 7 * ONE_DAY;
 
+	public static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+	public static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+	public static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
+	public static final WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY, 1);
+	public static final ZoneId zoneId = ZoneId.systemDefault();
+
 	public static Map<Object,Integer> normalWeekNumCalendarWeekNumMap=new HashMap<>();
+	public static Map<Object,Integer> calendarWeekNumNormalWeekNumMap=new HashMap<>();
+	public static Map<Integer,String> weekNumNormalWeekNameMap=new HashMap<>();
 
 	static {
 		normalWeekNumCalendarWeekNumMap.put(1,Calendar.MONDAY);
@@ -163,6 +175,22 @@ public class DateUtil {
 		normalWeekNumCalendarWeekNumMap.put("星期五",Calendar.FRIDAY);
 		normalWeekNumCalendarWeekNumMap.put("星期六",Calendar.SATURDAY);
 		normalWeekNumCalendarWeekNumMap.put("星期七",Calendar.SUNDAY);
+
+		calendarWeekNumNormalWeekNumMap.put(Calendar.MONDAY,1);
+		calendarWeekNumNormalWeekNumMap.put(Calendar.TUESDAY,2);
+		calendarWeekNumNormalWeekNumMap.put(Calendar.WEDNESDAY,3);
+		calendarWeekNumNormalWeekNumMap.put(Calendar.THURSDAY,4);
+		calendarWeekNumNormalWeekNumMap.put(Calendar.FRIDAY,5);
+		calendarWeekNumNormalWeekNumMap.put(Calendar.SATURDAY,6);
+		calendarWeekNumNormalWeekNumMap.put(Calendar.SUNDAY,7);
+
+		weekNumNormalWeekNameMap.put(1,"周一");
+		weekNumNormalWeekNameMap.put(2,"周二");
+		weekNumNormalWeekNameMap.put(3,"周三");
+		weekNumNormalWeekNameMap.put(4,"周四");
+		weekNumNormalWeekNameMap.put(5,"周五");
+		weekNumNormalWeekNameMap.put(6,"周六");
+		weekNumNormalWeekNameMap.put(7,"周日");
 	}
 
 	// ~ 方法 ////////////////////////////////////////////////////////////////