index.js 34.6 KB
Newer Older
1
import React, { Component } from 'react'
2 3
import HeaderBar from '@/common/HeaderBar'
import './video.scss'
zhanghaozhe committed
4 5
import { NavLink, Route, Redirect, Switch, Link } from 'react-router-dom'
import { http, getParam, browser } from '@/utils'
6 7 8
import Recommendation from './recommendation'
import VideoCatalog from './video-catalog'
import DatumCatalog from './datum-catalog'
9
import { Toast } from 'antd-mobile'
10 11
import videojs from 'video.js'
import 'video.js/dist/video-js.min.css'
12 13 14
import { Modal } from "antd-mobile"
import { Loading } from '@/common'
import { connect } from "react-redux"
15
import jsCookie from 'js-cookie'
zhanghaozhe committed
16
import io from 'socket.io-client'
xuzhenghua committed
17
import Single from "@/components/detail/single";
wangshuo committed
18
import SingleSuccess from "../detail/single/singleSuccess";
19
import './CustomPlayButton'
zhanghaozhe committed
20

xuzhenghua committed
21

zhanghaozhe committed
22
let alert = Modal.alert
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
function ProgressShareModal(props) {
    return (
        props.isShow &&
        <div className='progress-share-modal-wrapper'>
            <div className="progress-share-modal">
                <div className="title">每日打卡</div>
                <ul className="progress-container">
                    <li>
                        <div className="title">累计学习</div>
                        <div className="number"><span className='num'>{props.data.learn_day_count}</span>天</div>
                    </li>
                    <li>
                        <div className="title">行动力超过</div>
                        <div className="number"><span className='num'>{parseFloat(props.data.action_power)}</span>%
                        </div>
                    </li>
                </ul>
                <div className="share-container">
                    <div className="title">分享到</div>
                    <ul>
                        <li className='share-icon'>
xuzhenghua committed
45
                            <a style={{display: 'block'}} href={props.data.url}>
zhanghaozhe committed
46 47
                                <div className="icon"><i className='iconfont iconweixinzhifu'/></div>
                                <div className='text'>微信好友</div>
xuzhenghua committed
48
                            </a>
49 50
                        </li>
                        <li className='share-icon'>
xuzhenghua committed
51
                            <a style={{display: 'block'}} href={props.data.url}>
zhanghaozhe committed
52 53
                                <div className="icon"><i className='iconfont iconpengyouquaniconx'/></div>
                                <div className='text'>朋友圈</div>
xuzhenghua committed
54
                            </a>
55 56 57 58 59 60 61 62 63
                        </li>
                    </ul>
                </div>
                <i className="iconfont iconiconfront-2 close" onClick={props.closeShareModal}/>
            </div>
        </div>
    )
}

64 65
class Video extends Component {

zhanghaozhe committed
66 67
    video   //video element
    player  //video player instance
zhanghaozhe committed
68

zhanghaozhe committed
69
    courseID
zhanghaozhe committed
70

zhanghaozhe committed
71
    ws  //websocket instance
zhanghaozhe committed
72
    timer
73 74 75 76 77 78
    token
    count
    watchSec
    previousPlaybackRate = 1
    currentPlaybackRate = 1
    reconnect = true
xuzhenghua committed
79
    // timeEnough = false
zhanghaozhe committed
80

zhanghaozhe committed
81 82 83
    recordSocket
    recordTimer

xuzhenghua committed
84 85 86 87 88
    isCurrentVideoFirstPlay  = true

    WATCHTIME = "watch_time"
    COUNTSCHEDULE = "count_schedule"
    RECENTLEARN = "recent_learn"
89

90
    state = {
zhanghaozhe committed
91
        title: '',
zhanghaozhe committed
92
        courseId: null,
zhanghaozhe committed
93
        videoList: [],
zhanghaozhe committed
94 95 96 97
        datum: [],
        currentVideoSrc: '',
        activeIndex: 0,
        isAuth: true,
wangshuo committed
98
        course: {}, // course.course_id 为 0 或 '' 时 为免费课程
zhanghaozhe committed
99
        salePrice: null,
zhanghaozhe committed
100
        vCourseId: null,
101 102
        isLoading: true,
        isShowShareModal: false,
xuzhenghua committed
103 104 105
        shareData: {},
        singleBox: false,
        singMess: '',
wangshuo committed
106 107 108
        singleType: 1,// 单集购买需要
        nowPrice: 0,// 单集购买需要
        laterPrice: 0,// 单集购买需要
109 110 111 112
    }


