瀏覽代碼

Merge remote-tracking branch 'origin/master'

zouxuan 4 年之前
父節點
當前提交
756cda7575

+ 5 - 2
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/PracticeGroupDao.java

@@ -6,6 +6,7 @@ import com.ym.mec.biz.dal.entity.CourseSchedule;
 import com.ym.mec.biz.dal.entity.CourseScheduleEvaluate;
 import com.ym.mec.biz.dal.entity.PracticeGroup;
 import com.ym.mec.biz.dal.enums.GroupStatusEnum;
+import com.ym.mec.biz.dal.enums.PracticeGroupType;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.security.core.parameters.P;
 
@@ -136,7 +137,8 @@ public interface PracticeGroupDao extends com.ym.mec.common.dal.BaseDAO<Long, Pr
      * @author Joburgess
      * @date 2020/2/18
      */
-    List<PracticeCourseDto> findUserBuyPracticeGroups(@Param("userId") Integer userId);
+    List<PracticeCourseDto> findUserBuyPracticeGroups(@Param("userId") Integer userId,
+                                                      @Param("type") PracticeGroupType type);
 
 
     List<PracticeCourseDto> findUserBuyPracticeGroupsWithDate(@Param("userId") Integer userId,
@@ -167,7 +169,8 @@ public interface PracticeGroupDao extends com.ym.mec.common.dal.BaseDAO<Long, Pr
      * @date 2020/2/26
      */
     List<PracticeGroup> findUserStatusPracticeGroups(@Param("userId") Integer userId,
-                                                     @Param("groupStatus") GroupStatusEnum groupStatusEnum);
+                                                     @Param("groupStatus") GroupStatusEnum groupStatusEnum,
+                                                     @Param("groupType")PracticeGroupType groupType);
 
     /**
      * @param userId:

+ 13 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CourseTimeDto.java

@@ -1,9 +1,11 @@
 package com.ym.mec.biz.dal.dto;
 
+import com.ym.mec.biz.dal.entity.ClassGroupTeacherMapper;
 import com.ym.mec.biz.dal.entity.CourseSchedule;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.util.Date;
+import java.util.List;
 
 public class CourseTimeDto {
 
@@ -35,6 +37,17 @@ public class CourseTimeDto {
     @ApiModelProperty(value = "是否跳过节假日 true-跳过 false-不跳过", required = true)
     private Boolean isHoliday = false;
 
+    @ApiModelProperty(value = "老师设置", required = true)
+    private List<ClassGroupTeacherMapper> classGroupTeacherMapperList;
+
+    public List<ClassGroupTeacherMapper> getClassGroupTeacherMapperList() {
+        return classGroupTeacherMapperList;
+    }
+
+    public void setClassGroupTeacherMapperList(List<ClassGroupTeacherMapper> classGroupTeacherMapperList) {
+        this.classGroupTeacherMapperList = classGroupTeacherMapperList;
+    }
+
     public Boolean getHoliday() {
         return isHoliday;
     }

+ 14 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/TeacherServeDto.java

@@ -1,5 +1,8 @@
 package com.ym.mec.biz.dal.dto;
 
+import com.ym.mec.biz.dal.enums.JobNatureEnum;
+import io.swagger.annotations.ApiModelProperty;
+
 import java.util.Date;
 
 /**
@@ -28,6 +31,17 @@ public class TeacherServeDto {
 
     private String operatorName;
 
+    @ApiModelProperty(value = "工作性质(兼职 PART_JOB、全职FULL_JOB)", required = false)
+    private JobNatureEnum jobNature;
+
+    public JobNatureEnum getJobNature() {
+        return jobNature;
+    }
+
+    public void setJobNature(JobNatureEnum jobNature) {
+        this.jobNature = jobNature;
+    }
+
     public Integer getTeacherId() {
         return teacherId;
     }

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

@@ -114,6 +114,8 @@ public class CourseSchedule {
 	@ApiModelProperty(value = "助教编号列表(用于记录调整日志)")
 	private String teachingTeacherIds;
 
+	private String teachingTeacherNames;
+
 	/**  */
 	private java.util.Date createTime;
 
