Selaa lähdekoodia

Merge branch 'feature/0529-live' into master_saas

shangke 2 vuotta sitten
vanhempi
commit
c4526825e8

+ 88 - 0
.idea/httpRequests/http-requests-log.http

@@ -7,6 +7,76 @@ Accept-Encoding: br,deflate,gzip,x-gzip
 
 ###
 
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=2030
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T155507.200.json
+
+###
+
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=2030
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T155111.200.json
+
+###
+
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=2030
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T155043.200.json
+
+###
+
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=2030
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T154917.200.json
+
+###
+
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=2030
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T154631.200.json
+
+###
+
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=2030
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T154529.200.json
+
+###
+
+GET http://127.0.0.1:9002/teacherCourseSchedule/liveCourseScheduleTime?courseScheduleId=1678
+Authorization: bearer 2cd308e9-0b8b-4b08-b3cd-f34dc50a8dfd
+Proxy-Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+<> 2023-06-07T152014.200.json
+
+###
+
 GET http://127.0.0.1:8005/teacher/findTeacherByTenantId
 Authorization: bearer 7e4145d6-111d-429b-893a-4546df0f58ed
 tenantId: 1
@@ -800,3 +870,21 @@ Accept-Encoding: br,deflate,gzip,x-gzip
 
 ###
 
+POST http://127.0.0.1:8005/studentManage/userDetail
+Authorization: bearer 81d0c352-fcc8-4812-87f5-0f7a68d10451
+Content-Type: application/json
+coopId: 1
+Content-Length: 63
+Connection: Keep-Alive
+User-Agent: Apache-HttpClient/4.5.14 (Java/17.0.6)
+Accept-Encoding: br,deflate,gzip,x-gzip
+
+{
+  "studentId": 2248340,
+  "musicGroupId": 23042419330600001
+}
+
+<> 2023-06-01T160136.200.json
+
+###
+

+ 63 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/CourseScheduleWrapper.java

@@ -0,0 +1,63 @@
+package com.ym.mec.biz.dal.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 课程表数据类
+ * Created by Eric.Shang on 2023/6/7.
+ */
+public class CourseScheduleWrapper {
+
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("课程表")
+    public static class LiveCourseSchedule implements Serializable {
+
+        @ApiModelProperty("直播间编号")
+        private String liveRoomId;
+
+        @ApiModelProperty("声部编号")
+        private String subjectId;
+
+        @ApiModelProperty("课程结束后是否自动关闭课程")
+        private Boolean autoCloseFlag;
+
+        @ApiModelProperty("课程结束后多少分钟关闭网络教室")
+        private String autoCloseNetworkRoomTime;
+
+        @ApiModelProperty("获取当前课程剩余时长")
+        private Integer surplusTime;
+
+        @ApiModelProperty("当前时间戳")
+        private Long timestamp;
+
+        @ApiModelProperty("课程表时间")
+        private List<CourseScheduleTime> courseScheduleTimes;
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("课程表时间")
+    public static class CourseScheduleTime implements Serializable {
+
+        @ApiModelProperty("开始时间")
+        private Long startTime;
+
+        @ApiModelProperty("结束时间")
+        private Long endTime;
+    }
+
+}

+ 8 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/CourseScheduleService.java

@@ -12,13 +12,13 @@ import com.ym.mec.biz.dal.enums.YesOrNoEnum;
 import com.ym.mec.biz.dal.page.*;
 import com.ym.mec.biz.dal.school.dto.ClassesForDayDto;
 import com.ym.mec.biz.dal.school.dto.CourseStudentDto;
+import com.ym.mec.biz.dal.vo.CourseScheduleWrapper;
 import com.ym.mec.biz.dal.wrapper.DailySummaryOfClassesForTheCurrentSemesterWrapper;
 import com.ym.mec.biz.dal.wrapper.TeachingPointWrapper;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.QueryInfo;
 import com.ym.mec.common.service.BaseService;
-import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import java.util.Date;
@@ -770,5 +770,12 @@ public interface CourseScheduleService extends BaseService<Long, CourseSchedule>
      */
     Boolean teachingPointCourse(TeachingPointWrapper.TeachingPoint teachingPoint);
 
+	/**
+	 * 获取老师课程时间
+	 * @param courseScheduleId 课程编号
+	 * @return CourseScheduleWrapper.CourseSchedule
+	 */
+	CourseScheduleWrapper.LiveCourseSchedule getLiveCourseScheduleTime(Long courseScheduleId);
+
     List<CourseScheduleStudentDto> queryDetailList(CourseDetailQueryInfo courseDetailQueryInfo);
 }