    componentDidMount() {
FE committed
113 114
        if (window.location.protocol === 'https:') {
            window.location.replace('http' + window.location.href.slice(5))
zhanghaozhe committed
115 116 117
            return
        }

zhanghaozhe committed
118
        this.courseID = getParam('id')
zhanghaozhe committed
119
        if (!this.courseID) {
zhanghaozhe committed
120 121 122
            this.props.history.replace('/')
            return
        }
zhanghaozhe committed
123 124 125
        this.setState({
            courseId: this.courseID
        })
FE committed
126
        const {location, location: {state = {}}} = this.props;
zhanghaozhe committed
127
        if (state.oid) {
wangshuo committed
128 129 130 131 132 133 134 135
            this.check(state.oid);
        }
        if (getParam('is_class') === 1 || getParam('weixinpay')) {
            this.payCallback()
        }
        if (browser.isWeixin) {
            this.isweixinPay()
        }
136
        this.token = jsCookie.get('token')
zhanghaozhe committed
137
        this.getVideoList()
zhanghaozhe committed
138
        this.getDatumCatalog()
zhanghaozhe committed
139 140 141
        this.setupRecord()
    }

xuzhenghua committed
142
    // 直接购买
xuzhenghua committed
143
    tobuy = () => {
FE committed
144
        // 详情页单集购买到该页面,url中的id不是课程id
zhanghaozhe committed
145
        const {course = {}} = this.state;
FE committed
146
        http.get(`${API['base-api']}/m/cart/addtopreorder/[${course.course_id}]`).then((res) => {
xuzhenghua committed
147
            if (res.data.errno === 0) {
FE committed
148
                this.props.history.push(`/order?id=${course.course_id}`, {simple: 1})
xuzhenghua committed
149 150 151 152 153 154 155
            } else {
                Toast.info(res.data.msg, 2);
            }
        })
    }
    // 购买单集
    toSingleset = (item) => {
156
        // console.log(item);
xuzhenghua committed
157 158
        this.setState({
            singleBox: true,
wangshuo committed
159
            singleType: 1,
xuzhenghua committed
160 161
            singMess: item
        })
wangshuo committed
162
        window.localStorage.setItem('singMess', JSON.stringify(item))
xuzhenghua committed
163 164 165 166
    }

