From 5ec90174fcd7d0567ad8902dd585e2c174ef02c7 Mon Sep 17 00:00:00 2001 From: Administrator <123456> Date: Fri, 25 Feb 2022 08:27:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E5=AD=A6=E4=B9=A0=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/config/config.ts | 2 +- .../pages/course/components/VideoJS/index.tsx | 58 +++-- web/src/pages/course/detail/index.tsx | 189 +++++++++++---- web/src/pages/course/detail/service.ts | 41 +++- web/src/pages/course/list/index.tsx | 223 ++++++++---------- 5 files changed, 319 insertions(+), 194 deletions(-) diff --git a/web/config/config.ts b/web/config/config.ts index 92bbdd2..d1764ec 100644 --- a/web/config/config.ts +++ b/web/config/config.ts @@ -119,7 +119,7 @@ export default defineConfig({ { name: '课程列表', icon: 'smile', - path: '/course/detail', + path: '/course/detail/:msg', component: './course/detail', }, ], diff --git a/web/src/pages/course/components/VideoJS/index.tsx b/web/src/pages/course/components/VideoJS/index.tsx index 5eb1915..1b37c2a 100644 --- a/web/src/pages/course/components/VideoJS/index.tsx +++ b/web/src/pages/course/components/VideoJS/index.tsx @@ -1,40 +1,68 @@ -import React from "react"; +import React, {useEffect,useState} from "react"; import videojs from "video.js"; import "video.js/dist/video-js.css"; import "videojs-contrib-hls"; export const VideoJS = ( props: any ) => { - + const [count,setCount]=useState(0); + const countRef=React.useRef(count); const videoRef = React.useRef(null); const playerRef = React.useRef(null); - const { options, onReady } = props; - + const { options, onReady,saveLearning,getTime } = props; React.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); - + 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, videoRef]); - + + }, [options]); + // useEffect(()=>{ + // videoRef.current.addEventListener() + // },[]); + + React.useEffect(()=>{ + countRef.current=count; + },[count]) + + + if(count!==0){ + if(countRef.current.toFixed(2)!==count.toFixed(2)){ + // console.log('countRef.current前一次',countRef.current.toFixed(2)); + // console.log('count这一次',count.toFixed(2)) + getTime(count.toFixed(2)); + saveLearning(count); + + } + } + + return (
); - } \ 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 d3a38a4..c831c9e 100644 --- a/web/src/pages/course/detail/index.tsx +++ b/web/src/pages/course/detail/index.tsx @@ -1,7 +1,8 @@ import { AlignLeftOutlined, LaptopOutlined, NotificationOutlined, PlusOutlined, UserOutlined } from '@ant-design/icons'; import { Button, Card, Col, Layout, List, Menu, Progress, Row, Typography } from 'antd'; import { PageContainer } from '@ant-design/pro-layout'; -import { useRequest } from 'umi'; +import {useParams, useRequest} from 'umi'; +import {useEffect, useState} from 'react'; import { queryFakeList } from './service'; import type { CardListItemDataType } from './data'; import styles from './style.less'; @@ -10,19 +11,79 @@ import Sider from 'antd/lib/layout/Sider'; import SubMenu from 'antd/lib/menu/SubMenu'; import { VideoJS } from '../components/VideoJS'; import { useRef } from 'react'; - +import {listMyLearningChapterCourse1, viewCourseGetMyLearning,saveMyLearning} from './service'; +import cookie from 'react-cookies'; const { Paragraph } = Typography; const CardList = () => { + const [currentLearning, SetCurrentLearning] = useState(); + const [courseId, SetCourseId] = useState(); + let time=0; const videoRef = useRef(null); - const { data, loading } = useRequest(() => { - return queryFakeList({ - count: 8, + const params = useParams(); + const ids = params.msg.split(',');//chapter_id,course_id,subject_id + + + + console.log('courseIdcourseIdcourseIdcourseId',courseId) + /** 获取课节 */ + const { data } = useRequest(() => { + return listMyLearningChapterCourse1({ + chapter_id: ids[0], + identity_id:cookie.load('identity_id'), + person_id:cookie.load('person_id'), + subject_id: ids[2], }); }); - const list = data?.list || []; + /** 获取视频 */ + const {data: learning, run, loading } = useRequest((params:{course_id:number}) => { + // SetCourseId(ids[1]); + return viewCourseGetMyLearning({ + identity_id:cookie.load('identity_id'), + person_id:cookie.load('person_id'), + subject_id: ids[2],//chapter_list[0].subject_id + chapter_id: ids[0],//chapter_list[0].chapter_id + course_id:params?.course_id, + }); + }); + + console.log('learning',learning) + //保存进度 + 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,//视频总长度 + }); + }); + + + /** 首次页面 当data 变化 执行run, chapterCourse 变化 进行currentCourse赋值 */ + useEffect(() => { + if(data !== undefined && data !== null){ + run({course_id:ids[1]}); + SetCurrentLearning(learning) + } + //setSelectedCourse({}) + },[data]); + /** run后 chapterCourse 变化 进行currentCourse赋值 */ + useEffect(() => { + if(data !== undefined){ + SetCurrentLearning(learning) + } + //setSelectedCourse({}) + },[learning]); + + + // const content = (
{ actions={[]} extra={<>开始学习时间: 2020-4-9距离结束时间:300天考核学时:36学时} > - } title={false} description={ @@ -44,73 +105,105 @@ const CardList = () => { 学习进度: - + 上次学习:生涯规划之升学路径知多少 主讲人:盖笑松 - + } />
); - //const videoInfo = {url:'http://cctvalih5ca.v.myalicdn.com/live/cctv1_2/index.m3u8', img:''} //const videoInfo = {url:'https://media.w3.org/2010/05/sintel/trailer_hd.mp4', img:''} - const videoInfo = {url:'http://10.10.14.199/dsideal_yy/html/down/M3u8/2D/2D99BF1D-2F37-47FB-8A24-45112A236B8F.m3u8', img:''} - + 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 ( - + - } title="章节目录"> - 第1节 特质因素理论 - 第2节 生涯发展理论 - 第3节 明尼苏达工作适应论 - + } title="课节目录"> + { + data!==undefined? + data.map((item)=>{ + return( + { + SetCourseId(item.course_id); + run({course_id:item.course_id}) + }}>{item.course_name} + ) + }):'' + + } + + { - videoInfo.url && 加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) - language: 'zh-CN', - aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3") - fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。 - sources: [ - { - src: videoInfo.url, - type: 'application/x-mpegURL' + 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 // 全屏按钮 } - ], - poster: videoInfo.img, // 你的封面地址 - width: document.documentElement.clientWidth, - notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。 - controlBar: { - timeDivider: true, - durationDisplay: true, - remainingTimeDisplay: true, - fullscreenToggle: true // 全屏按钮 - } - - - }} onReady={(play: any)=>{ + + + }} + onReady={(play: any)=>{ console.log('play====',play); - videoRef.current = play + videoRef.current = play; play.play() - }}/> + }} + saveLearning={()=>{saveLearning()}} + getTime={(info)=>{ + // setTime(info); + time=info; + console.log('接收的秒数',info) + }} + /> } diff --git a/web/src/pages/course/detail/service.ts b/web/src/pages/course/detail/service.ts index fee9a31..164c81c 100644 --- a/web/src/pages/course/detail/service.ts +++ b/web/src/pages/course/detail/service.ts @@ -1,10 +1,43 @@ import { request } from 'umi'; import type { CardListItemDataType } from './data.d'; -export async function queryFakeList(params: { - count: number; -}): Promise<{ data: { list: CardListItemDataType[] } }> { - return request('/api/card_fake_list', { +// export async function queryFakeList(params: { +// count: number; +// }): Promise<{ data: { list: CardListItemDataType[] } }> { +// return request('/api/card_fake_list', { +// params, +// }); +// } + + +//获取课节 +export async function listMyLearningChapterCourse1(params: { + chapter_id: number; + identity_id: number; + person_id: number; + subject_id: number +}){ + return request(' /dsideal_yy/ypt/careerTraining/learning/listMyLearningChapterCourse', { params, }); } + + +export async function viewCourseGetMyLearning(data: { [key: string]: any }, options?: { [key: string]: any }) { + return request('/dsideal_yy/ypt/careerTraining/learning/viewCourseGetMyLearning', { + data, + method: 'POST', + requestType: "form", + ...(options || {}), + }); +} + +//保存进度 +export async function saveMyLearning(data: { [key: string]: any }, options?: { [key: string]: any }) { + return request('/dsideal_yy/ypt/careerTraining/learning/saveMyLearning', { + data, + method: 'POST', + requestType: "form", + ...(options || {}), + }); +} diff --git a/web/src/pages/course/list/index.tsx b/web/src/pages/course/list/index.tsx index 43dab26..913aa54 100644 --- a/web/src/pages/course/list/index.tsx +++ b/web/src/pages/course/list/index.tsx @@ -7,29 +7,13 @@ import { viewMyLearningSubject,listMyLearningChapterCourse } from './service'; import type { CardListItemDataType } from './data.d'; import styles from './style.less'; import SubMenu from 'antd/lib/menu/SubMenu'; -console.log('course/list') const { Paragraph } = Typography; import cookie from 'react-cookies'; -// const getList = async (subject_id,chapter_id ) => { -// // const hide = message.loading('正在配置'); -// try { -// const a=await listMyLearningChapterCourse({ -// identity_id:cookie.load('identity_id'), -// person_id:cookie.load('person_id'), -// subject_id:subject_id, -// chapter_id:chapter_id, -// }); -// // message.success('配置成功'); -// return a; -// } catch (error) { -// // message.error('配置失败请重试!'); -// return false; -// } -// }; +import {history} from "@@/core/history"; + const CardList = () => { const params = useParams(); - console.log('params',params); const ids = params.msg.split(','); const [currentCourse, SetCurrentCourse] = useState() @@ -46,12 +30,12 @@ const CardList = () => { }); }); - const list = data?.list||[]; + // const list = data?.list||[]; const subject_data=data?data.subject:[]; const last_data=data?data.last_learning_course:[]; const chapter_list=data?data.chapter_list:[]; -//console.log('currentCourse', currentCourse) +// console.log('list', list) /** 获取课程详情 */ const {data: chapterCourse, run, loading } = useRequest((params:{subject_id:number, chapter_id:number}) => { @@ -63,46 +47,24 @@ const CardList = () => { }); }); - /** 首次页面 当data 变化 执行run, chapterCourse 变化 进行currentCourse赋值 */ + /** 首次页面 当data 变化 执行run, chapterCourse 变化 进行currentCourse赋值 */ useEffect(() => { - console.log('chapterCourse...', chapterCourse) - if(data !== undefined && data !== null){ + // console.log('chapterCourse首次页面...', chapterCourse) + if(data !== undefined && data !== null&&chapter_list.length!==0){ run({subject_id:data?.chapter_list[0]?.subject_id, chapter_id:data?.chapter_list[0]?.chapter_id}) SetCurrentCourse(chapterCourse) } //setSelectedCourse({}) },[data]); - /** run后 chapterCourse 变化 进行currentCourse赋值 */ + /** run后 chapterCourse 变化 进行currentCourse赋值 */ useEffect(() => { - console.log('chapterCourse...', chapterCourse) + // console.log('chapterCourse变化...', chapterCourse) if(data !== undefined){ - console.log('data', data) SetCurrentCourse(chapterCourse) } //setSelectedCourse({}) - },[chapterCourse]); - // if(chapter_list.length!==0){ - // - // // const msg = useRequest(() => { - // // return listMyLearningChapterCourse({ - // // identity_id:cookie.load('identity_id'), - // // person_id:cookie.load('person_id'), - // // subject_id:chapter_list?chapter_list[0].subject_id:'', - // // chapter_id:chapter_list?chapter_list[0].chapter_id:'', - // // - // // }); - // // }); - // // console.log('msg',msg) - // } - - // const msg = await listMyLearningChapterCourse({ - // identity_id:cookie.load('identity_id'), - // person_id:cookie.load('person_id'), - // subject_id:chapter_list[0].subject_id, - // chapter_id:chapter_list[0].chapter_id, - // }); - // console.log('msg======',msg) + },[chapterCourse]); const content = (
@@ -126,7 +88,9 @@ const CardList = () => { 学习进度: - 上次学习:{last_data?last_data.course_name:'--'} 主讲人:{last_data?last_data.lecture_teacher:'--'} + 上次学习:{last_data?last_data.course_name:'--'} + 主讲人:{last_data?last_data.lecture_teacher:'--'} + @@ -136,8 +100,6 @@ const CardList = () => {
); - - console.log('iddddddd',chapter_list.length!==0?chapter_list[0].chapter_id.toString():'') const nullData: Partial = {}; return ( @@ -154,7 +116,7 @@ const CardList = () => { chapter_list.length!==0? chapter_list.map((item)=>{ return( - { run({subject_id:item.subject_id, chapter_id:item.chapter_id}) @@ -164,88 +126,97 @@ const CardList = () => { }):'' } - {/*生涯规划理论*/} - {/*生涯规划基本步骤*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - {/*生涯测评的应用与实践*/} - + {console.log('chapterCourse', chapterCourse)} - { - chapterCourse !== undefined ? - <> - <>{chapterCourse[0]?.course_name} - <>{chapterCourse[0]?.lecture_teacher} - + {console.log('chapterCourse', typeof (chapterCourse))} + { + chapterCourse !== undefined &&chapterCourse !== ''? + chapterCourse.map((item,index)=>{ + return( +
+
+
第{item?.sort_no}讲
+
{item?.course_name}
+
{item?.course_hours}小时
+
+ +
+
+ +
+
+ + +
+ ) + }) + : <>暂无 } - - > - rowKey="id" - // loading={loading} - grid={{ - gutter: 1, - xs: 1, - sm: 2, - md: 1, - lg: 1, - xl: 1, - xxl: 1, - }} - dataSource={[nullData, ...list]} - renderItem={(item) => { - if (item && item.id) { - return ( - - - {item.title}} - description={ - - - 第1讲 - - - - {item.description} - - - - 23分钟 - - - - - - - - - } - /> - - - ); - } - }} - /> + + {/* >*/} + {/* rowKey="id"*/} + {/* // loading={loading}*/} + {/* grid={{*/} + {/* gutter: 1,*/} + {/* xs: 1,*/} + {/* sm: 2,*/} + {/* md: 1,*/} + {/* lg: 1,*/} + {/* xl: 1,*/} + {/* xxl: 1,*/} + {/* }}*/} + {/* dataSource={[nullData, chapterCourse]}*/} + {/* renderItem={(item) => {*/} + {/* if (item && item.id) {*/} + {/* return (*/} + {/* */} + {/* */} + {/* {item.title}}*/} + {/* description={*/} + {/* */} + {/* */} + {/* 第1讲*/} + {/* */} + {/* */} + {/* */} + {/* {item.description}*/} + {/* */} + {/* */} + {/* */} + {/* 23分钟*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* }*/} + {/* />*/} + {/* */} + {/* */} + {/* );*/} + {/* }*/} + {/* }}*/} + {/*/>*/}