|
@@ -3,8 +3,8 @@ 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 { asyncConfirm, asyncSMessage } from '@src/services/AsyncTools';
|
|
|
+import { formatTreeData, formatSeconds, formatDate, formatPercent, getMap } from '@src/services/Tools';
|
|
|
import Continue from '../../../components/Continue';
|
|
|
import Step from '../../../components/Step';
|
|
|
import Panel from '../../../components/Panel';
|
|
@@ -15,7 +15,7 @@ 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 { Card1 } from '../../../components/Card';
|
|
|
import ListTable from '../../../components/ListTable';
|
|
|
import ProgressText from '../../../components/ProgressText';
|
|
|
import IconButton from '../../../components/IconButton';
|
|
@@ -25,13 +25,16 @@ import { Sentence } from '../../../stores/sentence';
|
|
|
import { Question } from '../../../stores/question';
|
|
|
import { Course } from '../../../stores/course';
|
|
|
import { User } from '../../../stores/user';
|
|
|
-import { CourseModuleShow } from '../../../../Constant';
|
|
|
+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 exerciseColumns = [
|
|
|
{
|
|
|
title: '练习册',
|
|
@@ -286,18 +289,21 @@ export default class extends Page {
|
|
|
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.setState({ tabs, courseStructs });
|
|
|
+ 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();
|
|
|
});
|
|
|
- this.setState({
|
|
|
- courseTabs: CourseModuleShow.map(row => {
|
|
|
- row.title = row.label;
|
|
|
- row.key = row.value;
|
|
|
- return row;
|
|
|
- }),
|
|
|
- });
|
|
|
}
|
|
|
|
|
|
initData() {
|
|
@@ -309,6 +315,13 @@ export default class extends Page {
|
|
|
});
|
|
|
}
|
|
|
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();
|
|
|
}
|
|
@@ -420,7 +433,7 @@ export default class extends Page {
|
|
|
}
|
|
|
|
|
|
refreshCourseProcess() {
|
|
|
- const { courseTabs, structId } = this.state;
|
|
|
+ const { courseTabs, courseStructs, struct } = this.state;
|
|
|
let { tab2 } = this.state;
|
|
|
let tab;
|
|
|
if (tab2 === '') {
|
|
@@ -430,19 +443,24 @@ export default class extends Page {
|
|
|
} 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 });
|
|
|
+ const [courseStruct] = courseStructs.filter(row => row.key === struct);
|
|
|
+ Course.progress(tab.value, courseStruct ? courseStruct.id : null).then(result => {
|
|
|
+ const courseMap = {};
|
|
|
+ const now = new Date().getTime();
|
|
|
+ courseMap.open = result.filter(row => !row.isUsed);
|
|
|
+ courseMap.end = result.filter(row => row.isUsed && new Date(row.useEndTime).getTime() < now);
|
|
|
+ courseMap.process = result.filter(row => row.isUsed && new Date(row.useEndTime).getTime() >= now);
|
|
|
+ this.setState({ courseMap });
|
|
|
});
|
|
|
}
|
|
|
|
|
|
refreshListPreview() {
|
|
|
- Question.listPreview().then(result => {
|
|
|
- this.setState({ previews: result });
|
|
|
+ const { recordId, endTime, finish } = this.state;
|
|
|
+ Course.listPreview({ recordId, endTime, finish }).then(result => {
|
|
|
+ this.setState({ previews: result.list });
|
|
|
+ });
|
|
|
+ Course.record(recordId).then(result => {
|
|
|
+ this.setState({ record: result });
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -499,11 +517,6 @@ export default class extends Page {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- onChangePreviewType(type) {
|
|
|
- this.setState({ previewType: type });
|
|
|
- this.refreshPreview();
|
|
|
- }
|
|
|
-
|
|
|
onChangeTab(level, tab) {
|
|
|
const { tab1 } = this.state;
|
|
|
const data = {};
|
|
@@ -517,6 +530,30 @@ export default class extends Page {
|
|
|
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':
|
|
@@ -533,6 +570,14 @@ export default class extends Page {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 开通课程
|
|
|
+ open(recordId) {
|
|
|
+ Order.useRecord(recordId).then(() => {
|
|
|
+ asyncSMessage('开通成功');
|
|
|
+ this.refresh();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
restart(item) {
|
|
|
asyncConfirm('提示', '是否重置', () => {
|
|
|
Question.restart(item.paper.id).then(() => {
|
|
@@ -591,7 +636,7 @@ export default class extends Page {
|
|
|
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 : []);
|
|
|
+ const children = (subject && subject.children) ? subject.children : (tab1 === 'preview' && previewType === PREVIEW_COURSE ? courseTabs : []);
|
|
|
return (
|
|
|
<div>
|
|
|
{latest && (
|
|
@@ -648,18 +693,74 @@ export default class extends Page {
|
|
|
}
|
|
|
|
|
|
renderPreviewCourse() {
|
|
|
- const { allCourse, courseProgress } = this.state;
|
|
|
+ const { courseStructs, struct, tab2, courseTabs, courseMap = {} } = this.state;
|
|
|
return (
|
|
|
<div className="work-body">
|
|
|
+ <div className="work-nav" hidden={courseTabs && courseTabs.length > 0 && tab2 !== courseTabs[0].key}>
|
|
|
+ <Tabs
|
|
|
+ type="tag"
|
|
|
+ active={struct || ''}
|
|
|
+ space={5}
|
|
|
+ tabs={courseStructs}
|
|
|
+ onChange={key => {
|
|
|
+ this.onChangeCourse(key);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
<div className="work-nav">
|
|
|
- <div className="left">完成情况</div>
|
|
|
- <div className="right theme c-p" onClick={() => this.onChangePreviewType(PREVIEW_LIST)}>
|
|
|
- 全部作业 >
|
|
|
- </div>
|
|
|
+ <div className="left">学习中</div>
|
|
|
+ </div>
|
|
|
+ <Division col="3">
|
|
|
+ {(courseMap.process || []).map(row => {
|
|
|
+ return <Card1
|
|
|
+ title={`${row.course.title}${row.vsNo > 0 ? `V${row.vsNo}` : ''}${row.number > 0 ? `(${row.number}课时)` : ''}`}
|
|
|
+ tag={CourseModuleMap[row.course.courseModule]}
|
|
|
+ status={row.isStop && !row.isSuspend ? '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);
|
|
|
+ }}
|
|
|
+ />;
|
|
|
+ })}
|
|
|
+ </Division>
|
|
|
+ <div className="work-nav">
|
|
|
+ <div className="left">待开通</div>
|
|
|
+ </div>
|
|
|
+ <Division col="3">
|
|
|
+ {(courseMap.wait || []).map(row => {
|
|
|
+ return <Card1
|
|
|
+ title={`${row.course.title}${row.vsNo > 0 ? `V${row.vsNo}` : ''}${row.number > 0 ? `(${row.number}课时)` : ''}`}
|
|
|
+ tag={CourseModuleMap[row.course.courseModule]}
|
|
|
+ status='open'
|
|
|
+ data={row}
|
|
|
+ onOpen={() => {
|
|
|
+ this.open(row.id);
|
|
|
+ }}
|
|
|
+ />;
|
|
|
+ })}
|
|
|
+ </Division>
|
|
|
+ <div className="work-nav">
|
|
|
+ <div className="left">已结束</div>
|
|
|
</div>
|
|
|
<Division col="3">
|
|
|
- {allCourse.map(item => {
|
|
|
- return <Card data={item} process={courseProgress[item.id]} previewAction={this.previewAction} />;
|
|
|
+ {(courseMap.end || []).map(row => {
|
|
|
+ return <Card1
|
|
|
+ title={`${row.course.title}${row.vsNo > 0 ? `V${row.vsNo}` : ''}${row.number > 0 ? `(${row.number}课时)` : ''}`}
|
|
|
+ tag={CourseModuleMap[row.course.courseModule]}
|
|
|
+ status='end'
|
|
|
+ data={row}
|
|
|
+ onPreview={() => {
|
|
|
+ this.onPreviewList(row.id);
|
|
|
+ }}
|
|
|
+ />;
|
|
|
})}
|
|
|
</Division>
|
|
|
</div>
|
|
@@ -667,12 +768,23 @@ export default class extends Page {
|
|
|
}
|
|
|
|
|
|
renderPreviewList() {
|
|
|
- const { previews } = this.state;
|
|
|
+ const { previews = [], record = {}, search = {} } = this.state;
|
|
|
+ const { finish, endTime } = 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 (
|
|
|
<div className="work-body">
|
|
|
<div className="work-nav">
|
|
|
- <div className="left">全部作业</div>
|
|
|
- <div className="right theme c-p" onClick={() => this.onChangePreviewType(PREVIEW_COURSE)}>
|
|
|
+ <div className="left">{`${(record.course || {}).title || ''}${record.vsNo > 0 ? `V${record.vsNo}` : ''}${record.number > 0 ? `(${record.number}课时)` : ''}`}全部作业</div>
|
|
|
+ <div className="right theme c-p" onClick={() => this.onPreviewCourse()}>
|
|
|
我的课程 >
|
|
|
</div>
|
|
|
</div>
|
|
@@ -680,13 +792,47 @@ export default class extends Page {
|
|
|
filters={[
|
|
|
{
|
|
|
type: 'radio',
|
|
|
- checked: 'today',
|
|
|
+ checked: finishTime,
|
|
|
list: [{ key: 'today', title: '今日需完成' }, { key: 'tomorrow', title: '明日需完成' }],
|
|
|
+ onChange: (item) => {
|
|
|
+ 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: 'unfinish',
|
|
|
- list: [{ key: 'unfinish', title: '未完成' }, { key: 'finish', title: '已完成' }],
|
|
|
+ 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}
|