    // 自组件传给父组件的boxHide
    boxHide = (val) => {
xuzhenghua committed
167
        this.setState({singleBox: val, singleType: 1})
xuzhenghua committed
168 169
    }

wangshuo committed
170
    // 单集购买 H5支付成功后回调
zhanghaozhe committed
171
    payCallback = () => {
wangshuo committed
172
        const _this = this;
zhanghaozhe committed
173
        if (!getParam('oid')) {
wangshuo committed
174
            return;
zhanghaozhe committed
175
        } else {
wangshuo committed
176 177 178
            this.setState({
                singMess: JSON.parse(window.localStorage.getItem('singMess'))
            })
wangshuo committed
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
            _this.intervalPayStatus = setInterval(function () {
                http.get(`${API['base-api']}/m/orderState/oid/${getParam('oid')}`).then(res => {
                    if (res.data.errno === 401) {
                        clearInterval(_this.intervalPayStatus);
                        _this.intervalPayStatus = null;
                        // 获取课程类型
                        http.get(`${API['base-api']}/class_order_status/${getParam('oid')}`).then((res) => {
                            if (Number(res.data.data.errno) === 200) {
                                // 正常购买单集成功
                                _this.setState({
                                    singleType: 6,
                                })
                            } else if (Number(res.data.data.errno) === 201) {
                                // 0元参团
                                _this.setState({
                                    singleType: 4,
                                })
                            } else if (Number(res.data.data.errno) === 202) {
                                // 0元购
                                _this.setState({
                                    singleType: 3,
                                })
                            } else if (Number(res.data.data.errno) === 203) {
                                // 三天内特价
                                _this.setState({
                                    nowPrice: res.data.data.data.now_price,
                                    laterPrice: res.data.data.data.three_day_later_price,
                                    singleType: 2,
                                })
                            } else {
                                Toast.info(res.data.data.msg, 2)
                            }
                        })
                    }
                })
            }, 1000)
        }
    };
    // 单集购买 微信内支付成功后回调
zhanghaozhe committed
218
    isweixinPay = () => {
wangshuo committed
219 220 221 222 223 224
        let _this = this;
        let weixin_code = getParam('code');
        if (weixin_code) {
            if (!getParam('oid')) {
                return
            } else {
wangshuo committed
225 226 227
                this.setState({
                    singMess: JSON.parse(window.localStorage.getItem('singMess'))
                })
wangshuo committed
228 229 230 231
                // this.props.weixinPay(weixin_code)
                http.get(`${API['base-api']}/pay/wxpay/pub_charge/oid/${getParam('oid')}/code/${weixin_code}`).then((res) => {
                    if (res.data.errno === 0) {
                        const data = res.data.data;
zhanghaozhe committed
232

wangshuo committed
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
                        function onBridgeReady() {
                            WeixinJSBridge.invoke(
                                'getBrandWCPayRequest', {
                                    "appId": data.appId,                //公众号名称,由商户传入
                                    "timeStamp": data.timeStamp,        //时间戳,自1970年以来的秒数
                                    "nonceStr": data.nonceStr,          //随机串
                                    "package": data.package,
                                    "signType": data.signType,          //微信签名方式:
                                    "paySign": data.paySign             //微信签名
                                },
                                function (res) {
                                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                                        Toast.info('支付成功', 2);
                                        _this.intervalPayStatus = setInterval(function () {
                                            http.get(`${API['base-api']}/m/orderState/oid/${getParam('oid')}`).then(res => {
                                                if (res.data.errno === 401) {
                                                    clearInterval(_this.intervalPayStatus);
                                                    _this.intervalPayStatus = null;
                                                    // 获取课程类型
                                                    http.get(`${API['base-api']}/class_order_status/${getParam('oid')}`).then((res) => {
                                                        if (Number(res.data.data.errno) === 200) {
                                                            // 正常购买单集成功
                                                            _this.setState({
                                                                singleType: 6,
                                                            })
                                                        } else if (Number(res.data.data.errno) === 201) {
                                                            // 0元参团
                                                            _this.setState({
                                                                singleType: 4,
                                                            })
                                                        } else if (Number(res.data.data.errno) === 202) {
                                                            // 0元购
                                                            _this.setState({
                                                                singleType: 3,
                                                            })
                                                        } else if (Number(res.data.data.errno) === 203) {
                                                            // 三天内特价
                                                            _this.setState({
                                                                nowPrice: res.data.data.data.now_price,
                                                                laterPrice: res.data.data.data.three_day_later_price,
                                                                singleType: 2,
                                                            })
                                                        } else {
                                                            Toast.info(res.data.data.msg, 2)
                                                        }
                                                    })
                                                }
                                            })
                                        }, 1000)
                                    } else {
                                        alert('支付失败')
                                    }
                                }
                            )
                        }
zhanghaozhe committed
288

wangshuo committed
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
                        if (typeof WeixinJSBridge == "undefined") {
                            if (document.addEventListener) {
                                document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false)
                            } else if (document.attachEvent) {
                                document.attachEvent('WeixinJSBridgeReady', onBridgeReady)
                                document.attachEvent('onWeixinJSBridgeReady', onBridgeReady)
                            }
                        } else {
                            onBridgeReady()
                        }
                    } else {
                        Toast.info(res.data.msg, 2)
                    }
                })
            }
        }
    };
    // 判断支付是否成功
    check = (oid) => {
wangshuo committed
308 309 310
        this.setState({
            singMess: JSON.parse(window.localStorage.getItem('singMess'))
        })
wangshuo committed
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
        http.get(`${API['base-api']}/class_order_status/${oid}`).then((res) => {
            if (Number(res.data.data.errno) === 200) {
                // 正常购买单集成功
                this.setState({
                    singleType: 6,

                })
            } else if (Number(res.data.data.errno) === 201) {
                // 0元参团
                this.setState({
                    singleType: 4,

                })
            } else if (Number(res.data.data.errno) === 202) {
                // 0元购
                this.setState({
                    singleType: 3,

                })
            } else if (Number(res.data.data.errno) === 203) {
                // 三天内特价
                this.setState({
                    nowPrice: res.data.data.data.now_price,
                    laterPrice: res.data.data.data.three_day_later_price,
                    singleType: 2,

                })
            } else {
                Toast.info(res.data.data.msg, 2)
            }
        })
    }
