Selaa lähdekoodia

1、网管课初始类型
2、网管试听课

Joburgess 5 vuotta sitten
vanhempi
commit
d69ff13996

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

@@ -263,4 +263,13 @@ public interface PracticeGroupDao extends com.ym.mec.common.dal.BaseDAO<Long, Pr
      * @param memo
      */
     void updateMemo(@Param("groupId") Long groupId, @Param("memo") String memo);
+
+    /**
+     * @describe 获取学生最后一节网管课对应的声部
+     * @author Joburgess
+     * @date 2020/4/23
+     * @param studentId:
+     * @return java.lang.Integer
+     */
+    Integer findLastPracticeSubject(@Param("studentId") Integer studentId);
 }

+ 40 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/EduPracticeGroupService.java

@@ -7,6 +7,7 @@ import com.ym.mec.common.entity.HttpResponseResult;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @Author Joburgess
@@ -34,16 +35,52 @@ public interface EduPracticeGroupService {
     void orderCallback(StudentPaymentOrder order);
 
     /**
+     * @describe 获取陪练课预约参数——试听
+     * @author Joburgess
+     * @date 2020/1/31
+     * @param userId: 用户编号
+     * @return java.util.Map
+     */
+    Map getTrialPracticeApplyParams(Integer userId);
+
+    /**
      * @describe 获取可以指派试听课的老师列表
      * @author Joburgess
      * @date 2020/4/23
-     * @param studentOrganId: 学生分部编号
      * @param subjectId: 声部编号
      * @param studentId: 学生编号
      * @return java.util.List<com.ym.mec.biz.dal.dto.SimpleUserDto>
      */
-    List<SimpleUserDto> findEnableAssignTeachers(@Param("studentOrganId") Integer studentOrganId,
-                                                 @Param("subjectId") Integer subjectId,
+    List<SimpleUserDto> findEnableAssignTeachers(@Param("subjectId") Integer subjectId,
                                                  @Param("studentId") Integer studentId);
 
+    /**
+     * @describe 获取一周内可以预约课程的时间——试听
+     * @author Joburgess
+     * @date 2020/2/2
+     * @return java.util.Map
+     */
+    Map<Integer, List<String>> getEnableApplyDatesWithWeek();
+
+    /**
+     * @describe 获取指定教师的空闲时间——试听
+     * @author Joburgess
+     * @date 2020/2/10
+     * @param userId: 用户编号
+     * @param teacherId: 教师编号
+     * @param monday: 周一日期
+     * @return java.util.Map
+     */
+    Map getTrialPracticeTeacherFreeTimes(Integer userId, Integer teacherId, String monday);
+
+    /**
+     * @describe 网管试听课创建
+     * @author Joburgess
+     * @date 2020/2/17
+     * @param practiceGroupBuyParams: 购买参数
+     * @param operatorInfo: 操作者信息
+     * @return void
+     */
+    HttpResponseResult createTrialPracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams, String operatorInfo);
+
 }

+ 575 - 4
mec-biz/src/main/java/com/ym/mec/biz/service/impl/EduPracticeGroupServiceImpl.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;
@@ -20,6 +22,7 @@ import com.ym.mec.common.service.IdGeneratorService;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
 import com.ym.mec.util.date.DateUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,9 +34,9 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
