|  | @@ -21,6 +21,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.*;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.enums.*;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.service.*;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.support.DistributedLock;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.support.PageUtil;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.vo.*;
 | 
	
	
		
			
				|  | @@ -34,7 +35,6 @@ import com.yonge.toolset.utils.date.DateUtil;
 | 
	
		
			
				|  |  |  import com.yonge.toolset.utils.obj.ObjectUtil;
 | 
	
		
			
				|  |  |  import org.apache.commons.collections.CollectionUtils;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  | -import org.redisson.api.RLock;
 | 
	
		
			
				|  |  |  import org.redisson.api.RMap;
 | 
	
		
			
				|  |  |  import org.redisson.api.RedissonClient;
 | 
	
		
			
				|  |  |  import org.slf4j.Logger;
 | 
	
	
		
			
				|  | @@ -870,12 +870,12 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | -     * @Description: 学生购买陪练课
 | 
	
		
			
				|  |  | +     * @Description: 陪练课购买记录
 | 
	
		
			
				|  |  |       * @Author: cy
 | 
	
		
			
				|  |  | -     * @Date: 2022/4/21
 | 
	
		
			
				|  |  | +     * @Date: 2022/5/16
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | -    public HttpResponseResult<OrderCreateRes> buyPracticeCourse(OrderReq.OrderReqInfo orderReqInfo) {
 | 
	
		
			
				|  |  | +    public HttpResponseResult<OrderCreateRes> buyPracticeCourseTran(OrderReq.OrderReqInfo orderReqInfo) {
 | 
	
		
			
				|  |  |          log.info("buyPracticeCourse  param:{}", JSON.toJSONString(orderReqInfo));
 | 
	
		
			
				|  |  |          Long studentId = orderReqInfo.getUserId();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -897,88 +897,84 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
 | 
	
		
			
				|  |  |          if (multiply.compareTo(scheduleDto.getCoursePrice()) != 0) {
 | 
	
		
			
				|  |  |              throw new BizException("价格异常。预计价格:{},实际价格:{}", multiply, scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          //批量检查老师课时在数据库是否重复
 | 
	
		
			
				|  |  |          batchCheckTeacherCourseTime(scheduleDto.getTeacherId(), dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
 | 
	
		
			
				|  |  |          //批量检查学生课时在数据库是否重复
 | 
	
		
			
				|  |  |          batchCheckStudentCourseTime(studentId, dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        RLock lock = redissonClient.getLock("buyPractice:teacherId:" + scheduleDto.getTeacherId());
 | 
	
		
			
				|  |  | -        try {
 | 
	
		
			
				|  |  | -            if (lock.tryLock(60, 20, TimeUnit.SECONDS)) {
 | 
	
		
			
				|  |  | -                //批量检查老师课时在数据库是否重复
 | 
	
		
			
				|  |  | -                batchCheckTeacherCourseTime(scheduleDto.getTeacherId(), dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
 | 
	
		
			
				|  |  | -                //批量检查学生课时在数据库是否重复
 | 
	
		
			
				|  |  | -                batchCheckStudentCourseTime(studentId, dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                String orderNo = orderReqInfo.getOrderNo();
 | 
	
		
			
				|  |  | -                scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
 | 
	
		
			
				|  |  | -                scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
 | 
	
		
			
				|  |  | -                scheduleDto.setMixStudentNum(1);
 | 
	
		
			
				|  |  | -                scheduleDto.setStudentId(studentId);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                //写入course_group
 | 
	
		
			
				|  |  | -                baseMapper.addCourseGroup(scheduleDto);
 | 
	
		
			
				|  |  | -                Long groupId = scheduleDto.getGroupId();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                //根据老师id获取默认配置声部原价
 | 
	
		
			
				|  |  | -                TeacherSubjectPrice teacherSubjectPrice = teacherFreeTimeDao.selectSubjectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());
 | 
	
		
			
				|  |  | -                BigDecimal subjectPrice = teacherSubjectPrice.getSubjectPrice();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                //每课实际价格
 | 
	
		
			
				|  |  | -                Map<Integer, BigDecimal> courseAveragePrice = WrapperUtil.getAveragePrice(scheduleDto.getCourseNum(), scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                List<CourseScheduleDate> classTime = scheduleDto.getClassTime();
 | 
	
		
			
				|  |  | -                for (int i = 0; i < classTime.size(); i++) {
 | 
	
		
			
				|  |  | -                    CourseScheduleDate date = classTime.get(i);
 | 
	
		
			
				|  |  | -                    CourseSchedule schedule = new CourseSchedule();
 | 
	
		
			
				|  |  | -                    schedule.setClassDate(date.getClassDate());
 | 
	
		
			
				|  |  | -                    schedule.setStartTime(date.getStartTime());
 | 
	
		
			
				|  |  | -                    schedule.setEndTime(date.getEndTime());
 | 
	
		
			
				|  |  | -                    schedule.setCourseGroupId(groupId);
 | 
	
		
			
				|  |  | -                    schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
 | 
	
		
			
				|  |  | -                    schedule.classNum(i + 1);
 | 
	
		
			
				|  |  | -                    schedule.setTeacherId(scheduleDto.getTeacherId());
 | 
	
		
			
				|  |  | -                    schedule.setLock(1);
 | 
	
		
			
				|  |  | -                    schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
 | 
	
		
			
				|  |  | -                    schedule.setCreatedBy(scheduleDto.getStudentId());
 | 
	
		
			
				|  |  | -                    //写入course_schedule
 | 
	
		
			
				|  |  | -                    baseMapper.insert(schedule);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    Long scheduleId = schedule.getId();
 | 
	
		
			
				|  |  | -                    CourseScheduleStudentPayment payment = new CourseScheduleStudentPayment();
 | 
	
		
			
				|  |  | -                    payment.setUserId(scheduleDto.getStudentId());
 | 
	
		
			
				|  |  | -                    payment.setCourseId(scheduleId);
 | 
	
		
			
				|  |  | -                    payment.setCourseGroupId(groupId);
 | 
	
		
			
				|  |  | -                    payment.setCourseType(CourseScheduleEnum.PRACTICE.getCode());
 | 
	
		
			
				|  |  | -                    payment.setOrderNo(orderNo);
 | 
	
		
			
				|  |  | -                    payment.setOriginalPrice(subjectPrice);//原价
 | 
	
		
			
				|  |  | -                    payment.setExpectPrice(subjectPrice);//预计价格
 | 
	
		
			
				|  |  | -                    payment.setActualPrice(courseAveragePrice.get(i + 1));//实际价格
 | 
	
		
			
				|  |  | -                    //写入course_schedule_student_payment
 | 
	
		
			
				|  |  | -                    courseScheduleStudentPaymentService.save(payment);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                OrderCreateRes orderCreateRes = new OrderCreateRes();
 | 
	
		
			
				|  |  | -                orderCreateRes.setRes(true);
 | 
	
		
			
				|  |  | -                orderCreateRes.setMerchId(scheduleDto.getTeacherId());
 | 
	
		
			
				|  |  | -                orderCreateRes.setBizId(groupId);
 | 
	
		
			
				|  |  | -                orderCreateRes.setOriginalPrice(scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  | -                orderCreateRes.setExpectPrice(scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  | -                orderCreateRes.setGoodNum(scheduleDto.getCourseNum());
 | 
	
		
			
				|  |  | -                orderCreateRes.setGoodType(GoodTypeEnum.PRACTICE);
 | 
	
		
			
				|  |  | -                HttpResponseResult<OrderCreateRes> httpResponseResult = new HttpResponseResult<>();
 | 
	
		
			
				|  |  | -                httpResponseResult.setData(orderCreateRes);
 | 
	
		
			
				|  |  | -                log.info("buyPracticeCourse  return {}", httpResponseResult);
 | 
	
		
			
				|  |  | -                return httpResponseResult;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        } catch (InterruptedException e) {
 | 
	
		
			
				|  |  | -            log.error("runIfLockCanGet error lockName : {}", "buyPractice:teacherId:" + scheduleDto.getTeacherId(), e);
 | 
	
		
			
				|  |  | -            throw new RuntimeException("runIfLockCanGet error lockName :" + "buyPractice:teacherId:" + scheduleDto.getTeacherId(), e);
 | 
	
		
			
				|  |  | -        } finally {
 | 
	
		
			
				|  |  | -            lock.unlock();
 | 
	
		
			
				|  |  | +        String orderNo = orderReqInfo.getOrderNo();
 | 
	
		
			
				|  |  | +        scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
 | 
	
		
			
				|  |  | +        scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
 | 
	
		
			
				|  |  | +        scheduleDto.setMixStudentNum(1);
 | 
	
		
			
				|  |  | +        scheduleDto.setStudentId(studentId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //写入course_group
 | 
	
		
			
				|  |  | +        baseMapper.addCourseGroup(scheduleDto);
 | 
	
		
			
				|  |  | +        Long groupId = scheduleDto.getGroupId();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //根据老师id获取默认配置声部原价
 | 
	
		
			
				|  |  | +        TeacherSubjectPrice teacherSubjectPrice = teacherFreeTimeDao.selectSubjectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());
 | 
	
		
			
				|  |  | +        BigDecimal subjectPrice = teacherSubjectPrice.getSubjectPrice();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //每课实际价格
 | 
	
		
			
				|  |  | +        Map<Integer, BigDecimal> courseAveragePrice = WrapperUtil.getAveragePrice(scheduleDto.getCourseNum(), scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<CourseScheduleDate> classTime = scheduleDto.getClassTime();
 | 
	
		
			
				|  |  | +        for (int i = 0; i < classTime.size(); i++) {
 | 
	
		
			
				|  |  | +            CourseScheduleDate date = classTime.get(i);
 | 
	
		
			
				|  |  | +            CourseSchedule schedule = new CourseSchedule();
 | 
	
		
			
				|  |  | +            schedule.setClassDate(date.getClassDate());
 | 
	
		
			
				|  |  | +            schedule.setStartTime(date.getStartTime());
 | 
	
		
			
				|  |  | +            schedule.setEndTime(date.getEndTime());
 | 
	
		
			
				|  |  | +            schedule.setCourseGroupId(groupId);
 | 
	
		
			
				|  |  | +            schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
 | 
	
		
			
				|  |  | +            schedule.classNum(i + 1);
 | 
	
		
			
				|  |  | +            schedule.setTeacherId(scheduleDto.getTeacherId());
 | 
	
		
			
				|  |  | +            schedule.setLock(1);
 | 
	
		
			
				|  |  | +            schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
 | 
	
		
			
				|  |  | +            schedule.setCreatedBy(scheduleDto.getStudentId());
 | 
	
		
			
				|  |  | +            //写入course_schedule
 | 
	
		
			
				|  |  | +            baseMapper.insert(schedule);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Long scheduleId = schedule.getId();
 | 
	
		
			
				|  |  | +            CourseScheduleStudentPayment payment = new CourseScheduleStudentPayment();
 | 
	
		
			
				|  |  | +            payment.setUserId(scheduleDto.getStudentId());
 | 
	
		
			
				|  |  | +            payment.setCourseId(scheduleId);
 | 
	
		
			
				|  |  | +            payment.setCourseGroupId(groupId);
 | 
	
		
			
				|  |  | +            payment.setCourseType(CourseScheduleEnum.PRACTICE.getCode());
 | 
	
		
			
				|  |  | +            payment.setOrderNo(orderNo);
 | 
	
		
			
				|  |  | +            payment.setOriginalPrice(subjectPrice);//原价
 | 
	
		
			
				|  |  | +            payment.setExpectPrice(subjectPrice);//预计价格
 | 
	
		
			
				|  |  | +            payment.setActualPrice(courseAveragePrice.get(i + 1));//实际价格
 | 
	
		
			
				|  |  | +            //写入course_schedule_student_payment
 | 
	
		
			
				|  |  | +            courseScheduleStudentPaymentService.save(payment);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return HttpResponseResult.failed();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        OrderCreateRes orderCreateRes = new OrderCreateRes();
 | 
	
		
			
				|  |  | +        orderCreateRes.setRes(true);
 | 
	
		
			
				|  |  | +        orderCreateRes.setMerchId(scheduleDto.getTeacherId());
 | 
	
		
			
				|  |  | +        orderCreateRes.setBizId(groupId);
 | 
	
		
			
				|  |  | +        orderCreateRes.setOriginalPrice(scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  | +        orderCreateRes.setExpectPrice(scheduleDto.getCoursePrice());
 | 
	
		
			
				|  |  | +        orderCreateRes.setGoodNum(scheduleDto.getCourseNum());
 | 
	
		
			
				|  |  | +        orderCreateRes.setGoodType(GoodTypeEnum.PRACTICE);
 | 
	
		
			
				|  |  | +        HttpResponseResult<OrderCreateRes> httpResponseResult = new HttpResponseResult<>();
 | 
	
		
			
				|  |  | +        httpResponseResult.setData(orderCreateRes);
 | 
	
		
			
				|  |  | +        log.info("buyPracticeCourse  return {}", httpResponseResult);
 | 
	
		
			
				|  |  | +        return httpResponseResult;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * @Description: 学生购买陪练课
 | 
	
		
			
				|  |  | +     * @Author: cy
 | 
	
		
			
				|  |  | +     * @Date: 2022/4/21
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public HttpResponseResult<OrderCreateRes> buyPracticeCourse(OrderReq.OrderReqInfo orderReqInfo) {
 | 
	
		
			
				|  |  | +        ObjectMapper objectMapper = new ObjectMapper();
 | 
	
		
			
				|  |  | +        PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderReqInfo.getBizContent(), PracticeScheduleDto.class);
 | 
	
		
			
				|  |  | +        return DistributedLock.of(redissonClient)
 | 
	
		
			
				|  |  | +                .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + scheduleDto.getTeacherId())
 | 
	
		
			
				|  |  | +                        , () -> this.buyPracticeCourseTran(orderReqInfo), 60L, TimeUnit.SECONDS);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 |