Browse Source

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

zouxuan 5 years ago
parent
commit
923a943f7f

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

@@ -263,4 +263,23 @@ 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);
+
+    /**
+     * @describe 获取学生的网管试听课
+     * @author Joburgess
+     * @date 2020/4/24
+     * @param studentId:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.PracticeGroup>
+     */
+    List<PracticeGroup> findStudentTrialPractices(@Param("studentId") Integer studentId);
+    int countStudentTrialPractices(@Param("studentId") Integer studentId);
 }

+ 4 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java

@@ -58,6 +58,10 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     HOMEWORK_STUDENT_REPLY_PUSH("HOMEWORK_STUDENT_REPLY_PUSH", "学生作业回复提醒"),
     HOMEWORK_TEACHER_REPLY_PUSH("HOMEWORK_TEACHER_REPLY_PUSH", "教师回复作业提醒"),
 
+    /**试听课*/
+    TRIAL_PRACTICE_CREATE_STUDENT_PUSH("TRIAL_PRACTICE_CREATE_STUDENT_PUSH", "试听课安排"),
+    TRIAL_PRACTICE_CREATE_TEACHER_PUSH("TRIAL_PRACTICE_CREATE_TEACHER_PUSH", "试听课安排"),
+
     /** 课外训练消息 */
     EXTRA_REMIND_PUSH("EXTRA_REMIND_PUSH", "作业提醒"),
     EXTRA_REMIND_IM("EXTRA_REMIND_IM", "作业提醒"),

+ 49 - 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,61 @@ 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);
+
+    /**
+     * @describe 获取学生的试听课
+     * @author Joburgess
+     * @date 2020/4/24
+     * @param studentId:
+     * @return java.util.List<com.ym.mec.biz.dal.entity.PracticeGroup>
+     */
+    Map<String, Object> getStudentTrialPractices(Integer studentId);
+
 }

+ 539 - 5
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,537 @@ public class EduPracticeGroupServiceImpl implements EduPracticeGroupService{
     }
 
     @Override
