import React from 'react';
import './index.less';
import { Modal, Tooltip } from 'antd';
// import { Link } from 'react-router-dom';
import Page from '@src/containers/Page';
import { asyncConfirm, asyncSMessage } from '@src/services/AsyncTools';
import { formatTreeData, formatSeconds, formatDate, formatPercent, getMap } from '@src/services/Tools';
import { AnswerCarousel, Comment } from '../../../components/Other';
import Continue from '../../../components/Continue';
import Step from '../../../components/Step';
import Panel from '../../../components/Panel';
import List from '../../../components/List';
import Tabs from '../../../components/Tabs';
import Module from '../../../components/Module';
import InputItem from '../../../components/InputItem';
import Button from '../../../components/Button';
import AnswerButton from '../../../components/AnswerButton';
import Division from '../../../components/Division';
import { Card1 } from '../../../components/Card';
import ListTable from '../../../components/ListTable';
import ProgressText from '../../../components/ProgressText';
import IconButton from '../../../components/IconButton';
import QAList from '../../../components/QAList';
import { Main } from '../../../stores/main';
import { My } from '../../../stores/my';
import { Sentence } from '../../../stores/sentence';
import { Question } from '../../../stores/question';
import { Course } from '../../../stores/course';
import { User } from '../../../stores/user';
import { CourseModuleShow, CourseModule } from '../../../../Constant';
import { Order } from '../../../stores/order';
const SENTENCE = 'sentence';
const PREVIEW = 'preview';
const PREVIEW_COURSE = 'PREVIEW_COURSE';
const PREVIEW_LIST = 'PREVIEW_LIST';
const CourseModuleMap = getMap(CourseModule, 'value', 'label');
const CourseSorted = getMap([{ value: 'sc', sort: 1 }, { value: 'rc', sort: 2 }, { value: 'cr', sort: 3 }], 'value', 'sort');
export default class extends Page {
constructor(props) {
super(props);
this.previewColumns = [{
title: '练习册',
width: 250,
align: 'left',
render: record => {
let progress = 0;
if (record.report) {
progress = formatPercent(record.report.userNumber, record.report.questionNumber);
}
return (
);
},
}, {
title: '正确率',
width: 150,
align: 'left',
render: item => {
return (
--
{formatPercent(item.stat.totalCorrect, item.stat.totalNumber, false)}
);
},
}, {
title: '全站用时',
width: 150,
align: 'left',
render: record => {
let time = '--';
if (record.report) {
time = formatSeconds(record.report.userTime / record.report.userNumber);
}
return (
{time}
全站{formatSeconds(record.stat.totalTime / record.stat.totalNumber)}
);
},
}, {
title: '最近做题',
width: 150,
align: 'left',
render: (record) => {
const time = record.report ? record.report.updateTime : record.paper ? record.paper.latestTime : null;
return (
{time && formatDate(time, 'YYYY-MM-DD')}
{time && formatDate(time, 'HH:mm')}
);
},
}, {
title: '操作',
width: 180,
align: 'left',
render: record => {
return (
{!record.report && {
Question.startLink('preview', record);
}} />}
{(record.report && !record.report.isFinish) && {
Question.continueLink('preview', record);
}} />}
{(record.report) && {
this.restart(record);
}} />}
);
},
}, {
title: '报告',
width: 30,
align: 'right',
render: record => {
return (
{record.report && !!record.report.isFinish && {
Question.reportLink(record);
}} />}
);
},
}];
this.sentenceColums = [{
title: '练习册',
width: 250,
align: 'left',
render: record => {
let progress = 0;
if (record.report) {
progress = formatPercent(record.report.userNumber, record.report.questionNumber);
}
return (
);
},
}, {
title: '正确率',
width: 150,
align: 'left',
render: record => {
let correct = '--';
if (record.report) {
correct = formatPercent(record.report.userCorrect, record.report.userNumber, false);
}
return (
{correct}
全站{formatPercent(record.stat.totalCorrect, record.stat.totalNumber, false)}
);
},
}, {
title: '全站用时',
width: 150,
align: 'left',
render: record => {
let time = '--';
if (record.report) {
time = formatSeconds(record.report.userTime / record.report.userNumber);
}
return (
{time}
全站{formatSeconds(record.stat.totalTime / record.stat.totalNumber)}
);
},
}, {
title: '最近做题',
width: 150,
align: 'left',
render: record => {
const time = record.report ? record.report.updateTime : record.paper ? record.paper.latestTime : null;
return (
{time && formatDate(time, 'YYYY-MM-DD')}
{time && formatDate(time, 'HH:mm')}
);
},
}, {
title: '操作',
width: 180,
align: 'left',
render: record => {
return (
{!record.report && (
{
User.needLogin()
.then(() => {
Question.startLink('sentence', record);
});
}}
/>
)}
{record.report && !record.report.isFinish && (
{
User.needLogin()
.then(() => {
Question.continueLink('sentence', record);
});
}}
/>
)}
{record.report && (
{
User.needLogin()
.then(() => {
this.restart(record);
});
}}
/>
)}
);
},
}, {
title: '报告',
width: 30,
align: 'right',
render: record => {
return (
{record.report && !!record.report.isFinish > 0 && {
User.needLogin()
.then(() => {
Question.reportLink(record);
});
}} />}
);
},
}];
}
initState() {
this.code = null;
this.exerciseProgress = {};
this.courseProgress = {};
this.inited = false;
return {
tab1: SENTENCE,
tab2: '',
tab3: 'faq',
previewType: PREVIEW_COURSE,
tabs: [],
allCourse: [],
courseProgress: {},
};
}
init() {
Main.getExercise().then(result => {
const list = result.map(row => {
row.title = `${row.titleZh}${row.titleEn}`;
row.key = row.extend;
return row;
});
const tabs = formatTreeData(list, 'id', 'title', 'parentId');
// 课程顶级分类
const courseStructs = result.filter(row => row.isCourse && row.level === 1);
courseStructs.unshift({ key: '', name: '全部' });
tabs.push({ key: PREVIEW, name: '预习作业' });
this.courseStructMap = getMap(courseStructs, 'id', 'title');
this.setState({
tabs,
courseStructs,
courseTabs: CourseModuleShow.map(row => {
row.title = row.label;
row.key = row.value;
return row;
}),
});
this.inited = true;
this.refreshData();
});
Main.getContract('course')
.then(result => {
this.setState({ contract: result });
});
}
initData() {
const { info = {} } = this.props.user;
if (info.latestExercise) {
// 获取最后一次做题记录
Question.baseReport(info.latestExercise).then(result => {
this.setState({ latest: result });
});
}
const data = Object.assign(this.state, this.state.search);
if (!data.tab1) {
data.tab1 = SENTENCE;
}
if (data.recordId) {
// 作业列表
data.previewType = PREVIEW_LIST;
}
this.setState(data);
if (this.inited) this.refreshData();
}
refreshData(tab) {
const { tab1 } = this.state;
switch (tab || tab1) {
case SENTENCE:
this.refreshSentence();
break;
case PREVIEW:
this.refreshPreview();
break;
default:
this.refreshExercise(tab || tab1);
}
}
refreshSentence() {
const { sentence } = this.state;
Main.getSentence().then(result => {
this.setState({ sentenceInfo: result });
});
if (!sentence) {
User.clearSentenceTrail();
Sentence.getInfo()
.then(result => {
// result.code = '123123';
// result.trailPages = 20;
this.setState({ sentence: result });
if (result.dataId) {
Main.listComment({ page: 1, size: 100, channel: 'course_data', position: result.dataId }).then(r => {
this.setState({ comments: r.list });
});
}
return result;
})
.then(({ code, trailPages, chapters = [] }) => {
return Sentence.listArticle().then(result => {
const chapterSteps = [];
const chapterMap = {};
const map = {};
const trailArticles = [];
let totalPage = 0;
let introduction = null;
let exerciseChapter = null;
let index = 0;
let lastChapter = -1;
chapters.forEach(row => {
chapterMap[row.value] = row;
if (row.exercise) exerciseChapter = row;
});
result.forEach(article => {
if (article.chapter === 0) introduction = article;
if (!map[article.chapter]) {
map[article.chapter] = [];
}
article.startPage = totalPage + 1;
article.endPage = totalPage + article.pages;
if (article.chapter) {
article.position = `Part ${article.part}`;
} else {
// 设置list中的样式
article.style = 'introduction';
}
totalPage += article.pages;
if (article.startPage < trailPages) {
if (lastChapter !== article.chapter) {
lastChapter = article.chapter;
trailArticles.push(Object.assign({ articles: [] }, chapterMap[article.chapter] || {}));
}
trailArticles[trailArticles.length - 1].articles.push(article);
}
map[article.chapter].push(article);
});
if (!code) {
chapterSteps.push('试用');
}
// 添加前言
if (introduction) {
chapterSteps.push(`${introduction.title}`);
chapterMap[0] = {
title: introduction.title,
value: 0,
};
}
index += 1;
chapters.forEach(row => {
chapterSteps.push(`「${index}」${row.short || ''}`);
index += 1;
});
this.setState({ articleMap: map, trailArticles, chapterSteps, introduction, chapterMap, exerciseChapter });
});
})
.then(() => {
return Sentence.listPaper().then(result => {
this.setState({ paperList: result, paperFilterList: result });
});
});
Main.listFaq({ page: 1, size: 100, channel: 'exercise-sentence' }).then(result => {
this.setState({ faqs: result.list });
});
}
}
refreshPreview() {
const { previewType } = this.state;
switch (previewType) {
case PREVIEW_LIST:
this.refreshListPreview();
break;
case PREVIEW_COURSE:
default:
this.refreshCourseProcess();
break;
}
}
refreshCourseProcess() {
const { courseTabs, courseStructs, struct } = this.state;
let { tab2 } = this.state;
let tab;
if (tab2 === '') {
tab2 = courseTabs[0].key;
this.setState({ tab2 });
([tab] = courseTabs);
} else {
([tab] = courseTabs.filter(row => row.key === tab2));
}
const [courseStruct] = courseStructs.filter(row => row.key === struct);
Course.progress(tab.value, courseStruct ? courseStruct.id : null).then(result => {
const courseMap = {};
// 排序:sc,rc,cr
result = result.map(row => {
row.sort = CourseSorted[row.course.extend] || 10;
return row;
});
result.sort((a, b) => {
return a.sort < b.sort ? -1 : (a.sort > b.sort ? 1 : 0);
});
const now = new Date().getTime();
courseMap.open = result.filter(row => !row.isUsed && (!row.useEndTime || new Date(row.useEndTime).getTime() > now));
courseMap.end = result.filter(row => row.isUsed && (!row.isSuspend || (row.isSuspend && row.restoreTime)) && new Date(row.useEndTime).getTime() < now);
courseMap.process = result.filter(row => row.isUsed && ((!row.isSuspend && new Date(row.useEndTime).getTime() >= now) || (row.isSuspend && !row.restoreTime)));
this.setState({ courseMap });
});
Main.listFaq({ page: 1, size: 100, channel: 'exercise-preview' }).then(result => {
this.setState({ faqs: result.list });
});
}
refreshListPreview() {
const { recordId, endTime, finish } = this.state;
Course.listPreview({ recordId, endTime, finish }).then(result => {
this.setState({ previews: result });
});
Course.record(recordId).then(result => {
this.setState({ record: result });
});
}
refreshExercise(tab) {
const { tabs, tab1 } = this.state;
let { tab2 } = this.state;
if (!tabs) {
// 等待数据加载
return;
}
const [subject] = tabs.filter(row => row.key === tab);
// 切换tab1的情况
if (tab2 === '' || tab1 !== tab) {
tab2 = subject.children[0].key;
this.setState({ tab2 });
}
const [type] = subject.children.filter(row => row.key === tab2);
Question.getExerciseProgress(type.id).then(result => {
// const exerciseProgress = getMap(r, 'id');
result = result.map(row => {
row.title = `${row.titleZh}`;
row.info = [
{
title: '已做',
number: row.userNumber || '-',
unit: '题',
},
{
title: '剩余',
number: row.userNumber ? row.questionNumber - row.userNumber : '-',
unit: '题',
},
{
title: '总计',
number: row.questionNumber || 0,
unit: '题',
},
];
if (row.userStat) {
row.correct = formatPercent(row.userStat.userCorrect, row.userStat.userNumber, false);
} else {
row.correct = '--';
}
row.progress = formatPercent(row.questionNumber - row.userNumber || 0, row.questionNumber);
row.totalCorrect = formatPercent(row.stat.totalCorrect, row.stat.totalNumber, false);
row.pieValue = formatPercent(row.userNumber, row.questionNumber);
row.pieText = formatPercent(row.userNumber, row.questionNumber, false);
row.pieSubText = `共${row.questionNumber}题`;
row.children = row.children.map(r => {
r.title = r.title || r.titleZh;
r.progress = formatPercent(r.userNumber, r.questionNumber);
return r;
});
return row;
});
this.setState({ exerciseProgress: result });
});
}
onChangeTab(level, tab) {
const { tab1 } = this.state;
const data = {};
if (level > 1) {
data.tab1 = tab1;
data.tab2 = tab;
} else {
data.tab1 = tab;
}
// this.refreshData(tab);
this.refreshQuery(data);
}
onChangeCourse(struct) {
const { tab1, tab2 } = this.state;
const data = {
tab1, tab2, struct,
};
this.refreshQuery(data);
}
onPreviewCourse() {
const { tab1, tab2, struct } = this.state;
const data = {
tab1, tab2, struct,
};
this.refreshQuery(data);
}
onPreviewList(recordId) {
const { tab1, tab2, struct } = this.state;
const data = {
tab1, tab2, struct, recordId,
};
this.refreshQuery(data);
}
previewAction(type, item) {
switch (type) {
case 'start':
Question.startLink('preview', item);
break;
case 'restart':
this.restart(item);
break;
case 'continue':
Question.continueLink('preview', item);
break;
default:
break;
}
}
// 开通课程
open(recordId) {
Order.useRecord(recordId).then(() => {
this.refresh();
}).catch((err) => {
asyncSMessage(err.message, 'error');
});
}
restart(item) {
asyncConfirm('提示', '你打算重做本套练习,过往做题记录可至「个人中心-报告」查看。', () => {
Question.restart(item.paper.id).then(() => {
this.refresh();
});
});
}
exerciseList(item) {
User.needLogin().then(() => {
linkTo(`/exercise/list/${item.id}`);
});
}
activeSentence() {
User.needLogin().then(() => {
Sentence.active(this.code)
.then(() => {
// 重新获取长难句信息
User.clearSentenceTrail();
this.setState({ sentence: null, articleMap: null, paperList: null });
this.refresh();
})
.catch(err => {
this.setState({ sentenceError: err.message });
});
});
}
trailSentence() {
User.needLogin().then(() => {
User.sentenceTrail();
this.setState({ sentenceError: null });
});
}
sentenceRead(article) {
if (article) {
linkTo(`/sentence/read?chapter=${article.chapter}&part=${article.part}`);
} else {
linkTo('/sentence/read');
}
}
sentenceFilter(value) {
const { paperChecked, paperList } = this.state;
value = paperChecked === value ? null : value;
const list = paperList.filter(row => {
const finish = row.paper ? row.paper.finishTimes > 0 : false;
if (value === 0) {
return !finish;
} if (value === 1) {
return finish;
}
return true;
});
this.setState({ paperFilterList: list, paperChecked: value });
}
clearExercise() {
My.clearLatestExercise()
.then(() => {
const { info } = this.props.user;
info.latestExercise = 0;
User.infoHandle(info);
});
this.setState({ latest: null });
}
renderView() {
const { tab1, tab2, tabs, latest, sentenceModel, previewType, courseTabs = [] } = this.state;
const [subject] = tabs.filter(row => row.key === tab1);
const children = (subject && subject.children) ? subject.children : (tab1 === 'preview' && previewType === PREVIEW_COURSE ? courseTabs : []);
return (
{latest && (
{
this.clearExercise();
}}
onContinue={() => {
Question.continueLink('exercise', { id: latest.originId, report: latest });
}}
onRestart={() => {
this.restart(latest);
Question.startLink('exercise', { id: latest.originId, report: latest });
}}
// onNext={() => {
// Question.continueLink('exercise', { id: latest.originId, report: latest });
// }}
/>
)}
{
this.onChangeTab(1, key);
}}
/>
{children && children.length > 1 && (
this.onChangeTab(2, key)} />
)}
{tab1 !== SENTENCE && tab1 !== PREVIEW && this.renderExercise()}
{tab1 === SENTENCE && this.renderSentence()}
{tab1 === PREVIEW && this.renderPreview()}
{tab1 !== SENTENCE && this.state.faqs && }
{tab1 === SENTENCE && this.renderSentenceInfo()}
{sentenceModel && this.renderInputCodeModel()}
);
}
renderPreview() {
const { previewType } = this.state;
switch (previewType) {
case PREVIEW_COURSE:
return this.renderPreviewCourse();
case PREVIEW_LIST:
return this.renderPreviewList();
default:
return ;
}
}
renderPreviewCourse() {
const { courseStructs, struct, tab2, courseTabs, courseMap = {}, contract = {} } = this.state;
return (
0 && tab2 !== courseTabs[0].key}>
{
this.onChangeCourse(key);
}}
/>
{(courseMap.process || []).map(row => {
return 0 ? `V${row.vsNo}` : ''}${row.number > 0 ? `(${row.number}课时)` : ''}`}
tag={CourseModuleMap[row.course.courseModule]}
status={row.isSuspend && !row.restoreTime ? 'stop' : 'ing'}
list={(row.papers || []).map(r => {
let progress = 0;
if (r.report) {
progress = formatPercent(r.report.userNumber, r.report.questionNumber);
}
r.progress = progress;
return r;
})}
data={row}
onPreview={() => {
this.onPreviewList(row.id);
}}
previewAction={(type, item) => {
this.previewAction(type, item);
}}
/>;
})}
{(courseMap.open || []).map(row => {
return 0 ? `V${row.vsNo}` : ''}${row.number > 0 ? `(${row.number}课时)` : ''}`}
tag={CourseModuleMap[row.course.courseModule]}
contract={contract}
status='open'
data={row}
onOpen={() => {
this.open(row.id);
}}
/>;
})}
{(courseMap.end || []).map(row => {
return 0 ? `V${row.vsNo}` : ''}${row.number > 0 ? `(${row.number}课时)` : ''}`}
tag={CourseModuleMap[row.course.courseModule]}
status='end'
data={row}
onPreview={() => {
this.onPreviewList(row.id);
}}
/>;
})}
);
}
renderPreviewList() {
const { previews = [], record = {}, search = {} } = this.state;
const { finish } = search;
// let finishTime = '';
// if (endTime) {
// const endTimeD = new Date(endTime);
// const now = new Date();
// if ((now.getTime() + 86400000) > endTimeD.getTime()) {
// finishTime = 'today';
// } else {
// finishTime = 'tomorrow';
// }
// }
return (
{`${(record.course || {}).title || ''}${record.vsNo > 0 ? `V${record.vsNo}` : ''}${record.number > 0 ? `(${record.number}课时)` : ''}`}全部作业
linkTo('/my/course')}>
我的课程 >
{
// if (item.key === finishTime) {
// this.search({ endTime: null });
// } else if (item.key === 'today') {
// const a = new Date();
// a.setDate(a.getDate() + 1);
// a.setHours(0);
// a.setMinutes(0);
// a.setMilliseconds(0);
// a.setSeconds(0);
// this.search({ endTime: formatDate(a, 'YYYY-MM-DD') });
// } else if (item.key === 'tomorrow') {
// const a = new Date();
// a.setDate(a.getDate() + 2);
// a.setHours(0);
// a.setMinutes(0);
// a.setMilliseconds(0);
// a.setSeconds(0);
// this.search({ endTime: formatDate(a, 'YYYY-MM-DD') });
// } else {
// this.search({ endTime: null });
// }
// },
// },
{
type: 'radio',
checked: finish,
list: [{ key: '0', title: '未完成' }, { key: '1', title: '已完成' }],
onChange: (item) => {
if (item.key === finish) {
this.search({ finish: null });
} else if (item.key === '0') {
this.search({ finish: '0' });
} else if (item.key === '1') {
this.search({ finish: '1' });
} else {
this.search({ finish: null });
}
},
},
]}
data={previews}
columns={this.previewColumns}
/>
);
}
renderSentence() {
const { sentence = {} } = this.state;
const { sentenceTrail } = this.props.user;
if (sentence.code || sentenceTrail) {
return this.renderSentenceArticle();
}
return this.renderInputCode();
}
renderSentenceInfo() {
const { sentence = {}, tab3, sentenceInfo = {}, faqs = [], comments = [] } = this.state;
const { sentenceTrail } = this.props.user;
if (sentence.code || sentenceTrail) {
return null;
}
return
{
this.setState({ tab3: key });
}} />
{tab3 === 'faq' && User.needLogin().then(() => this.setState({ showFaq: true, faq: { channel: 'exercise-sentence' } }))}
/>}
{tab3 === 'code' && }
{tab3 === 'comment' && (comments || []).map((item) => {
return ;
})}
;
}
renderSentenceArticle() {
const {
sentence = {},
introduction,
chapterSteps,
chapterStep = 1,
exerciseChapter = {},
chapterMap = {},
articleMap = {},
trailArticles = [],
paperFilterList = [],
paperList = [],
paperChecked,
sentenceInfo = {},
} = this.state;
const { sentenceTrail } = this.props.user;
let maxStep = 0;
if (sentenceTrail) {
// 试用只能访问第一step
maxStep = 1;
// 查找练习章节
}
// 减去前言计算chapter
const chapter = introduction ? chapterStep - 1 : chapterStep;
const chapterInfo = chapterMap[chapter] || {};
let isExercise = false;
if (chapterInfo && chapterInfo.exercise) {
isExercise = true;
}
return (
{sentence.code &&
CODE: {sentence.code}
}
{sentenceTrail && (
)}
{
this.setState({ chapterStep: step });
}}
message="请购买后访问"
maxStep={maxStep}
/>
{/* 正常前言 */}
{sentence.code && chapter === 0 && (
{
this.sentenceRead();
}}
/>
)}
{/* 正常文章 */}
{sentence.code && chapter > 0 && !isExercise && (
{
this.sentenceRead(part);
}}
/>
)}
{/* 正常练习 */}
{sentence.code && isExercise && (
{
this.sentenceFilter(item.key);
},
},
]}
data={paperFilterList}
columns={this.sentenceColums}
/>
)}
{/* 试读文章 */}
{sentenceTrail &&
trailArticles.map(info => {
return (
{
this.sentenceRead(part);
}}
/>
);
})}
{/* 试练 */}
{sentenceTrail && (
)}
);
}
renderInputCode() {
const { sentenceError, sentenceInfo = {} } = this.state;
return (
输入《千行GMAT长难句》专属 Code,解锁在线练习功能。
{
this.code = value;
}}
/>
{sentenceError && {sentenceError}
}
);
}
renderInputCodeModel() {
const { sentenceError, sentenceInfo = {} } = this.state;
return (
请输入CODE
{
this.code = value;
}}
/>
{sentenceError && {sentenceError}
}
this.activeSentence()}>
确认
this.setState({ sentenceModel: false })}
>
取消
);
}
renderExercise() {
const { exerciseProgress = [] } = this.state;
return (
{(exerciseProgress || []).map(struct => {
const [first] = struct.children;
let col = 3;
if (first && first.type === 'paper') {
col = 4;
}
return (
{
User.needLogin()
.then(() => {
if (item.type === 'paper') {
if (item.progress === 0) {
Question.startLink('exercise', item);
} else if (item.progress === 100) {
Question.startLink('exercise', item);
} else {
Question.continueLink('exercise', item);
}
} else {
this.exerciseList(item);
}
});
}}
/>
);
})}
);
}
}