page.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import React from 'react';
  2. import './index.less';
  3. import { Link } from 'react-router-dom';
  4. import Page from '@src/containers/Page';
  5. import { asyncConfirm } from '@src/services/AsyncTools';
  6. import Tabs from '../../../components/Tabs';
  7. import Module from '../../../components/Module';
  8. import Input from '../../../components/Input';
  9. import Button from '../../../components/Button';
  10. import Division from '../../../components/Division';
  11. import Card from '../../../components/Card';
  12. import ListTable from '../../../components/ListTable';
  13. import ProgressText from '../../../components/ProgressText';
  14. import IconButton from '../../../components/IconButton';
  15. import { Main } from '../../../stores/main';
  16. import { Question } from '../../../stores/question';
  17. const HARD = 'HARD';
  18. const PREVIEW = 'PREVIEW';
  19. const PREVIEW_CLASS = 'PREVIEW_CLASS';
  20. const PREVIEW_TASK = 'PREVIEW_TASK';
  21. export default class extends Page {
  22. initState() {
  23. return {
  24. level1Tab: PREVIEW,
  25. level2Tab: '',
  26. previewType: PREVIEW_CLASS,
  27. tabs: [],
  28. allClass: [],
  29. classProcess: {},
  30. };
  31. }
  32. initData() {
  33. Main.getExercise().then(result => {
  34. const list = result;
  35. const map = {};
  36. for (let i = 0; i < result.length; i += 1) {
  37. const item = result[i];
  38. if (!map[item.parentId]) map[item.parentId] = [];
  39. map[item.parentId].push(item);
  40. }
  41. const tabs = [];
  42. let allClass = [];
  43. tabs.push({ key: HARD, name: '长难句' });
  44. if (map[0]) {
  45. for (let i = 0; i < map[0].length; i += 1) {
  46. const item = map[0][i];
  47. tabs.push({ key: item.id, name: `${item.titleZh} ${item.titleEn}` });
  48. if (map[item.id]) {
  49. allClass = allClass.concat(map[item.id]);
  50. }
  51. }
  52. }
  53. tabs.push({ key: PREVIEW, name: '预习作业' });
  54. this.setState({ tabs, allClass, list, map });
  55. });
  56. this.refreshClassProcess();
  57. }
  58. refreshPreview() {
  59. const { previewType } = this.state;
  60. if (previewType === PREVIEW_CLASS) {
  61. this.refreshClassProcess();
  62. }
  63. if (previewType === PREVIEW_TASK) {
  64. this.refreshPreview();
  65. }
  66. }
  67. onChangePreviewType(type) {
  68. this.setState({ previewType: type });
  69. this.refreshPreview();
  70. }
  71. refreshClassProcess() {
  72. Question.getClassProcess().then(result => {
  73. const classProcess = {};
  74. for (let i = 0; i < result.length; i += 1) {
  75. const item = result[i];
  76. classProcess[item.category].push(item);
  77. }
  78. this.setState({ classProcess });
  79. });
  80. }
  81. refreshListPreview() {
  82. Question.listPreview().then(result => {
  83. this.setState({ previews: result });
  84. });
  85. }
  86. onChangeTab(level, tab) {
  87. const state = {};
  88. state[`level${level}Tab`] = tab;
  89. this.setState(state);
  90. }
  91. previewAction(type, item) {
  92. switch (type) {
  93. case 'start':
  94. this.startPreview(item);
  95. break;
  96. case 'restart':
  97. this.restartPreview(item);
  98. break;
  99. case 'continue':
  100. this.continuePreview(item);
  101. break;
  102. default:
  103. break;
  104. }
  105. }
  106. startPreview(item) {
  107. linkTo(`/start/${item.id}?type=preview`);
  108. }
  109. restartPreview(item) {
  110. asyncConfirm('提示', '是否重置', () => {
  111. Question.restart(item.report.id).then(() => {
  112. this.refreshPreview();
  113. });
  114. });
  115. }
  116. continuePreview(item) {
  117. linkTo(`/start/${item.id}?type=preview&r=${item.report.id}`);
  118. }
  119. renderView() {
  120. const { level1Tab, level2Tab, tabs, map } = this.state;
  121. return (
  122. <div>
  123. <div className="content">
  124. <Module className="m-t-2">
  125. <Tabs type="card" active={level1Tab} tabs={tabs} onChange={key => this.onChangeTab(1, key)} />
  126. {(level1Tab !== HARD || level1Tab !== PREVIEW) && (
  127. <Tabs active={level2Tab} tabs={map[level2Tab]} onChange={key => this.onChangeTab(2, key)} />
  128. )}
  129. </Module>
  130. {(level1Tab !== HARD || level1Tab !== PREVIEW) && this.renderType()}
  131. {level1Tab === HARD && this.renderHard()}
  132. {level1Tab === PREVIEW && this.renderWork()}
  133. </div>
  134. </div>
  135. );
  136. }
  137. renderWork() {
  138. const { previewType } = this.state;
  139. switch (previewType) {
  140. case PREVIEW_CLASS:
  141. return this.renderAllClass();
  142. case PREVIEW_TASK:
  143. return this.renderAllTask();
  144. default:
  145. return <div />;
  146. }
  147. }
  148. renderAllClass() {
  149. const { allClass, classProcess } = this.props;
  150. return (
  151. <Division col="3">
  152. {allClass.map(item => {
  153. return <Card data={item} process={classProcess[item.id]} previewAction={this.previewAction} />;
  154. })}
  155. </Division>
  156. );
  157. }
  158. renderAllTask() {
  159. const { previews } = this.props;
  160. return (
  161. <ListTable
  162. filters={[
  163. { type: 'radio', checked: 'first', list: [{ key: 'first', title: 123 }, { key: 'two', title: 321 }] },
  164. { type: 'select', checked: 'first', list: [{ key: 'first', title: 123 }, { key: 'two', title: 321 }] },
  165. ]}
  166. data={previews}
  167. columns={[
  168. {
  169. title: '练习册',
  170. width: 250,
  171. align: 'left',
  172. render: item => {
  173. return (
  174. <div className="table-row">
  175. <div className="night f-s-16">{item.title}</div>
  176. <div>
  177. <ProgressText
  178. progress={item.report.id ? item.repport.userNumber / item.report.questionNumber : 0}
  179. size="small"
  180. />
  181. </div>
  182. </div>
  183. );
  184. },
  185. },
  186. {
  187. title: '正确率',
  188. width: 150,
  189. align: 'left',
  190. render: item => {
  191. return (
  192. <div className="table-row">
  193. <div className="night f-s-16 f-w-b">--</div>
  194. <div className="f-s-12">{item.stat.totalCorrect / item.stat.totalNumber}</div>
  195. </div>
  196. );
  197. },
  198. },
  199. {
  200. title: '全站用时',
  201. width: 150,
  202. align: 'left',
  203. render: item => {
  204. return (
  205. <div className="table-row">
  206. <div className="night f-s-16 f-w-b">--</div>
  207. <div className="f-s-12">全站{item.stat.totalTime / item.stat.totalNumber}s</div>
  208. </div>
  209. );
  210. },
  211. },
  212. {
  213. title: '最近做题',
  214. width: 150,
  215. align: 'left',
  216. render: () => {
  217. return (
  218. <div className="table-row">
  219. <div>2019-04-28</div>
  220. <div>07:30</div>
  221. </div>
  222. );
  223. },
  224. },
  225. {
  226. title: '操作',
  227. width: 180,
  228. align: 'left',
  229. render: item => {
  230. return (
  231. <div className="table-row p-t-1">
  232. {!item.repport.id && (
  233. <IconButton type="start" tip="Start" onClick={() => this.previewAction('start', item)} />
  234. )}
  235. {item.repport.id && (
  236. <IconButton
  237. className="m-r-2"
  238. type="continue"
  239. tip="Continue"
  240. onClick={() => this.previewAction('continue', item)}
  241. />
  242. )}
  243. {item.repport.id && (
  244. <IconButton type="restart" tip="Restart" onClick={() => this.previewAction('restart', item)} />
  245. )}
  246. </div>
  247. );
  248. },
  249. },
  250. {
  251. title: '报告',
  252. width: 30,
  253. align: 'right',
  254. render: item => {
  255. return (
  256. <div className="table-row p-t-1">
  257. {item.report.userNumber === item.report.questionNumber && <IconButton type="report" tip="Report" />}
  258. </div>
  259. );
  260. },
  261. },
  262. ]}
  263. />
  264. );
  265. }
  266. renderHard() {
  267. return this.renderInputCode();
  268. }
  269. renderType() {
  270. return <div />;
  271. }
  272. renderInputCode() {
  273. return (
  274. <Module className="code-module">
  275. <div className="title">输入《千行GMAT长难句》专属 Code,解锁在线练习功能。</div>
  276. <div className="input-block">
  277. <Input size="lager" placeholder="请输入CODE" />
  278. <Button size="lager">解锁</Button>
  279. </div>
  280. <div className="tip">
  281. <Link to="/" className="left link">
  282. 什么是CODE?
  283. </Link>
  284. <span>没有 CODE?</span>
  285. <Link to="/" className="link">
  286. 去获取 >>
  287. </Link>
  288. <Link to="/" className="right link">
  289. 试用 >>
  290. </Link>
  291. </div>
  292. </Module>
  293. );
  294. }
  295. }