-    public List<SimpleUserDto> findEnableAssignTeachers(Integer studentOrganId, Integer subjectId, Integer studentId) {
-        Teacher student = teacherDao.get(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) {
+        SysUser student = teacherDao.getUser(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 = LocalDate.parse(mondayStr, ddf);
+        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, "请确定上课时间");
+        }
+        if(DateUtil.daysBetween(practiceGroupBuyParams.getFirstCourseTime(),practiceGroupBuyParams.getSecondCourseTime())>7){
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "两次课程的时间需安排在七天内");
+        }
+
+        studentDao.lockUser(practiceGroupBuyParams.getStudentId());
+
+        int studentTrialPracticeNum = practiceGroupDao.countStudentTrialPractices(practiceGroupBuyParams.getStudentId());
+        if(studentTrialPracticeNum>=3){
+            return BaseController.failed(HttpStatus.EXPECTATION_FAILED, "指定的学生已存在三组试听课");
+        }
+
+        SysUser student = teacherDao.getUser(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);
+
+        List<Date> courseDates=new ArrayList<>();
+        courseDates.add(practiceGroupBuyParams.getFirstCourseTime());
+        courseDates.add(practiceGroupBuyParams.getSecondCourseTime());
+        courseDates.sort(Comparator.comparing(Date::getTime));
+
+        Date now=new Date();
+        if(courseDates.get(0).before(now)){
+            throw new BizException("课程开始时间不得小于当前时间");
+        }
+
+        practiceGroupBuyParams.setName(subject.getName() + "•" + student.getUsername());
+
+        TeacherFreeTime teacherFreeTime = teacherFreeTimeDao.findTeacherFreeTime(practiceGroupBuyParams.getUserId());
+        if (Objects.isNull(teacherFreeTime)) {
+            return BaseController.failed(HttpStatus.MULTIPLE_CHOICES,"抱歉啦,当前所选时段组合,「" + teacher.getRealName() + "」老师已被预约,请重新选择时段或更换老师后重试。");
+        }
+
+        practiceGroupBuyParams.setCoursesStartDate(courseDates.get(0));
+        practiceGroupBuyParams.setCoursesExpireDate(DateUtil.addMinutes(courseDates.get(1),practiceCourseMinutes));
+        practiceGroupBuyParams.setOrganId(student.getOrganId());
+        practiceGroupBuyParams.setSingleClassMinutes(practiceCourseMinutes);
+        practiceGroupBuyParams.setGroupStatus(GroupStatusEnum.NORMAL);
+        practiceGroupBuyParams.setType(PracticeGroupType.TRIAL);
+        practiceGroupDao.insert(practiceGroupBuyParams);
+
+        //创建班级信息
+        ClassGroup classGroup = new ClassGroup();
+        classGroup.setSubjectIdList(practiceGroupBuyParams.getSubjectId().toString());
+        classGroup.setExpectStudentNum(1);
+        classGroup.setStudentNum(1);
+        classGroup.setName(practiceGroupBuyParams.getName());
+        classGroup.setTotalClassTimes(2);
+        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(BigDecimal.ZERO);
+        classGroupTeacherSalary.setOnlineClassesSalary(BigDecimal.ZERO);
+        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<>();
+
+        List<CourseSchedule> practiceCourses = new ArrayList<>();
+        for (Date courseDate : courseDates) {
+            CourseSchedule courseSchedule=new CourseSchedule();
+            LocalDateTime courseStartDateTime = LocalDateTime.ofInstant(courseDate.toInstant(), DateUtil.zoneId);
+            LocalDateTime courseEndDateTime = courseStartDateTime.plusMinutes(practiceCourseMinutes);
+            courseSchedule.setClassDate(Date.from(courseStartDateTime.atZone(DateUtil.zoneId).toInstant()));
+            courseSchedule.setStartClassTime(Date.from(courseStartDateTime.atZone(DateUtil.zoneId).toInstant()));
+            courseSchedule.setEndClassTime(Date.from(courseEndDateTime.atZone(DateUtil.zoneId).toInstant()));
+            courseSchedule.setName(practiceGroupBuyParams.getName());
+            courseSchedule.setTeacherId(practiceGroupBuyParams.getUserId());
+            courseSchedule.setActualTeacherId(practiceGroupBuyParams.getUserId());
+            courseSchedule.setTeachMode(TeachModeEnum.ONLINE);
+            courseSchedule.setGroupType(GroupType.PRACTICE);
+            courseSchedule.setType(CourseSchedule.CourseScheduleType.PRACTICE);
+            courseSchedule.setStatus(CourseStatusEnum.NOT_START);
+            courseSchedule.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+            courseSchedule.setClassGroupId(classGroup.getId());
+            courseSchedule.setStatus(CourseStatusEnum.NOT_START);
+            courseSchedule.setCreateTime(now);
+            courseSchedule.setUpdateTime(now);
+            courseSchedule.setIsLock(0);
+            practiceCourses.add(courseSchedule);
+        }
+        practiceCourses.sort(Comparator.comparing(CourseSchedule::getStartClassTime));
+        courseScheduleDao.batchAddCourseSchedules(practiceCourses);
+
+        BigDecimal teacherDefaultSalary=BigDecimal.ZERO;
+        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(BigDecimal.ZERO);
+            courseScheduleStudentPayment.setClassGroupId(classGroup.getId());
+            courseScheduleStudentPayment.setCreateTime(now);
+            courseScheduleStudentPayment.setUpdateTime(now);
+            courseScheduleStudentPayments.add(courseScheduleStudentPayment);
+
+            //教师签到记录
+            TeacherAttendance teacherAttendance = new TeacherAttendance();
+            teacherAttendance.setMusicGroupId(practiceGroupBuyParams.getId().toString());
+            teacherAttendance.setTeacherId(practiceGroupBuyParams.getUserId());
+            teacherAttendance.setClassGroupId(classGroup.getId());
+            teacherAttendance.setGroupType(GroupType.PRACTICE);
+            teacherAttendance.setCourseScheduleId(courseSchedule.getId());
+            teacherAttendance.setCreateTime(now);
+            teacherAttendances.add(teacherAttendance);
+        }
+        courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaries);
+        courseScheduleStudentPaymentDao.batchInsert(courseScheduleStudentPayments);
+        teacherAttendanceDao.batchInsert(teacherAttendances);
+
+        try {
+            courseScheduleService.checkNewCourseSchedulesWithoutMusicGroup(practiceCourses,false);
+        } catch (Exception e) {
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            String errMessage;
+            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);
+        }
+
+        try{
+            DateTimeFormatter mmdd = DateTimeFormatter.ofPattern("M月d日");
+            DateTimeFormatter hhmm = DateTimeFormatter.ofPattern("H:mm");
+            LocalDateTime oneCourseStartTime = LocalDateTime.ofInstant(courseDates.get(0).toInstant(), DateUtil.zoneId);
+            String oneCourseMMdd=mmdd.format(oneCourseStartTime);
+            String oneCourseHHmm=hhmm.format(oneCourseStartTime);
+            String oneCourseStartTimeDayOfWeekName = DateUtil.weekNumNormalWeekNameMap.get(oneCourseStartTime.getDayOfWeek().getValue());
+            String oneCourseTimeStr = oneCourseMMdd + "(" + oneCourseStartTimeDayOfWeekName + ")" + oneCourseHHmm;
+            LocalDateTime twoCourseStartTime = LocalDateTime.ofInstant(courseDates.get(1).toInstant(), DateUtil.zoneId);
+            String twoCourseMMdd=mmdd.format(twoCourseStartTime);
+            String twoCourseHHmm=hhmm.format(twoCourseStartTime);
+            String twoCourseStartTimeDayOfWeekName = DateUtil.weekNumNormalWeekNameMap.get(twoCourseStartTime.getDayOfWeek().getValue());
+            String twoCourseTimeStr = twoCourseMMdd + "(" + twoCourseStartTimeDayOfWeekName + ")" + twoCourseHHmm;
+
+            Map<Integer, String> userMap = new HashMap<>();
+            userMap.put(practiceGroupBuyParams.getStudentId(), practiceGroupBuyParams.getStudentId().toString());
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TRIAL_PRACTICE_CREATE_STUDENT_PUSH,
+                    userMap, null, 0, null, "STUDENT", student.getUsername(), teacher.getRealName(),
+                    oneCourseTimeStr, twoCourseTimeStr);
+//            Map<Integer, String> userPhoneMap = new HashMap<>();
+//            userPhoneMap.put(practiceGroupBuyParams.getStudentId(), student.getPhone());
+//            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.YIMEI, MessageTypeEnum.TRIAL_PRACTICE_CREATE_STUDENT_PUSH,
+//                    userPhoneMap, null, 0, null, "STUDENT", student.getUsername(), teacher.getRealName(),
+//                    oneCourseTimeStr, twoCourseTimeStr);
+
+            Map<Integer, String> teacherMap = new HashMap<>();
+            teacherMap.put(practiceGroupBuyParams.getUserId(), practiceGroupBuyParams.getUserId().toString());
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TRIAL_PRACTICE_CREATE_TEACHER_PUSH,
+                    teacherMap, null, 0, null, "TEACHER", teacher.getRealName(), practiceGroupBuyParams.getName(),
+                    oneCourseTimeStr, twoCourseTimeStr);
+//            Map<Integer, String> teacherPhoneMap = new HashMap<>();
+//            teacherPhoneMap.put(practiceGroupBuyParams.getUserId(), teacher.getPhone());
+//            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.YIMEI, MessageTypeEnum.TRIAL_PRACTICE_CREATE_TEACHER_PUSH,
+//                    teacherPhoneMap, null, 0, null, "TEACHER", teacher.getRealName(), practiceGroupBuyParams.getName(),
+//                    oneCourseTimeStr, twoCourseTimeStr);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return BaseController.succeed();
+    }
+
+    @Override
+    public Map<String, Object> getStudentTrialPractices(Integer studentId) {
+        List<PracticeGroup> studentTrialPractices = practiceGroupDao.findStudentTrialPractices(studentId);
+        Integer existNoMemoGroup = 0;
+        for (PracticeGroup studentTrialPractice : studentTrialPractices) {
+            if (StringUtils.isBlank(studentTrialPractice.getMemo())){
+                existNoMemoGroup=1;
+                break;
+            }
+        }
+        Map<String, Object> result=new HashMap<>();
+        result.put("existNoMemoGroup", existNoMemoGroup);
+        result.put("practices", studentTrialPractices);
+        return result;
+    }
 }

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

