Procházet zdrojové kódy

fix 直播转回放

he2802 před 3 roky
rodič
revize
574ae9e203

+ 10 - 0
zhongzheng-admin/src/main/java/com/zhongzheng/controller/schedule/ScheduleController.java

@@ -2,6 +2,8 @@ package com.zhongzheng.controller.schedule;
 
 import com.zhongzheng.common.core.controller.BaseController;
 import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.modules.polyv.bo.PolyvLiveQueryBo;
+import com.zhongzheng.modules.polyv.service.IPolyvLiveService;
 import com.zhongzheng.modules.schedule.service.IScheduleService;
 import com.zhongzheng.modules.user.bo.UserQueryBo;
 import io.swagger.annotations.Api;
@@ -28,6 +30,7 @@ public class ScheduleController extends BaseController {
     private final IScheduleService iScheduleService;
 
 
+
     /**
      * 商品购买发送消息
      * @return
@@ -169,4 +172,11 @@ public class ScheduleController extends BaseController {
         iScheduleService.overLive(bo);
         return AjaxResult.success();
     }
+
+    @ApiOperation("保利威直播更新回放")
+    @GetMapping("/liveToReplay")
+    public AjaxResult liveToReplay(UserQueryBo bo) throws Exception {
+        iScheduleService.liveToReplay(bo);
+        return AjaxResult.success();
+    }
 }

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/grade/vo/ClassPeriodVo.java

@@ -178,6 +178,11 @@ public class ClassPeriodVo implements Comparable<ClassPeriodVo> {
 	private Long liveEndTime;
 	@ApiModelProperty("直播地址")
 	private String liveUrl;
+	/** 保利威真实直播时长,单位秒 */
+	@Excel(name = "保利威真实直播时长,单位秒")
+	@ApiModelProperty("保利威真实直播时长,单位秒")
+	private Long realDuration;
+
 
 	@Override
 	public int compareTo(ClassPeriodVo o) {

+ 39 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/order/service/impl/OrderGoodsServiceImpl.java

@@ -10,8 +10,10 @@ import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.SecurityUtils;
 import com.zhongzheng.modules.bank.mapper.QuestionMapper;
 import com.zhongzheng.modules.course.domain.CourseModule;
+import com.zhongzheng.modules.course.vo.CourseVo;
 import com.zhongzheng.modules.goods.bo.GoodsQueryBo;
 import com.zhongzheng.modules.goods.domain.Goods;
+import com.zhongzheng.modules.goods.service.IGoodsCourseService;
 import com.zhongzheng.modules.goods.service.IGoodsService;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
 import com.zhongzheng.modules.grade.domain.ClassGradeGoods;
@@ -20,6 +22,7 @@ import com.zhongzheng.modules.grade.service.IClassGradeGoodsService;
 import com.zhongzheng.modules.grade.service.IClassGradeService;
 import com.zhongzheng.modules.grade.service.IClassGradeUserService;
 import com.zhongzheng.modules.grade.vo.ClassGradeVo;
+import com.zhongzheng.modules.grade.vo.ClassPeriodVo;
 import com.zhongzheng.modules.order.bo.OrderAddBo;
 import com.zhongzheng.modules.order.bo.OrderGoodsAddBo;
 import com.zhongzheng.modules.order.bo.OrderGoodsEditBo;
@@ -33,7 +36,9 @@ import com.zhongzheng.modules.order.vo.OrderGoodsVo;
 import com.zhongzheng.modules.order.vo.OrderListVo;
 import com.zhongzheng.modules.order.vo.OrderVo;
 import com.zhongzheng.modules.user.bo.UserExamGoodsQueryBo;
+import com.zhongzheng.modules.user.bo.UserStudyRecordQueryBo;
 import com.zhongzheng.modules.user.service.IUserExamGoodsService;
+import com.zhongzheng.modules.user.service.IUserStudyRecordService;
 import io.swagger.models.auth.In;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -77,6 +82,13 @@ public class OrderGoodsServiceImpl extends ServiceImpl<OrderGoodsMapper, OrderGo
     private IUserExamGoodsService iUserExamGoodsService;
 
 
+    @Autowired
+    private IGoodsCourseService iGoodsCourseService;
+
+    @Autowired
+    private IUserStudyRecordService iUserStudyRecordService;
+
+
     @Override
     public OrderGoodsVo queryById(Long orderGoodsId) {
         OrderGoods db = this.baseMapper.selectById(orderGoodsId);
@@ -311,7 +323,33 @@ public class OrderGoodsServiceImpl extends ServiceImpl<OrderGoodsMapper, OrderGo
 
     @Override
     public List<OrderGoodsVo> listLiveGoodsList(GoodsQueryBo bo) {
-        return this.baseMapper.listLiveGoodsList(bo);
+        List<CourseVo> courseVoList = iGoodsCourseService.selectList(bo.getGoodsId());
+        Integer totalLiveNum = 0; //总直播次数(含回放)
+        Integer overLiveNum = 0; //已经直播次数
+        Long liveTime = 0L; //直播总秒数
+        for(CourseVo courseVo : courseVoList){
+            UserStudyRecordQueryBo queryBo = new UserStudyRecordQueryBo();
+            queryBo.setCourseId(courseVo.getCourseId());
+            List<ClassPeriodVo> sectionList = iUserStudyRecordService.menuAllList(queryBo); //课程所有节列表
+            for(ClassPeriodVo periodVo : sectionList){
+                if(periodVo.getSectionType()==2){
+                    totalLiveNum++;
+                }
+                if(periodVo.getSectionType()==3){
+                    totalLiveNum++;
+                    overLiveNum++;
+                    liveTime+=periodVo.getRealDuration();
+                }
+
+            }
+        }
+        List<OrderGoodsVo> list = this.baseMapper.listLiveGoodsList(bo);
+        for(OrderGoodsVo vo : list){
+            vo.setTotalLiveNum(totalLiveNum);
+            vo.setOverLiveNum(overLiveNum);
+            vo.setLiveTime(liveTime);
+        }
+        return list;
     }
 
     public boolean joinGrade(Long orderGoodsId, Long gradeId, Long userId, Long goodsId) {

+ 19 - 4
zhongzheng-system/src/main/java/com/zhongzheng/modules/order/vo/OrderGoodsVo.java

@@ -36,6 +36,14 @@ public class OrderGoodsVo {
 	@Excel(name = "用户ID")
 	@ApiModelProperty("用户ID")
 	private Long userId;
+	/** 身份证号 */
+	@Excel(name = "*学员身份证号码")
+	@ApiModelProperty("身份证号")
+	private String idCard;
+	/** 真实姓名 */
+	@Excel(name = "真实姓名")
+	@ApiModelProperty("真实姓名")
+	private String realname;
 
 	/** 商品采集数据 */
 	@Excel(name = "商品采集数据")
@@ -148,8 +156,7 @@ public class OrderGoodsVo {
 	@Excel(name = "商品订单状态")
 	@ApiModelProperty("商品订单状态 -1关闭 0待支付 1已支付 2已退款")
 	private Integer orderGoodsStatus;
-	@ApiModelProperty("用户名称")
-	private String realname;
+
 	/** 班级有效期开始时间 */
 	@Excel(name = "班级有效期开始时间")
 	@ApiModelProperty("班级有效期开始时间")
@@ -208,6 +215,14 @@ public class OrderGoodsVo {
 	@Excel(name = "关闭原因")
 	@ApiModelProperty("关闭原因")
 	private String closeReason;
-
-
+	@ApiModelProperty("总直播次数(含回放)")
+	private Integer totalLiveNum = 0;
+	@ApiModelProperty("已经直播次数")
+	private Integer overLiveNum = 0;
+	@ApiModelProperty("直播总秒数")
+	private Long liveTime = 0L;
+	@ApiModelProperty("观看直播累计时长秒数")
+	private Long seeTime = 0L;
+	@ApiModelProperty("已参加直播次数")
+	private Integer joinLiveNum = 0;
 }

+ 4 - 2
zhongzheng-system/src/main/java/com/zhongzheng/modules/polyv/bo/PolyvLiveQueryBo.java

@@ -22,6 +22,8 @@ public class PolyvLiveQueryBo extends BaseEntity {
 	private String channelId;
 	@ApiModelProperty("用户ID")
 	private Long userId;
-
-
+	@ApiModelProperty("节ID")
+	private Long sectionId;
+	@ApiModelProperty("场次ID")
+	private String sessionId;
 }

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/polyv/service/IPolyvLiveService.java

@@ -11,6 +11,8 @@ import com.zhongzheng.modules.polyv.vo.PolyvCataData;
 import com.zhongzheng.modules.polyv.vo.PolyvVideoQuerVo;
 import com.zhongzheng.modules.polyv.vo.PolyvVideoVo;
 import com.zhongzheng.modules.polyv.vo.PolyvVo;
+import net.polyv.live.v1.entity.channel.playback.LiveChannelVideoListResponse;
+import net.polyv.live.v1.entity.channel.playback.LiveListChannelSessionInfoResponse;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -29,4 +31,7 @@ public interface IPolyvLiveService {
 
 
 	Map<String,Object> getLiveSign(PolyvLiveQueryBo bo) throws IOException, NoSuchAlgorithmException;
+
+	LiveChannelVideoListResponse.ChannelVedioInfo getListChannelSession(PolyvLiveQueryBo bo) throws Exception, NoSuchAlgorithmException;
+	LiveChannelVideoListResponse.ChannelVedioInfo getChannelVideo(PolyvLiveQueryBo bo) throws IOException, NoSuchAlgorithmException;
 }

+ 68 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/polyv/service/impl/PolyvLiveServiceImpl.java

@@ -41,7 +41,12 @@ import net.polyv.common.v1.exception.PloyvSdkException;
 import net.polyv.live.v1.constant.LiveConstant;
 import net.polyv.live.v1.entity.channel.operate.LiveChannelAuthTokenRequest;
 import net.polyv.live.v1.entity.channel.operate.LiveChannelAuthTokenResponse;
+import net.polyv.live.v1.entity.channel.playback.LiveChannelVideoListRequest;
+import net.polyv.live.v1.entity.channel.playback.LiveChannelVideoListResponse;
+import net.polyv.live.v1.entity.channel.playback.LiveListChannelSessionInfoRequest;
+import net.polyv.live.v1.entity.channel.playback.LiveListChannelSessionInfoResponse;
 import net.polyv.live.v1.service.channel.impl.LiveChannelOperateServiceImpl;
+import net.polyv.live.v1.service.channel.impl.LiveChannelPlaybackServiceImpl;
 import net.polyv.live.v1.util.LiveSignUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -124,4 +129,67 @@ public class PolyvLiveServiceImpl implements IPolyvLiveService {
         }
         return map;
     }
+    //获取该频道最近一次场次
+    @Override
+    public LiveChannelVideoListResponse.ChannelVedioInfo getListChannelSession(PolyvLiveQueryBo bo) throws Exception, NoSuchAlgorithmException {
+        LiveListChannelSessionInfoRequest liveListChannelSessionInfoRequest = new LiveListChannelSessionInfoRequest();
+        LiveListChannelSessionInfoResponse liveListChannelSessionInfoResponse;
+        try {
+            Calendar instance = Calendar.getInstance();
+            instance.set(2020, 10, 1);
+            liveListChannelSessionInfoRequest.setChannelId(bo.getChannelId())
+                    .setStartDate(instance.getTime())
+                    .setEndDate(new Date())
+                    .setCurrentPage(1);
+            liveListChannelSessionInfoResponse = new LiveChannelPlaybackServiceImpl().listChannelSessionInfo(
+                    liveListChannelSessionInfoRequest);
+            if (liveListChannelSessionInfoResponse != null) {
+                if(Validator.isNotEmpty(liveListChannelSessionInfoResponse.getContents())&&liveListChannelSessionInfoResponse.getContents().size()>0){
+                    //获取该房间最近一次场次
+                    LiveListChannelSessionInfoResponse.ChannelSessionInfo sessionInfo = liveListChannelSessionInfoResponse.getContents().get(0);
+                    bo.setSessionId(sessionInfo.getSessionId());
+                    return getChannelVideo(bo);
+                }
+                System.out.println("测试查询频道直播场次信息成功{}");
+                System.out.println(JSON.toJSONString(liveListChannelSessionInfoResponse));
+                //to do something ......
+       //         log.debug("测试查询频道直播场次信息成功{}", JSON.toJSONString(liveListChannelSessionInfoResponse));
+            }
+        } catch (PloyvSdkException e) {
+            //参数校验不合格 或者 请求服务器端500错误,错误信息见PloyvSdkException.getMessage()
+            // 异常返回做B端异常的业务逻辑,记录log 或者 上报到ETL 或者回滚事务
+            throw e;
+        } catch (Exception e) {
+            throw e;
+        }
+        return null;
+    }
+
+    @Override
+    public LiveChannelVideoListResponse.ChannelVedioInfo getChannelVideo(PolyvLiveQueryBo bo) throws IOException, NoSuchAlgorithmException {
+        LiveChannelVideoListRequest liveChannelVideoListRequest = new LiveChannelVideoListRequest();
+        LiveChannelVideoListResponse liveChannelVideoListResponse;
+        try {
+            liveChannelVideoListRequest.setChannelId(bo.getChannelId())
+                    .setSessionIds(bo.getSessionId());
+            liveChannelVideoListResponse = new LiveChannelPlaybackServiceImpl().listChannelVideo(
+                    liveChannelVideoListRequest);
+
+            if (liveChannelVideoListResponse != null) {
+                //to do something ......
+                //获取场次的详细信息
+                if(Validator.isNotEmpty(liveChannelVideoListResponse.getChannelVedioInfos())&&liveChannelVideoListResponse.getChannelVedioInfos().size()>0){
+                    return liveChannelVideoListResponse.getChannelVedioInfos().get(0);
+                }
+               System.out.println(JSON.toJSONString(liveChannelVideoListResponse));
+            }
+        } catch (PloyvSdkException e) {
+            //参数校验不合格 或者 请求服务器端500错误,错误信息见PloyvSdkException.getMessage()
+            // 异常返回做B端异常的业务逻辑,记录log 或者 上报到ETL 或者回滚事务
+            throw e;
+        } catch (Exception e) {
+            throw e;
+        }
+        return null;
+    }
 }

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/schedule/service/IScheduleService.java

@@ -48,4 +48,6 @@ public interface IScheduleService extends IService<PolyvVideo> {
     void officialPeriodPush(UserQueryBo bo);
 
     void overLive(UserQueryBo bo);
+
+    void liveToReplay(UserQueryBo bo) throws Exception;
 }

+ 55 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/schedule/service/impl/ScheduleServiceImpl.java

@@ -19,6 +19,8 @@ import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.http.HttpUtils;
 import com.zhongzheng.common.utils.polyv.PolyvUtils;
 import com.zhongzheng.modules.alisms.vo.ResultBean;
+import com.zhongzheng.modules.bank.domain.Exam;
+import com.zhongzheng.modules.bank.domain.QuestionBusiness;
 import com.zhongzheng.modules.base.service.IProfileTpService;
 import com.zhongzheng.modules.base.vo.ProfileTpVo;
 import com.zhongzheng.modules.base.vo.UserProfileVo;
@@ -26,6 +28,7 @@ import com.zhongzheng.modules.course.bo.CourseChapterSectionQueryBo;
 import com.zhongzheng.modules.course.bo.CourseMenuQueryBo;
 import com.zhongzheng.modules.course.bo.CourseModuleChapterQueryBo;
 import com.zhongzheng.modules.course.domain.CourseBusiness;
+import com.zhongzheng.modules.course.domain.CourseSection;
 import com.zhongzheng.modules.course.service.ICourseChapterSectionService;
 import com.zhongzheng.modules.course.service.ICourseMenuService;
 import com.zhongzheng.modules.course.service.ICourseModuleChapterService;
@@ -79,6 +82,7 @@ import com.zhongzheng.modules.order.service.IOrderService;
 import com.zhongzheng.modules.order.vo.OrderGoodsVo;
 import com.zhongzheng.modules.order.vo.OrderListVo;
 import com.zhongzheng.modules.order.vo.OrderVo;
+import com.zhongzheng.modules.polyv.bo.PolyvLiveQueryBo;
 import com.zhongzheng.modules.polyv.bo.PolyvVideoAddBo;
 import com.zhongzheng.modules.polyv.bo.PolyvVideoEditBo;
 import com.zhongzheng.modules.polyv.bo.PolyvVideoQueryBo;
@@ -86,6 +90,7 @@ import com.zhongzheng.modules.polyv.domain.PolyvVideDo;
 import com.zhongzheng.modules.polyv.domain.PolyvVideo;
 import com.zhongzheng.modules.polyv.domain.TokenResponse;
 import com.zhongzheng.modules.polyv.mapper.PolyvVideoMapper;
+import com.zhongzheng.modules.polyv.service.IPolyvLiveService;
 import com.zhongzheng.modules.polyv.vo.PolyvVideoQuerVo;
 import com.zhongzheng.modules.polyv.vo.PolyvVideoVo;
 import com.zhongzheng.modules.polyv.vo.PolyvVo;
@@ -97,6 +102,8 @@ import com.zhongzheng.modules.user.mapper.UserStudyRecordMapper;
 import com.zhongzheng.modules.user.service.*;
 import com.zhongzheng.modules.user.vo.*;
 import com.zhongzheng.modules.wx.service.IWxPayService;
+import net.polyv.live.v1.entity.channel.playback.LiveChannelVideoListResponse;
+import net.polyv.live.v1.entity.channel.playback.LiveListChannelSessionInfoResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -110,6 +117,7 @@ import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import static com.alibaba.fastjson.JSONPatch.OperationType.add;
 import static com.squareup.okhttp.internal.Util.md5Hex;
 
 /**
@@ -159,6 +167,7 @@ public class ScheduleServiceImpl extends ServiceImpl<PolyvVideoMapper, PolyvVide
 
     @Autowired
     private ICourseSectionService iCourseSectionService;
+
     @Autowired
     private ICourseMenuService iCourseMenuService;
 
@@ -183,6 +192,9 @@ public class ScheduleServiceImpl extends ServiceImpl<PolyvVideoMapper, PolyvVide
     @Autowired
     private IUserSubscribeService iUserSubscribeService;
 
+    @Autowired
+    private IPolyvLiveService iPolyvLiveService;
+
     @Autowired
     private IUserStudyRecordService iUserStudyRecordService;
 
@@ -192,6 +204,7 @@ public class ScheduleServiceImpl extends ServiceImpl<PolyvVideoMapper, PolyvVide
     @Autowired
     private IUserPlanService userPlanService;
 
+
     @Autowired
     private UserPlanMapper userPlanMapper;
 
@@ -1065,6 +1078,48 @@ public class ScheduleServiceImpl extends ServiceImpl<PolyvVideoMapper, PolyvVide
 
     }
 
+    @Override
+    public void liveToReplay(UserQueryBo bo) {
+        Long nowTime = DateUtils.getNowTime();
+        Long startTime = nowTime - 3600 * 24 ;
+        //获取今天直播结束的所有直播节
+        List<CourseSectionVo> list = iCourseSectionService.overSectionList(startTime,nowTime);
+        for(CourseSectionVo sectionVo : list){
+            PolyvLiveQueryBo queryBo = new PolyvLiveQueryBo();
+            try{
+                queryBo.setChannelId(sectionVo.getLiveUrl()); //频道房间ID
+                LiveChannelVideoListResponse.ChannelVedioInfo info = iPolyvLiveService.getListChannelSession(queryBo);
+                if(Validator.isNotEmpty(info)){
+                    //秒数误差在1个小时以内的判定为节的保利威直播
+                    if(Math.abs(sectionVo.getLiveEndTime().longValue()-(info.getEndTime().getTime()/1000))<3600){
+                        if("complete".equals(info.getRecordFileType())){
+                            CourseSection oldSection = iCourseSectionService.getOne(new LambdaQueryWrapper<CourseSection>()
+                                    .eq(CourseSection::getSessionId, info.getChannelSessionId())
+                                    .last("limit 1"));
+                            if(Validator.isEmpty(oldSection)){
+                                //录播完成状态且场次ID没被使用
+                                sectionVo.setSessionId(info.getChannelSessionId());//场次ID
+                                sectionVo.setRealDuration(info.getDuration().longValue()); //视频秒数
+                                sectionVo.setRealLiveStartTime(info.getStartTime().getTime());
+                                sectionVo.setRealLiveEndTime(info.getEndTime().getTime());
+                                sectionVo.setRecordingUrl(info.getUrl());
+                                sectionVo.setSectionType(3); //直播变为回放
+                                CourseSection section = BeanUtil.toBean(sectionVo, CourseSection.class);
+                                section.setUpdateTime(DateUtils.getNowTime());
+                                iCourseSectionService.updateById(section);
+                            }
+                            }
+                    }
+                }
+            }catch (Exception e){
+
+            }
+
+
+        }
+
+    }
+
     //获得可用学习天数
     private static int getDutyDays(Date  startDateStr, Date endDateStr,Long[] longs,Long studyDay)  {
         int result = 0;

+ 9 - 4
zhongzheng-system/src/main/resources/mapper/modules/user/UserStudyRecordMapper.xml

@@ -134,6 +134,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="liveStartTime" column="live_start_time"/>
         <result property="liveEndTime" column="live_end_time"/>
         <result property="liveUrl" column="live_url"/>
+        <result property="realDuration" column="real_duration"/>
     </resultMap>
 
 
@@ -1096,7 +1097,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         NULL as section_type,
         NULL as live_start_time,
         NULL as live_end_time,
-        NULL as live_url
+        NULL as live_url,
+        NULL as real_duration
         FROM
         course_menu cm
         where 1=1
@@ -1113,7 +1115,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         NULL as section_type,
         NULL as live_start_time,
         NULL as live_end_time,
-        NULL as live_url
+        NULL as live_url,
+        NULL as real_duration
         FROM
         course_menu cm
         LEFT JOIN goods_course gc on gc.course_id = cm.course_id
@@ -1129,7 +1132,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         cs.section_type,
         cs.live_start_time,
         cs.live_end_time,
-        cs.live_url
+        cs.live_url,
+        cs.real_duration
         FROM
         course_menu cm
         LEFT JOIN course_section cs on cm.menu_id = cs.section_id
@@ -1148,7 +1152,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         3 AS type,
         cs.live_start_time,
         cs.live_end_time,
-        cs.live_url
+        cs.live_url,
+        cs.real_duration
         FROM
         course_chapter_section ccs
         LEFT JOIN course_section cs on ccs.section_id = cs.section_id