page.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. import React from 'react';
  2. import { Breadcrumb, Tooltip, Switch } from 'antd';
  3. import './index.less';
  4. import Page from '@src/containers/Page';
  5. import { asyncConfirm, asyncSMessage } from '@src/services/AsyncTools';
  6. import { formatPercent, formatDate } from '@src/services/Tools';
  7. import ListTable from '../../../components/ListTable';
  8. import ProgressText from '../../../components/ProgressText';
  9. import IconButton from '../../../components/IconButton';
  10. import Button from '../../../components/Button';
  11. import { Main } from '../../../stores/main';
  12. import { Question } from '../../../stores/question';
  13. export default class extends Page {
  14. initState() {
  15. this.qxCatColumns = [
  16. {
  17. title: '模考',
  18. width: 210,
  19. align: 'left',
  20. render: record => {
  21. let progress = 0;
  22. if (record.report) {
  23. progress = formatPercent(record.report.userNumber, record.report.questionNumber);
  24. }
  25. return [
  26. <div className="table-row" style={{ paddingRight: 40 }}>
  27. <div className="night f-s-16">
  28. {record.title}
  29. {record.paper && record.paper.paperNo > 0 ? String.fromCharCode(64 + record.paper.paperNo) : ''}
  30. </div>
  31. <div>
  32. <ProgressText progress={progress} size="small" />
  33. </div>
  34. </div>,
  35. this.state.showPrev && record.prevReport && (
  36. <div className="table-row prev t-3">
  37. <div className="night f-s-16">
  38. {record.title}
  39. {record.prevPaper && record.prevPaper.paperNo > 0
  40. ? String.fromCharCode(64 + record.prevPaper.paperNo)
  41. : ''}
  42. </div>
  43. </div>
  44. ),
  45. ];
  46. },
  47. },
  48. {
  49. title: 'Total',
  50. width: 110,
  51. align: 'left',
  52. render: record => {
  53. return [
  54. <div className="table-row">
  55. <div className="night f-s-16 f-w-b">
  56. {record.report ? `${record.report.score.totalScore}分${record.report.score.totalRank}th` : '-分-th'}
  57. </div>
  58. <div className="f-s-12">全站: {Math.round(record.totalScore / record.totalTimes)}分</div>
  59. </div>,
  60. this.state.showPrev && record.prevReport && (
  61. <div className="table-row prev t-3">
  62. <div className="night f-s-16 f-w-b">
  63. {record.prevReport.score.totalScore}分{record.prevReport.score.totalRank}th
  64. </div>
  65. <div className="f-s-12">全站: {Math.round(record.secondTotalScore / record.secondTotalTimes)}分</div>
  66. </div>
  67. ),
  68. ];
  69. },
  70. },
  71. {
  72. title: 'Verbal',
  73. width: 110,
  74. align: 'left',
  75. render: record => {
  76. return [
  77. <div className="table-row">
  78. <div className="night f-s-16 f-w-b">
  79. {record.report ? `${record.report.score.verbalScore}分${record.report.score.verbalRank}th` : '-分-th'}
  80. </div>
  81. <div className="f-s-12">全站: {Math.round(record.verbalScore / record.totalTimes)}分</div>
  82. </div>,
  83. this.state.showPrev && record.prevReport && (
  84. <div className="table-row prev t-3">
  85. <div className="night f-s-16 f-w-b">
  86. {record.prevReport.score.verbalScore}分{record.prevReport.score.verbalRank}th
  87. </div>
  88. <div className="f-s-12">全站: {Math.round(record.secondVerbalScore / record.secondTotalTimes)}分</div>
  89. </div>
  90. ),
  91. ];
  92. },
  93. },
  94. {
  95. title: 'Quant',
  96. width: 110,
  97. align: 'left',
  98. render: record => {
  99. return [<div className="table-row">
  100. <div className="night f-s-16 f-w-b">
  101. {record.report ? `${record.report.score.quantScore}分${record.report.score.quantRank}th` : '-分-th'}
  102. </div>
  103. <div className="f-s-12">全站: {Math.round(record.quantScore / record.totalTimes)}分</div>
  104. </div>,
  105. this.state.showPrev && record.prevReport && (
  106. <div className="table-row prev t-3">
  107. <div className="night f-s-16 f-w-b">
  108. {record.prevReport.score.quantScore}分{record.prevReport.score.quantRank}th
  109. </div>
  110. <div className="f-s-12">全站: {Math.round(record.secondQuantScore / record.secondTotalTimes)}分</div>
  111. </div>
  112. ),
  113. ];
  114. },
  115. },
  116. {
  117. title: 'IR',
  118. width: 110,
  119. align: 'left',
  120. render: record => {
  121. return [<div className="table-row">
  122. <div className="night f-s-16 f-w-b">
  123. {record.report ? `${record.report.score.irScore}分${record.report.score.irRank}th` : '-分-th'}
  124. </div>
  125. <div className="f-s-12">全站: {Math.round(record.irScore / record.totalTimes)}分</div>
  126. </div>,
  127. this.state.showPrev && record.prevReport && (
  128. <div className="table-row prev t-3">
  129. <div className="night f-s-16 f-w-b">
  130. {record.prevReport.score.irScore}分{record.prevReport.score.irRank}th
  131. </div>
  132. <div className="f-s-12">全站: {Math.round(record.secondIrScore / record.secondTotalTimes)}分</div>
  133. </div>
  134. ),
  135. ];
  136. },
  137. },
  138. {
  139. title: '做题时间',
  140. width: 100,
  141. align: 'left',
  142. render: record => {
  143. return [<div className="table-row">
  144. <div>{record.report && formatDate(record.report.updateTime, 'YYYY-MM-DD')}</div>
  145. <div>{record.report && formatDate(record.report.updateTime, 'HH:mm')}</div>
  146. </div>,
  147. this.state.showPrev && record.prevReport && (
  148. <div className="table-row prev t-3">
  149. <div>{formatDate(record.prevReport.updateTime, 'YYYY-MM-DD')}</div>
  150. <div>{formatDate(record.prevReport.updateTime, 'HH:mm')}</div>
  151. </div>
  152. ),
  153. ];
  154. },
  155. },
  156. {
  157. title: '操作',
  158. width: 110,
  159. align: 'left',
  160. render: record => {
  161. return [<div className="table-row p-t-1">
  162. {!record.report && (
  163. <IconButton
  164. className="m-r-5"
  165. type="start"
  166. tip="Start"
  167. onClick={() => {
  168. Question.startLink('examination', record);
  169. }}
  170. />
  171. )}
  172. {record.report && !record.report.isFinish && (
  173. <IconButton
  174. type="continue"
  175. tip="Continue"
  176. onClick={() => {
  177. Question.continueLink('examination', record);
  178. }}
  179. />
  180. )}
  181. </div>,
  182. this.state.showPrev && record.prevReport && (
  183. <div className="table-row prev" />
  184. ),
  185. ];
  186. },
  187. },
  188. {
  189. title: '报告',
  190. width: 50,
  191. align: 'right',
  192. render: record => {
  193. return [<div className="table-row p-t-1">
  194. {record.report && record.report.isFinish && (
  195. <IconButton
  196. className="m-r-5"
  197. type="report"
  198. tip="Report"
  199. onClick={() => {
  200. Question.reportLink(record);
  201. }}
  202. />
  203. )}
  204. </div>,
  205. this.state.showPrev && (
  206. <div className="prev">
  207. {record.prevReport && (
  208. <IconButton
  209. type="report"
  210. tip="Report"
  211. onClick={() => {
  212. Question.reportPrevLink(record);
  213. }}
  214. />
  215. )}
  216. </div>
  217. ),
  218. ];
  219. },
  220. },
  221. ];
  222. this.catColumns = [
  223. {
  224. title: '模考',
  225. width: 210,
  226. align: 'left',
  227. render: record => {
  228. let progress = 0;
  229. if (record.report) {
  230. progress = formatPercent(record.report.userNumber, record.report.questionNumber);
  231. }
  232. return (
  233. <div className="table-row">
  234. <div className="night f-s-16">
  235. {record.title}
  236. {record.paper && record.paper.paperNo > 0 ? String.fromCharCode(64 + record.paper.paperNo) : ''}
  237. </div>
  238. <div>
  239. <ProgressText progress={progress} size="small" />
  240. </div>
  241. </div>
  242. );
  243. },
  244. },
  245. {
  246. title: 'Total',
  247. width: 110,
  248. align: 'left',
  249. render: record => {
  250. return (
  251. <div className="table-row">
  252. <div className="night f-s-16 f-w-b">
  253. {record.report ? `${record.report.score.totalScore}分${record.report.score.totalRank}th` : '-分-th'}
  254. </div>
  255. <div className="f-s-12">全站: {Math.round(record.totalScore / record.totalTimes)}分</div>
  256. </div>
  257. );
  258. },
  259. },
  260. {
  261. title: 'Verbal',
  262. width: 110,
  263. align: 'left',
  264. render: record => {
  265. return (
  266. <div className="table-row">
  267. <div className="night f-s-16 f-w-b">
  268. {record.report ? `${record.report.score.verbalScore}分${record.report.score.verbalRank}th` : '-分-th'}
  269. </div>
  270. <div className="f-s-12">全站: {Math.round(record.verbalScore / record.totalTimes)}分</div>
  271. </div>
  272. );
  273. },
  274. },
  275. {
  276. title: 'Quant',
  277. width: 110,
  278. align: 'left',
  279. render: record => {
  280. return (
  281. <div className="table-row">
  282. <div className="night f-s-16 f-w-b">
  283. {record.report ? `${record.report.score.quantScore}分${record.report.score.quantRank}th` : '-分-th'}
  284. </div>
  285. <div className="f-s-12">全站: {Math.round(record.quantScore / record.totalTimes)}分</div>
  286. </div>
  287. );
  288. },
  289. },
  290. {
  291. title: 'IR',
  292. width: 110,
  293. align: 'left',
  294. render: record => {
  295. return (
  296. <div className="table-row">
  297. <div className="night f-s-16 f-w-b">
  298. {record.report ? `${record.report.score.irScore}分${record.report.score.irRank}th` : '-分-th'}
  299. </div>
  300. <div className="f-s-12">全站: {Math.round(record.irScore / record.totalTimes)}分</div>
  301. </div>
  302. );
  303. },
  304. },
  305. {
  306. title: '做题时间',
  307. width: 100,
  308. align: 'left',
  309. render: record => {
  310. return (
  311. <div className="table-row">
  312. <div>{record.report && formatDate(record.report.updateTime, 'YYYY-MM-DD')}</div>
  313. <div>{record.report && formatDate(record.report.updateTime, 'HH:mm')}</div>
  314. </div>
  315. );
  316. },
  317. },
  318. {
  319. title: '操作',
  320. width: 110,
  321. align: 'left',
  322. render: record => {
  323. return (
  324. <div className="table-row p-t-1">
  325. {!record.report && (
  326. <IconButton
  327. type="start"
  328. tip="Start"
  329. onClick={() => {
  330. Question.startLink('examination', record);
  331. }}
  332. />
  333. )}
  334. {record.report && !record.report.isFinish && (
  335. <IconButton
  336. className="m-r-2"
  337. type="continue"
  338. tip="Continue"
  339. onClick={() => {
  340. Question.continueLink('examination', record);
  341. }}
  342. />
  343. )}
  344. <IconButton
  345. type="restart"
  346. tip="Restart"
  347. onClick={() => {
  348. this.restart(record);
  349. }}
  350. />
  351. </div>
  352. );
  353. },
  354. },
  355. {
  356. title: '报告',
  357. width: 50,
  358. align: 'right',
  359. render: record => {
  360. return (
  361. <div className="table-row p-t-1">
  362. {record.report && record.report.isFinish && (
  363. <IconButton
  364. type="report"
  365. tip="Report"
  366. onClick={() => {
  367. Question.reportLink(record);
  368. }}
  369. />
  370. )}
  371. {this.state.showPrev && (
  372. <div className="prev">
  373. {record.prevReport && (
  374. <IconButton
  375. type="report"
  376. tip="Report"
  377. onClick={() => {
  378. Question.reportPrevLink(record);
  379. }}
  380. />
  381. )}
  382. </div>
  383. )}
  384. </div>
  385. );
  386. },
  387. },
  388. ];
  389. this.columns = [
  390. {
  391. title: '模考',
  392. width: 210,
  393. align: 'left',
  394. render: record => {
  395. let progress = 0;
  396. if (record.report) {
  397. progress = formatPercent(record.report.userNumber, record.report.questionNumber);
  398. }
  399. return (
  400. <div className="table-row">
  401. <div className="night f-s-16">{record.title}</div>
  402. <div>
  403. <ProgressText progress={progress} times={record.paper ? record.paper.times : 0} size="small" />
  404. </div>
  405. </div>
  406. );
  407. },
  408. },
  409. {
  410. title: 'Total',
  411. width: 110,
  412. align: 'left',
  413. render: () => {
  414. return (
  415. <div className="table-row">
  416. <div className="f-s-12">仅CAT模考<br />提供分数</div>
  417. </div>
  418. );
  419. },
  420. },
  421. {
  422. title: 'Verbal',
  423. width: 110,
  424. align: 'left',
  425. render: record => {
  426. return (
  427. <div className="table-row">
  428. <div className="f-s-12">
  429. {record.report
  430. ? formatPercent(record.report.setting.number.verbal, this.nums.verbal.number, false)
  431. : '0%'}
  432. </div>
  433. </div>
  434. );
  435. },
  436. },
  437. {
  438. title: 'Quant',
  439. width: 110,
  440. align: 'left',
  441. render: record => {
  442. return (
  443. <div className="table-row">
  444. <div className="f-s-12">
  445. {record.report
  446. ? formatPercent(record.report.setting.number.quant, this.nums.quant.number, false)
  447. : '0%'}
  448. </div>
  449. </div>
  450. );
  451. },
  452. },
  453. {
  454. title: 'IR',
  455. width: 110,
  456. align: 'left',
  457. render: record => {
  458. return (
  459. <div className="table-row">
  460. <div className="f-s-12">
  461. {record.report ? formatPercent(record.report.setting.number.ir, this.nums.ir.number, false) : '0%'}
  462. </div>
  463. </div>
  464. );
  465. },
  466. },
  467. {
  468. title: '做题时间',
  469. width: 100,
  470. align: 'left',
  471. render: record => {
  472. if (!record.report) return null;
  473. return (
  474. <div className="table-row">
  475. <div>{formatDate(record.report.updateTime, 'YYYY-MM-DD')}</div>
  476. <div>{formatDate(record.report.updateTime, 'HH:mm')}</div>
  477. </div>
  478. );
  479. },
  480. },
  481. {
  482. title: '操作',
  483. width: 110,
  484. align: 'left',
  485. render: record => {
  486. return (
  487. <div className="table-row p-t-1">
  488. {!record.report && (
  489. <IconButton
  490. type="start"
  491. tip="Start"
  492. onClick={() => {
  493. Question.startLink('examination', record);
  494. }}
  495. />
  496. )}
  497. {record.report && !record.report.isFinish && (
  498. <IconButton
  499. className="m-r-2"
  500. type="continue"
  501. tip="Continue"
  502. onClick={() => {
  503. Question.continueLink('examination', record);
  504. }}
  505. />
  506. )}
  507. <IconButton
  508. type="restart"
  509. tip="Restart"
  510. onClick={() => {
  511. this.restart(record);
  512. }}
  513. />
  514. </div>
  515. );
  516. },
  517. },
  518. {
  519. title: '报告',
  520. width: 50,
  521. align: 'right',
  522. render: record => {
  523. if (!record.report || !record.report.isFinish) return null;
  524. return (
  525. <div className="table-row p-t-1">
  526. <IconButton
  527. type="report"
  528. tip="Report"
  529. onClick={() => {
  530. Question.reportLink(record);
  531. }}
  532. />
  533. </div>
  534. );
  535. },
  536. },
  537. ];
  538. this.inited = false;
  539. return {};
  540. }
  541. init() {
  542. const { id } = this.params;
  543. Main.getExaminationParent(id).then(result => {
  544. const navs = result.map(row => {
  545. row.title = `${row.titleZh}${row.titleEn}`;
  546. return row;
  547. });
  548. this.cat = navs.filter(row => row.isAdapt > 0).length > 0;
  549. this.qxCat = navs.filter(row => row.isAdapt > 1).length > 0;
  550. Main.getExaminationNumber().then(nums => {
  551. this.nums = nums;
  552. this.inited = true;
  553. this.setState({ navs });
  554. this.refreshData();
  555. });
  556. });
  557. }
  558. initData() {
  559. const data = Object.assign(this.state, this.state.search);
  560. this.setState(data);
  561. if (this.inited) this.refreshData();
  562. }
  563. refreshData() {
  564. if (this.cat) {
  565. Question.getExaminationInfo().then(result => {
  566. this.setState({ examination: result });
  567. });
  568. }
  569. this.refreshExamination();
  570. }
  571. refreshExamination() {
  572. Question.getExaminationList(Object.assign({ structId: this.params.id }, this.state.search))
  573. .then(result => {
  574. this.setState({ list: result.list, total: result.total });
  575. })
  576. .catch(err => {
  577. asyncSMessage(err.message, 'warn');
  578. // linkTo('/examination');
  579. });
  580. }
  581. restart(item) {
  582. asyncConfirm('提示', '是否重置', () => {
  583. Question.restart(item.paper.id).then(() => {
  584. this.refresh();
  585. });
  586. });
  587. }
  588. resetCat() {
  589. asyncConfirm('提示', '是否重置', () => {
  590. Question.resetCat().then(() => {
  591. this.refresh();
  592. });
  593. });
  594. }
  595. renderView() {
  596. const { list, navs, search, examination = {} } = this.state;
  597. const { finish } = search;
  598. return (
  599. <div>
  600. <div className="content">
  601. <Breadcrumb separator=">">
  602. <Breadcrumb.Item href="/examination">模考</Breadcrumb.Item>
  603. {(navs || []).map(row => {
  604. return <Breadcrumb.Item>{row.title}</Breadcrumb.Item>;
  605. })}
  606. </Breadcrumb>
  607. <ListTable
  608. rightAction={
  609. <div hidden={!this.qxCat}>
  610. <span>有效期至:{examination.expireTime && formatDate(examination.expireTime, 'YYYY-MM-DD')}</span>
  611. {examination.reset && (
  612. <span>
  613. 第一遍模考成绩
  614. <Switch
  615. checked={this.state.showPrev}
  616. onChange={() => {
  617. this.setState({ showPrev: !this.state.showPrev });
  618. }}
  619. />
  620. </span>
  621. )}
  622. {!examination.reset && examination.canReset && (
  623. <Button
  624. size="small"
  625. radius
  626. onClick={() => {
  627. this.resetExamination();
  628. }}
  629. >
  630. Reset
  631. </Button>
  632. )}
  633. {!examination.reset && !examination.canReset && (
  634. <Tooltip overlayClassName="gray" placement="top" title="全部模考做完才可重置">
  635. <a>
  636. <Button size="small" disabled radius>
  637. Reset
  638. </Button>
  639. </a>
  640. </Tooltip>
  641. )}
  642. </div>
  643. }
  644. filters={[
  645. {
  646. type: 'radio',
  647. checked: finish,
  648. list: [{ key: '0', title: '未完成' }, { key: '1', title: '已完成' }],
  649. onChange: item => {
  650. if (item.key === finish) {
  651. this.search({ finish: null });
  652. } else if (item.key === '0') {
  653. this.search({ finish: 0 });
  654. } else if (item.key === '1') {
  655. this.search({ finish: 1 });
  656. } else {
  657. this.search({ finish: null });
  658. }
  659. },
  660. },
  661. ]}
  662. data={[{}, {}, {}] || list}
  663. columns={this.qxCatColumns}
  664. />
  665. </div>
  666. </div>
  667. );
  668. }
  669. }