Kaynağa Gözat

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

liujunchi 3 yıl önce
ebeveyn
işleme
67c5caff66
18 değiştirilmiş dosya ile 456 ekleme ve 199 silme
  1. 42 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/VipCardRecordController.java
  2. 2 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleDao.java
  3. 15 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentDao.java
  4. 26 23
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/VipCardRecordDao.java
  5. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VipCardRecordSearch.java
  6. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseSchedule.java
  7. 3 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudent.java
  8. 5 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  9. 7 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VipCardRecordService.java
  10. 171 142
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  11. 12 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VipCardRecordServiceImpl.java
  12. 35 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/VipCardRecordVo.java
  13. 5 6
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  14. 10 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleStudentMapper.xml
  15. 3 4
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserBindingTeacherMapper.xml
  16. 9 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/VipCardRecordMapper.xml
  17. 61 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/VipCardRecordController.java
  18. 27 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java

+ 42 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/VipCardRecordController.java

@@ -0,0 +1,42 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.support.PageUtil;
+import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/vipCardRecord")
+@Api(value = "购买会员卡记录表", tags = "购买会员卡记录表")
+public class VipCardRecordController extends BaseController {
+
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<VipCardRecordVo> detail(@PathVariable("id") Long id) {
+    	return succeed(vipCardRecordService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入vipCardRecordSearch")
+    public HttpResponseResult<PageInfo<VipCardRecordVo>> page(@RequestBody VipCardRecordSearch query) {
+		IPage<VipCardRecordVo> pages = vipCardRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+}

+ 2 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleDao.java

@@ -215,17 +215,14 @@ public interface CourseScheduleDao extends BaseMapper<CourseSchedule> {
     List<CourseSchedule> selectSchedule(Integer courseId);
 
     //更新课程状态
-    void updateStartTime(List<Long> list);
+    void updateStartTime(List<CourseSchedule> list);
 
     //更新课程状态
-    void updateEndTime();
+    void updateEndTime(List<CourseSchedule> list);
 
     //根据日期查课程id
     List<Long> selectIdList(String day);
 
     //更新老师课酬
     void updateTeacherSalary(List<Long> list);
-
-    //查询课程id(开课时间 ≤ NOW ≤ 结束时间)
-    List<Long> selectUpStartIds();
 }

+ 15 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentDao.java

@@ -0,0 +1,15 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleStudent;
+
+import java.util.List;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/27
+ */
+public interface CourseScheduleStudentDao extends BaseMapper<CourseScheduleStudent> {
+    //批量添加学员
+    void insertBatch(List<CourseScheduleStudent> list);
+}

+ 26 - 23
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/VipCardRecordDao.java

@@ -10,35 +10,38 @@ import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
 
 
-public interface VipCardRecordDao extends BaseMapper<VipCardRecord>{
-	/**
-	 * 查询详情
+public interface VipCardRecordDao extends BaseMapper<VipCardRecord> {
+    /**
+     * 查询详情
+     *
      * @author liweifan
      * @date 2022-03-30 13:53:51
      * @return: com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo
-	 */
-	VipCardRecordVo detail(@Param("id") Long id);
+     */
+    VipCardRecordVo detail(@Param("id") Long id, @Param("userId") Long userId);
 
-	/**
-	 * 分页查询
+    /**
+     * 分页查询
+     *
      * @author liweifan
      * @date 2022-03-30 13:53:51
      * @return: com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo
-	 */
-	List<VipCardRecordVo> selectPage(@Param("page") IPage page, @Param("param") VipCardRecordSearch vipCardRecord);
+     */
+    List<VipCardRecordVo> selectPage(@Param("page") IPage page, @Param("param") VipCardRecordSearch vipCardRecord);
 
-	/***
-	 * 查询临期3天会员
-	 * @author liweifan
-	 * @updateTime 2022/5/5 19:33
-	 * @return: java.util.List<com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo>
-	 */
-	List<VipCardRecordVo> selectTemporaryRecord();
-	/***
-	 * 查询到期会员
-	 * @author liweifan
-	 * @updateTime 2022/5/5 20:18
-	 * @return: java.util.List<com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo>
-	 */
-	List<VipCardRecordVo> selectExpireRecord();
+    /***
+     * 查询临期3天会员
+     * @author liweifan
+     * @updateTime 2022/5/5 19:33
+     * @return: java.util.List<com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo>
+     */
+    List<VipCardRecordVo> selectTemporaryRecord();
+
+    /***
+     * 查询到期会员
+     * @author liweifan
+     * @updateTime 2022/5/5 20:18
+     * @return: java.util.List<com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo>
+     */
+    List<VipCardRecordVo> selectExpireRecord();
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VipCardRecordSearch.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.biz.dal.dto.search;
 
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 
 /**
  * @Author: liweifan
@@ -11,4 +12,14 @@ import io.swagger.annotations.ApiModel;
 public class VipCardRecordSearch extends QueryInfo{
 	private static final long serialVersionUID = 1L;
 
+	@ApiModelProperty(hidden = true)
+	private Long userId;
+
+	public Long getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Long userId) {
+		this.userId = userId;
+	}
 }

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseSchedule.java

@@ -65,6 +65,10 @@ public class CourseSchedule implements Serializable {
     @ApiModelProperty(value = "实际上课人数")
     private Integer exStudentNum;
 
+    @TableField("single_course_time_")
+    @ApiModelProperty(value = "单课时长")
+    private Integer singleCourseTime;
+
     @TableField("created_by_")
     @ApiModelProperty(value = "创建人")
     private Long createdBy;
@@ -81,6 +85,14 @@ public class CourseSchedule implements Serializable {
     @ApiModelProperty(value = "更新时间")
     private Date updatedTime;
 
+    public Integer getSingleCourseTime() {
+        return singleCourseTime;
+    }
+
+    public void setSingleCourseTime(Integer singleCourseTime) {
+        this.singleCourseTime = singleCourseTime;
+    }
+
     public static CourseSchedule build() {
         return new CourseSchedule();
     }

+ 3 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudent.java

@@ -25,7 +25,7 @@ public class CourseScheduleStudent implements Serializable {
 
     @TableField("student_id_")
     @ApiModelProperty(value = "学生id")
-    private String studentId;
+    private Long studentId;
 
     public Long getId() {
         return id;
@@ -43,11 +43,11 @@ public class CourseScheduleStudent implements Serializable {
         this.courseId = courseId;
     }
 
-    public String getStudentId() {
+    public Long getStudentId() {
         return studentId;
     }
 
-    public void setStudentId(String studentId) {
+    public void setStudentId(Long studentId) {
         this.studentId = studentId;
     }
 }

+ 5 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java

@@ -184,7 +184,7 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
 
     void buyPracticeCourseFailed(UserOrderDetailVo orderParam);
 
-    void courseAdjust(CourseAdjustVo adjustVo,Long teacherId);
+    void courseAdjust(CourseAdjustVo adjustVo, Long teacherId);
 
     StudentHomePage queryLiveAndVideo(Long studentId, Long teacherId, YesOrNoEnum appAuditVersion);
 
@@ -227,7 +227,6 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
     /**
      * 发送"当日陪练课未评价/布置作业
      * (每晚9点30,已评价/已布置不发)"
-     *
      */
     void sendTodayNotRepliedAndNotDecorateHomework();
 
@@ -240,5 +239,9 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
     void teacherSalaryTask();
 
     PinaoRoomTimeVo selectRemainTime(Long teacherId);
+
+    PageInfo<CourseStudentVo> selectStudent(Map<String, Object> param);
+
+    void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
 }
 

+ 7 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VipCardRecordService.java

@@ -16,13 +16,18 @@ import com.yonge.cooleshow.common.entity.HttpResponseResult;
  * @date 2022-03-30
  */
 public interface VipCardRecordService extends IService<VipCardRecord>  {
-
+	/**
+	 * 查询详情
+	 * @author liweifan
+	 * @date 2022-03-30
+	 */
+	VipCardRecordVo detail(Long id);
 	/**
      * 查询详情
      * @author liweifan
  	 * @date 2022-03-30
      */
-	VipCardRecordVo detail(Long id);
+	VipCardRecordVo detail(Long id,Long userId);
 
     /**
      * 分页查询

+ 171 - 142
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java

@@ -96,6 +96,10 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
     private HolidaysFestivalsDao holidaysFestivalsDao;
     @Autowired
     private PinaoRoomTimeDao pinaoRoomTimeDao;
+    @Autowired
+    private UserBindingTeacherDao userBindingTeacherDao;
+    @Autowired
+    private CourseScheduleStudentDao courseScheduleStudentDao;
 
     @Override
     public CourseScheduleDao getDao() {
@@ -1485,12 +1489,26 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
      */
     @Transactional(rollbackFor = Exception.class)
     public void scheduleTask() {
-        //查询课程id(开课时间 ≤ NOW ≤ 结束时间)
-        List<Long> startIds=baseMapper.selectUpStartIds();
-        if (CollectionUtils.isNotEmpty(startIds)){
-            baseMapper.updateStartTime(startIds);
+        //更新课程开始状态(开课时间 ≤ NOW ≤ 结束时间)
+        List<CourseSchedule> courseStart = baseMapper.selectList(Wrappers.<CourseSchedule>lambdaQuery()
+                .eq(CourseSchedule::getLock, 0)
+                .eq(CourseSchedule::getType, CourseScheduleEnum.NOT_START)
+                .le(CourseSchedule::getStartTime, new Date())
+                .ge(CourseSchedule::getEndTime, new Date()));
+        if (CollectionUtils.isNotEmpty(courseStart)) {
+            baseMapper.updateStartTime(courseStart);
+        }
+
+        //更新课程结束状态(NOW ≥ 结束时间)
+        List<String> typeList = Arrays.asList(CourseScheduleEnum.ING.getCode(), CourseScheduleEnum.NOT_START.getCode());
+        List<CourseSchedule> courseEnd = baseMapper.selectList(Wrappers.<CourseSchedule>lambdaQuery()
+                .in(CourseSchedule::getType, typeList)
+                .eq(CourseSchedule::getLock, 0)
+                .le(CourseSchedule::getEndTime, new Date()));
+        if (CollectionUtils.isNotEmpty(courseEnd)) {
+            baseMapper.updateEndTime(courseEnd);
+            //TODO 根据老师&学生id 更新绑定学员结课时间
         }
-        baseMapper.updateEndTime();
     }
 
     /**
@@ -1510,145 +1528,156 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         baseMapper.updateTeacherSalary(idList);
     }
 
+    /**
+     * @Description: 查询琴房剩余时长、冻结时长、统计学员人数
+     * @Author: cy
+     * @Date: 2022/5/27
+     */
     public PinaoRoomTimeVo selectRemainTime(Long teacherId) {
         return pinaoRoomTimeDao.selectRemainTime(teacherId);
     }
 
-//    public PageInfo<CourseStudentVo> selectStudent(Map<String, Object> param) {
-//        Integer courseId = (Integer) param.get("courseId");
-//        if (courseId != null) {
-//            CourseScheduleStudent teacherTime = baseMapper.selectOne(Wrappers.<CourseScheduleStudent>lambdaQuery().eq(CourseScheduleStudent::getCourseScheduleId, courseId));
-//            if (teacherTime == null) {
-//                throw new BizException("未查到课程");
-//            }
-//            String studentIdList = teacherTime.getStudentIdList();
-//            List<String> idList = Arrays.asList(studentIdList.split(","));
-//            param.put("idList", idList);//根据课程id查询报课学员
-//        }
-//        return PageUtil.pageInfo(userBindingTeacherDao.selectStudent(PageUtil.getPageInfo(param), param));
-//    }
-//
-//    public void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
-//        DistributedLock.of(redissonClient)
-//                .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + teacherId)
-//                        , () -> this.checkArrangeCourse(arrangeCourseVo, teacherId), 60L, TimeUnit.SECONDS);
-//    }
-//
-//    @Transactional(rollbackFor = Exception.class)
-//    public void checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
-//        Integer classNum = arrangeCourseVo.getClassNum();//课时数
-//        Integer singleClssTime = arrangeCourseVo.getSingleClssTime();//单课时长
-//        List<Long> studentIds = arrangeCourseVo.getStudentIds();//学员id集合
-//        Integer consumTime = classNum * singleClssTime * studentIds.size();//消耗时长
-//        List<CourseTimeEntity> timeList = arrangeCourseVo.getTimeList();//选课时间
-//        Integer consumeTime = arrangeCourseVo.getConsumeTime();
-//
-//        //校验课时
-//        if (timeList.size() != classNum) {
-//            throw new BizException("课时数与排课数不符");
-//        }
-//
-//        //校验消耗时长
-//        if (!consumTime.equals(consumeTime)) {
-//            throw new BizException("时长计算错误");
-//        }
-//
-//        //校验上下课时间
-//        for (int i = 1; i <= timeList.size(); i++) {
-//            if (!DateUtil.offsetMinute(timeList.get(i).getStartTime(), singleClssTime).equals(timeList.get(i).getEndTime())) {
-//                throw new BizException("第{}节课结束时间计算错误", i);
-//            }
-//        }
-//
-//        //校验时长
-//        PinaoRoomTime pinaoRoomTime = pinaoRoomTimeDao.selectOne(Wrappers.<PinaoRoomTime>lambdaQuery().eq(PinaoRoomTime::getTeacherId, teacherId));
-//        if (pinaoRoomTime == null) {
-//            throw new BizException("未查询到老师剩余时长");
-//        }
-//        Long remainTime = pinaoRoomTime.getRemainTime();
-//        Long frozenTime = pinaoRoomTime.getFrozenTime();
-//        if (consumTime > remainTime) {
-//            throw new BizException("剩余时长不足");
-//        }
-//
-//        //校验学员是否绑定
-//        List<UserBindingTeacher> bindingTeachers = userBindingTeacherDao.selectList(Wrappers.<UserBindingTeacher>lambdaQuery().eq(UserBindingTeacher::getTeacherId, teacherId));
-//        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(bindingTeachers)) {
-//            throw new BizException("无绑定学员");
-//        }
-//        List<Long> studentList = bindingTeachers.stream().map(UserBindingTeacher::getStudentId).collect(Collectors.toList());
-//        for (Long studentId : studentIds) {
-//            if (!studentList.contains(studentId)) {
-//                throw new BizException("学员id:{},未绑定", studentId);
-//            }
-//        }
-//
-//        //校验传入时间是否交集
-//        if (timeList.size() > 1) {
-//            for (int i = 0; i < timeList.size(); i++) {
-//                if (i == timeList.size() - 1) {
-//                    break;
-//                }
-//                CourseTimeEntity o = timeList.get(i);
-//                List<CourseTimeEntity> newList = timeList.subList(i + 1, timeList.size());
-//                boolean checkParamTime = courseScheduleService.checkCourseTime(newList, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime, o.getStartTime(), o.getEndTime());
-//                if (checkParamTime) {
-//                    throw new BizException(DateUtil.dateToString(o.getStartTime(), "yyyy年MM月dd号 HH点mm分") + "的课程时间重复!");
-//                }
-//            }
-//        }
-//
-//        //批量检查老师课时在数据库是否重复
-//        groupService.batchCheckTeacherCourseTime(teacherId, timeList, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime);
-//
-//        //校验购买的课程组每节课时间是否和自己的课时冲突
-//        for (Long studentId : studentIds) {
-//            groupService.batchCheckStudentCourseTime(studentId, timeList, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime);
-//        }
-//
-//        //添加课程组
-//        CourseGroup courseGroup = new CourseGroup();
-//        courseGroup.setType(CourseScheduleEnum.PIANO_ROOM_CLASS.getCode());
-//        courseGroup.setTeacherId(teacherId);
-//        courseGroup.setName(arrangeCourseVo.getCourseName());
-//        courseGroup.setSubjectId(arrangeCourseVo.getSubjectId());
-//        courseGroup.setSingleCourseMinutes(singleClssTime);
-//        courseGroup.setCourseNum(classNum);
-//        courseGroup.setStatus(CourseGroupEnum.NOT_SALE.getCode());
-//        courseGroup.setCreatedBy(teacherId);
-//        courseGroupDao.insert(courseGroup);
-//
-//        for (int i = 0; i < timeList.size(); i++) {
-//            //添加课程
-//            CourseTimeEntity courseTimeEntity = timeList.get(i);
-//            CourseSchedule schedule = new CourseSchedule();
-//            schedule.setCourseGroupId(courseGroup.getId());
-//            schedule.setType(CourseScheduleEnum.PIANO_ROOM_CLASS.getCode());
-//            schedule.classNum(i + 1);
-//            schedule.setTeacherId(teacherId);
-//            schedule.setClassDate(DateUtil.trunc(courseTimeEntity.getStartTime()));
-//            schedule.setStartTime(courseTimeEntity.getStartTime());
-//            schedule.setEndTime(courseTimeEntity.getEndTime());
-//            schedule.setLock(0);
-//            schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
-//            schedule.setCreatedBy(teacherId);
-//            courseScheduleDao.insert(schedule);
-//
-//            //添加course_schedule_teacher_time
-//            CourseScheduleStudent teacherTime = new CourseScheduleStudent();
-//            teacherTime.setCourseGroupId(courseGroup.getId());
-//            teacherTime.setCourseScheduleId(schedule.getId());
-//            teacherTime.setTeacherId(teacherId);
-//            teacherTime.setStudentIdList(org.apache.commons.lang.StringUtils.join(studentIds, ","));
-//            teacherTime.setClassNum(i + 1);
-//            teacherTime.setConsumeTime(Long.valueOf(singleClssTime));
-//            baseMapper.insert(teacherTime);
-//        }
-//
-//        //扣减pinao_room_time
-//        PinaoRoomTime roomTime = new PinaoRoomTime();
-//        roomTime.setRemainTime(remainTime - consumTime);
-//        roomTime.setFrozenTime(frozenTime + consumTime);
-//        pinaoRoomTimeDao.update(roomTime, Wrappers.<PinaoRoomTime>lambdaQuery().eq(PinaoRoomTime::getTeacherId, teacherId));
-//    }
+    /**
+     * @Description: 我的学员&课内学员
+     * @Author: cy
+     * @Date: 2022/5/27
+     */
+    public PageInfo<CourseStudentVo> selectStudent(Map<String, Object> param) {
+        Integer courseId = (Integer) param.get("courseId");
+        if (courseId != null) {
+            List<CourseScheduleStudent> studentList = courseScheduleStudentDao.selectList(Wrappers.<CourseScheduleStudent>lambdaQuery().eq(CourseScheduleStudent::getCourseId, courseId));
+            param.put("studentList", studentList);//根据课程id查询报课学员
+        }
+        return PageUtil.pageInfo(userBindingTeacherDao.selectStudent(PageUtil.getPageInfo(param), param));
+    }
+
+    /**
+     * @Description: 排课
+     * @Author: cy
+     * @Date: 2022/5/27
+     */
+    public void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
+        DistributedLock.of(redissonClient)
+                .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + teacherId)
+                        , () -> this.checkArrangeCourse(arrangeCourseVo, teacherId), 60L, TimeUnit.SECONDS);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public void checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
+        Integer classNum = arrangeCourseVo.getClassNum();//课时数
+        Integer singleClssTime = arrangeCourseVo.getSingleClssTime();//单课时长
+        List<Long> studentIds = arrangeCourseVo.getStudentIds();//学员id集合
+        Integer consumTime = classNum * singleClssTime * studentIds.size();//消耗时长
+        List<CourseTimeEntity> timeList = arrangeCourseVo.getTimeList();//选课时间
+        Integer consumeTime = arrangeCourseVo.getConsumeTime();
+
+        //校验课时
+        if (timeList.size() != classNum) {
+            throw new BizException("课时数与排课数不符");
+        }
+
+        //校验消耗时长
+        if (!consumTime.equals(consumeTime)) {
+            throw new BizException("时长计算错误");
+        }
+
+        //校验上下课时间
+        for (int i = 0; i < timeList.size(); i++) {
+            if (!DateUtil.offsetMinute(timeList.get(i).getStartTime(), singleClssTime).equals(timeList.get(i).getEndTime())) {
+                throw new BizException("第{}节课结束时间计算错误", i + 1);
+            }
+        }
+
+        //校验时长
+        PinaoRoomTime pinaoRoomTime = pinaoRoomTimeDao.selectOne(Wrappers.<PinaoRoomTime>lambdaQuery().eq(PinaoRoomTime::getTeacherId, teacherId));
+        if (pinaoRoomTime == null) {
+            throw new BizException("未查询到老师剩余时长");
+        }
+        Long remainTime = pinaoRoomTime.getRemainTime();
+        Long frozenTime = pinaoRoomTime.getFrozenTime();
+        if (consumTime > remainTime) {
+            throw new BizException("剩余时长不足");
+        }
+
+        //校验学员是否绑定
+        List<UserBindingTeacher> bindingTeachers = userBindingTeacherDao.selectList(Wrappers.<UserBindingTeacher>lambdaQuery().eq(UserBindingTeacher::getTeacherId, teacherId));
+        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(bindingTeachers)) {
+            throw new BizException("无绑定学员");
+        }
+        List<Long> studentList = bindingTeachers.stream().map(UserBindingTeacher::getStudentId).collect(Collectors.toList());
+        for (Long studentId : studentIds) {
+            if (!studentList.contains(studentId)) {
+                throw new BizException("学员id:{},未绑定", studentId);
+            }
+        }
+
+        //校验传入时间是否交集
+        if (timeList.size() > 1) {
+            for (int i = 0; i < timeList.size(); i++) {
+                if (i == timeList.size() - 1) {
+                    break;
+                }
+                CourseTimeEntity o = timeList.get(i);
+                List<CourseTimeEntity> newList = timeList.subList(i + 1, timeList.size());
+                boolean checkParamTime = this.checkCourseTime(newList, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime, o.getStartTime(), o.getEndTime());
+                if (checkParamTime) {
+                    throw new BizException(DateUtil.dateToString(o.getStartTime(), "yyyy年MM月dd号 HH点mm分") + "的课程时间重复!");
+                }
+            }
+        }
+
+        //批量检查老师课时在数据库是否重复
+        this.batchCheckTeacherCourseTime(teacherId, timeList, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime);
+
+        //校验购买的课程组每节课时间是否和自己的课时冲突
+        for (Long studentId : studentIds) {
+            this.batchCheckStudentCourseTime(studentId, timeList, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime);
+        }
+
+        //添加课程组
+        CourseGroup courseGroup = new CourseGroup();
+        courseGroup.setType(CourseScheduleEnum.PIANO_ROOM_CLASS.getCode());
+        courseGroup.setTeacherId(teacherId);
+        courseGroup.setName(arrangeCourseVo.getCourseName());
+        courseGroup.setSubjectId(arrangeCourseVo.getSubjectId());
+        courseGroup.setSingleCourseMinutes(singleClssTime);
+        courseGroup.setCourseNum(classNum);
+        courseGroup.setStatus(CourseGroupEnum.NOT_SALE.getCode());
+        courseGroup.setCreatedBy(teacherId);
+        courseGroupService.getDao().insert(courseGroup);
+
+        for (int i = 0; i < timeList.size(); i++) {
+            //添加课程
+            CourseTimeEntity courseTimeEntity = timeList.get(i);
+            CourseSchedule schedule = new CourseSchedule();
+            schedule.setCourseGroupId(courseGroup.getId());
+            schedule.setType(CourseScheduleEnum.PIANO_ROOM_CLASS.getCode());
+            schedule.classNum(i + 1);
+            schedule.setTeacherId(teacherId);
+            schedule.setClassDate(DateUtil.trunc(courseTimeEntity.getStartTime()));
+            schedule.setStartTime(courseTimeEntity.getStartTime());
+            schedule.setEndTime(courseTimeEntity.getEndTime());
+            schedule.setLock(0);
+            schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
+            schedule.setCreatedBy(teacherId);
+            schedule.setSingleCourseTime(singleClssTime);
+            baseMapper.insert(schedule);
+
+            //添加course_schedule_student
+            List<CourseScheduleStudent> list = new ArrayList<>();
+            for (Long studentId : studentIds) {
+                CourseScheduleStudent teacherTime = new CourseScheduleStudent();
+                teacherTime.setStudentId(studentId);
+                teacherTime.setCourseId(schedule.getId());
+                list.add(teacherTime);
+            }
+            courseScheduleStudentDao.insertBatch(list);
+        }
+
+        //扣减pinao_room_time
+        PinaoRoomTime roomTime = new PinaoRoomTime();
+        roomTime.setRemainTime(remainTime - consumTime);
+        roomTime.setFrozenTime(frozenTime + consumTime);
+        pinaoRoomTimeDao.update(roomTime, Wrappers.<PinaoRoomTime>lambdaQuery().eq(PinaoRoomTime::getTeacherId, teacherId));
+    }
 }