-import java.time.DayOfWeek;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.WeekFields;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -98,6 +101,8 @@ public class EduPracticeGroupServiceImpl implements EduPracticeGroupService{
     private TeacherDefaultPracticeGroupSalaryDao teacherDefaultPracticeGroupSalaryDao;
     @Autowired
     private ContractService contractService;
+    @Autowired
+    private StudentDao studentDao;
 
     private static final Logger LOGGER = LoggerFactory
             .getLogger(EduPracticeGroupService.class);
@@ -587,8 +592,574 @@ public class EduPracticeGroupServiceImpl implements EduPracticeGroupService{
     }
 
     @Override
-    public List<SimpleUserDto> findEnableAssignTeachers(Integer studentOrganId, Integer subjectId, Integer studentId) {
+    public Map getTrialPracticeApplyParams(Integer userId) {
+        Map result = new HashMap();
+        SysConfig practiceSubjectIdListConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_SUBJECT_ID_LIST);
+        SysConfig practiceApplyIntervalTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_INTERVAL_TIME);
+        SysConfig practiceCourseMinutesConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_COURSE_MINUTES);
+
+        List<Subject> subjects = subjectDao.findBySubjectByIdList(practiceSubjectIdListConfig.getParanValue());
+        Integer userDefaultSubjectId = practiceGroupDao.findLastPracticeSubject(userId);
+
+        Collections.swap(subjects,6,7);
+        result.put("subjects", subjects);
+        result.put("userDefaultSubjectId", userDefaultSubjectId);
+        result.put("practiceApplyIntervalMinutes", practiceApplyIntervalTimeConfig.getParanValue(Integer.class));
+        result.put("practiceCourseMinutes", practiceCourseMinutesConfig.getParanValue(Integer.class));
+        return result;
+    }
+
+    @Override
+    public List<SimpleUserDto> findEnableAssignTeachers(Integer subjectId, Integer studentId) {
         Teacher student = teacherDao.get(studentId);
         return practiceGroupDao.findEnableAssignTeachers(student.getOrganId(), subjectId, studentId);
     }
