|
@@ -1,37 +1,122 @@
|
|
|
import React, { Component } from 'react';
|
|
|
import './index.less';
|
|
|
import Page from '@src/containers/Page';
|
|
|
-import { formatDate, formatMonth, getMap } from '@src/services/Tools';
|
|
|
+import { formatDate, formatMonth, getMap, formatPercent } from '@src/services/Tools';
|
|
|
import Ratio from '../../../components/Ratio';
|
|
|
import UserAction from '../../../components/UserAction';
|
|
|
-import { PrepareStatus, ExperiencePercent } from '../../../../Constant';
|
|
|
+import UserPagination from '../../../components/UserPagination';
|
|
|
+import { ExperienceScore, ExperienceDay, PrepareStatus, ExperiencePercent } from '../../../../Constant';
|
|
|
+import { Main } from '../../../stores/main';
|
|
|
+import { My } from '../../../stores/my';
|
|
|
+import { Course } from '../../../stores/course';
|
|
|
|
|
|
const PrepareStatusMap = getMap(PrepareStatus, 'value', 'label');
|
|
|
const ExperiencePercentMap = getMap(ExperiencePercent, 'value', 'label');
|
|
|
-
|
|
|
+const colorList = ['#2754E0', '#3F86EA', '#41A6F3', '#9BD4FF'];
|
|
|
export default class extends Page {
|
|
|
initState() {
|
|
|
+ const prepareStatusSelect = PrepareStatus.map(row => {
|
|
|
+ return {
|
|
|
+ title: row.label,
|
|
|
+ key: row.value,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ prepareStatusSelect.unshift({
|
|
|
+ title: '身份',
|
|
|
+ key: '',
|
|
|
+ });
|
|
|
+ const experienceDaySelect = ExperienceDay.map(row => {
|
|
|
+ return {
|
|
|
+ title: row.label,
|
|
|
+ key: row.value,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ experienceDaySelect.unshift({
|
|
|
+ title: '备考周期',
|
|
|
+ key: '',
|
|
|
+ });
|
|
|
+ const experienceScoreSelect = ExperienceScore.map(row => {
|
|
|
+ return {
|
|
|
+ title: row.label,
|
|
|
+ key: row.value,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ experienceScoreSelect.unshift({
|
|
|
+ title: '分手成绩',
|
|
|
+ key: '',
|
|
|
+ });
|
|
|
+ const experiencePercentSelect = ExperiencePercent.map(row => {
|
|
|
+ return {
|
|
|
+ title: row.label,
|
|
|
+ key: row.value,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ experiencePercentSelect.unshift({
|
|
|
+ title: '提分幅度',
|
|
|
+ key: '',
|
|
|
+ });
|
|
|
return {
|
|
|
- tab: '1',
|
|
|
- key: '1',
|
|
|
- filterMap: {},
|
|
|
- list: [{}, {}],
|
|
|
+ prepareStatusSelect,
|
|
|
+ experienceDaySelect,
|
|
|
+ experienceScoreSelect,
|
|
|
+ experiencePercentSelect,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- onChangeTab(tab) {
|
|
|
- this.setState({ tab });
|
|
|
+ init() {
|
|
|
+ Main.getExperience()
|
|
|
+ .then(result => {
|
|
|
+ const totalScoreNumber = result.score.reduce((x, y) => x + y, 0);
|
|
|
+ const totalPercentNumber = result.percent.reduce((x, y) => x + y, 0);
|
|
|
+ const scoreList = ExperienceScore.map((row, index) => {
|
|
|
+ const percent = formatPercent(result.score[index] || 0, totalScoreNumber);
|
|
|
+ return {
|
|
|
+ color: colorList[index],
|
|
|
+ label: `${row.label} ${percent} ${result.score[index] || 0}人`,
|
|
|
+ value: percent,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ const percentList = ExperiencePercent.map((row, index) => {
|
|
|
+ const percent = formatPercent(result.percent[index] || 0, totalPercentNumber);
|
|
|
+ return {
|
|
|
+ color: colorList[index],
|
|
|
+ label: `${row.label} ${percent} ${result.percent[index] || 0}人`,
|
|
|
+ value: percent,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.setState({ data: result, scoreList, percentList });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ initData() {
|
|
|
+ const data = Object.assign(this.state, this.state.search);
|
|
|
+ if (data.order) {
|
|
|
+ data.sortMap = { [data.order]: data.direction };
|
|
|
+ }
|
|
|
+ data.filterMap = this.state.search;
|
|
|
+ this.setState(data);
|
|
|
+
|
|
|
+ Course.listExperience(Object.assign({}, this.state.search))
|
|
|
+ .then(result => {
|
|
|
+ this.setState({ list: result.list, total: result.total });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ onFilter(value) {
|
|
|
+ this.search(value, false);
|
|
|
+ this.initData();
|
|
|
}
|
|
|
|
|
|
- onChangeItem(key) {
|
|
|
- this.setState({ key });
|
|
|
+ onChangePage(page) {
|
|
|
+ this.search({ page }, false);
|
|
|
+ this.initData();
|
|
|
}
|
|
|
|
|
|
renderView() {
|
|
|
return (
|
|
|
<div>
|
|
|
<div className="top content t-8">
|
|
|
- 千行课堂 > 全部课程 > OG20综合刷题 > 课时3 > <span className="t-1">心经首页</span>
|
|
|
+ 千行课堂 > <span className="t-1">学员表现</span>
|
|
|
</div>
|
|
|
{this.renderDetail()}
|
|
|
</div>
|
|
@@ -39,82 +124,63 @@ export default class extends Page {
|
|
|
}
|
|
|
|
|
|
renderDetail() {
|
|
|
- const { filterMap, list } = this.state;
|
|
|
+ const { filterMap, list, data = {}, scoreList, percentList, total, page } = this.state;
|
|
|
+ const { prepareStatusSelect, experienceDaySelect, experienceScoreSelect, experiencePercentSelect } = this.state;
|
|
|
return [
|
|
|
<div className="center">
|
|
|
<div className="content">
|
|
|
<div className="total-list">
|
|
|
<div className="total-item">
|
|
|
<div className="title">学员人数</div>
|
|
|
- <div className="label">1231431</div>
|
|
|
+ <div className="label">{data.number || 0}</div>
|
|
|
</div>
|
|
|
<div className="total-item">
|
|
|
<div className="title">考分分布</div>
|
|
|
<Ratio
|
|
|
size="small"
|
|
|
- values={[
|
|
|
- { color: '#2754E0', label: '750+ 36% 3600人', value: 10 },
|
|
|
- { color: '#41A6F3', label: '750+ 36% 3600人', value: 10 },
|
|
|
- { color: '#9BD4FF', label: '750+ 36% 3600人', value: 10 },
|
|
|
- ]}
|
|
|
+ values={scoreList || []}
|
|
|
/>
|
|
|
</div>
|
|
|
<div className="total-item">
|
|
|
<div className="title">出分周期</div>
|
|
|
- <div className="label">35天</div>
|
|
|
+ <div className="label">{data.period || 0}天</div>
|
|
|
</div>
|
|
|
<div className="total-item">
|
|
|
- <div className="title">考分分布</div>
|
|
|
+ <div className="title">提分比例</div>
|
|
|
<Ratio
|
|
|
size="small"
|
|
|
- values={[
|
|
|
- { color: '#2754E0', label: '750+ 36% 3600人', value: 10 },
|
|
|
- { color: '#41A6F3', label: '750+ 36% 3600人', value: 10 },
|
|
|
- { color: '#9BD4FF', label: '750+ 36% 3600人', value: 10 },
|
|
|
- ]}
|
|
|
+ values={percentList || []}
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
<UserAction
|
|
|
selectList={[
|
|
|
{
|
|
|
- children: [
|
|
|
- {
|
|
|
- key: 'subject',
|
|
|
- placeholder: '学科',
|
|
|
- select: [],
|
|
|
- },
|
|
|
- {
|
|
|
- placeholder: '题型',
|
|
|
- key: 'questionType',
|
|
|
- be: 'subject',
|
|
|
- selectMap: [],
|
|
|
- },
|
|
|
- ],
|
|
|
+ key: 'prepareStatus',
|
|
|
+ select: prepareStatusSelect,
|
|
|
},
|
|
|
{
|
|
|
- label: '范围',
|
|
|
- children: [
|
|
|
- {
|
|
|
- key: 'one',
|
|
|
- placeholder: '全部',
|
|
|
- select: [],
|
|
|
- },
|
|
|
- {
|
|
|
- key: 'two',
|
|
|
- be: 'one',
|
|
|
- placeholder: '全部',
|
|
|
- selectMap: [],
|
|
|
- },
|
|
|
- ],
|
|
|
+ key: 'experienceDay',
|
|
|
+ select: experienceDaySelect,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'experienceScore',
|
|
|
+ select: experienceScoreSelect,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'experiencePercent',
|
|
|
+ select: experiencePercentSelect,
|
|
|
},
|
|
|
]}
|
|
|
filterMap={filterMap}
|
|
|
onFilter={value => this.onFilter(value)}
|
|
|
/>
|
|
|
{list.map(item => {
|
|
|
- return <Article data={item} onClick={() => {}} onUnCollect={() => this.collectArticle(item, false)} />;
|
|
|
+ return <Article data={item} />;
|
|
|
})}
|
|
|
+ {total > 0 && list.length > 0 && (
|
|
|
+ <UserPagination total={total} current={page} pageSize={this.state.search.size} onChange={p => this.onChangePage(p)} />
|
|
|
+ )}
|
|
|
</div>
|
|
|
</div>,
|
|
|
];
|
|
@@ -122,29 +188,54 @@ export default class extends Page {
|
|
|
}
|
|
|
|
|
|
class Article extends Component {
|
|
|
+ constructor(props) {
|
|
|
+ super(props);
|
|
|
+ this.state = {};
|
|
|
+ }
|
|
|
+
|
|
|
+ onCollect() {
|
|
|
+ const { data } = this.props;
|
|
|
+ const { collect } = this.state;
|
|
|
+ if (collect === false || !data.collect) {
|
|
|
+ My.addExperienceCollect(data.id)
|
|
|
+ .then(() => {
|
|
|
+ this.setState({ collect: true });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ My.delExperienceCollect(data.id)
|
|
|
+ .then(() => {
|
|
|
+ this.setState({ collect: false });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
render() {
|
|
|
- const { data, onClick, onCollect } = this.props;
|
|
|
+ const { data } = this.props;
|
|
|
+ const { collect } = this.state;
|
|
|
return (
|
|
|
- <div className="article-item p-t-2 b-b" onClick={() => onClick && onClick()}>
|
|
|
+ <div className="article-item p-t-2 b-b" onClick={() => linkTo(`/course/experience/detail/${data.id}`)}>
|
|
|
<div className="t-1 t-s-14 f-w-b">
|
|
|
{data.title}
|
|
|
<div className="f-r t-3 t-s-12 f-w-d">
|
|
|
- <span>{formatDate(data.updateTime, 'YYYY-MM-DD HH:mm:ss')}</span>
|
|
|
+ <span>{data.updateTime && formatDate(data.updateTime, 'YYYY-MM-DD HH:mm:ss')}</span>
|
|
|
<span className="m-l-2">阅读 {data.viewNumber}</span>
|
|
|
- <span className="m-l-2" onClick={() => onCollect()}>
|
|
|
- 收藏
|
|
|
+ <span className="m-l-2" onClick={(e) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ this.onCollect();
|
|
|
+ }}>
|
|
|
+ {(collect === false || !data.collect) ? '收藏' : '取消收藏'}
|
|
|
</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div className="t-1 t-s-12 m-b-2">
|
|
|
<span className="m-r-2">{data.user ? data.user.nickname : data.nickname}</span>
|
|
|
<span className="m-r-2">{PrepareStatusMap[data.prepareStatus]}</span>
|
|
|
- <span className="m-r-2">备考:{formatMonth(data.experienceDay, false)}</span>
|
|
|
+ <span className="m-r-2">备考:{!!data.experienceDay && formatMonth(data.experienceDay, false)}</span>
|
|
|
<span className="m-r-2">
|
|
|
{data.experienceScore}分 /提分 {ExperiencePercentMap[data.experiencePercent]}
|
|
|
</span>
|
|
|
</div>
|
|
|
- <div className="t-2 m-b-2 detail" dangerouslySetInnerHTML={{ __html: data.content }} />
|
|
|
+ <div className="t-2 m-b-2 detail">{data.description}</div>
|
|
|
</div>
|
|
|
);
|
|
|
}
|