+ 12 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VipCardRecordServiceImpl.java

@@ -33,7 +33,13 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 
     @Override
     public VipCardRecordVo detail(Long id) {
-        VipCardRecordVo detail = baseMapper.detail(id);
+        VipCardRecordVo detail = baseMapper.detail(id, null);
+        return detail;
+    }
+
+    @Override
+    public VipCardRecordVo detail(Long id, Long userId) {
+        VipCardRecordVo detail =  baseMapper.detail(id, userId);
         return detail;
     }
 
@@ -59,7 +65,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
             record.setUpdateTime(new Date());
 
             VipCardRecord vipCardRecord = new VipCardRecord();
-            BeanUtils.copyProperties(record,vipCardRecord);
+            BeanUtils.copyProperties(record, vipCardRecord);
             baseMapper.updateById(vipCardRecord);
         }
 
@@ -78,7 +84,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
             record.setUpdateTime(new Date());
 
             VipCardRecord vipCardRecord = new VipCardRecord();
-            BeanUtils.copyProperties(record,vipCardRecord);
+            BeanUtils.copyProperties(record, vipCardRecord);
             baseMapper.updateById(vipCardRecord);
         }
 
@@ -92,7 +98,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         try {
             String url = sysMessageService.selectConfigUrl(MessageTypeEnum.VIP_EXPIRE_THIRTY_DAY.getCode());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.VIP_EXPIRE_THIRTY_DAY,
-                    receivers, null, 0,  url, ClientEnum.STUDENT.getCode());
+                    receivers, null, 0, url, ClientEnum.STUDENT.getCode());
         } catch (Exception e) {
             log.error("会员到期3天极光消息推送异常,userId={}", userId);
         }
