import React from 'react'; import { Link } from 'react-router-dom'; import './index.less'; import Page from '@src/containers/Page'; import Assets from '@src/components/Assets'; import { getMap, formatPercent, formatDate } from '@src/services/Tools'; import Footer from '../../../components/Footer'; import { FaqModal, CommentModal, FinishModal, CourseNoteModal, AskCourseModal } from '../../../components/OtherModal'; import { Contact, AnswerCarousel, Comment } from '../../../components/Other'; import Tabs from '../../../components/Tabs'; import { Icon as GIcon } from '../../../components/Icon'; import Button from '../../../components/Button'; import IconButton from '../../../components/IconButton'; import UserTable from '../../../components/UserTable'; import ProgressText from '../../../components/ProgressText'; import { OpenText } from '../../../components/Open'; import Video from '../../../components/Video'; import { Main } from '../../../stores/main'; import { Course } from '../../../stores/course'; import { User } from '../../../stores/user'; import { Order } from '../../../stores/order'; import { Question } from '../../../stores/question'; import { My } from '../../../stores/my'; export default class extends Page { initState() { this.columns = [ { title: '学习内容', key: 'title', render: (text, record) => { const { no } = this.state; if (no === record.no) { // 当前正在 } return `课时 ${record.no}: ${text}`; }, }, { title: '预习作业', key: 'paper', render: text => { text = text || {}; const progress = text.report ? formatPercent(text.report.userNumber, text.report.questionNumber) : 0; const times = text.paper ? text.paper.finishTimes : 0; return (
{!text.report && ( { User.needLogin().then(() => { Question.startLink('preview', text); }); }} /> )} {text.report && !text.report.isFinish && ( { User.needLogin().then(() => { Question.continueLink('preview', text); }); }} /> )} {text.report && ( { User.needLogin().then(() => { Question.restart('preview', text); }); }} /> )} {text.report && !!text.report.isFinish && ( { User.needLogin().then(() => { Question.reportLink('preview', text); }); }} /> )}
); }, }, { title: '进度', key: 'progress', render: (text, record) => { const { paper = {} } = record; return `${paper.paper && paper.paper.finishTimes > 0 ? `${paper.paper.finishTimes}次+` : ''}${ paper.report ? formatPercent(paper.report.userNumber, paper.report.questionNumber, false) : '0%'}`; }, }, { title: '最近学习', key: 'lastTime', render: (text, record) => { const { paper = {} } = record; return paper.report && formatDate(paper.report.updateTime, 'YYYY-MM-DD HH:mm:ss'); }, }, { title: '笔记', key: 'note', render: (text, record) => { return ; }, }, { title: '问答', key: 'ask', render: (text, record) => { return ( {`${record.answerNumber || 0}/${record.askNumber || 0}`} ); }, }, ]; return { tab: '1', rightTab: '1', key: '1', add: false, list: [{ key: '1' }, { key: '2' }, { key: '3' }], data: {}, position: 0, }; } init() { Main.dataStruct().then(result => { const dataStructSelect = result.map(row => { return { title: `${row.titleZh}${row.titleEn}`, key: row.id, }; }); const dataStructMap = getMap(dataStructSelect, 'key'); this.setState({ dataStructSelect, dataStructMap }); }); Main.getBase().then(result => { this.setState({ base: result }); }); } formatRecord(row) { row.paperMap = {}; if (row.papers) { row.papers.forEach(paper => { if (paper.courseNo) row.paperMap[paper.courseNo] = paper; }); } row.progressMap = {}; if (row.progress) { row.progress.forEach(progress => { row.progressMap[progress.courseNoId] = progress; }); } row.courseNoMap = {}; row.courseTime = 0; if (row.courseNos) { row.courseNos.forEach(no => { row.courseNoMap[no.id] = no; row.courseTime += no.time; no.paper = row.paperMap[no.id]; no.progress = row.progressMap[no.id]; }); } if (row.currentNo) { row.currentCourseNo = row.courseNoMap[row.currentNo]; } else { row.currentNo = 0; } return row; } initData() { const { id } = this.params; Course.detail(id).then(result => { result = this.formatRecord(result); // result.have = true; // result.waters = ['高*', '152****4895']; this.setState({ data: result }); // 选择课时 if (this.state.search.no) { this.onChangeItem(this.state.search.no); } else { this.onChangeItem(1); } this.refreshNote(); }); Main.listComment({ page: 1, size: 100, channel: 'course-video', position: id }).then(result => { this.comments = result.list; this.setState({ comments: result.list }); }); } refreshAsk(position) { const { id } = this.params; const { item = {} } = this.state; Course.listAsk(Object.assign({ page: 1, size: 1000, courseId: id, courseNoId: item.id, position })).then(result => { this.setState({ asks: result.list }); }); } refreshNote() { const { id } = this.params; const { data } = this.state; if (!data.have) return; My.listCourseNote({ courseId: id, page: 1, size: data.courseNos.length }) .then((result) => { this.noteMap = getMap(result.list, 'courseNoId'); data.courseNos.forEach((row) => { const note = this.noteMap[row.id]; if (note) row.note = true; }); this.setState({ data }); }); } onChangeRightTab(rightTab) { this.setState({ rightTab }); } onChangeTab(tab) { this.setState({ tab }); } onChangeItem(key) { key = Number(key); this.changeQuery({ no: key }); this.setState({ no: key }); const { data, item } = this.state; const index = key - 1; const timelineSelect = []; const current = data.courseNos[index]; if (current) { const max = current.time; let start = 0; let end = start + 5; while (start < max) { timelineSelect.push({ title: `${start} - ${end}min`, key: `${start}`, }); start += 5; end = Math.min(start + 5, max); } } // 切换播放,记录进度 if (item) { this.updateProgress(item.id, this.lastSecond, item.time, true); } this.setState({ item: current, timelineSelect }); } onTimeUpdate(second) { const { position, item = {}, data } = this.state; if (!data.have) { // 如果是试用,则按秒数增加 second += (item.startTrail || 0) * 60; } const minute = parseInt(second / 60, 10); const nowPosition = parseInt(minute / 5, 10) * 5; if (nowPosition !== position) { this.refreshAsk(position); this.setState({ position: nowPosition }); // 定时更新进度 this.updateProgress(item.id, second, item.time); } this.lastSecond = second; this.showWater(second); } playVideo(second) { // 开始计时 this.lastTime = new Date(); this.showWater(second); } showWater(second, extend) { const { data, water = {} } = this.state; const { waters = [] } = data; if (!this.lastTime && water.show) { water.show = false; second -= 1; water.transition = ''; } else if (!water.show) { water.show = true; water.transition = 'transform 1s linear 0s'; } if (water.show) { water.opacity = 1; } else { water.opacity = 0; } if (extend) { Object.assign(water, extend); } const time = 15; const stop = 0; const times = (second / (time + stop)); const index = parseInt(times % waters.length, 10); const current = (second % (time + stop)); water.style = [2, 0, 2, 1][parseInt((times % 4), 10)] + 1; water.text = waters[[0, 1][index]]; // console.log(water.show, current, current / 4, (current / 4) % 2); if (water.show) { water.opacity = (current / 4) % 2 > 1 ? 0 : 1; } // if (water.style % 2) { // water.transform = `translateX(${current * 100 / time}%)`; // } else { water.transform = `translateX(${100 - ((current - stop / 2) * 100 / time)}%)`; // } this.setState({ water }); } onChangeProgress(second) { this.showWater(second - 1, this.lastTime ? { transition: '', opacity: 0 } : { transition: '', opacity: 0 }); setTimeout(() => { this.showWater(second, this.lastTime ? { transition: 'transform 1s linear 0s', opacity: 1 } : { transition: '', opacity: 0 }); }, 1); } pauseVideo(second) { // 停止计时 const now = new Date(); if (this.lastTime != null) { this.time += (now.getTime() - this.lastTime.getTime()) / 1000; } this.lastTime = null; this.showWater(second); } next() { const { data, item } = this.state; if (data.courseNos.length === item.no) { return; } this.onChangeItem(item.no + 1); } onVideoAction(key) { const { rightTab, showTab, showAsk, showNote, item = {} } = this.state; switch (key) { case 'ask': return this.setState({ showAsk: !showAsk }); case 'note': return this.setState({ showNote: !showNote, note: this.noteMap ? this.noteMap[item.id] || {} : {} }); case 'answer': return this.setState({ showTab: rightTab === '1' ? !showTab : true, rightTab: '1' }); case 'list': return this.setState({ showTab: rightTab === '2' ? !showTab : true, rightTab: '2' }); default: return ''; } } updateProgress(courseNoId, currentTime, totalTime, record) { if (!this.lastTime) return; const { id } = this.params; const now = new Date(); this.time += (now.getTime() - this.lastTime.getTime()) / 1000; this.lastTime = now; const progress = formatPercent(currentTime, totalTime); if (record || this.time > 600) { // 最长5分钟记录一次 Course.noProgress(id, courseNoId, progress, this.time, courseNoId); this.time = 0; } else { Course.noProgress(id, courseNoId, progress, null, null); } } buy() { const { data } = this.props; User.needLogin().then(() => { Order.speedPay({ productType: 'course', productId: data.id }).then(result => { User.needPay(result).then(() => { this.refresh(); }); }); }); } add() { const { data } = this.props; User.needLogin().then(() => { Order.addCheckout({ productType: 'course', productId: data.id }).then(() => { this.setState({ add: true }); }); }); } viewAsk(id) { Course.askView(id); } setVideo(video) { this.video = video; } renderView() { const { base = {}, data = {}, item = {}, add, rightTab, showTab, showAsk, showNote, dataStructMap = {}, showComment, comment = {}, showFaq, faq = {}, showFinish, note = {}, ask = {}, timelineSelect = [], water = {} } = this.state; const { courseNos = [] } = data; return (
千行课堂 > 全部课程 > {data.parentStructId > 0 ? `${(dataStructMap[data.parentStructId] || {}).title} >` : ''}{' '} {(dataStructMap[data.structId] || {}).title} > {data.title} > 课程详情
{data.title}
{!data.have && } {!data.have && } {data.have && }
授课老师:{data.teacher}
{data.have && }
{item && }
0) ? 'have' : ''} tab-warpper`}> this.onChangeRightTab(key)} />
{this[`renderRightTab${rightTab}`]()}
{data.have && }
(showTab ? document.getElementById(this.video.state.id) : document.body)} show={showAsk} defaultData={ask} course={data} courseNo={item} selectList={timelineSelect} onConfirm={() => this.setState({ showAsk: false })} onCancel={() => this.setState({ showAsk: false })} /> (showTab ? document.getElementById(this.video.state.id) : document.body)} show={showNote} defaultData={note} course={data} courseNos={courseNos} noteMap={this.noteMap} onConfirm={() => { this.setState({ showNote: false }); this.refreshNote(); }} onCancel={() => this.setState({ showNote: false })} /> this.setState({ showComment: false, commnet: {}, showFinish: true })} onCancel={() => this.setState({ showComment: false, commnet: {} })} onClose={() => this.setState({ showComment: false, commnet: {} })} /> this.setState({ showFaq: false, faq: {} })} onConfirm={() => this.setState({ showFaq: false, faq: {}, showFinish: true })} /> document.getElementById(this.video.state.id)} show={showFinish} onConfirm={() => this.setState({ showFinish: false })} />
); } renderRightTab1() { const { asks = [], data = {}, position } = this.state; return [
{position}:00~{position + 5}:00 全部问答 >
,
{asks.map(item => { return (
提问
{item.content}
{item.answerStatus > 0 && (
回答
)} {item.answerStatus > 0 && (
this.viewAsk(item.id)}>{item.answer}
)}
); })}
, ]; } renderRightTab2() { const { data = {}, no } = this.state; const { courseNos = [] } = data; return (
{courseNos.map(item => { return (
this.onChangeItem(item.no)}> 课时{item.no} {item.title}
); })}
); } renderTab() { const { tab } = this.state; return [
this.onChangeTab(key)} /> {this[`renderTab${tab}`]()}
, ]; } renderTab1() { const { data = {} } = this.state; return (
老师资历
基本参数
授课重点
适合人群
); } renderTab2() { const { data } = this.state; return (
); } renderTab3() { return (
千行小助手:
1232104-310431
微信扫码添加千行小助手为好友,
咨询课程,了解更多信息
); } renderTab4() { const { faqs, data = {} } = this.state; return (
User.needLogin().then(() => this.setState({ showFaq: true, faq: { channel: 'course-video', position: data.id } }))} />
); } renderTab5() { const { data = {} } = this.state; return (
); } renderTab6() { const { data = {}, comments = [] } = this.state; return (
{data.have &&
} {(comments || []).map(item => { return ; })}
); } }