zhanghaozhe committed
343 344

    setupRecord = () => {
xuzhenghua committed
345
        this.recordSocket = io(API.record, {
zhanghaozhe committed
346 347
            transports: ['websocket'],
            forceNew: true
zhanghaozhe committed
348
        })
zhanghaozhe committed
349
        // this.recordSocket = io(API.record)
xuzhenghua committed
350 351 352
        // this.recordSocket.on('seek', time => {
        //     this.player.currentTime(time)
        // })
zhanghaozhe committed
353

xuzhenghua committed
354
        // 开启定时器 每5秒发送一次学习记录 --删除
zhanghaozhe committed
355 356 357 358 359
        this.recordTimer = setInterval(() => {
            this.sendRecord()
        }, 5000)
    }

xuzhenghua committed
360
    // 发送学习记录
zhanghaozhe committed
361
    sendRecord = () => {
zhanghaozhe committed
362
        if (this.recordSocket && this.player) {
zhanghaozhe committed
363 364 365
            this.recordSocket.emit('addRecord', this.recordUserInfo())
        }
    }
xuzhenghua committed
366
    // 返回学习记录的数据
zhanghaozhe committed
367 368 369 370 371
    recordUserInfo = () => {
        let {uid} = this.props.user.data
        return {
            uid,
            course_id: this.courseID,
zhanghaozhe committed
372
            video_id: this.state.videoList[this.state.activeIndex]['id'],
zhanghaozhe committed
373 374 375
            video_time: parseInt(this.player.currentTime()),
            plat: 5
        }
zhanghaozhe committed
376 377
    }

xuzhenghua committed
378
    // 9502 初始化 监听事件
zhanghaozhe committed
379
    setupWS = () => {
zhanghaozhe committed
380
        this.ws = new WebSocket(API["process-api"]);
381 382
        this.ws.addEventListener('error', () => {
            this.ws = null
zhanghaozhe committed
383 384
        })
        this.ws.addEventListener('close', () => {
zhanghaozhe committed
385
            if (this.reconnect) {
386
                this.ws = null
zhanghaozhe committed
387
                setTimeout(() => {
zhanghaozhe committed
388
                    this.setupWS();
zhanghaozhe committed
389
                }, 1000)
390 391
            }
            clearInterval(this.timer)
xuzhenghua committed
392
            this.timer = null;
393 394 395
        })
        this.ws.addEventListener('message', e => {
            const data = JSON.parse(e.data);
wangshuo committed
396
            data.code == 4040 && (this.reconnect = false);
xuzhenghua committed
397 398 399 400 401 402
            if(data.code === 0) {
                console.log("上次的学习记录" + JSON.stringify(data));
                if(data.data && data.data.position) {
                    this.player.currentTime(data.data.position);
                }
            }
zhanghaozhe committed
403
        })
zhanghaozhe committed
404 405
    }

zhanghaozhe committed
406
    sendMessage = message => {
wangshuo committed
407 408 409 410 411 412 413 414 415 416 417 418
        let readyState = this.ws.readyState, _this = this;
        if(readyState === 1) {
            this.ws && this.ws.send(JSON.stringify(message))
        }else if(readyState === 3) {
            this.ws.close();
            this.ws = null;
            let reconnect = setTimeout(function() {
                clearTimeout(reconnect);
                reconnect = null;
                _this.ws = new WebSocket(PROCESS_URL);
            }, 500);
        }
419
    }
zhanghaozhe committed
420

421 422
    //视频结束请求接口
    getShareProgressInfo = () => {
zhanghaozhe committed
423
        http.get(`${API['base-api']}/m/aist/share_data/${this.courseID}/${this.state.videoList[this.state.activeIndex]['id']}`)
424 425 426 427 428 429 430 431
            .then(res => {
                const {data} = res
                if (data.errno == 200) {
                    this.setState({shareData: data.data, isShowShareModal: true})
                }
            })
    }

xuzhenghua committed
432
    //告诉服务端计算进度
433
    countSchedule = () => {
zhanghaozhe committed
434 435
        const {videoList, activeIndex, vCourseId, course = {}} = this.state
        if (Number(course.course_id) === 0 || course.course_id === '') {
wangshuo committed
436 437 438
            console.log('免费课程 拦截');
            return;
        }
xuzhenghua committed
439
        let ctype = 0;
zhanghaozhe committed
440
        if (course.is_aist) {
xuzhenghua committed
441
            ctype = 2;
wangshuo committed
442
        }
xuzhenghua committed
443 444 445 446 447 448 449 450 451 452 453
        // 计算进度 根据ctype判断 课程类型 0-视频 1-直播 2-AI特训营
        this.sendMessage({
            mtype: 'count_schedule',
            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,
            ctype: ctype,
        })
454

wangshuo committed
455 456
    }
    // 发送时间消息