+
+    @Override
+    public Map<Integer, List<String>> getEnableApplyDatesWithWeek() {
+        Map<Integer, List<String>> result = new HashMap<>();
+        SysConfig practiceApplyIntervalTimeConfig = sysConfigService.findByParamName(SysConfigService.PRACTICE_APPLY_INTERVAL_TIME);
+        Integer practiceApplyIntervalMinutes = practiceApplyIntervalTimeConfig.getParanValue(Integer.class);
+        LocalTime dayStartTime=LocalTime.parse("00:00:00",DateUtil.timeFormatter);
+        LocalTime dayEndTime=LocalTime.parse("00:00:00",DateUtil.timeFormatter);
+        List<String> dayApplyTimes=new ArrayList<>();
+        while (true){
+            dayApplyTimes.add(dayStartTime.format(DateUtil.timeFormatter));
+            dayStartTime=dayStartTime.plusMinutes(practiceApplyIntervalMinutes);
+            if(dayStartTime.compareTo(dayEndTime)==0){
+                break;
+            }
+        }
+        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 getTrialPracticeTeacherFreeTimes(Integer userId, Integer teacherId, String mondayStr) {
+        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();
+        int holiday = 0;
+        if (Objects.nonNull(teacherFreeTime)) {
+            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();
+
+        LocalDate monday = LocalDateTime.parse(mondayStr, ddf).toLocalDate();
+        LocalDate sunday = monday.with(weekFields.dayOfWeek(), DayOfWeek.SUNDAY.getValue());
+
+        Map<Integer, List<String>> weekNumApplyTimesMap = getEnableApplyDatesWithWeek();
+        List<CourseSchedule> allTeacherCourses = courseScheduleDao.findTeacherCoursesWithDateRangeWithoutMusicGroup(teacherId, Date.from(monday.atStartOfDay(zoneId).toInstant()), Date.from(sunday.atStartOfDay(zoneId).toInstant()));
+        allTeacherCourses.sort(Comparator.comparing(CourseSchedule::getStartClassTime));
+
+        JSONObject teacherLeaveData = null;
+        if (checkTeacherLeaveDate) {
+            teacherLeaveData = allTeacherLeaveData.getJSONObject(teacherId.toString());
+        }
+
+        if (Objects.isNull(teacherLeaveData)) {
+            checkTeacherLeaveDate = false;
+        }
+
+        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);
+                LocalDate tempDate = LocalDate.parse(dateStr, ddf);
+                if (tempDate.compareTo(monday)<0
+                        ||tempDate.compareTo(tempDate)>=0){
+                    continue;
+                }
+                List<String> applyTimeStrs = weekNumApplyTimesMap.get(parse.getDayOfWeek().getValue());
+                if(CollectionUtils.isEmpty(applyTimeStrs)){
+                    continue;
+                }
+                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(leaveEndTime) <= 0
+                            && defaultApplyEndTime.compareTo(leaveStartTime) >= 0) {
+                        iterator.remove();
+                        continue;
+                    }
+                }
+                if(!CollectionUtils.isEmpty(applyTimeStrs)){
+                    weekNumApplyTimesMap.put(parse.getDayOfWeek().getValue(), applyTimeStrs);
+                }else{
+                    weekNumApplyTimesMap.remove(parse.getDayOfWeek().getValue());
+                }
+            }
+        }
+
+        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);
+                if(CollectionUtils.isEmpty(applyTimeStrs)){
+                    continue;
+                }
+                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();
+                    }
+                }
+                if(CollectionUtils.isEmpty(applyTimeStrs)){
+                    weekNumApplyTimeIterator.remove();
+                }else{
+                    weekNumApplyTimesMap.put(weekNum,applyTimeStrs);
+                }
+            }else{
+                weekNumApplyTimeIterator.remove();
+            }
+        }
+
+        if (CollectionUtils.isEmpty(allTeacherCourses)) {
+            result.put("teacherFreeDays", weekNumApplyTimesMap);
+            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;
+                }
+            }
+            if(CollectionUtils.isEmpty(applyTimeStrs)){
+                weekNumApplyTimesMap.remove(courseStartTime.getDayOfWeek().getValue());
+            }else{
+                weekNumApplyTimesMap.put(courseStartTime.getDayOfWeek().getValue(), applyTimeStrs);
+            }
+        }
+        if(weekNumApplyTimesMap.size()<=1){
+            weekNumApplyTimesMap=new HashMap<>();
+        }
+        result.put("teacherFreeDays", weekNumApplyTimesMap);
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
+    public HttpResponseResult createTrialPracticeGroup(PracticeGroupBuyDto practiceGroupBuyParams, String operatorInfo) {
+        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.getFirstCourseTime())||Objects.isNull(practiceGroupBuyParams.getSecondCourseTime())){
+            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();
+        LocalDate courseStartDay=LocalDate.now();
+
+        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 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());
+
+        practiceGroupBuyParams.setName(subject.getName() + "•" + sysUser.getUsername());
+        List<CourseSchedule> practiceCourses = createPracticeCourses(practiceGroupBuyParams, practiceCourseMinutes);
+        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 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);
+        practiceGroupBuyParams.setGroupStatus(GroupStatusEnum.LOCK);
+        practiceGroupBuyParams.setMemo(operatorInfo+",教务代买");
+        practiceGroupBuyParams.setType(PracticeGroupType.CHARGE);
+        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);
+        }
+        courseScheduleDao.batchAddCourseSchedules(practiceCourses);
+        TeacherDefaultPracticeGroupSalary teacherDefaultPracticeGroupSalary = teacherDefaultPracticeGroupSalaryDao.findByTeacherAndCourseMinutes(practiceGroupBuyParams.getUserId(),practiceCourseMinutes);
+        BigDecimal teacherDefaultSalary=new BigDecimal(practiceCourseSalaryConfig.getParanValue());
+        if(Objects.nonNull(teacherDefaultPracticeGroupSalary)){
+            teacherDefaultSalary=teacherDefaultPracticeGroupSalary.getMainTeacherSalary();
+        }
+        BigDecimal studentSingleCourseCost=amount.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.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.checkNewCourseSchedulesWithoutMusicGroup(practiceCourses,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.setMemo(operatorInfo+",教务代买");
+        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());
+                studentPaymentOrder.setRoutingOrganId(42);
+
+                sysUserCashAccountService.updateBalance(practiceGroupBuyParams.getStudentId(), studentPaymentOrder.getExpectAmount().negate(),PlatformCashAccountDetailTypeEnum.PAY_FEE,operatorInfo+",教务代买");
+
+                studentPaymentOrder.setPayTime(now);
+                this.orderCallback(studentPaymentOrder);
+
+                Map<String,Object> result=new HashMap<>();
+                result.put("orderNo",studentPaymentOrder.getOrderNo());
+
+                return BaseController.succeed(result);
+            }else{
+                throw new BizException("账户余额不足,请完成账户充值");
+            }
+        }else{
+            throw new BizException("当前购买方式暂时只支持用户余额购买");
+        }
+    }
 }