@@ -384,7 +384,7 @@
 	
 	<select id="queryStudentNotStartCourseTimesOfOnline" resultMap="studentCourseTimesDto">
 		SELECT cssp.`user_id_`,count(*) totalTimes, 
-		sum(CASE type_ WHEN 'FREE' THEN 0 WHEN 'CHARGE' THEN 1 END) practiceTmes,
+		sum(CASE pg.type_ WHEN 'FREE' THEN 0 WHEN 'CHARGE' THEN 1 END) practiceTmes,
 		sum(case when (pg.type_='FREE' AND cssp.`group_type_` = 'PRACTICE' ) then 1 ELSE 0 END) freePracticeTimes
 		FROM course_schedule_student_payment cssp LEFT JOIN course_schedule cs on cssp.course_schedule_id_ = cs.id_
 		LEFT JOIN practice_group pg ON pg.id_ = cs.music_group_id_ AND cs.group_type_ = 'PRACTICE'

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

@@ -560,4 +560,40 @@
             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>
+
+    <select id="findStudentTrialPractices" resultMap="PracticeGroupDto">
+        SELECT
+            pg.id_,
+            pg.name_,
+            pg.user_id_,
+            su.real_name_ teacher_name_,
+            MIN(CONCAT(cs.class_date_, ' ', cs.start_class_time_)) courses_start_date_,
+            MAX(CONCAT(cs.class_date_, ' ', cs.end_class_time_)) courses_expire_date_,
+            pg.memo_
+        FROM
+            practice_group pg
+            LEFT JOIN course_schedule cs ON cs.music_group_id_ = pg.id_
+            LEFT JOIN sys_user su ON su.id_=pg.user_id_
+        WHERE
+            pg.student_id_ = #{studentId}
+            AND cs.group_type_ = 'PRACTICE'
+            AND pg.type_ = 'TRIAL'
+        GROUP BY pg.id_
+        ORDER BY pg.id_
+    </select>
+    <select id="countStudentTrialPractices" resultType="int">
+        SELECT
+            COUNT(pg.id_)
+        FROM
+            practice_group pg
+        WHERE
+            pg.student_id_ = #{studentId}
+            AND pg.type_ = 'TRIAL'
+    </select>
 </mapper>

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

@@ -6,6 +6,7 @@ import com.ym.mec.biz.dal.dao.EmployeeDao;
 import com.ym.mec.biz.dal.dao.TeacherDao;
 import com.ym.mec.biz.dal.dto.PracticeGroupBuyDto;
 import com.ym.mec.biz.dal.entity.Employee;
+import com.ym.mec.biz.dal.entity.PracticeGroup;
 import com.ym.mec.biz.dal.page.StudentQueryInfo;
 import com.ym.mec.biz.service.EduPracticeGroupService;
 import com.ym.mec.biz.service.PracticeGroupService;
@@ -182,6 +183,23 @@ public class EduPracticeGroupController extends BaseController {
         return practiceGroupService.cancelWaitPayOrder(studentId, groupId);
     }
 
+    @ApiOperation("获取陪练课预约参数——试听")
+    @GetMapping(value = "/getTrialPracticeApplyParams")
+    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 +210,57 @@ 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 = "/getTrialPracticeTeacherFreeTimes")
+    public HttpResponseResult getTrialPracticeTeacherFreeTimes(Integer studentId, Integer teacherId, String monday){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if(Objects.isNull(studentId)){
+            return failed("请指定学生");
+        }
+        if(Objects.isNull(teacherId)){
+            return failed("请指定教师");
+        }
+        return succeed(eduPracticeGroupService.getTrialPracticeTeacherFreeTimes(studentId, 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()+")");
+    }
+
+    @ApiOperation("获取学生的试听课")
+    @GetMapping(value = "/getStudentTrialPractices")
+    public HttpResponseResult getStudentTrialPractices(Integer studentId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(eduPracticeGroupService.getStudentTrialPractices(studentId));
+    }
+
+    @ApiOperation("更新课程组信息")
+    @GetMapping(value = "/updatePractice")
+    public HttpResponseResult updatePractice(PracticeGroup practiceGroup){
+        practiceGroupService.update(practiceGroup);
+        return succeed();
+    }
+
 }