457
    sendWatchTime = (sec, rate) => {
wangshuo committed
458 459
        const {videoList, activeIndex, vCourseId, course = {}} = this.state
        // 免费课程不发送
xuzhenghua committed
460 461 462 463
        // if (Number(course.course_id) === 0 || course.course_id === '') {
        //     console.log('免费课程 拦截');
        //     return;
        // }
wangshuo committed
464
        // 时间为0 不发送消息
zhanghaozhe committed
465
        if (Number(sec) === 0) {
wangshuo committed
466 467
            return;
        }
xuzhenghua committed
468
        let ctype = 0;
zhanghaozhe committed
469
        if (course.is_aist) {
xuzhenghua committed
470
            ctype = 2;
wangshuo committed
471
        }
xuzhenghua committed
472 473 474 475 476
        // 时间足够不发送
        // if(this.timeEnough) {
        //     console.log('5001 时间足够');
        //     return;
        // }
477
        this.sendMessage({
xuzhenghua committed
478
            mtype: 'watch_time',
479 480 481
            rate,
            time: sec,
            video_id: videoList[activeIndex]['id'],
wangshuo committed
482
            course_id: this.state.courseId,
483 484 485
            v_course_id: vCourseId,
            uid: this.props.user.data.uid,
            token: this.token,
xuzhenghua committed
486 487 488
            platform: 5,
            position: parseInt(this.player.currentTime()),
            ctype: ctype,
489
        })
zhanghaozhe committed
490 491 492
    }

    setupTimer = () => {
493 494 495
        this.count = 0
        this.watchSec = 0
        clearInterval(this.timer)
xuzhenghua committed
496
        this.timer = null;
zhanghaozhe committed
497
        this.timer = setInterval(() => {
498 499 500 501 502 503
            if (this.player && this.player.player()) {
                if (this.count === 5) {
                    this.sendWatchTime(this.watchSec, this.currentPlaybackRate)
                    this.count = this.watchSec = 0
                } else {
                    !this.player.paused() && this.watchSec++
xuzhenghua committed
504
                    !this.player.paused() && this.count++
505
                }
zhanghaozhe committed
506
            }
507
        }, 1000)
zhanghaozhe committed
508

zhanghaozhe committed
509 510
    }

xuzhenghua committed
511
    // 初始化视频播放器
zhanghaozhe committed
512
    initializePlayer = () => {
513
        window.HELP_IMPROVE_VIDEOJS = false;
zhanghaozhe committed
514
        this.player = videojs(this.video, {
515 516
            controls: true,
            preload: 'auto',
517
            bigPlayButton: false,
518 519
            textTrackDisplay: false,
            posterImage: false,
zhanghaozhe committed
520
            errorDisplay: false,
zhanghaozhe committed
521 522 523 524 525
            playbackRates: ['0.75', '1', '1.5', '2'],
            controlBar: {
                pictureInPictureToggle: false
            }
        })
526
        this.player.addChild('CustomPlayButtonCover')
zhanghaozhe committed
527 528
        this.player.on('ready', () => {
            this.recordSocket.emit('load', this.recordUserInfo())
zhanghaozhe committed
529
        })
xuzhenghua committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
        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();
            }
        })
552 553 554 555 556 557 558
        this.player.on('ratechange', () => {
            this.currentPlaybackRate = this.player.playbackRate()
            this.sendWatchTime(this.watchSec, this.previousPlaybackRate)
            this.count = this.watchSec = 0
            this.previousPlaybackRate = this.currentPlaybackRate
        })
        this.player.on('ended', () => {
xuzhenghua committed
559 560 561
            this.sendWatchTime(this.watchSec, this.currentPlaybackRate);
            this.count = this.watchSec = 0;
            this.countSchedule(); // 计算进度 -- 播放完毕
wangshuo committed
562 563 564 565
            // 返现课程才出现打卡记录
            if(this.state.course.is_aist) {
                this.getShareProgressInfo()
            }
wangshuo committed
566
            clearInterval(this.timer);
xuzhenghua committed
567
            this.timer = null;
zhanghaozhe committed
568
        })
