diff --git a/web/src/pages/course/components/VideoJS.tsx b/web/src/pages/course/components/VideoJS.tsx index 1de0a65..45f291b 100644 --- a/web/src/pages/course/components/VideoJS.tsx +++ b/web/src/pages/course/components/VideoJS.tsx @@ -1,61 +1,40 @@ -import React, {forwardRef, useEffect,useImperativeHandle,useState} from "react"; +import React, { useEffect } from "react"; import videojs from "video.js"; import "video.js/dist/video-js.css"; import "videojs-contrib-hls"; - -// React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。 -const VideoJS = ( props: any, ref: any) => { +export const VideoJS = ( props: any ) => { const videoRef = React.useRef(null); const playerRef = React.useRef(null); const { options, onReady, width, height } = props; - + console.log('props', props) useEffect(() => { + + // make sure Video.js player is only initialized once if (!playerRef.current) { const videoElement = videoRef.current; if (!videoElement) return; + const player = playerRef.current = videojs(videoElement, options, () => { - // console.log("player is ready"); + console.log("player is ready"); onReady && onReady(player); }); } else { // you can update player here [update player through props] const player = playerRef.current; + console.log('playerplayerplayer===',player); player.src(options.sources[0].src); - // player.autoplay(true); - videoRef.current.addEventListener('play',()=>{ - console.log('播放'); - //setCount(player.currentTime()); - //playerRef.current.currentTime(count) - // player.currentTime(count) - // getTime(player.currentTime()); - // saveLearning(); - }); - videoRef.current.addEventListener('pause',()=>{ - console.log('停止了') - }) - } - }, [options]); + player.autoplay(true); - // 暴露组件的方法 接受外部获取的ref - useImperativeHandle(ref, () => ({ - // 构造ref的获取数据方法 - currentTime: (time: number) => { - if(time){ - playerRef?.current?.currentTime(time) - } - return playerRef?.current?.currentTime() || 0 - }, - })); + } + }, [options, videoRef]); return (
); } -// forwardRef这个组件能够将其接受的 ref 属性转发到其组件树下 -export default forwardRef( VideoJS ); \ No newline at end of file diff --git a/web/src/pages/course/detail/index.tsx b/web/src/pages/course/detail/index.tsx index 3f125ca..679f764 100644 --- a/web/src/pages/course/detail/index.tsx +++ b/web/src/pages/course/detail/index.tsx @@ -10,21 +10,24 @@ import { Content } from 'antd/lib/layout/layout'; import Sider from 'antd/lib/layout/Sider'; import SubMenu from 'antd/lib/menu/SubMenu'; -import { useRef } from 'react'; +import React,{ useRef } from 'react'; import {listMyLearningChapterCourse1, viewCourseGetMyLearning,saveMyLearning} from './service'; import cookie from 'react-cookies'; -import VideoJS from '../components/VideoJS'; +import { VideoJS } from '../components/VideoJS'; const { Paragraph } = Typography; - +let num=0; const CardList = () => { const params = useParams(); const ids = params.msg.split(',');//chapter_id,course_id,subject_id const [currentLearning, SetCurrentLearning] = useState(); const [courseId, SetCourseId] = useState(ids[1]); - let time=0; - const videoRef = useRef(null); - + const [video, setVideo] = useState({}); + const [nums,setNums]=useState(0); + let timer=useRef(); + let video_second=0; + // const videoRef = useRef(null); + const playerRef = React.useRef(null); // 播放器引用 console.log('courseIdcourseIdcourseIdcourseId',courseId) /** 获取课节 */ const { data } = useRequest(() => { @@ -46,23 +49,51 @@ const CardList = () => { chapter_id: ids[0],//chapter_list[0].chapter_id course_id:params?.course_id, }); + },{ + onSuccess:(result)=>{ + console.log('result9999',result); + let info={img:'',url:''}; + if(JSON.stringify(result.course.attachment_json.url)!=='{}'){ + info.url= '/dsideal_yy/html/'+result.course.attachment_json.url; + info.img=result.course.attachment_json.img; + } + setVideo(info); + + } }); - console.log('learning',learning) + console.log('video',video) //保存进度 - const {data: progress, run:saveProgress, } = useRequest((params:{time:number}) => { - return saveMyLearning({ - chapter_id:learning?.learning.chapter_id,//章节id - course_id:courseId?courseId:ids[1],//课程id - identity_id:cookie.load('identity_id'), - learning_id:learning?.learning.learning_id,//学习记录id - learning_second:0,//距离上次提交持续学习秒数(非必填) - person_id:cookie.load('person_id'), - play_second:params?.time,//当前播放时间点(秒数) - subject_id:learning?.learning.subject_id,//主题id - video_second:learning?.course.course_minutes*60,//视频总长度 - }); - }); + // const saveProcess = async((params:{time:number,num:number}) => { + // console.log('num保存是',num) + // // return saveMyLearning({ + // // chapter_id:learning?.learning.chapter_id,//章节id + // // course_id:courseId?courseId:ids[1],//课程id + // // identity_id:cookie.load('identity_id'), + // // learning_id:learning?.learning.learning_id,//学习记录id + // // learning_second:num,//距离上次提交持续学习秒数(非必填) + // // person_id:cookie.load('person_id'), + // // play_second:params?.time,//当前播放时间点(秒数) + // // subject_id:learning?.learning.subject_id,//主题id + // // video_second:video_second,//视频总长度 + // // }); + // }); + + + const saveProcess = async (info)=>{ + console.log('num保存是',info) + await saveMyLearning({ + chapter_id:learning?.learning.chapter_id,//章节id + course_id:courseId?courseId:ids[1],//课程id + identity_id:cookie.load('identity_id'), + learning_id:learning?.learning.learning_id,//学习记录id + learning_second:info.num,//距离上次提交持续学习秒数(非必填) + person_id:cookie.load('person_id'), + play_second:info.time,//当前播放时间点(秒数) + subject_id:learning?.learning.subject_id,//主题id + video_second:video_second,//视频总长度 + }) + } /** 首次页面 当data 变化 执行run, chapterCourse 变化 进行currentCourse赋值 */ useEffect(() => { @@ -119,17 +150,12 @@ const CardList = () => { const videoInfo = {url:'http://10.10.14.199/dsideal_yy/html/down/M3u8/2D/2D99BF1D-2F37-47FB-8A24-45112A236B8F.m3u8', img:''}//有视频 // const videoInfo=learning?.course.attachment_json;isg const nullData: Partial = {}; - const saveLearning=()=>{ - console.log('保存进队'); - saveProgress({time:time}) - }; // const saveLearning=useEffect(() => { // console.log('保存进队'); // saveProgress({time:time}) // },[time]); - console.log('time',time) return ( { { - videoInfo.url && 加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) - language: 'zh-CN', - aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3") - fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。 - sources: [ - { - // src: 'http://10.10.24.121:8000/dsideal_yy/html/'+videoInfo.url, - src: videoInfo.url, - type: 'application/x-mpegURL' - } - ], - poster: videoInfo.img, // 你的封面地址 - width: document.documentElement.clientWidth, - notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。 - controlBar: { - timeDivider: true, - durationDisplay: true, - remainingTimeDisplay: true, - fullscreenToggle: true // 全屏按钮 - } - }} - ref={videoRef} + video?.url&&( + 加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) + language: 'zh-CN', + aspectRatio: '4:3', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3") + fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。 + sources: [ + { + src: JSON.stringify(video)!=='{}'?video.url:'', // 测试地址后续请删除 + // src: '/dsideal_yy/html/down/Syzx/6e/6e4e88a3-0c71-4298-ba5b-ac1c3f52d587.mp4' , // 测试地址后续请删除 + //type: 'application/x-mpegURL' + } + ], + poster: JSON.stringify(video)!=='{}'?video.img:'', // 你的封面地址 + width: document.documentElement.clientWidth, + notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。 + controlBar: { + timeDivider: true, + durationDisplay: true, + remainingTimeDisplay: true, + fullscreenToggle: true // 全屏按钮 + } + }} + onReady={(play: any) => { + //console.log('play====', play); + playerRef.current = play + // play.play(); + play.on('play',function (event) { + console.log('播放-------------------------------') + num=0; + timer.current=setInterval(()=>{; + // console.log('timer-----------',timer) + num++ + },1000) + }) + play.on("timeupdate", function (event) { + //const _timeCurrent = Date.parse(new Date().toString()) / 1000; // 当前时间 + //setTimeUpdateState(_timeCurrent); //timeUpdateState + if(play.currentTime()===this.duration()){ + console.log('播放完了',num) + clearInterval(timer.current) + saveProcess({time:play.currentTime(),num:num}) + + } + // console.log('playcurrentTime--', play.currentTime()) + // console.log('play-%-', parseInt(play.currentTime()) % 30) + if (parseInt(play.currentTime())>0&&parseInt(play.currentTime()) % 30 === 0) { // 每15秒更新进度 + console.log(1) + saveProcess({time:play.currentTime(),num:30}) + } + //var currentTime = parseInt(this.currentTime()); //当前时间 + video_second = this.duration(); //视频时常 + // console.log('duration',duration) + //var percent = (currentTime / duration * 100).toFixed(0) + "%"; + //console.log('event',event); + //$("#current").text(this.currentTime()); + //$("#duration").text(duration); + }) + }} /> + ) + } + diff --git a/web/src/pages/user/Login/index.tsx b/web/src/pages/user/Login/index.tsx index 1aaf553..f4fd024 100644 --- a/web/src/pages/user/Login/index.tsx +++ b/web/src/pages/user/Login/index.tsx @@ -47,6 +47,7 @@ const Login: React.FC = () => { // 登录产生cookie const msg = await login({ ...values, type }); if (msg.success === true) { + console.log('dengdgdgdgdgd---------------------------------') const defaultLoginSuccessMessage = '登录成功!'; message.success(defaultLoginSuccessMessage); await fetchUserInfo(); @@ -68,6 +69,7 @@ const Login: React.FC = () => { }; const { status, type: loginType } = userLoginState; + return (
@@ -216,6 +218,11 @@ const Login: React.FC = () => { /> )} +
{ + window.open("http://10.10.14.199/dsideal_yy/html/pwdfind/pwdfind_fir.html?register_flag=11","_blaknk"); + }} + >忘记密码