page.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. import React, { Component } from 'react';
  2. import './index.less';
  3. import { Icon, Checkbox } from 'antd';
  4. import Page from '@src/containers/Page';
  5. import { timeRange, getMap } from '@src/services/Tools';
  6. import UserLayout from '../../../layouts/User';
  7. import UserTable from '../../../components/UserTable';
  8. import UserAction from '../../../components/UserAction';
  9. import menu, { refreshQuestionType, refreshStruct } from '../index';
  10. import Tabs from '../../../components/Tabs';
  11. import Modal from '../../../components/Modal';
  12. import Select from '../../../components/Select';
  13. import GIcon from '../../../components/Icon';
  14. import { TimeRange, QuestionType } from '../../../../Constant';
  15. import { My } from '../../../stores/my';
  16. const QuestionTypeMap = getMap(QuestionType, 'value', 'label');
  17. const columns = [
  18. {
  19. key: 'question_type',
  20. title: '题型',
  21. render: (text, record) => {
  22. return QuestionTypeMap[record.questionType];
  23. },
  24. fixSort: true,
  25. },
  26. {
  27. key: 'title',
  28. title: '题目ID',
  29. fixSort: true,
  30. },
  31. {
  32. key: 'description',
  33. title: '内容',
  34. },
  35. { key: 'time', title: '耗时', sort: true },
  36. { key: 'correct', title: '错误率', sort: true },
  37. { key: 'latest_time', title: '最近做题' },
  38. {
  39. key: '',
  40. title: '',
  41. render() {
  42. return <GIcon name="note" />;
  43. },
  44. },
  45. ];
  46. const exportType = [
  47. { key: '1', title: '题目' },
  48. { key: '2', title: '官方解析' },
  49. { key: '3', title: '我的笔记' },
  50. { key: '4', title: '千行解析', auth: true },
  51. { key: '5', title: '题源联想', auth: true },
  52. { key: '6', title: '相关问答', auth: true },
  53. ];
  54. export default class extends Page {
  55. constructor(props) {
  56. props.size = 10;
  57. super(props);
  58. }
  59. initState() {
  60. return {
  61. tab: 'question',
  62. timerange: 'today',
  63. filterMap: {},
  64. sortMap: {},
  65. list: [{}, {}],
  66. selectList: [],
  67. allChecked: false,
  68. showDetail: false,
  69. };
  70. }
  71. initData() {
  72. const data = Object.assign(this.state, this.state.search);
  73. data.filterMap = this.state.search;
  74. if (data.order) {
  75. data.sortMap = { [data.order]: data.direction };
  76. }
  77. if (data.timerange) {
  78. data.filterMap.timerange = data.timerange;
  79. }
  80. switch (data.tab) {
  81. case 'question':
  82. return this.refreshQuestion(data);
  83. case 'article':
  84. return this.refreshArticle(data);
  85. default:
  86. return null;
  87. }
  88. }
  89. refreshQuestion(data) {
  90. const [startTime, endTime] = timeRange(data.timerange);
  91. refreshQuestionType(this, data.subject, data.questionType, {
  92. all: true,
  93. needSentence: true,
  94. allSubject: true,
  95. }).then(({ questionTypes }) => {
  96. return refreshStruct(this, data.tab, data.one, data.two, {
  97. all: true,
  98. needPreview: false,
  99. needTextbook: true,
  100. }).then(({ structIds, latest, year }) => {
  101. My.listQuestionCollect(
  102. Object.assign(
  103. { module: data.tab, questionTypes, structIds, latest, year, startTime, endTime },
  104. this.state.search,
  105. {
  106. order: Object.keys(data.sortMap)
  107. .map(key => {
  108. if (key === 'title') return 'pid desc, no desc';
  109. return `${key} ${data.sortMap[key]}`;
  110. })
  111. .join(','),
  112. },
  113. ),
  114. ).then(result => {
  115. this.setState({ list: result.list, total: result.total });
  116. });
  117. });
  118. });
  119. }
  120. refreshArticle(data) {
  121. const [startTime, endTime] = timeRange(data.timerange);
  122. My.listExperienceCollect(Object.assign({ startTime, endTime }, this.state.search)).then(result => {
  123. this.setState({ list: result.list, total: result.total });
  124. });
  125. }
  126. onTabChange(tab) {
  127. const data = { tab };
  128. this.refreshQuery(data);
  129. }
  130. onFilter(value) {
  131. this.search(value);
  132. }
  133. onSort(value) {
  134. const keys = Object.keys(value);
  135. // this.search({ order: keys.length ? keys.join('|') : null, direction: keys.length ? Object.values(value).join('|') : null });
  136. const { sortMap } = this.state;
  137. const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
  138. this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
  139. }
  140. onChangePage(page) {
  141. this.search({ page });
  142. }
  143. onAll(checked) {
  144. if (checked) {
  145. const { data = [] } = this.state;
  146. const list = [];
  147. data.forEach(item => {
  148. list.push(item.key);
  149. });
  150. this.setState({ selectList: list, allChecked: true });
  151. } else {
  152. this.setState({ selectList: [], allChecked: false });
  153. }
  154. }
  155. onAction() { }
  156. onSelect(selectList) {
  157. this.setState({ selectList });
  158. }
  159. renderView() {
  160. const { config } = this.props;
  161. return <UserLayout active={config.key} menu={menu} center={this.renderTable()} />;
  162. }
  163. renderTable() {
  164. const { tab } = this.state;
  165. return (
  166. <div className="table-layout">
  167. <Tabs
  168. border
  169. type="division"
  170. theme="theme"
  171. size="small"
  172. space={2.5}
  173. width={100}
  174. active={tab}
  175. tabs={[{ key: 'question', title: '题目' }, { key: 'article', title: '文章' }]}
  176. onChange={key => this.onChangeTab(key)}
  177. />
  178. {this[`renderTab${tab}`]()}
  179. {this.renderModal()}
  180. </div>
  181. );
  182. }
  183. renderTabquestion() {
  184. const {
  185. questionSubjectSelect,
  186. questionSubjectMap = {},
  187. oneSelect,
  188. twoSelectMap = {},
  189. filterMap = {},
  190. sortMap = {},
  191. list = [],
  192. } = this.state;
  193. const { selectList = [], allChecked, page, total } = this.state;
  194. return (
  195. <div className="tab-1-layout">
  196. <UserAction
  197. search
  198. selectList={[
  199. {
  200. children: [
  201. {
  202. key: 'subject',
  203. placeholder: '学科',
  204. select: questionSubjectSelect,
  205. },
  206. {
  207. placeholder: '题型',
  208. key: 'questionType',
  209. be: 'subject',
  210. selectMap: questionSubjectMap,
  211. },
  212. ],
  213. },
  214. {
  215. label: '范围',
  216. children: [
  217. {
  218. key: 'one',
  219. placeholder: '全部',
  220. select: oneSelect,
  221. },
  222. {
  223. key: 'two',
  224. be: 'one',
  225. placeholder: '全部',
  226. selectMap: twoSelectMap,
  227. },
  228. ],
  229. },
  230. {
  231. right: true,
  232. key: 'timerange',
  233. select: TimeRange,
  234. },
  235. ]}
  236. filterMap={filterMap}
  237. onFilter={value => this.onFilter(value)}
  238. />
  239. <UserAction
  240. allCheckbox
  241. allChecked={allChecked}
  242. help
  243. btnList={[
  244. { title: '移除', key: 'remove' },
  245. { title: '组卷', key: 'group', tag: 'vip' },
  246. { title: '导出', key: 'export', tag: 'vip', disabled: true },
  247. ]}
  248. right={
  249. <div className="tip">
  250. 2019-06-03 15:30 组卷50题,做对30题。<span>移除正确题目</span> or <span>忽略</span>
  251. </div>
  252. }
  253. onAll={checked => this.onAll(checked)}
  254. onAction={key => this.onAction(key)}
  255. />
  256. <UserTable
  257. select
  258. columns={columns}
  259. sortMap={sortMap}
  260. data={list}
  261. current={page}
  262. total={total}
  263. selectList={selectList}
  264. onSelect={l => this.onSelect(l)}
  265. onSort={v => this.onSort(v)}
  266. onChange={p => this.onChangePage(p)}
  267. />
  268. </div>
  269. );
  270. }
  271. renderTabarticle() {
  272. const { filterMap = {}, sortMap = {} } = this.state;
  273. return (
  274. <div className="tab-1-layout">
  275. <UserAction
  276. selectList={[
  277. {
  278. key: 'one',
  279. right: true,
  280. select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
  281. },
  282. ]}
  283. sortList={[
  284. {
  285. key: '1',
  286. label: '收藏时间',
  287. },
  288. {
  289. key: '2',
  290. label: '更新时间',
  291. },
  292. ]}
  293. sortMap={sortMap}
  294. filterMap={filterMap}
  295. onFilter={value => this.onFilter(value)}
  296. onSort={value => this.onSort(value)}
  297. />
  298. {[{}, {}, {}].map(item => {
  299. return <Article data={item} onClick={() => this.setState({ showDetail: true })} />;
  300. })}
  301. </div>
  302. );
  303. }
  304. renderModal() {
  305. return [
  306. <ArticleDetail show={this.state.showDetail} onClose={() => this.setState({ showDetail: false })} />,
  307. <Modal title="操作提示" confirmText="好的,知道了" btnAlign="center" onConfirm={() => { }}>
  308. <div className="flex-layout m-b-2">
  309. <div className="flex-block">
  310. <div className="t-1 t-s-18">组卷功能</div>
  311. <div className="t-2">操作数量:10-50;</div>
  312. <div className="t-2">注意事项:可跨题型、不可跨学科。</div>
  313. </div>
  314. <div className="flex-block">
  315. <div className="t-1 t-s-18">导出功能</div>
  316. <div className="t-2">操作数量:1-100;</div>
  317. <div className="t-2">注意事项:“综合推理IR”暂时无法导出。</div>
  318. </div>
  319. </div>
  320. <div className="t-3">
  321. *您可点击
  322. <Icon type="question-circle" theme="filled" />
  323. 查阅以上信息。
  324. </div>
  325. </Modal>,
  326. <Modal title="组卷练习" confirmText="好的,知道了" btnAlign="center" onConfirm={() => { }}>
  327. <div className="t-2 t-s-18">不可同时选中语文题和数学题,请重新选择。</div>
  328. </Modal>,
  329. <Modal title="组卷练习" confirmText="开始练习" onConfirm={() => { }} onCancel={() => { }}>
  330. <div className="t-2 t-s-18">
  331. 您共选择了 <span className="t-4">50</span> 道题目,是否开始练习?
  332. </div>
  333. <div className="t-2 t-s-16">
  334. <Checkbox checked className="m-r-5" />
  335. 剔除已组卷练习 <Select
  336. theme="white"
  337. value="1"
  338. list={[{ key: '1', title: '2' }, { key: '2', title: '3' }]}
  339. />{' '}
  340. 次以上的错题
  341. </div>
  342. </Modal>,
  343. <Modal title="移出" onConfirm={() => { }} onCancel={() => { }}>
  344. <div className="t-2 t-s-18">
  345. 当前选中的 <span className="t-4">50</span> 道题即将被移出错题本,移出后无法恢复,是否继续?
  346. </div>
  347. </Modal>,
  348. <Modal title="导出" confirmText="好的,知道了" btnAlign="center" onConfirm={() => { }}>
  349. <div className="t-2 t-s-18">正在下载中,请不要关闭当前页面!</div>
  350. </Modal>,
  351. <Modal title="导出" confirmText="导出" onConfirm={() => { }} onCancel={() => { }}>
  352. <div className="t-2 t-s-18 m-b-5">
  353. 当前共选中 <span className="t-4">50</span> 道题,请确认需要导出的内容:
  354. </div>
  355. <div className="t-2 t-s-16">
  356. {exportType.map(item => {
  357. return (
  358. <div className="d-i-b m-b-5" style={{ width: 135 }}>
  359. <Checkbox checked className="m-r-5" />
  360. {item.title}
  361. </div>
  362. );
  363. })}
  364. </div>
  365. </Modal>,
  366. <Modal title="导出" confirmText="导出" onConfirm={() => { }} onCancel={() => { }}>
  367. <div className="t-2 t-s-18 m-b-5">
  368. 当前共选中 <span className="t-4">50</span> 道题,请确认需要导出的内容:
  369. </div>
  370. <div className="t-2 t-s-16 m-b-2">
  371. {exportType
  372. .filter(item => !item.auth)
  373. .map(item => {
  374. return (
  375. <div className="d-i-b m-b-2" style={{ width: 135 }}>
  376. <Checkbox checked className="m-r-5" />
  377. {item.title}
  378. </div>
  379. );
  380. })}
  381. </div>
  382. <div className="b-b m-b-2 m-t-2" />
  383. <div className="t-3 m-b-1">
  384. 以下内容需实名认证后才可导出: <a className="f-r">去认证 ></a>
  385. </div>
  386. <div className="t-2 t-s-16 m-b-2">
  387. {exportType
  388. .filter(item => item.auth)
  389. .map(item => {
  390. return (
  391. <div className="d-i-b" style={{ width: 135 }}>
  392. <Checkbox disabled className="m-r-5" />
  393. {item.title}
  394. </div>
  395. );
  396. })}
  397. </div>
  398. </Modal>,
  399. ];
  400. }
  401. }
  402. class ArticleDetail extends Component {
  403. render() {
  404. const { show, onClose, onPrev, onNext } = this.props;
  405. return (
  406. <Modal
  407. className="article-detail-modal"
  408. body={false}
  409. show={show}
  410. width={720}
  411. maskClosable
  412. close={false}
  413. onClose={onClose}
  414. center
  415. >
  416. <Icon type="left" className="prev" onClick={() => onPrev && onPrev()} />
  417. <Icon type="right" className="next" onClick={() => onNext && onNext()} />
  418. <div className="t-1 t-s-20 m-b-5">文章标题文章标题文章标题文章标题文章标题文章标题</div>
  419. <div className="t-1 t-s-12 m-b-2">
  420. <span className="m-r-2">翻翻le</span>
  421. <span className="m-r-2">学生-D</span>
  422. <span className="m-r-2">备考:2个月</span>
  423. <span className="m-r-2">750分 /提分 150+</span>
  424. <span className="t-4">更多信息</span>
  425. </div>
  426. <div className="t-2 t-s-18 detail">
  427. {' '}
  428. GMAT阅读难不一定是长度问题,主要是内容比较晦涩,结构不好把握的文章,千万不要慌张,不要害怕,此时的恐慌会让你整个昏头,不知道自己在读什么,做GMAT阅读题的时候,也许会重读好几遍,不仅慢,正确率也不好。
  429. 遇到这种类型的文章,读第一遍的时候,不要纠结于细节,甚至于不要看细节,挑出主题句和总结句,以及文章中起承转合的词或者句,然后忽略一切变态词汇。读完GMAT阅读之后,保证让自己知道这个文章讲的是个什么事,有可能你并不知道这个事情是什么,即使知道它叫什么也不要紧。然后看题,根据题目,问到什么就回去找什么,找到的东西你可能也不明白是什么。但一般情况下,较难的GMAT阅读文章的题目会相对于简单,甚至有类似送分的白痴题。因此,只要你能找对地方,静下心来,淡定应考,不要害怕,就能做对较难的GMAT阅读。
  430. 遇到这种类型的文章,读第一遍的时候,不要纠结于细节,甚至于不要看细节,挑出主题句和总结句,以及文章中起承转合的词或者句,然后忽略一切变态词汇。读完GMAT阅读之后,保证让自己知道这个文章讲的是个什么事,有可能你并不知道这个事情是什么,即使知道它叫什么也不要紧。然后看题,根据题目,问到什么就回去找什么,找到的东西你可能也不明白是什么。但一般情况下,较难的GMAT阅读文章的题目会相对于简单,甚至有类似送分的白痴题。因此,只要你能找对地方,静下心来,淡定应考,不要害怕,就能做对较难的GMAT阅读。
  431. 遇到这种类型的文章,读第一遍的时候,不要纠结于细节,甚至于不要看细节,挑出主题句和总结句,以及文章中起承转合的词或者句,然后忽略一切变态词汇。读完GMAT阅读之后,保证让自己知道这个文章讲的是个什么事,有可能你并
  432. 遇到这种类型的文章,读第一遍的时候,不要纠结于细节,甚至于不要看细节,挑出主题句和总结句,以及文章中起承转合的词或者句,然后忽略一切变态词汇。读完GMAT阅读之后,保证让自己知道这个文章讲的是个什么事,有可能你并
  433. </div>
  434. </Modal>
  435. );
  436. }
  437. }
  438. class Article extends Component {
  439. render() {
  440. const { onClick } = this.props;
  441. return (
  442. <div className="article-item p-t-2 b-b" onClick={() => onClick && onClick()}>
  443. <div className="t-1 t-s-14 f-w-b">
  444. GMAT 考试题型包括哪些呢?
  445. <div className="f-r t-3 t-s-12 f-w-d">
  446. <span>2019-04-27 15:13:31</span>
  447. <span className="m-l-2">阅读 8990</span>
  448. <span className="m-l-2">取消收藏</span>
  449. </div>
  450. </div>
  451. <div className="t-1 t-s-12 m-b-2">
  452. <span className="m-r-2">翻翻le</span>
  453. <span className="m-r-2">学生-D</span>
  454. <span className="m-r-2">备考:2个月</span>
  455. <span className="m-r-2">750分 /提分 150+</span>
  456. </div>
  457. <div className="t-2 m-b-2 detail">
  458. GMAT考试由分析写作、推理、数学和语文四部分组成。分别为: a)分析性写作评价(Analytical Writing
  459. Assessment)A:GMAT考试由分析写作、推理、数学和语文四部分组成。分别为: a)分析性写作评价(Analytical Writing
  460. Assessment)GMAT考试由分析写作、推理、数学和语文四部分组成。分别为: a)分析性写作评价(Analytical Writing
  461. Assessment)A:GMAT考试由分析写作、推理、数学和语文四部分组成。分别为: a)分析性写作评价(Analytical Writing
  462. Assessment)A:GMAT考试由分析写作、推理、数学和语文四部分组成。分别为: a)分析性写作评价
  463. </div>
  464. </div>
  465. );
  466. }
  467. }