zhanghaozhe committed
569 570 571 572 573 574 575 576 577 578
        this.player.on('seeked', () => {
            this.sendRecord()
        })
    }

    sendLastRecord = () => {
        http.post(`${API.home}/m/course/record_last_video`, {
            v_course_id: this.state.course['v_course_id'],
            video_id: this.state.videoList[this.state.activeIndex].id
        })
zhanghaozhe committed
579 580 581
    }

    componentWillUnmount() {
zhanghaozhe committed
582
        this.player && this.player.dispose()
zhanghaozhe committed
583

zhanghaozhe committed
584
        clearInterval(this.timer)
xuzhenghua committed
585
        this.timer = null;
zhanghaozhe committed
586
        this.ws && this.ws.close()
zhanghaozhe committed
587
        this.ws = null
zhanghaozhe committed
588 589 590 591

        clearInterval(this.recordTimer)
        this.recordSocket && this.recordSocket.close()
        this.recordSocket = null
zhanghaozhe committed
592 593
    }

xuzhenghua committed
594
    // 选择新的视频
595
    selectVideo = index => {
xuzhenghua committed
596 597 598
        if (index === this.state.activeIndex) {
            return
        }
xuzhenghua committed
599 600
        console.log('selectVideo 先发送时间 再发送进度 在重置定时器');
        this.isCurrentVideoFirstPlay = true; // 切换视频则重置这个变量 因为新视频肯定是首次播放
wangshuo committed
601
        this.sendWatchTime(this.watchSec, this.currentPlaybackRate)
xuzhenghua committed
602
        this.countSchedule(); // 计算进度 -- 选择新视频(可能是M端特有的)
wangshuo committed
603
        this.setupTimer();
xuzhenghua committed
604

FE committed
605 606
        this.setState(
            {
xuzhenghua committed
607 608 609
                activeIndex: index
            },
            () => {
xuzhenghua committed
610

611
                if (this.hasAuth(this.state.activeIndex)) {
zhanghaozhe committed
612 613 614
                    this.setPlayerSrc(this.state.videoList[index]['play_url'])
                    this.sendLastRecord()
                    this.playVideo()
zhanghaozhe committed
615
                } else {
FE committed
616
                    this.getCoursePrice();
zhanghaozhe committed
617
                }
xuzhenghua committed
618
            }
wangshuo committed
619
        );
620 621
    }

622 623 624
    getLastVideoIndex = lastIndex => {
        return this.state.videoList.findIndex(item => item.id == lastIndex)
    }
625

zhanghaozhe committed
626
    getVideoList = () => {
FE committed
627
        let url = '';
xuzhenghua committed
628 629
        if (getParam('video_id')) {
            url = `${API.home}/m/course/play/${this.courseID + '?video_id=' + getParam('video_id')}`
xuzhenghua committed
630 631 632
            http.post(`${API['base-api']}/sys/get_class_audition`, {
                video_id: getParam('video_id')
            })
xuzhenghua committed
633 634 635
        } else {
            url = `${API.home}/m/course/play/${this.courseID}`
        }
FE committed
636
        http.get(url).then(res => {
zhanghaozhe committed
637 638 639 640 641 642 643 644 645 646 647
                const {data = {}, code} = res.data;
                if (code === 200) {
                    this.setState(
                        state => ({
                            videoList: data['lessons'],
                            currentVideoSrc: data['lessons'][state.activeIndex]['play_url'],
                            course: data.course,
                            courseId: data.course['course_id'],
                            vCourseId: data.course['v_course_id'],
                            title: data.course['course_title'],
                            isLoading: false
zhanghaozhe committed
648
                        }),
649
                        this.playSetup
zhanghaozhe committed
650
                    )
651 652 653
                } else {
                    Toast.info(data.msg)
                }
FE committed
654 655
            }
        )
656 657
    }

658
    playSetup = () => {
FE committed
659
        // is_aist,是否AI特训营
zhanghaozhe committed
660
        const {course = {}} = this.state;
xuzhenghua committed
661 662 663
        // if (Number(course.course_id) === 0 || course.course_id === '') {
        //     console.log('免费课程 拦截');
        // }else{
wangshuo committed
664
            let _this = this;
FE committed
665 666
            this.setupWS();
            this.setupTimer();
wangshuo committed
667 668 669
            let scheduleTime = setTimeout(function () {
                clearTimeout(scheduleTime);
                scheduleTime = null;
xuzhenghua committed
670
                _this.countSchedule(); // 刚进入页面的时候 就计算进度  先获取视频列表getVideoList 获取列表后 播放选择的视频 然后计算进度
wangshuo committed
671
            }, 1000);
xuzhenghua committed
672
        // }
FE committed
673 674 675 676 677
        let index = this.getLastVideoIndex(course.last_video_id);
        index = index >= 0 ? index : 0;
        this.setState(
            {
                activeIndex: index
FE committed
678
            },
FE committed
679 680 681 682 683 684 685 686 687 688
            () => {
                if (this.lessonAvailable(index)) {
                    if (this.hasAuth(index)) {
                        Promise.resolve().then(() => {
                            this.initializePlayer()
                            this.playWithAuth()
                        })
                    } else {
                        this.getCoursePrice();
                    }
689
                } else {
FE committed
690 691 692 693 694 695
                    alert('暂无视频', '', [{
                        text: 'OK',
                        onPress: () => {
                            this.props.history.push('/')
                        }
                    }])
696 697
                }
            }
FE committed
698
        );
699 700 701

    }