@@ -100,7 +106,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         try {
             String url = sysMessageService.selectConfigUrl(MessageTypeEnum.SMS_VIP_EXPIRE_THIRTY_DAY.getCode());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_VIP_EXPIRE_THIRTY_DAY,
-                    receivers, null, 0, null, ClientEnum.STUDENT.getCode() ,url);
+                    receivers, null, 0, null, ClientEnum.STUDENT.getCode(), url);
         } catch (Exception e) {
             log.error("会员到期3天短信消息推送异常,userId={}", userId);
         }
@@ -121,7 +127,7 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         try {
             String url = sysMessageService.selectConfigUrl(MessageTypeEnum.SMS_VIP_EXPIRE.getCode());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_VIP_EXPIRE,
-                    receivers, null, 0, null, ClientEnum.STUDENT.getCode(),url);
+                    receivers, null, 0, null, ClientEnum.STUDENT.getCode(), url);
         } catch (Exception e) {
             log.error("会员到期3天短信消息推送异常,userId={}", userId);
         }

+ 35 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/VipCardRecordVo.java

@@ -1,7 +1,11 @@
 package com.yonge.cooleshow.biz.dal.vo;
 
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
+import com.yonge.cooleshow.biz.dal.enums.PeriodEnum;
 import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
 
 /**
  * @Author: liweifan
@@ -10,12 +14,14 @@ import io.swagger.annotations.ApiModel;
 @ApiModel(value = "VipCardRecordVo对象", description = "购买会员卡记录表查询视图对象")
 public class VipCardRecordVo extends VipCardRecord{
 	private static final long serialVersionUID = 1L;
-	/***
-	 * 手机号
-	 * @author liweifan
-	 * @updateTime 2022/5/5 20:11
-	 */
+
 	private String phone;