+ 129 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.ym.mec.auth.api.entity.SysUser;
@@ -14,6 +15,7 @@ import com.ym.mec.biz.dal.mapper.CourseSchedulePlusMapper;
 import com.ym.mec.biz.dal.page.*;
 import com.ym.mec.biz.dal.school.dto.ClassesForDayDto;
 import com.ym.mec.biz.dal.school.dto.CourseStudentDto;
+import com.ym.mec.biz.dal.vo.CourseScheduleWrapper;
 import com.ym.mec.biz.dal.vo.ImLiveRoomVideoVo;
 import com.ym.mec.biz.dal.wrapper.DailySummaryOfClassesForTheCurrentSemesterWrapper;
 import com.ym.mec.biz.dal.wrapper.TeachingPointWrapper;
@@ -41,6 +43,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.ListUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
@@ -53,6 +57,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import java.lang.reflect.InvocationTargetException;
 import java.math.BigDecimal;
+import java.text.MessageFormat;
 import java.text.ParseException;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
@@ -184,6 +189,9 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
     private TeacherAttendanceService teacherAttendanceService;
     @Autowired
     private LessonExaminationService lessonExaminationService;
+	@Autowired
+	private ImLiveBroadcastRoomService imLiveBroadcastRoomService;
+
 
     @Autowired
     private ImLiveRoomVideoDao imLiveRoomVideoDao;
@@ -5916,4 +5924,125 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 		}
 	}
 