zhanghaozhe committed
702
    setPlayerSrc = src => {
zhanghaozhe committed
703
        if (!this.player) {
xuzhenghua committed
704 705
            this.initializePlayer()
        }
zhanghaozhe committed
706 707 708 709 710 711 712
        this.player.src({
            src,
            type: 'application/x-mpegURL'
        })
    }

    playVideo = () => {
xuzhenghua committed
713 714 715 716
        this.player.ready(() => {
            this.player.play()
        })

zhanghaozhe committed
717 718
    }

719 720

    getDatumCatalog() {
zhanghaozhe committed
721
        http.get(`${API.home}/m/course/data/${this.courseID}`)
722 723 724 725 726 727 728 729 730 731 732 733 734 735
            .then(res => {
                const data = res.data
                if (data.code === 200) {

                    this.setState({
                        datum: data.data
                    })

                } else {
                    Toast.info(data.msg)
                }
            })
    }

736 737
    lessonAvailable = index => {
        return this.state.videoList[index]['video_size'] !== 0
zhanghaozhe committed
738 739 740
    }

    getCoursePrice = () => {
zhanghaozhe committed
741
        const {course = {}} = this.state;
FE committed
742
        http.get(`${API.home}/sys/course/price/${course.course_id}`)
zhanghaozhe committed
743 744 745 746 747 748 749 750 751 752 753
            .then(res => {
                const {data} = res
                if (data.code === 200) {
                    this.setState({
                        salePrice: data.data['sale_price']
                    })
                }
            })
    }

    playWithAuth = () => {
zhanghaozhe committed
754
        const {videoList, activeIndex} = this.state
zhanghaozhe committed
755

756
        if (this.hasAuth(activeIndex)) {
zhanghaozhe committed
757
            this.setPlayerSrc(videoList[activeIndex]['play_url'])
zhanghaozhe committed
758 759 760
        }
    }

761 762
    hasAuth = index => {
        const {videoList} = this.state
xuzhenghua committed
763

764
        let lesson = videoList[index]
xuzhenghua committed
765

xuzhenghua committed
766 767 768 769 770 771 772 773 774 775
        if (lesson['video_auth']) {
            this.setState({
                isAuth: true
            })
            return true
        } else {
            this.setState({
                isAuth: false
            })
            return false
zhanghaozhe committed
776 777 778 779

        }
    }