@@ -171,6 +173,14 @@ public class CourseSchedule {
 
 	private int isSignOut = 3;
 
+	public String getTeachingTeacherNames() {
+		return teachingTeacherNames;
+	}
+
+	public void setTeachingTeacherNames(String teachingTeacherNames) {
+		this.teachingTeacherNames = teachingTeacherNames;
+	}
+
 	public String getTeachingTeacherIds() {
 		return teachingTeacherIds;
 	}

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/StudentRepair.java

@@ -214,6 +214,9 @@ public class StudentRepair {
     @ApiModelProperty(value = "更新时间", required = false)
     private Date updateTime;
 
+    @ApiModelProperty(value = "辅件金额", required = false)
+    private BigDecimal repairGoodsAmount = BigDecimal.ZERO;
+
     public String getGoodsJson() {
         return goodsJson;
     }
@@ -498,4 +501,12 @@ public class StudentRepair {
     public void setRepairImg(String repairImg) {
         this.repairImg = repairImg;
     }
+
+    public BigDecimal getRepairGoodsAmount() {
+        return repairGoodsAmount;
+    }
+
+    public void setRepairGoodsAmount(BigDecimal repairGoodsAmount) {
+        this.repairGoodsAmount = repairGoodsAmount;
+    }
 }

+ 12 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/PracticeGroupService.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.service;
 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.enums.PracticeGroupType;
 import com.ym.mec.biz.dal.page.PracticeGroupQueryInfo;
 import com.ym.mec.biz.dal.page.StudentBuyPracticeQueryInfo;
 import com.ym.mec.biz.dal.page.StudentQueryInfo;
@@ -193,6 +194,16 @@ public interface PracticeGroupService extends BaseService<Long, PracticeGroup> {
      */
     HttpResponseResult buyPracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams);
 
+	/**
+	 * @describe 创建关心包课程
+	 * @author Joburgess
+	 * @date 2021/1/28 0028
+	 * @param practiceGroupBuyParams:
+	 * @param operatorInfo:
+	 * @return com.ym.mec.common.entity.HttpResponseResult
+	 */
+	HttpResponseResult createPackagePracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams);
+
     /**
      * @describe 支付订单回调
      * @author Joburgess
@@ -209,7 +220,7 @@ public interface PracticeGroupService extends BaseService<Long, PracticeGroup> {
 	 * @param userId:
 	 * @return java.util.List<com.ym.mec.biz.dal.dto.PracticeCourseDto>
 	 */
-	List<PracticeCourseDto> findUserHistoryBuyPracticeGroups(Integer userId, Long groupId);
+	List<PracticeCourseDto> findUserHistoryBuyPracticeGroups(Integer userId, Long groupId, PracticeGroupType type);
 
 	/**
 	 * @describe 查询订单信息

+ 60 - 50
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ClassGroupServiceImpl.java

@@ -2277,6 +2277,7 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
         if (classGroup == null) {
             throw new BizException("班级不存在");
         }
+        MusicGroup musicGroup = musicGroupDao.get(classGroup.getMusicGroupId());
 
         Boolean confirmGenerate = false;
         if (Objects.nonNull(classGroup4MixDtos.get(0).getConfirmGenerate())) {
@@ -2288,35 +2289,29 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
             teachMode = TeachModeEnum.ONLINE;
         }
 
-        List<ClassGroupTeacherMapper> byClassGroup = classGroupTeacherMapperDao.findByClassGroup(classGroupId);
-        List<ClassGroupTeacherMapper> newTeacherMapperList = classGroup4MixDtos.get(0).getClassGroupTeacherMapperList();
-        MusicGroup musicGroup = musicGroupDao.get(classGroup.getMusicGroupId());
-        if (musicGroup.getStatus() == PROGRESS) {
-            if (byClassGroup != null && byClassGroup.size() > 0) {
-                ClassGroupTeacherMapper groupTeacherMapper = byClassGroup.stream().filter(classGroupTeacherMapper -> classGroupTeacherMapper.getTeacherRole() == TeachTypeEnum.BISHOP).findFirst().get();
-                if (groupTeacherMapper != null) {
-                    imGroupMemberService.quit(classGroupId.longValue(), groupTeacherMapper.getUserId());
+        //1、更新班级关联老师信息
+        if (Objects.nonNull(classGroup4MixDtos.get(0).getCourseAddType()) && classGroup4MixDtos.get(0).getCourseAddType().equals("onlyUpdateTeacher")) {
+            List<ClassGroupTeacherMapper> byClassGroup = classGroupTeacherMapperDao.findByClassGroup(classGroupId);
+            List<ClassGroupTeacherMapper> newTeacherMapperList = classGroup4MixDtos.get(0).getClassGroupTeacherMapperList();
+            if(musicGroup.getStatus() == PROGRESS){
+                if (byClassGroup != null && byClassGroup.size() > 0) {
+                    ClassGroupTeacherMapper groupTeacherMapper = byClassGroup.stream().filter(classGroupTeacherMapper -> classGroupTeacherMapper.getTeacherRole() == TeachTypeEnum.BISHOP).findFirst().get();
+                    if (groupTeacherMapper != null) {
+                        imGroupMemberService.quit(classGroupId.longValue(), groupTeacherMapper.getUserId());
+                    }
+                }
+                if (newTeacherMapperList.size() > 0) {
+                    //获取之前的班级老师
+                    Set<Integer> groupTeacher = classGroupDao.findGroupTeacher(classGroupId);
+                    groupTeacher.forEach(e -> {
+                        imGroupMemberService.quit(classGroupId.longValue(), e);
+                    });
+                    newTeacherMapperList.forEach(e -> {
+                        imGroupMemberService.join(classGroupId.longValue(), e.getUserId(), "指导老师", false);
+                    });
                 }
             }
-            if (newTeacherMapperList.size() > 0) {
-                //获取之前的班级老师
-                Set<Integer> groupTeacher = classGroupDao.findGroupTeacher(classGroupId);
-                groupTeacher.forEach(e -> {
-                    imGroupMemberService.quit(classGroupId.longValue(), e);
-                });
-                newTeacherMapperList.forEach(e -> {
-                    imGroupMemberService.join(classGroupId.longValue(), e.getUserId(), "指导老师", false);
-                });
-            }
-        }
-        //1、更新班级关联老师信息
-        List<ClassGroupTeacherMapper> newClassGroupTeacherMapperList = classGroup4MixDtos.get(0).getClassGroupTeacherMapperList();
 
-        Set<Integer> noRepeatTeacherIds = newClassGroupTeacherMapperList.stream().map(ClassGroupTeacherMapper::getUserId).collect(Collectors.toSet());
-        if (noRepeatTeacherIds.size() != newClassGroupTeacherMapperList.size()) {
-            throw new BizException("主教与助教存在冲突");
-        }
-        if (Objects.nonNull(classGroup4MixDtos.get(0).getCourseAddType()) && classGroup4MixDtos.get(0).getCourseAddType().equals("onlyUpdateTeacher")) {
             List<Integer> classGroupIds = new ArrayList<>();
             classGroupIds.add(classGroupId);
             // 删除历史记录
@@ -2345,30 +2340,6 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
 
         String subjectNames = subjectList.stream().map(Subject::getName).collect(Collectors.joining("/"));
 
-        Integer teacherId = null;
-        for (ClassGroupTeacherMapper groupTeacherMapper : newClassGroupTeacherMapperList) {
-            groupTeacherMapper.setGroupType(classGroup.getGroupType());
-            groupTeacherMapper.setClassGroupId(classGroup.getId());
-            groupTeacherMapper.setMusicGroupId(classGroup4MixDtos.get(0).getMusicGroupId());
-            if (groupTeacherMapper.getTeacherRole().equals(TeachTypeEnum.BISHOP)) {
-                teacherId = groupTeacherMapper.getUserId();
-            }
-        }
-
-        Set<String> newTeacher = newClassGroupTeacherMapperList.stream().map(
-                classGroupTeacherMapper -> classGroupTeacherMapper.getTeacherRole().getCode() + classGroupTeacherMapper.getUserId()
-        ).collect(Collectors.toSet());
-
-        List<ClassGroupTeacherMapper> oldClassGroupTeacherMapperList = classGroupTeacherMapperDao.findClassGroupTeachers(classGroup.getId().toString());
-
-        Set<String> oldTeacher = oldClassGroupTeacherMapperList.stream().map(
-                classGroupTeacherMapper -> classGroupTeacherMapper.getTeacherRole().getCode() + classGroupTeacherMapper.getUserId()
-        ).collect(Collectors.toSet());
-
-        if (oldTeacher.size() != newTeacher.size() || !newTeacher.containsAll(oldTeacher)) {
-            classGroupTeacherMapperService.classGroupTeachersInsert(newClassGroupTeacherMapperList);
-        }
-
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
         //2、获取班级学生
@@ -2408,10 +2379,37 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
                 holidayDays = new HashSet<>(JSON.parseArray(holidaySetting.getParanValue(), String.class));
             }
 
+            Set<Integer> allTeacherIds = new HashSet<>();
+            List<SimpleUserDto> allTeacherInfo = new ArrayList<>();
+            if(!confirmGenerate){
+                for (CourseTimeDto courseTimeDto : classGroup4MixDto.getCourseTimeDtoList()) {
+                    List<ClassGroupTeacherMapper> newClassGroupTeacherMapperList = courseTimeDto.getClassGroupTeacherMapperList();
+                    Set<Integer> teacherIds = newClassGroupTeacherMapperList.stream().map(t -> t.getUserId()).collect(Collectors.toSet());
+                    if(!CollectionUtils.isEmpty(teacherIds)){
+                        allTeacherIds.addAll(teacherIds);
+                    }
+                }
+                if(!CollectionUtils.isEmpty(allTeacherIds)){
+                    allTeacherInfo = teacherDao.getUsersSimpleInfo(new ArrayList<>(allTeacherIds));
+                }
+            }
+
             WhileNode:
             while (true) {
                 int dayOfWeek = now.getDayOfWeek().getValue();
                 for (CourseTimeDto courseTimeDto : classGroup4MixDto.getCourseTimeDtoList()) {
+                    List<ClassGroupTeacherMapper> newClassGroupTeacherMapperList = courseTimeDto.getClassGroupTeacherMapperList();
+
+                    Set<Integer> noRepeatTeacherIds = newClassGroupTeacherMapperList.stream().map(ClassGroupTeacherMapper::getUserId).collect(Collectors.toSet());
+                    if (noRepeatTeacherIds.size() != newClassGroupTeacherMapperList.size()) {
+                        throw new BizException("主教与助教存在冲突");
+                    }
+
+                    Integer teacherId = newClassGroupTeacherMapperList.stream().filter(ct->TeachTypeEnum.BISHOP.equals(ct.getTeacherRole())).findAny().get().getUserId();
+                    if(Objects.isNull(teacherId)){
+                        throw new BizException("请设置主教");
+                    }
+
                     if (courseTimeDto.getDayOfWeek() < 1 || courseTimeDto.getDayOfWeek() > 7) {
                         throw new BizException("排课循环周期错误,请核查");
                     }
@@ -2489,6 +2487,18 @@ public class ClassGroupServiceImpl extends BaseServiceImpl<Integer, ClassGroup>
                     courseScheduleDao.insert(courseSchedule);
                     courseScheduleList.add(courseSchedule);
 
+                    if(!confirmGenerate){
+                        Set<Integer> teacherIds = newClassGroupTeacherMapperList.stream().filter(ct->TeachTypeEnum.TEACHING.equals(ct.getTeacherRole())).map(ClassGroupTeacherMapper::getUserId).collect(Collectors.toSet());
+                        SimpleUserDto mainTeacher = allTeacherInfo.stream().filter(t -> teacherId.equals(t.getUserId())).findAny().get();
+                        if(Objects.nonNull(mainTeacher)){
+                            courseSchedule.setActualTeacherName(mainTeacher.getUserName());
+                        }
+                        List<SimpleUserDto> teachingTeachers = allTeacherInfo.stream().filter(t -> teacherIds.contains(t.getUserId())).collect(Collectors.toList());
+                        if(!CollectionUtils.isEmpty(teachingTeachers)){
+                            courseSchedule.setTeachingTeacherNames(StringUtils.join(teachingTeachers.stream().map(SimpleUserDto::getUserName).collect(Collectors.toList()), ","));
+                        }
+                    }
+
                     for (ClassGroupTeacherMapper classGroupTeacherMapper : newClassGroupTeacherMapperList) {
                         CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
                         courseScheduleTeacherSalary.setCourseScheduleId(courseSchedule.getId());

+ 0 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/EduPracticeGroupServiceImpl.java

@@ -498,8 +498,6 @@ public class EduPracticeGroupServiceImpl implements EduPracticeGroupService{
         }
     }
 
-
-
     @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
     public HttpResponseResult createPackagePracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams, String operatorInfo) {

+ 430 - 2
mec-biz/src/main/java/com/ym/mec/biz/service/impl/PracticeGroupServiceImpl.java

@@ -3205,6 +3205,422 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
 
     @Override
     @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public HttpResponseResult createPackagePracticeGroup(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);
+        SysConfig practicePromotionActivityStartDateConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_PROMOTION_ACTIVITY_START_DATE);
+
+        Date now = new Date();
+
+        LocalDate courseStartDay = LocalDate.now();
+        LocalDate tempCourseLocalDate = LocalDate.parse("2020-03-01", DateUtil.dateFormatter);
+        if (courseStartDay.isBefore(tempCourseLocalDate)) {
+            courseStartDay = tempCourseLocalDate;
+        }
+
+        if (Objects.isNull(practiceGroupBuyParams.getEducationalTeacherId())) {
+            List<String> musicGroupIds = studentRegistrationDao.queryStudentMusicGroup(practiceGroupBuyParams.getStudentId());
+            if (!CollectionUtils.isEmpty(musicGroupIds) && musicGroupIds.size() <= 1) {
+                MusicGroup musicGroup = musicGroupDao.get(musicGroupIds.get(0));
+                if (Objects.nonNull(musicGroup)) {
+                    practiceGroupBuyParams.setEducationalTeacherId(musicGroup.getEducationalTeacherId());
+                }
+            }
+        }
+
+        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());
+        courseExpiredDate = DateUtil.addSeconds(courseExpiredDate, -1);
+        practiceGroupBuyParams.setCoursesExpireDate(courseExpiredDate);
+
+        LocalDate courseExpiredSunday = currentExpiredDay.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.SUNDAY.getValue());
+        Date courseExpiredSundayDate = Date.from(courseExpiredSunday.atStartOfDay(DateUtil.zoneId).toInstant());
+
+        practiceGroupBuyParams.setName(subject.getName() + "•" + sysUser.getUsername());
+        List<CourseSchedule> practiceCourses = new ArrayList<>();
+
+        Student student = studentDao.get(practiceGroupBuyParams.getStudentId());
+        List<PracticeGroup> userStatusPracticeGroups = practiceGroupDao.findUserStatusPracticeGroups(practiceGroupBuyParams.getStudentId(), null, PracticeGroupType.COME_ON_PACKAGE);
+        long normalGroupNum = userStatusPracticeGroups.stream().filter(p -> GroupStatusEnum.LOCK.equals(p.getGroupStatus()) || GroupStatusEnum.NORMAL.equals(p.getGroupStatus())).count();
+        if(Objects.isNull(student.getComeOnPackage())||student.getComeOnPackage().equals(0)){
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "该学员暂无加油包排课资格");
+        }else if(student.getComeOnPackage().equals(2)||normalGroupNum>0){
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "该学员已使用加油包排课资格");
+        }
+        Integer courseTimes = 8;
+
+        while (practiceCourses.size()<courseTimes) {
+            courseStartDay=courseStartDay.plusDays(1);
+            int dayOfWeek = courseStartDay.get(DateUtil.weekFields.dayOfWeek());
+            for (PracticeDrillTimeDto drillTime : practiceGroupBuyParams.getDrillTimes()) {
+                if(practiceCourses.size()==courseTimes){
+                    break;
+                }
+                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.setStartClassTime(Date.from(courseStartDateTime.atZone(DateUtil.zoneId).toInstant()));
+                    courseSchedule.setEndClassTime(Date.from(courseEndDateTime.atZone(DateUtil.zoneId).toInstant()));
+                    courseSchedule.setClassDate(courseSchedule.getStartClassTime());
+                    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);
+                    practiceCourses.add(courseSchedule);
+
+                    if(practiceCourses.size()==courseTimes){
+                        break;
+                    }
+
+                    CourseSchedule courseSchedule1=new CourseSchedule();
+                    BeanUtils.copyProperties(courseSchedule, courseSchedule1);
+                    courseSchedule1.setStartClassTime(courseSchedule.getEndClassTime());
+                    courseSchedule1.setEndClassTime(Date.from(courseEndDateTime.plusMinutes(practiceCourseMinutes).atZone(DateUtil.zoneId).toInstant()));
+                    courseSchedule1.setClassDate(courseSchedule1.getStartClassTime());
+                    practiceCourses.add(courseSchedule1);
+
+                }
+            }
+        }
+
+        practiceCourses.sort(Comparator.comparing(CourseSchedule::getStartClassTime));
+
+        LocalDate classStartDate = LocalDateTime.ofInstant(practiceCourses.get(0).getClassDate().toInstant(), DateUtil.zoneId).toLocalDate();
+        LocalDate courseStartMonday = classStartDate.with(DateUtil.weekFields.dayOfWeek(), DayOfWeek.MONDAY.getValue());
+        Date courseStartMondayDate = Date.from(courseStartMonday.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();
+            }
+        } else {
+            return BaseController.failed(HttpStatus.MULTIPLE_CHOICES, "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
+        }
+
+        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<>();
+
+        JSONObject drillTimesObject = new JSONObject();
+        for (PracticeDrillTimeDto drillTime : practiceGroupBuyParams.getDrillTimes()) {
+            drillTimesObject.put(String.valueOf(drillTime.getWeekNum()), drillTime.getTimeStr());
+        }
+
+        PracticeGroupSellPrice practiceGroupSellPrice = practiceGroupSellPriceDao.get(sysUser.getOrganId());
+        if (Objects.isNull(practiceGroupSellPrice)) {
+            throw new BizException("所在城市暂不参与此活动");
+        }
+
+        BigDecimal amount = PracticeGroupType.CARE_PACKAGE.equals(practiceGroupBuyParams.getType())?practiceGroupSellPrice.getCarePackagePrice():practiceGroupSellPrice.getComeOnPackagePrice();
+        if(Objects.isNull(amount)&&PracticeGroupType.COME_ON_PACKAGE.equals(practiceGroupBuyParams.getType())){
+            throw new BizException("请设置加油包价格");
+        }
+
+        practiceGroupBuyParams.setCoursesStartDate(practiceCourses.stream().min(Comparator.comparing(CourseSchedule::getStartClassTime)).get().getStartClassTime());
+        practiceGroupBuyParams.setCoursesExpireDate(practiceCourses.stream().max(Comparator.comparing(CourseSchedule::getEndClassTime)).get().getEndClassTime());
+        practiceGroupBuyParams.setDrillTimesJson(drillTimesObject.toJSONString());
+        practiceGroupBuyParams.setOrganId(sysUser.getOrganId());
+        practiceGroupBuyParams.setSingleClassMinutes(practiceCourseMinutes);
+        practiceGroupBuyParams.setGroupStatus(GroupStatusEnum.LOCK);
+        practiceGroupBuyParams.setType(PracticeGroupType.COME_ON_PACKAGE);
+        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()));
+        classGroupTeacherSalary.setOnlineClassesSalary(new BigDecimal(practiceCourseSalaryConfig.getParanValue()));
+        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);
+            courseSchedule.setOrganId(practiceGroupBuyParams.getOrganId());
+        }
+        courseScheduleDao.batchAddCourseSchedules(practiceCourses);
+        TeacherDefaultPracticeGroupSalary teacherDefaultPracticeGroupSalary = teacherDefaultPracticeGroupSalaryDao.findByTeacherAndCourseMinutes(practiceGroupBuyParams.getUserId(), practiceCourseMinutes);
+        BigDecimal teacherDefaultSalary = null;
+        if (Objects.nonNull(teacherDefaultPracticeGroupSalary)) {
+            teacherDefaultSalary = teacherDefaultPracticeGroupSalary.getMainTeacherSalary();
+        }
+        if(teacherDefaultSalary == null){
+            throw new BizException("请设置教师课酬");
+        }
+        BigDecimal studentSingleCourseCost = amount.divide(new BigDecimal(practiceCourses.size()), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
+
+        BigDecimal oneMonthOriginalPrice=practiceGroupBuyParams.getDrillTimesOnWeek()==1?practiceGroupSellPrice.getOnceOriginalPrice():practiceGroupSellPrice.getTwiceOriginalPrice();
+        BigDecimal originalAmount = oneMonthOriginalPrice.multiply(new BigDecimal(practiceGroupBuyParams.getBuyMonths()));
+        BigDecimal studentSingleCourseOriginalCost=originalAmount.divide(new BigDecimal(practiceCourses.size()), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN);
+
+        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(teacherDefaultSalary);
+            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(studentSingleCourseCost);
+            courseScheduleStudentPayment.setActualPrice(studentSingleCourseCost);
+            courseScheduleStudentPayment.setOriginalPrice(studentSingleCourseOriginalCost);
+            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);
+        courseScheduleStudentPaymentDao.batchInsert(courseScheduleStudentPayments);
+        teacherAttendanceDao.batchInsert(teacherAttendances);
+
+        try {
+            courseScheduleService.checkNewCourseSchedules(practiceCourses, false,false);
+        } catch (Exception e) {
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            String errMessage = new String();
+            if (e.getMessage().indexOf("主教冲突") != -1) {
+                errMessage = "抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。";
+            } else {
+                String courseName = e.getMessage().substring(e.getMessage().indexOf(")-") + 2);
+                courseName = courseName.substring(0, courseName.indexOf("("));
+                errMessage = "抱歉啦,当前所选时段组合,与您现有课程「";
+                errMessage += courseName;
+                errMessage += "」时段冲突,请选择其他时段重试。";
+            }
+            return BaseController.failed(HttpStatus.FOUND, errMessage);
+        }
+
+        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.PRACTICE_GROUP_BUY);
+        if (practiceGroupBuyParams.isRenew()) {
+            studentPaymentOrder.setType(OrderTypeEnum.PRACTICE_GROUP_RENEW);
+        }
+        studentPaymentOrder.setExpectAmount(amount);
+        studentPaymentOrder.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+        studentPaymentOrder.setActualAmount(studentPaymentOrder.getExpectAmount());
+        studentPaymentOrder.setClassGroupId(classGroup.getId());
+        studentPaymentOrder.setVersion(0);
+        studentPaymentOrderService.insert(studentPaymentOrder);
+
+        BigDecimal balance = BigDecimal.ZERO;
+        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) {
+                studentPaymentRouteOrderService.addRouteOrder(orderNo, practiceGroupBuyParams.getOrganId(), amount);
+
+                // 更新订单信息
+                studentPaymentOrder.setActualAmount(new BigDecimal(0));
+                studentPaymentOrder.setBalancePaymentAmount(studentPaymentOrder.getExpectAmount());
+                studentPaymentOrder.setStatus(DealStatusEnum.SUCCESS);
+                studentPaymentOrder.setUpdateTime(now);
+                studentPaymentOrder.setOrganId(practiceGroupBuyParams.getOrganId());
+                studentPaymentOrder.setRoutingOrganId(practiceGroupBuyParams.getOrganId());
+
+                sysUserCashAccountService.updateBalance(practiceGroupBuyParams.getStudentId(), studentPaymentOrder.getExpectAmount().negate(), PlatformCashAccountDetailTypeEnum.PAY_FEE, "网管课购买");
+
+                studentPaymentOrder.setPayTime(now);
+                this.orderCallback(studentPaymentOrder);
+
+                Map<String, Object> result = new HashMap<>();
+                result.put("orderNo", studentPaymentOrder.getOrderNo());
+
+                return BaseController.succeed(result);
+            } else {
+                if (userCashAccount.getBalance().doubleValue() > 0) {
+                    balance = userCashAccount.getBalance();
+                    sysUserCashAccountService.updateBalance(practiceGroupBuyParams.getStudentId(), balance.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,
+                    balance,
+                    orderNo,
+                    baseApiUrl + "/api-student/studentOrder/notify",
+                    baseApiUrl + "/api-student/studentOrder/paymentResult?orderNo=" + orderNo,
+                    "网管课购买",
+                    practiceGroupBuyParams.getName(),
+                    practiceGroupBuyParams.getOrganId(),
+                    "practiceBuy"
+            );
+
+            studentPaymentOrder.setOrganId(practiceGroupBuyParams.getOrganId());
+            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) {
+            LOGGER.error("网管课购买失败:", e.getCause());
+            throw new BizException("订单提交超时,请尝试重新提交购买");
+        }
+    }
+
+    @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.ING)) {
@@ -3298,6 +3714,12 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
         practiceGroup.setGroupStatus(GroupStatusEnum.NORMAL);
         practiceGroupDao.update(practiceGroup);
 
+        if(PracticeGroupType.COME_ON_PACKAGE.equals(practiceGroup.getType())){
+            Student student = studentDao.get(practiceGroup.getStudentId());
+            student.setComeOnPackage(2);
+            studentDao.update(student);
+        }
+
         try {
             contractService.transferPracticeCoursesContract(order.getUserId(), classGroup.getTotalClassTimes(), practiceGroup.getCoursesStartDate(), practiceGroup.getCoursesExpireDate(), order.getExpectAmount());
         } catch (Exception e) {
@@ -3364,14 +3786,17 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
     }
 
     @Override
-    public List<PracticeCourseDto> findUserHistoryBuyPracticeGroups(Integer userId, Long groupId) {
+    public List<PracticeCourseDto> findUserHistoryBuyPracticeGroups(Integer userId, Long groupId, PracticeGroupType type) {
         List<PracticeCourseDto> userPracticeGroups;
         if (Objects.nonNull(groupId)) {
             PracticeGroup practiceGroup = practiceGroupDao.get(groupId);
+            if(Objects.isNull(practiceGroup)){
+                throw new BizException("课程信息不存在");
+            }
             Date date = DateUtil.addSeconds(practiceGroup.getCoursesExpireDate(), 1);
             userPracticeGroups = practiceGroupDao.findUserBuyPracticeGroupsWithDate(userId, date);
         } else {
-            userPracticeGroups = practiceGroupDao.findUserBuyPracticeGroups(userId);
+            userPracticeGroups = practiceGroupDao.findUserBuyPracticeGroups(userId,type);
         }
 
         if (CollectionUtils.isEmpty(userPracticeGroups)) {
@@ -3387,6 +3812,9 @@ public class PracticeGroupServiceImpl extends BaseServiceImpl<Long, PracticeGrou
                 newCourseJson.put("weekName", DateUtil.weekNumNormalWeekNameMap.get(Integer.parseInt(weekNumStr)));
                 LocalTime courseStartTime = LocalTime.parse(courseJson.getString(weekNumStr), DateUtil.timeFormatter);
                 LocalTime courseEndTime = courseStartTime.plusMinutes(practiceCourseMinutes);
+                if(PracticeGroupType.COME_ON_PACKAGE.equals(userPracticeGroup.getType())){
+                    courseEndTime = courseStartTime.plusMinutes(2*practiceCourseMinutes);
+                }
                 newCourseJson.put("startTime", courseStartTime.format(DateUtil.timeFormatter));
                 newCourseJson.put("endTime", courseEndTime.format(DateUtil.timeFormatter));
                 coursesArry.add(newCourseJson);

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

@@ -447,7 +447,7 @@ public class StudentManageServiceImpl implements StudentManageService {
         PageInfo<MusicGroupStudentsDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
         Map<String, Object> params = new HashMap<>();
         MapUtil.populateMap(params, queryInfo);
-        List<MusicGroupStudentsDto> dataList = null;
+        List<MusicGroupStudentsDto> dataList = new ArrayList<>();
         List<StudentRegistration> studentRegistrations = studentRegistrationDao.getMusicGroupStu(queryInfo.getMusicGroupId());
         if(studentRegistrations.size() == 0){
             return pageInfo;
@@ -478,8 +478,8 @@ public class StudentManageServiceImpl implements StudentManageService {
         if (queryInfo.getIsExport() && count > 50000) {
             throw new BizException("数据集太大,不能导出.最大数据集不能超过50000");
         }
-        if (count > 0) {
-            pageInfo.setTotal(count);
+        pageInfo.setTotal(count);
+        if (queryInfo.getPage() <= pageInfo.getTotalPage()) {
             params.put("offset", pageInfo.getOffset());
             dataList = studentManageDao.queryMusicGroupStudent(params);
             //获取乐团学员欠费金额
@@ -502,9 +502,6 @@ public class StudentManageServiceImpl implements StudentManageService {
                 e.setNoPaymentAmount(totalAmountMap.get(e.getUserId()));
             });
         }
-        if (count == 0) {
-            dataList = new ArrayList<>();
-        }
         pageInfo.setRows(dataList);
         return pageInfo;
     }

+ 12 - 2
mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml

@@ -214,7 +214,12 @@
                  LEFT JOIN `subject` s ON pg.subject_id_ = s.id_
         WHERE student_id_ = #{userId}
           AND (pg.group_status_ = 'NORMAL' OR pg.group_status_ = 'LOCK')
-          AND pg.type_='CHARGE'
+          <if test="type!=null">
+              AND pg.type_=#{type,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+          </if>
+          <if test="type==null">
+              AND pg.type_='CHARGE'
+          </if>
     </select>
 
     <select id="findUserBuyPracticeGroupsWithDate" resultMap="PracticeCourseDto">
@@ -299,7 +304,12 @@
         SELECT *
         FROM practice_group
         WHERE student_id_ = #{userId}
-          AND group_status_ = #{groupStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+          <if test="groupStatus!=null">
+              AND group_status_ = #{groupStatus,typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+          </if>
+          <if test="groupType!=null">
+              AND type_ = #{groupType, typeHandler=com.ym.mec.common.dal.CustomEnumTypeHandler}
+          </if>
     </select>
     <select id="findUserLockPracticeGroupWithDate" resultMap="PracticeGroup">
         SELECT *

+ 2 - 0
mec-biz/src/main/resources/config/mybatis/StudentExtracurricularExercisesSituationMapper.xml

@@ -495,6 +495,7 @@
 		<result column="un_done_" property="unDone"/>
 		<result column="remind_time_" property="remindDate"/>
 		<result column="operator_name_" property="operatorName"/>
+		<result column="job_nature_" property="jobNature" typeHandler="com.ym.mec.common.dal.CustomEnumTypeHandler"/>
 	</resultMap>
 
 	<sql id="queryTeacherServeInfoCondition">
@@ -533,6 +534,7 @@
 			sees.sunday_,
 			sees.teacher_id_,
 			su.real_name_ teacher_name_,
+		    tea.job_nature_,
 			SUM(CASE sees.serve_type_ WHEN 'HOMEWORK' THEN sees.expect_exercises_num_ ELSE 0 END) homework_num_,
 			SUM(CASE sees.serve_type_ WHEN 'EXERCISE' THEN 1 ELSE 0 END) exercise_num_,
 			SUM( sees.expect_exercises_num_-sees.not_over_course_num_ )> SUM( sees.actual_exercises_num_ ) un_done_

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

@@ -281,7 +281,8 @@
     </sql>
     <sql id="queryTeacherAttendancesCondition">
         <where>
-            cs.del_flag_ = 0 AND (cs.new_course_id_ IS NULL OR cs.new_course_id_=cs.id_)
+            cs.del_flag_ = 0
+            AND (cs.new_course_id_ IS NULL OR cs.new_course_id_=cs.id_)
             <if test="search != null and search != ''">
                 AND (su.id_ = #{search} OR su.real_name_ LIKE CONCAT('%',#{search},'%') OR cs.id_ = #{search} OR cs.name_ LIKE CONCAT('%',#{search},'%'))
             </if>

+ 55 - 13
mec-student/src/main/java/com/ym/mec/student/controller/PracticeGroupController.java

@@ -2,17 +2,14 @@ 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.dao.ClassGroupDao;
-import com.ym.mec.biz.dal.dao.CourseScheduleEvaluateDao;
-import com.ym.mec.biz.dal.dao.PracticeGroupDao;
-import com.ym.mec.biz.dal.dao.SysConfigDao;
+import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.PracticeCourseDto;
 import com.ym.mec.biz.dal.dto.PracticeGroupBuyDto;
-import com.ym.mec.biz.dal.entity.ClassGroup;
-import com.ym.mec.biz.dal.entity.CourseScheduleEvaluate;
-import com.ym.mec.biz.dal.entity.PracticeGroup;
-import com.ym.mec.biz.dal.entity.SysConfig;
+import com.ym.mec.biz.dal.entity.*;
+import com.ym.mec.biz.dal.enums.GroupStatusEnum;
 import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.MessageTypeEnum;
+import com.ym.mec.biz.dal.enums.PracticeGroupType;
 import com.ym.mec.biz.service.PracticeGroupService;
 import com.ym.mec.biz.service.SysConfigService;
 import com.ym.mec.biz.service.SysMessageService;
@@ -20,15 +17,20 @@ import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
+import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.http.HttpUtil;
 import com.yonge.log.model.AuditLogAnnotation;
 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.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Author Joburgess
@@ -55,6 +57,8 @@ public class PracticeGroupController extends BaseController {
     private SysConfigDao sysConfigDao;
     @Autowired
     private CourseScheduleEvaluateDao courseScheduleEvaluateDao;
+    @Autowired
+    private StudentDao studentDao;
 
 //    private static final Set<Integer> ENABLE_APPLY_ORGANIDS = new HashSet<>(Arrays.asList(new Integer[]{28,34,37}));
 
@@ -173,12 +177,40 @@ public class PracticeGroupController extends BaseController {
 
     @ApiOperation("获取指定教师的空闲时间——付费")
     @GetMapping(value = "/getPayPracticeTeacherFreeTimes")
-    public Object getPayPracticeTeacherFreeTimes(Integer teacherId,Integer buyMonths, boolean renew, Long groupId){
+    public Object getPayPracticeTeacherFreeTimes(Integer teacherId,Integer buyMonths, boolean renew, Long groupId, PracticeGroupType type){
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        return succeed(practiceGroupService.getPayPracticeTeacherFreeTimes(sysUser.getId(),teacherId, buyMonths,renew,groupId));
+        Map payPracticeTeacherFreeTimes = practiceGroupService.getPayPracticeTeacherFreeTimes(sysUser.getId(),teacherId, buyMonths,renew,groupId);
+        if(Objects.nonNull(type)&&PracticeGroupType.COME_ON_PACKAGE.equals(type)){
+            Map<Integer, List<String>> weekNumApplyTimesMap = (Map<Integer, List<String>>) payPracticeTeacherFreeTimes.get("teacherFreeDays");
+            for (Map.Entry<Integer, List<String>> weekNumApplyTimesMapEntry : weekNumApplyTimesMap.entrySet()) {
+                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
+                Iterator<String> iterator = weekNumApplyTimesMapEntry.getValue().iterator();
+                while (iterator.hasNext()){
+                    String timeStr = iterator.next();
+                    if("23:30:00".equals(timeStr)){
+                        iterator.remove();
+                        continue;
+                    }
+                    LocalTime time = LocalTime.parse(timeStr, dtf);
+                    LocalTime nextTime = time.plusMinutes(30);
+                    if(weekNumApplyTimesMapEntry.getValue().contains(nextTime.format(DateUtil.timeFormatter))){
+                        continue;
+                    }
+                    iterator.remove();
+                }
+            }
+            Iterator<Map.Entry<Integer, List<String>>> iterator = weekNumApplyTimesMap.entrySet().iterator();
+            while (iterator.hasNext()) {
+                Map.Entry<Integer, List<String>> next = iterator.next();
+                if (CollectionUtils.isEmpty(next.getValue())) {
+                    iterator.remove();
+                }
+            }
+        }
+        return succeed(payPracticeTeacherFreeTimes);
     }
 
     @ApiOperation("获取学生上一次的购买信息--付费")
@@ -199,9 +231,15 @@ public class PracticeGroupController extends BaseController {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
         int studentExitChargePractices = practiceGroupDao.checkStudentExitChargePractice(sysUser.getId(),"2021-03-09 00:00:00");
+        Student student = studentDao.get(sysUser.getId());
         Map<String, Integer> result=new HashMap<>();
         result.put("organId", sysUser.getOrganId());
         result.put("isNewStudent", studentExitChargePractices<=0?0:1);
+
+        List<PracticeGroup> userStatusPracticeGroups = practiceGroupDao.findUserStatusPracticeGroups(sysUser.getId(), null, PracticeGroupType.COME_ON_PACKAGE);
+        long normalGroupNum = userStatusPracticeGroups.stream().filter(p -> GroupStatusEnum.NORMAL.equals(p.getGroupStatus())).count();
+
+        result.put("comeOnPackage", 1==student.getComeOnPackage()&&normalGroupNum<=0?1:0);
         return succeed(result);
     }
 
@@ -217,17 +255,21 @@ public class PracticeGroupController extends BaseController {
             throw new BizException("请联系老师确认您的所属分部");
         }
         practiceGroupBuyParams.setStudentId(sysUser.getId());
-        return practiceGroupService.buyPracticeGroup(practiceGroupBuyParams);
+        if(Objects.isNull(practiceGroupBuyParams.getType())||PracticeGroupType.CHARGE.equals(practiceGroupBuyParams.getType())){
+            return practiceGroupService.buyPracticeGroup(practiceGroupBuyParams);
+        }else{
+            return practiceGroupService.createPackagePracticeGroup(practiceGroupBuyParams);
+        }
     }
 
     @ApiOperation("获取用户历史购买的陪练课")
     @GetMapping(value = "/findUserHistoryBuyPracticeGroups")
-    public HttpResponseResult findUserHistoryBuyPracticeGroups(Long groupId){
+    public HttpResponseResult findUserHistoryBuyPracticeGroups(Long groupId, PracticeGroupType type){
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        return succeed(practiceGroupService.findUserHistoryBuyPracticeGroups(sysUser.getId(), groupId));
+        return succeed(practiceGroupService.findUserHistoryBuyPracticeGroups(sysUser.getId(), groupId, type));
     }
 
     @ApiOperation("查询订单信息")

+ 100 - 14
mec-web/src/main/java/com/ym/mec/web/controller/StudentRepairController.java

@@ -1,18 +1,27 @@
 package com.ym.mec.web.controller;
 
 
+import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.EmployeeDao;
+import com.ym.mec.biz.dal.dto.RepairGoodsDto;
+import com.ym.mec.biz.dal.entity.CooperationOrgan;
 import com.ym.mec.biz.dal.entity.Employee;
+import com.ym.mec.biz.dal.entity.StudentRepair;
+import com.ym.mec.biz.dal.page.CooperationOrganQueryInfo;
 import com.ym.mec.biz.dal.page.RepairStudentQueryInfo;
 import com.ym.mec.biz.service.StudentRepairService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
+import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.util.date.DateUtil;
+import com.ym.mec.util.excel.POIUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -21,10 +30,15 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 @RequestMapping("studentRepair")
 @Api(tags = "维修服务")
@@ -46,20 +60,20 @@ public class StudentRepairController extends BaseController {
         if (sysUser == null) {
             return failed("用户信息获取失败");
         }
-            Employee employee = employeeDao.get(sysUser.getId());
-            if (StringUtils.isEmpty(queryInfo.getOrganIdList())) {
-                queryInfo.setOrganIdList(employee.getOrganIdList());
-            }else if(StringUtils.isEmpty(employee.getOrganIdList())){
-                return failed("用户所在分部异常");
-            }else {
-                List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
-                if(!list.containsAll(Arrays.asList(queryInfo.getOrganIdList().split(",")))){
-                    return failed("非法请求");
-                }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(queryInfo.getOrganIdList())) {
+            queryInfo.setOrganIdList(employee.getOrganIdList());
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            return failed("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(queryInfo.getOrganIdList().split(",")))) {
+                return failed("非法请求");
             }
+        }
         Date endTime = queryInfo.getEndTime();
-        if(endTime != null){
-            queryInfo.setEndTime(DateUtil.addDays(endTime, 1));
+        if (endTime != null) {
+            queryInfo.setEndTime(DateUtil.getLastTimeWithDay(endTime));
         }
         queryInfo.setPayStatus(2);
         return succeed(studentRepairService.queryPage(queryInfo));
@@ -69,8 +83,80 @@ public class StudentRepairController extends BaseController {
     @ApiOperation("维修完成")
     @PostMapping(value = "/repairSuccess")
     @PreAuthorize("@pcs.hasPermissions('studentRepair/repairSuccess')")
-    public HttpResponseResult repairSuccess(Integer id,String description,Integer repairStatus) {
-        studentRepairService.repairSuccess(id,description,repairStatus);
+    public HttpResponseResult repairSuccess(Integer id, String description, Integer repairStatus) {
+        studentRepairService.repairSuccess(id, description, repairStatus);
         return succeed();
     }
+
+    @ApiOperation(value = "维修记录导出")
+    @RequestMapping("/export")
+    @PreAuthorize("@pcs.hasPermissions('studentRepair/export')")
+    public void export(RepairStudentQueryInfo queryInfo, HttpServletResponse response) throws Exception {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("用户信息获取失败");
+        }
+        Employee employee = employeeDao.get(sysUser.getId());
+        if (StringUtils.isEmpty(queryInfo.getOrganIdList())) {
+            queryInfo.setOrganIdList(employee.getOrganIdList());
+        } else if (StringUtils.isEmpty(employee.getOrganIdList())) {
+            throw new BizException("用户所在分部异常");
+        } else {
+            List<String> list = Arrays.asList(employee.getOrganIdList().split(","));
+            if (!list.containsAll(Arrays.asList(queryInfo.getOrganIdList().split(",")))) {
+                throw new BizException("非法请求");
+            }
+        }
+        Date endTime = queryInfo.getEndTime();
+        if (endTime != null) {
+            queryInfo.setEndTime(DateUtil.getLastTimeWithDay(endTime));
+        }
+        queryInfo.setPayStatus(2);
+        queryInfo.setRows(65000);
+
+        PageInfo<StudentRepair> pageList = studentRepairService.queryPage(queryInfo);
+
+        if (pageList.getTotal() <= 0) {
+            throw new BizException("没有可导出的记录");
+        }
+        for (StudentRepair row : pageList.getRows()) {
+            if (row.getGoodsJson() == null || row.getGoodsJson().equals("[]")) {
+                row.setAmount(row.getAmount().subtract(row.getExemptionAmount()));
+                row.setGoodsJson("");
+                continue;
+            }
+            List<RepairGoodsDto> repairGoodsDtos = JSONObject.parseArray(row.getGoodsJson(), RepairGoodsDto.class);
+            BigDecimal repairGoodsAmount = repairGoodsDtos.stream().map(RepairGoodsDto::getGroupPurchasePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal goodsRouteAmount = (row.getAmount().add(repairGoodsAmount).subtract(row.getExemptionAmount())).multiply(repairGoodsAmount).divide(row.getAmount().add(repairGoodsAmount), 2, BigDecimal.ROUND_DOWN);
+            BigDecimal repairRouteAmount = row.getAmount().add(repairGoodsAmount).subtract(row.getExemptionAmount()).subtract(goodsRouteAmount);
+            String goodiesStr = repairGoodsDtos.stream().map(RepairGoodsDto::getName).collect(Collectors.joining(","));
+            row.setGoodsJson(goodiesStr);
+            row.setRepairGoodsAmount(goodsRouteAmount);
+            row.setAmount(repairRouteAmount);
+        }
+
+        OutputStream outputStream = response.getOutputStream();
+        try {
+            String[] header = {"维修单号", "分部", "学生姓名", "学生编号", "维修技师", "维修类型", "维修单名称", "送修日期", "完成日期", "状态", "维修服务费", "商品价格", "销售商品"};
+            String[] body = {"transNo", "organName", "studentName", "studentId", "employeeName", "type == 0 ? '线下' : '线上'", "repairName", "createTime", "finishTime", "repairStatus == 0 ? '维修中' : '已完成'", "amount", "repairGoodsAmount", "goodsJson"};
+            HSSFWorkbook workbook = POIUtil.exportExcel(header, body, pageList.getRows());
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attachment;filename=repairList-" + DateUtil.getDate(new Date()) + ".xls");
+            response.flushBuffer();
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+            workbook.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 }

+ 1 - 1
mec-web/src/main/java/com/ym/mec/web/controller/education/EduPracticeGroupController.java

@@ -202,7 +202,7 @@ public class EduPracticeGroupController extends BaseController {
         if (sysUser == null) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        return succeed(practiceGroupService.findUserHistoryBuyPracticeGroups(studentId, groupId));
+        return succeed(practiceGroupService.findUserHistoryBuyPracticeGroups(studentId, groupId, null));
     }
 
     @ApiOperation("查询订单信息")