+ 6 - 0
mec-biz/src/main/resources/config/mybatis/PracticeGroupMapper.xml

@@ -560,4 +560,10 @@
             AND (t.organ_id_ = #{studentOrganId} OR FIND_IN_SET(#{studentOrganId},t.flow_organ_range_))
             AND NOT EXISTS (SELECT user_id_ FROM practice_group WHERE student_id_=#{studentId} AND t.id_=user_id_ AND type_='TRIAL')
     </select>
+
+    <select id="findLastPracticeSubject" resultType="int">
+        SELECT pg.subject_id_ FROM course_schedule_student_payment cssp LEFT JOIN course_schedule cs ON cs.id_=cssp.course_schedule_id_
+        LEFT JOIN practice_group pg ON cssp.music_group_id_=pg.id_
+        WHERE cssp.group_type_='PRACTICE' AND cssp.user_id_=#{studentId} ORDER BY CONCAT(cs.class_date_, ' ', cs.start_class_time_) DESC LIMIT 1
+    </select>
 </mapper>

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

@@ -182,6 +182,23 @@ public class EduPracticeGroupController extends BaseController {
         return practiceGroupService.cancelWaitPayOrder(studentId, groupId);
     }
 
+    @ApiOperation("获取陪练课预约参数——试听")
+    @GetMapping(value = "/getPayPracticeApplyParams")
+    public Object getTrialPracticeApplyParams(Integer studentId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if(Objects.isNull(studentId)){
+            throw new BizException("请指定学生");
+        }
+        SysUser student = teacherDao.getUser(studentId);
+        if(Objects.isNull(student)){
+            throw new BizException("指定的学生不存在");
+        }
+        return succeed(eduPracticeGroupService.getTrialPracticeApplyParams(studentId));
+    }
+
     @ApiOperation("获取转化失败的学员列表")
     @GetMapping(value = "/findConvertDefeatStudents")
     public HttpResponseResult findConvertDefeatStudents(QueryInfo queryInfo){
@@ -192,4 +209,40 @@ public class EduPracticeGroupController extends BaseController {
         return succeed(practiceGroupService.findConvertDefeatStudents(queryInfo));
     }
 
+    @ApiOperation("获取可以指派试听课的老师列表")
+    @GetMapping(value = "/findEnableAssignTeachers")
+    public HttpResponseResult findEnableAssignTeachers(Integer subjectId,Integer studentId){
+        return succeed(eduPracticeGroupService.findEnableAssignTeachers(subjectId,studentId));
+    }
+
+    @ApiOperation("获取指定教师的空闲时间——试听")
+    @GetMapping(value = "/getPayPracticeTeacherFreeTimes")
+    public HttpResponseResult getTrialPracticeTeacherFreeTimes(Integer userId, Integer teacherId, String monday){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if(Objects.isNull(userId)){
+            return failed("请指定学生");
+        }
+        if(Objects.isNull(teacherId)){
+            return failed("请指定教师");
+        }
+        return succeed(eduPracticeGroupService.getTrialPracticeTeacherFreeTimes(userId, teacherId, monday));
+    }
+
+    @ApiOperation("创建网管试听课")
+    @PostMapping(value = "/createTrialPracticeGroup")
+    public HttpResponseResult createTrialPracticeGroup(@RequestBody PracticeGroupBuyDto practiceGroupBuyParams){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if(Objects.isNull(practiceGroupBuyParams.getStudentId())){
+            throw new BizException("请指定学生");
+        }
+        practiceGroupBuyParams.setEducationalTeacherId(sysUser.getId());
+        return eduPracticeGroupService.createTrialPracticeGroup(practiceGroupBuyParams, sysUser.getRealName()+"("+sysUser.getId()+")");
+    }
+
 }