780 781

    render() {
FE committed
782
        let {match, location, history} = this.props
FE committed
783
        const {videoList, activeIndex, isAuth, salePrice, course, singleBox, singleType} = this.state;
FE committed
784
        let toHref = '';
zhanghaozhe committed
785 786
        if (location.state && location.state.to && location.state.to === 'detail') {
            toHref = `/detail?id=${course.course_id}`
FE committed
787
        }
788 789
        return (
            <div className='play'>
zhanghaozhe committed
790 791
                <HeaderBar title={this.state.title} arrow={true} toHref={() => {
                    toHref ? history.push(
FE committed
792 793 794 795
                        toHref,
                        {
                            to: 'classify'
                        }
zhanghaozhe committed
796 797
                    ) : history.go(-1)
                }}/>
zhanghaozhe committed
798 799
                <Loading isLoading={this.state.isLoading}>
                    <div className="video">
800 801 802 803 804
                        <video className={'video-js'} ref={el => this.video = el}
                               webkit-playsinline="true"
                               playsInline={true}
                               x-webkit-airplay="allow"
                               x5-video-player-type="h5">
zhanghaozhe committed
805 806 807
                            <source src={'/'} type='application/x-mpegURL'/>
                        </video>
                        {
xuzhenghua committed
808
                            !isAuth && !!videoList[activeIndex]['is_class'] && (
zhanghaozhe committed
809 810 811
                                <div className="purchase-box">
                                    <div className='hint'>您尚未购买该课时,请购买后学习。</div>
                                    <div className='btns'>
zhanghaozhe committed
812
                                        <button
FE committed
813 814 815 816 817
                                            type='button'
                                            onClick={this.tobuy}
                                            className='purchase-class'
                                        >
                                            ¥{salePrice} 购买课程
xuzhenghua committed
818
                                        </button>
zhanghaozhe committed
819
                                        <button
FE committed
820 821 822 823 824
                                            type='button'
                                            onClick={this.toSingleset.bind(this, videoList[activeIndex])}
                                            className='purchase-episode'
                                        >
                                            ¥{videoList.length && videoList[activeIndex]['class_price']} 购买单集
zhanghaozhe committed
825 826
                                        </button>
                                    </div>
zhanghaozhe committed
827
                                </div>
zhanghaozhe committed
828 829
                            )
                        }
xuzhenghua committed
830 831 832 833 834 835 836 837 838
                        {
                            !isAuth && !!course.is_aist && (
                                <div className="is-aist-box">
                                    <i className={'iconfont iconiconfront-21'}></i>
                                    <p className={'time'}>{videoList[activeIndex]['aist_start_time']}</p>
                                    <p className={'time'}>请耐心等待...</p>
                                </div>
                            )
                        }
839
                    </div>
zhanghaozhe committed
840 841
                    <div className='tab'>
                        <div>
zhanghaozhe committed
842
                            <NavLink to={{pathname: `${match.url}/video`, search: `?id=${this.courseID}`}}
zhanghaozhe committed
843 844 845 846 847
                                     replace
                                     activeClassName='active'
                            >视频</NavLink>
                        </div>
                        <div>
zhanghaozhe committed
848
                            <NavLink to={{pathname: `${match.url}/datum`, search: `?id=${this.courseID}`}}
zhanghaozhe committed
849 850 851 852
                                     replace
                                     activeClassName='active'
                            >资料</NavLink>
                        </div>
853
                    </div>
xuzhenghua committed
854 855

                    {/*单集购买*/}
wangshuo committed
856 857
                    {
                        singleBox &&
zhanghaozhe committed
858 859 860 861 862 863 864 865 866 867
                        <Single
                            courseId={course.course_id}
                            singleBox={this.state.singleBox}
                            boxHide={this.boxHide}
                            data={this.state.singMess}
                            singleType={this.state.singleType}
                            vcourseId={course.v_course_id}
                            videoId={this.state.singMess.video_id}
                            check={this.check}
                            title={this.state.singMess.course_tile}/>
wangshuo committed
868 869 870 871 872
                    }
                    {/* 单集购买成功 */}
                    {
                        singleType !== 1 &&
                        <SingleSuccess
FE committed
873
                            courseId={course.course_id}
wangshuo committed
874 875 876
                            boxHide={this.boxHide}
                            data={this.state.singMess}
                            singleType={singleType}
wangshuo committed
877
                            vcourseId={course.v_course_id}
wangshuo committed
878 879 880 881 882 883
                            videoId={this.state.singMess.video_id}
                            nowPrice={this.state.nowPrice}
                            laterPrice={this.state.laterPrice}
                        />
                    }

zhanghaozhe committed
884
                </Loading>
zhanghaozhe committed
885
                <Switch>
886 887 888 889
                    <Redirect exact from={'/play'} to={{
                        pathname: '/play/video',
                        search: location.search
                    }}/>
zhanghaozhe committed
890 891
                    <Route
                        path={`${match.path}/video`}
FE committed
892 893 894 895 896 897 898 899 900 901 902
                        render={props => {
                            return (
                                <VideoCatalog
                                    activeIndex={this.state.activeIndex}
                                    selectVideo={this.selectVideo}
                                    videoCatalog={videoList}
                                    {...props}
                                />
                            );
                        }}
                    />
zhanghaozhe committed
903 904 905 906
                    <Route path={`${match.path}/datum`} render={props => {
                        return <DatumCatalog {...props} datum={this.state.datum}/>
                    }}/>
                </Switch>
907
                <Route render={props => {
zhanghaozhe committed
908
                    return this.state.vCourseId ? <Recommendation {...props} vCourseId={this.state.vCourseId}/>
zhanghaozhe committed
909 910
                        : null
                }}/>
911 912 913 914
                <ProgressShareModal isShow={this.state.isShowShareModal}
                                    closeShareModal={() => this.setState({isShowShareModal: false})}
                                    data={this.state.shareData}
                />
xuzhenghua committed
915

916 917 918 919 920 921
            </div>
        );
    }
}


922 923 924
export default connect(
    state => ({user: state.user}),
    null
xuzhenghua committed
925
)(Video);