+
+	/**
+	 * 获取老师直播课程时间
+	 *
+	 * @param courseScheduleId 课程编号
+	 * @return CourseScheduleWrapper.CourseSchedule
+	 */
+	@Override
+	public CourseScheduleWrapper.LiveCourseSchedule getLiveCourseScheduleTime(Long courseScheduleId) {
+
+		CourseSchedule courseSchedule = courseScheduleDao.get(courseScheduleId);
+		if (Objects.isNull(courseSchedule)) {
+			throw new BizException("课程不存在");
+		}
+
+		if (courseSchedule.getTeachMode() == TeachModeEnum.OFFLINE) {
+			throw new BizException("请前往线下教室");
+		}
+
+		List<CourseScheduleWrapper.CourseScheduleTime> courseScheduleTimes = Lists.newArrayList();
+		courseScheduleTimes.add(CourseScheduleWrapper.CourseScheduleTime.builder()
+				.startTime(getDateTime(courseSchedule.getClassDate(), courseSchedule.getStartClassTime()).getMillis())
+				.endTime(getDateTime(courseSchedule.getClassDate(), courseSchedule.getEndClassTime()).getMillis())
+				.build());
+
+		// 是否是连堂课
+		String continueCourseTime = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME, courseSchedule.getTenantId());
+		if (StringUtils.isEmpty(continueCourseTime)) {
+			continueCourseTime = "5";
+		}
+
+		CourseSchedule schedule = courseSchedule;
+		// 如果当前课程是连堂课,那么获取第一节课的课程编号
+		while (true) {
+			String classDate = DateUtil.format(schedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
+			String startClassTime = DateUtil.format(schedule.getStartClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+			schedule = courseScheduleDao.getFirstCourse(schedule.getClassGroupId(), classDate + " " + startClassTime, schedule.getActualTeacherId(), continueCourseTime);
+			if (schedule != null) {
+				courseScheduleTimes.add(CourseScheduleWrapper.CourseScheduleTime.builder()
+						.startTime(getDateTime(schedule.getClassDate(), schedule.getStartClassTime()).getMillis())
+						.endTime(getDateTime(schedule.getClassDate(), schedule.getEndClassTime()).getMillis())
+						.build());
+			} else {
+				break;
+			}
+		}
+
+		if (courseScheduleTimes.size() <= 1) {
+
+			// 定时任务更新课程状态为进行中,判断当前课程状态是否匹配
+			if (CourseStatusEnum.NOT_START == courseSchedule.getStatus()) {
+				throw new BizException("直播课暂未开启,请稍后重试");
+			}
+			if (CourseStatusEnum.OVER == courseSchedule.getStatus()) {
+				throw new BizException("直播课已结束");
+			}
+		}
+
+		// 直播间配置
+		ImLiveBroadcastRoom liveBroadcastRoom = imLiveBroadcastRoomService.lambdaQuery()
+				.eq(ImLiveBroadcastRoom::getRoomUid, courseSchedule.getLiveRoomId())
+				.last("LIMIT 1")
+				.one();
+		if (Objects.isNull(liveBroadcastRoom)) {
+			throw new BizException("请先进入直播课教室");
+		}
+
+		// 当前时间
+		DateTime now = DateTime.now();
+
+		return CourseScheduleWrapper.LiveCourseSchedule.builder()
+				.liveRoomId(courseSchedule.getLiveRoomId())
+				.subjectId(liveBroadcastRoom.getSubjectId())
+				.autoCloseFlag(true)
+				.autoCloseNetworkRoomTime(getCloseNetworkRoomTime(courseSchedule, continueCourseTime))
+				.surplusTime(DateUtil.secondsBetween(new Date(), courseSchedule.getEndClassTime()))
+				.timestamp(now.getMillis())
+				.courseScheduleTimes(courseScheduleTimes)
+				.build();
+	}
+
+	/**
+	 * 课程开始时间
+	 * @param day 开始天
+	 * @param time 开始时间
+	 * @return DateTime
+	 */
+	private DateTime getDateTime(Date day, Date time) {
+		String liveStartTime = MessageFormat.format("{0} {1}", DateUtil.format(day, DateUtil.DEFAULT_PATTERN),
+				DateUtil.format(time, DateUtil.EXPANDED_TIME_FORMAT));
+
+		return DateTime.parse(liveStartTime, DateTimeFormat.forPattern(DateUtil.DEFAULT_PATTERN + " " + DateUtil.EXPANDED_TIME_FORMAT));
+	}
+
+	/**
+	 * 课程结束后多少分钟关闭网络教室
+	 * @param courseSchedule CourseSchedule
+	 * @param continueCourseTime 连堂课延迟时间
+	 * @return String
+	 */
+	public String getCloseNetworkRoomTime(CourseSchedule courseSchedule, String continueCourseTime) {
+
+		String autoCloseNetworkRoomTime = sysTenantConfigService.getTenantConfigValue(SysConfigService.COURSE_AFTER_BUFFER_TIME, courseSchedule.getTenantId());
+		if (StringUtils.isEmpty(autoCloseNetworkRoomTime)) {
+			autoCloseNetworkRoomTime = "15";
+		}
+		CourseSchedule schedule = courseSchedule;
+		//如果当前课程是连堂课,那么获取第一节课的课程编号
+		while (true) {
+			String classDate = DateUtil.format(schedule.getClassDate(), DateUtil.DEFAULT_PATTERN);
+			String endClassTime = DateUtil.format(schedule.getEndClassTime(), DateUtil.EXPANDED_TIME_FORMAT);
+			schedule = courseScheduleDao.getLastCourse(schedule.getClassGroupId(), classDate + " " + endClassTime, schedule.getActualTeacherId(), continueCourseTime);
+			if (schedule != null) {
+				autoCloseNetworkRoomTime = String.valueOf(DateUtil.minutesBetween(new Date(), schedule.getEndClassTime()));
+			} else {
+				break;
+			}
+		}
+		return autoCloseNetworkRoomTime;
+	}
+
 }

+ 16 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TeacherCourseScheduleController.java

@@ -9,6 +9,7 @@ import com.ym.mec.biz.dal.enums.ClassGroupStudentStatusEnum;
 import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.StudentAttendanceStatusEnum;
 import com.ym.mec.biz.dal.page.*;
+import com.ym.mec.biz.dal.vo.CourseScheduleWrapper;
 import com.ym.mec.biz.service.*;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
@@ -19,6 +20,8 @@ import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
 import com.yonge.log.model.AuditLogAnnotation;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.apache.commons.lang3.StringUtils;
@@ -374,4 +377,17 @@ public class TeacherCourseScheduleController extends BaseController {
         return succeed(scheduleService.queryStudyStandardWaitVisit(queryInfo));
     }
 
+    @ApiOperation(value = "获取老师直播课程时间")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "courseScheduleId", value = "课程id", required = true, dataType = "Long")
+    })
+    @GetMapping("/liveCourseScheduleTime")
+    public HttpResponseResult<CourseScheduleWrapper.LiveCourseSchedule> liveCourseScheduleTime(@RequestParam Long courseScheduleId){
+
+        if (Objects.isNull(courseScheduleId)) {
+            throw new BizException("课程编号不能为空");
+        }
+
+        return succeed(scheduleService.getLiveCourseScheduleTime(courseScheduleId));
+    }
 }