+	@ApiModelProperty("原价 ")
+	private BigDecimal originalPrice;
+	@ApiModelProperty("销售价 ")
+	private BigDecimal salePrice;
+	@ApiModelProperty("周期 ")
+	private PeriodEnum period;
 
 	public String getPhone() {
 		return phone;
@@ -24,4 +30,28 @@ public class VipCardRecordVo extends VipCardRecord{
 	public void setPhone(String phone) {
 		this.phone = phone;
 	}
+
+	public BigDecimal getOriginalPrice() {
+		return originalPrice;
+	}
+
+	public void setOriginalPrice(BigDecimal originalPrice) {
+		this.originalPrice = originalPrice;
+	}
+
+	public BigDecimal getSalePrice() {
+		return salePrice;
+	}
+
+	public void setSalePrice(BigDecimal salePrice) {
+		this.salePrice = salePrice;
+	}
+
+	public PeriodEnum getPeriod() {
+		return period;
+	}
+
+	public void setPeriod(PeriodEnum period) {
+		this.period = period;
+	}
 }

+ 5 - 6
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -792,18 +792,17 @@
     <select id="selectIdList" resultType="java.lang.Long">
         SELECT id_ FROM course_schedule WHERE lock_=0 AND class_date_ &lt;= #{day}
     </select>
-    <select id="selectUpStartIds" resultType="java.lang.Long">
-        SELECT id_ FROM course_schedule WHERE lock_=0
-        AND status_='NOT_START' AND start_time_ &lt;= NOW() AND NOW() &lt;= end_time_
-    </select>
     <update id="updateStartTime">
         UPDATE course_schedule SET status_='ING' WHERE id_ IN(
         <foreach collection="list" item="item" index="index" open="" close="" separator=",">
-            #{item}
+            #{item.id}
         </foreach>)
     </update>
     <update id="updateEndTime">
-        UPDATE course_schedule SET status_='COMPLETE' WHERE status_ != 'CANCEL' <![CDATA[ AND end_time_ <= NOW() ]]>
+        UPDATE course_schedule SET status_='COMPLETE' WHERE id_ IN(
+        <foreach collection="list" item="item" index="index" open="" close="" separator=",">
+            #{item.id}
+        </foreach>)
     </update>
     <update id="updateTeacherSalary" parameterType="java.util.List">
         UPDATE course_schedule_teacher_salary

+ 10 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleStudentMapper.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentDao">
+    <insert id="insertBatch">
+        INSERT INTO course_schedule_student (course_id_, student_id_) VALUES
+        <foreach collection ="list" item="item" separator =",">
+            (#{item.courseId}, #{item.studentId})
+        </foreach >
+    </insert>
+</mapper>

+ 3 - 4
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserBindingTeacherMapper.xml

@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.yonge.cooleshow.biz.dal.dao.UserBindingTeacherDao">
-
     <select id="selectStudent" resultType="com.yonge.cooleshow.biz.dal.vo.CourseStudentVo">
         SELECT
         su.id_ AS userId,
@@ -24,10 +23,10 @@
             <if test="param.userName !=null and param.userName !=''">
                 AND su.username_ LIKE CONCAT('%', #{param.userName}, '%')
             </if>
-            <if test="param.idList !=null and param.idList.size>0">
+            <if test="param.studentList !=null and param.studentList.size>0">
                 AND su.id_ IN
-                <foreach collection="param.idList" item="item" open="(" separator="," close=")">
-                    #{item}
+                <foreach collection="param.studentList" item="item" open="(" separator="," close=")">
+                    #{item.studentId}
                 </foreach>
             </if>
         </where>

+ 9 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/VipCardRecordMapper.xml

@@ -30,15 +30,23 @@
 
     <select id="detail" resultType="com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo">
         SELECT
-            <include refid="baseColumns"/>
+            <include refid="baseColumns"/>,
+            s.original_price_ as originalPrice,
+            s.sale_price_ as salePrice,
+            s.period_ as `period`
         FROM vip_card_record t
+        left join member_price_settings s on t.vip_card_id_ = s.id_
         where t.id_ = #{id}
+        <if test="userId != null">
+            and t.user_id_ = #{userId}
+        </if>
     </select>
     
     <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo">
 		SELECT         
         	<include refid="baseColumns" />
 		FROM vip_card_record t
+        order by t.create_time_ desc
 	</select>
 
     <select id="selectTemporaryRecord" resultType="com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo">

+ 61 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/VipCardRecordController.java

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.biz.dal.support.PageUtil;
+
+import com.yonge.toolset.utils.string.StringUtil;
+import io.swagger.annotations.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
+import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
+import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+
+@RestController
+@RequestMapping("/vipCardRecord")
+@Api(value = "购买会员卡记录表", tags = "购买会员卡记录表")
+public class VipCardRecordController extends BaseController {
+
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<VipCardRecordVo> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(vipCardRecordService.detail(id, user.getId()));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入vipCardRecordSearch")
+    public HttpResponseResult<PageInfo<VipCardRecordVo>> page(@RequestBody VipCardRecordSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        IPage<VipCardRecordVo> pages = vipCardRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 27 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java

@@ -168,5 +168,32 @@ public class TeacherCourseScheduleController extends BaseController {
         }
         return succeed(courseScheduleService.selectRemainTime(user.getId()));
     }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "userName", dataType = "String", value = "学员姓名"),
+            @ApiImplicitParam(name = "courseId", dataType = "Long", value = "课程id"),
+    })
+    @ApiOperation("我的学员&课内学员")
+    @PostMapping("/selectStudent")
+    public HttpResponseResult<PageInfo<CourseStudentVo>> selectStudent(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        return succeed(courseScheduleService.selectStudent(param));
+    }
+
+    @ApiOperation("排课")
+    @PostMapping("/arrangeCourse")
+    public HttpResponseResult<Object> arrangeCourse(@RequestBody ArrangeCourseVo arrangeCourseVo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
+        return succeed();
+    }
 }