page.js 17 KB

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