import React from 'react';
import './index.less';
import { Modal } from 'antd';
import { Link } from 'react-router-dom';
import Page from '@src/containers/Page';
import { asyncConfirm } from '@src/services/AsyncTools';
import { formatTreeData, formatSeconds, formatDate, formatPercent } from '@src/services/Tools';
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 Input from '../../../components/Input';
import Button from '../../../components/Button';
import AnswerButton from '../../../components/AnswerButton';
import Division from '../../../components/Division';
import Card from '../../../components/Card';
import ListTable from '../../../components/ListTable';
import ProgressText from '../../../components/ProgressText';
import IconButton from '../../../components/IconButton';
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 } from '../../../../Constant';
const SENTENCE = 'sentence';
const PREVIEW = 'preview';
const PREVIEW_COURSE = 'PREVIEW_COURSE';
const PREVIEW_LIST = 'PREVIEW_LIST';
const exerciseColumns = [
{
title: '练习册',
width: 250,
align: 'left',
render: item => {
return (
);
},
},
{
title: '正确率',
width: 150,
align: 'left',
render: item => {
return (
--
{formatPercent(item.stat.totalCorrect, item.stat.totalNumber, false)}
);
},
},
{
title: '全站用时',
width: 150,
align: 'left',
render: item => {
return (
--
全站{formatSeconds(item.stat.totalTime / item.stat.totalNumber)}
);
},
},
{
title: '最近做题',
width: 150,
align: 'left',
render: () => {
return (
);
},
},
{
title: '操作',
width: 180,
align: 'left',
render: item => {
return (
{!item.report && Question.startLink('preview', item)} />}
{item.report.id && !item.report.isFinish && (
Question.continueLink('preview', item)}
/>
)}
{item.report.id && this.restart('preview', item)} />}
);
},
},
{
title: '报告',
width: 30,
align: 'right',
render: item => {
return (
{item.report.isFinish && Question.reportLink(item)} />}
);
},
},
];
export default class extends Page {
constructor(props) {
super(props);
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;
if (!time) return null;
return (
{formatDate(time, 'YYYY-MM-DD')}
{formatDate(time, 'HH:mm')}
);
},
},
{
title: '操作',
width: 180,
align: 'left',
render: record => {
return (
{!record.report && (
{
Question.startLink('sentence', record);
}}
/>
)}
{record.report && !record.report.isFinish && (
{
Question.continueLink('sentence', record);
}}
/>
)}
{record.report && !!record.report.isFinish && (
{
this.restart(record);
}}
/>
)}
);
},
},
{
title: '报告',
width: 30,
align: 'right',
render: record => {
if (!record.report || !record.report.isFinish) return null;
return (
{
Question.reportLink(record);
}}
/>
);
},
},
];
}
initState() {
this.code = null;
this.columns = exerciseColumns;
this.exerciseProgress = {};
this.courseProgress = {};
this.inited = false;
return {
tab1: SENTENCE,
tab2: '',
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);
tabs.push({ key: PREVIEW, name: '预习作业' });
this.setState({ tabs, courseStructs });
this.inited = true;
this.refreshData();
});
this.setState({
courseTabs: CourseModuleShow.map(row => {
row.title = row.label;
row.key = row.value;
return row;
}),
});
}
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);
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;
if (!sentence) {
User.clearSentenceTrail();
Sentence.getInfo()
.then(result => {
// result.code = '123123';
// result.trailPages = 20;
this.setState({ sentence: result });
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 });
});
});
}
}
refreshPreview() {
const { previewType } = this.state;
switch (previewType) {
case PREVIEW_LIST:
this.refreshListPreview();
break;
case PREVIEW_COURSE:
default:
this.refreshCourseProcess();
break;
}
}
refreshCourseProcess() {
const { courseTabs, structId } = 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));
}
Course.progress(tab.courseModules, structId).then(result => {
const courseProgress = {};
for (let i = 0; i < result.length; i += 1) {
const item = result[i];
courseProgress[item.category].push(item);
}
this.setState({ courseProgress });
});
}
refreshListPreview() {
Question.listPreview().then(result => {
this.setState({ previews: 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.info = [
{
title: '已做',
number: row.userNumber || 0,
unit: '题',
},
{
title: '剩余',
number: row.questionNumber - row.userNumber || 0,
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.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 });
});
}
onChangePreviewType(type) {
this.setState({ previewType: type });
this.refreshPreview();
}
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);
}
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;
}
}
restart(item) {
asyncConfirm('提示', '是否重置', () => {
Question.restart(item.paper.id).then(() => {
this.refresh();
});
});
}
exerciseList(item) {
linkTo(`/exercise/list/${item.id}`);
}
activeSentence() {
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.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 { paperList } = this.state;
const list = paperList.filter(row => {
const finish = row.paper ? row.paper.times > 0 : false;
if (value === 0) {
return !finish;
}
return finish;
});
this.setState({ paperFilterList: list, paperChecked: value });
}
clearExercise() {
My.clearLatestExercise();
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 : (tab1 === 'preview' && previewType === 'PREVIEW_COURSE' ? courseTabs : []);
return (
{latest && (
{
this.clearExercise();
}}
onContinue={() => {
Question.continueLink('exercise', latest);
}}
onRestart={() => {
this.restart(latest);
}}
onNext={() => {
Question.continueLink('exercise', 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()}
{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 { allCourse, courseProgress } = this.state;
return (
完成情况
this.onChangePreviewType(PREVIEW_LIST)}>
全部作业 >
{allCourse.map(item => {
return ;
})}
);
}
renderPreviewList() {
const { previews } = this.state;
return (
全部作业
this.onChangePreviewType(PREVIEW_COURSE)}>
我的课程 >
);
}
renderSentence() {
const { sentence = {} } = this.state;
const { sentenceTrail } = this.props.user;
if (sentence.code || sentenceTrail) {
return this.renderSentenceArticle();
}
return this.renderInputCode();
}
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 } = this.state;
return (
请输入CODE
{
this.code = value;
}}
/>
{sentenceError &&
{sentenceError}
}
什么是CODE?
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 = 5;
}
return (
{
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);
}
}}
/>
);
})}
);
}
}