Commit 2a4c5b5b by xuzhenghua

checkout

parent 0e4d3d56
...@@ -3692,11 +3692,6 @@ ...@@ -3692,11 +3692,6 @@
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
}, },
"clipboard-copy": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-3.1.0.tgz",
"integrity": "sha512-Xsu1NddBXB89IUauda5BIq3Zq73UWkjkaQlPQbLNvNsd5WBMnTWPNKYR6HGaySOxGYZ+BKxP2E9X4ElnI3yiPA=="
},
"cliui": { "cliui": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
...@@ -3989,6 +3984,14 @@ ...@@ -3989,6 +3984,14 @@
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
}, },
"copy-to-clipboard": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.2.0.tgz",
"integrity": "sha512-eOZERzvCmxS8HWzugj4Uxl8OJxa7T2k1Gi0X5qavwydHIfuSHq2dTD09LOg/XyGq4Zpb5IsR/2OJ5lbOegz78w==",
"requires": {
"toggle-selection": "^1.0.6"
}
},
"core-js": { "core-js": {
"version": "2.6.5", "version": "2.6.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz",
...@@ -12084,6 +12087,15 @@ ...@@ -12084,6 +12087,15 @@
} }
} }
}, },
"react-copy-to-clipboard": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz",
"integrity": "sha512-ELKq31/E3zjFs5rDWNCfFL4NvNFQvGRoJdAKReD/rUPA+xxiLPQmZBZBvy2vgH7V0GE9isIQpT9WXbwIVErYdA==",
"requires": {
"copy-to-clipboard": "^3",
"prop-types": "^15.5.8"
}
},
"react-dev-utils": { "react-dev-utils": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-8.0.0.tgz", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-8.0.0.tgz",
...@@ -14502,6 +14514,11 @@ ...@@ -14502,6 +14514,11 @@
"repeat-string": "^1.6.1" "repeat-string": "^1.6.1"
} }
}, },
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
},
"topo": { "topo": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz",
......
...@@ -284,6 +284,9 @@ class Detail extends Component { ...@@ -284,6 +284,9 @@ class Detail extends Component {
http.get(`${API.home}/m/course/detail/${id}`).then((res) => { http.get(`${API.home}/m/course/detail/${id}`).then((res) => {
const {data, code} = res.data; const {data, code} = res.data;
if (code === 200) { if (code === 200) {
if(data['redirect_url'] !== ''){
window.location.href = data['redirect_url']
}
this.setState({ this.setState({
course: data course: data
}); });
......
...@@ -46,13 +46,13 @@ class Passport extends Component { ...@@ -46,13 +46,13 @@ class Passport extends Component {
{ {
logo: qq, logo: qq,
text: 'QQ', text: 'QQ',
url: `${API["passport-api"]}/mob/qqlogin?redirect_url=${this.redirectURL}`, url: `${API["passport-api"]}/mob/qqlogin?redirect_url=${encodeURIComponent(this.redirectURL)}`,
id: 'qq' id: 'qq'
}, },
{ {
logo: sina, logo: sina,
text: '新浪', text: '新浪',
url: `${API['passport-api']}/mob/sinalogin?redirect_url=${this.redirectURL}`, url: `${API['passport-api']}/mob/sinalogin?redirect_url=${encodeURIComponent(this.redirectURL)}`,
id: 'sina' id: 'sina'
} }
] ]
......
...@@ -75,11 +75,16 @@ class Video extends Component { ...@@ -75,11 +75,16 @@ class Video extends Component {
previousPlaybackRate = 1 previousPlaybackRate = 1
currentPlaybackRate = 1 currentPlaybackRate = 1
reconnect = true reconnect = true
timeEnough = false // timeEnough = false
recordSocket recordSocket
recordTimer recordTimer
isCurrentVideoFirstPlay = true
WATCHTIME = "watch_time"
COUNTSCHEDULE = "count_schedule"
RECENTLEARN = "recent_learn"
state = { state = {
title: '', title: '',
...@@ -341,21 +346,23 @@ class Video extends Component { ...@@ -341,21 +346,23 @@ class Video extends Component {
forceNew: true forceNew: true
}) })
// this.recordSocket = io(API.record) // this.recordSocket = io(API.record)
this.recordSocket.on('seek', time => { // this.recordSocket.on('seek', time => {
this.player.currentTime(time) // this.player.currentTime(time)
}) // })
// 开启定时器 每5秒发送一次学习记录 --删除
this.recordTimer = setInterval(() => { this.recordTimer = setInterval(() => {
this.sendRecord() this.sendRecord()
}, 5000) }, 5000)
} }
// 发送学习记录
sendRecord = () => { sendRecord = () => {
if (this.recordSocket && this.player) { if (this.recordSocket && this.player) {
this.recordSocket.emit('addRecord', this.recordUserInfo()) this.recordSocket.emit('addRecord', this.recordUserInfo())
} }
} }
// 返回学习记录的数据
recordUserInfo = () => { recordUserInfo = () => {
let {uid} = this.props.user.data let {uid} = this.props.user.data
return { return {
...@@ -367,6 +374,7 @@ class Video extends Component { ...@@ -367,6 +374,7 @@ class Video extends Component {
} }
} }
// 9502 初始化 监听事件
setupWS = () => { setupWS = () => {
this.ws = new WebSocket(API["process-api"]); this.ws = new WebSocket(API["process-api"]);
this.ws.addEventListener('error', () => { this.ws.addEventListener('error', () => {
...@@ -380,11 +388,17 @@ class Video extends Component { ...@@ -380,11 +388,17 @@ class Video extends Component {
}, 1000) }, 1000)
} }
clearInterval(this.timer) clearInterval(this.timer)
this.timer = null;
}) })
this.ws.addEventListener('message', e => { this.ws.addEventListener('message', e => {
const data = JSON.parse(e.data); const data = JSON.parse(e.data);
data.code == 4040 && (this.reconnect = false); data.code == 4040 && (this.reconnect = false);
data.code == 5001 && (this.timeEnough = true); if(data.code === 0) {
console.log("上次的学习记录" + JSON.stringify(data));
if(data.data && data.data.position) {
this.player.currentTime(data.data.position);
}
}
}) })
} }
...@@ -414,63 +428,53 @@ class Video extends Component { ...@@ -414,63 +428,53 @@ class Video extends Component {
}) })
} }
//告诉服务端计算进度 普通课程不发送 //告诉服务端计算进度
countSchedule = () => { countSchedule = () => {
const {videoList, activeIndex, vCourseId, course = {}} = this.state const {videoList, activeIndex, vCourseId, course = {}} = this.state
if (Number(course.course_id) === 0 || course.course_id === '') { if (Number(course.course_id) === 0 || course.course_id === '') {
console.log('免费课程 拦截'); console.log('免费课程 拦截');
return; return;
} }
// 时间足够不发送 let ctype = 0;
if(this.timeEnough) {
console.log('5001 时间足够');
return;
}
if (course.is_aist) { if (course.is_aist) {
// 返现课程 ctype = 2;
}
// 计算进度 根据ctype判断 课程类型 0-视频 1-直播 2-AI特训营
this.sendMessage({ this.sendMessage({
mtype: 'count_schedule', mtype: 'count_schedule',
uid: this.props.user.data.uid, uid: this.props.user.data.uid,
token: this.token, token: this.token,
platform: 5
})
} else {
// 普通课程
this.sendMessage({
mtype: 'c_count_schedule',
uid: this.props.user.data.uid,
token: this.token,
platform: 5, platform: 5,
video_id: videoList[activeIndex]['id'], video_id: videoList[activeIndex]['id'],
course_id: this.state.courseId, course_id: this.state.courseId,
v_course_id: vCourseId, v_course_id: vCourseId,
ctype: ctype,
}) })
}
} }
// 发送时间消息 // 发送时间消息
sendWatchTime = (sec, rate) => { sendWatchTime = (sec, rate) => {
const {videoList, activeIndex, vCourseId, course = {}} = this.state const {videoList, activeIndex, vCourseId, course = {}} = this.state
// 免费课程不发送 // 免费课程不发送
if (Number(course.course_id) === 0 || course.course_id === '') { // if (Number(course.course_id) === 0 || course.course_id === '') {
console.log('免费课程 拦截'); // console.log('免费课程 拦截');
return; // return;
} // }
// 时间为0 不发送消息 // 时间为0 不发送消息
if (Number(sec) === 0) { if (Number(sec) === 0) {
return; return;
} }
// 时间足够不发送 let ctype = 0;
if(this.timeEnough) {
console.log('5001 时间足够');
return;
}
let info_type = 'c_watch_time';
if (course.is_aist) { if (course.is_aist) {
info_type = 'watch_time'; ctype = 2;
} }
// 时间足够不发送
// if(this.timeEnough) {
// console.log('5001 时间足够');
// return;
// }
this.sendMessage({ this.sendMessage({
mtype: info_type, mtype: 'watch_time',
rate, rate,
time: sec, time: sec,
video_id: videoList[activeIndex]['id'], video_id: videoList[activeIndex]['id'],
...@@ -478,7 +482,9 @@ class Video extends Component { ...@@ -478,7 +482,9 @@ class Video extends Component {
v_course_id: vCourseId, v_course_id: vCourseId,
uid: this.props.user.data.uid, uid: this.props.user.data.uid,
token: this.token, token: this.token,
platform: 5 platform: 5,
position: parseInt(this.player.currentTime()),
ctype: ctype,
}) })
} }
...@@ -486,6 +492,7 @@ class Video extends Component { ...@@ -486,6 +492,7 @@ class Video extends Component {
this.count = 0 this.count = 0
this.watchSec = 0 this.watchSec = 0
clearInterval(this.timer) clearInterval(this.timer)
this.timer = null;
this.timer = setInterval(() => { this.timer = setInterval(() => {
if (this.player && this.player.player()) { if (this.player && this.player.player()) {
if (this.count === 5) { if (this.count === 5) {
...@@ -500,6 +507,7 @@ class Video extends Component { ...@@ -500,6 +507,7 @@ class Video extends Component {
} }
// 初始化视频播放器
initializePlayer = () => { initializePlayer = () => {
window.HELP_IMPROVE_VIDEOJS = false; window.HELP_IMPROVE_VIDEOJS = false;
this.player = videojs(this.video, { this.player = videojs(this.video, {
...@@ -518,6 +526,28 @@ class Video extends Component { ...@@ -518,6 +526,28 @@ class Video extends Component {
this.player.on('ready', () => { this.player.on('ready', () => {
this.recordSocket.emit('load', this.recordUserInfo()) this.recordSocket.emit('load', this.recordUserInfo())
}) })
this.player.on('play', () => {
const {videoList, activeIndex, vCourseId, course = {}} = this.state
// 当视频播放时 看是否是第一次播放(初次进入页面 刷新页面 切换视频 都是第一次播放 需要获取上次的播放时间)
if(this.isCurrentVideoFirstPlay) {
// 当某些原因导致视频暂停时(用户暂停 网络不好等) 再播放时不需要发送
this.isCurrentVideoFirstPlay = false;
// 发送消息 recent_learn
this.ws.send(JSON.stringify({
mtype: this.RECENTLEARN,
uid: this.props.user.data.uid,
token: this.token,
platform: 5,
video_id: videoList[activeIndex]['id'],
course_id: this.state.courseId,
v_course_id: vCourseId,
is_live: 0,
}))
}
if(!this.timer) {
this.setupTimer();
}
})
this.player.on('ratechange', () => { this.player.on('ratechange', () => {
this.currentPlaybackRate = this.player.playbackRate() this.currentPlaybackRate = this.player.playbackRate()
this.sendWatchTime(this.watchSec, this.previousPlaybackRate) this.sendWatchTime(this.watchSec, this.previousPlaybackRate)
...@@ -527,12 +557,13 @@ class Video extends Component { ...@@ -527,12 +557,13 @@ class Video extends Component {
this.player.on('ended', () => { this.player.on('ended', () => {
console.log('ended'); console.log('ended');
this.sendWatchTime(this.watchSec, this.currentPlaybackRate) this.sendWatchTime(this.watchSec, this.currentPlaybackRate)
this.countSchedule(); // 计算进度 this.countSchedule(); // 计算进度 -- 播放完毕
// 返现课程才出现打卡记录 // 返现课程才出现打卡记录
if(this.state.course.is_aist) { if(this.state.course.is_aist) {
this.getShareProgressInfo() this.getShareProgressInfo()
} }
clearInterval(this.timer); clearInterval(this.timer);
this.timer = null;
}) })
this.player.on('seeked', () => { this.player.on('seeked', () => {
this.sendRecord() this.sendRecord()
...@@ -550,6 +581,7 @@ class Video extends Component { ...@@ -550,6 +581,7 @@ class Video extends Component {
this.player && this.player.dispose() this.player && this.player.dispose()
clearInterval(this.timer) clearInterval(this.timer)
this.timer = null;
this.ws && this.ws.close() this.ws && this.ws.close()
this.ws = null this.ws = null
...@@ -558,13 +590,15 @@ class Video extends Component { ...@@ -558,13 +590,15 @@ class Video extends Component {
this.recordSocket = null this.recordSocket = null
} }
// 选择新的视频
selectVideo = index => { selectVideo = index => {
if (index === this.state.activeIndex) { if (index === this.state.activeIndex) {
return return
} }
console.log('selectVideo 先发送时间 在发送进度 在重置定时器'); console.log('selectVideo 先发送时间 再发送进度 在重置定时器');
this.isCurrentVideoFirstPlay = true; // 切换视频则重置这个变量 因为新视频肯定是首次播放
this.sendWatchTime(this.watchSec, this.currentPlaybackRate) this.sendWatchTime(this.watchSec, this.currentPlaybackRate)
this.countSchedule(); // 计算进度 this.countSchedule(); // 计算进度 -- 选择新视频(可能是M端特有的)
this.setupTimer(); this.setupTimer();
this.setState( this.setState(
...@@ -622,19 +656,18 @@ class Video extends Component { ...@@ -622,19 +656,18 @@ class Video extends Component {
playSetup = () => { playSetup = () => {
// is_aist,是否AI特训营 // is_aist,是否AI特训营
const {course = {}} = this.state; const {course = {}} = this.state;
if (Number(course.course_id) === 0 || course.course_id === '') { // if (Number(course.course_id) === 0 || course.course_id === '') {
console.log('免费课程 拦截'); // console.log('免费课程 拦截');
}else{ // }else{
let _this = this; let _this = this;
this.setupWS(); this.setupWS();
this.setupTimer(); this.setupTimer();
console.log('playSetup');
let scheduleTime = setTimeout(function () { let scheduleTime = setTimeout(function () {
clearTimeout(scheduleTime); clearTimeout(scheduleTime);
scheduleTime = null; scheduleTime = null;
_this.countSchedule(); _this.countSchedule(); // 刚进入页面的时候 就计算进度 先获取视频列表getVideoList 获取列表后 播放选择的视频 然后计算进度
}, 1000); }, 1000);
} // }
let index = this.getLastVideoIndex(course.last_video_id); let index = this.getLastVideoIndex(course.last_video_id);
index = index >= 0 ? index : 0; index = index >= 0 ? index : 0;
this.setState( this.setState(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment