page.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { Carousel } from 'antd';
  4. import { Link } from 'react-router-dom';
  5. import Fullscreen from 'react-fullscreen-crossbrowser';
  6. import './index.less';
  7. import Page from '@src/containers/Page';
  8. import { formatSeconds, formatPercent, formatDate, sortListWithOrder } from '@src/services/Tools';
  9. import Assets from '@src/components/Assets';
  10. import Navigation from '../../../components/Navigation';
  11. import Tabs from '../../../components/Tabs';
  12. import Icon from '../../../components/Icon';
  13. import Switch from '../../../components/Switch';
  14. import Select from '../../../components/Select';
  15. import AnswerSelect from '../../../components/AnswerSelect';
  16. import AnswerList from '../../../components/AnswerList';
  17. import AnswerButton from '../../../components/AnswerButton';
  18. import AnswerTable from '../../../components/AnswerTable';
  19. import OtherAnswer from '../../../components/OtherAnswer';
  20. import { AskTarget } from '../../../../Constant';
  21. import { Question } from '../../../stores/question';
  22. import { My } from '../../../stores/my';
  23. import Sentence from '../process/sentence';
  24. export default class extends Page {
  25. initState() {
  26. return {
  27. step: 0,
  28. hideAnalysis: true,
  29. analysisTab: 'official',
  30. showAnswer: false,
  31. noteField: AskTarget[0].key,
  32. showIds: false,
  33. // question: {
  34. // content: {
  35. // typeset: 'one',
  36. // },
  37. // // questionType: 'awa',
  38. // answer: {
  39. // subject: [[{ text: 'like', uuid: 'hKyz' }]],
  40. // options: ['parallel'],
  41. // },
  42. // stem: "<p><span uuid='kBJe'>I</span> <span uuid='hKyz'>like</span> <span uuid='fQXh'>book</span></p>",
  43. // },
  44. // userQuestion: {
  45. // userAnswer: {
  46. // subject: [{ text: 'I', uuid: 'kBJe' }],
  47. // options: ['compare'],
  48. // },
  49. // no: 2,
  50. // },
  51. // paper: {
  52. // title: '长难句练习',
  53. // questionNumber: 20,
  54. // },
  55. // report: {
  56. // paperModule: 'sentence',
  57. // },
  58. };
  59. }
  60. initData() {
  61. const { id } = this.params;
  62. Question.getDetailById(id).then(userQuestion => {
  63. const { question, questionNos, paper, note, report, setting } = userQuestion;
  64. let { questionNo } = userQuestion;
  65. if (!questionNo) ([questionNo] = questionNos);
  66. if (!question.answer) question.answer = { questions: [] };
  67. if (!question.answerDistributed) question.answerDistributed = { questions: [] };
  68. if (!userQuestion.userAnswer) userQuestion.userAnswer = { questions: [] };
  69. if ((report.setting || {}).disorder) {
  70. const { content } = question;
  71. // 还原做题顺序
  72. content.questions.forEach((q, i) => {
  73. q.select = sortListWithOrder(question.select, setting.questions[i]);
  74. });
  75. question.answer.questions.forEach((q, i) => {
  76. Object.keys(q).forEach((k) => {
  77. if (q[k]) q[k] = sortListWithOrder(q[k], setting.questions[i]);
  78. });
  79. });
  80. question.answerDistributed.questions.forEach((q, i) => {
  81. Object.keys(q).forEach((k) => {
  82. if (q[k]) q[k] = sortListWithOrder(q[k], setting.questions[i]);
  83. });
  84. });
  85. userQuestion.userAnswer.questions.forEach((q, i) => {
  86. Object.keys(q).forEach((k) => {
  87. if (q[k]) q[k] = sortListWithOrder(q[k], setting.questions[i]);
  88. });
  89. });
  90. }
  91. this.setState({ userQuestion, question, questionNo, note, paper, questionNos });
  92. });
  93. }
  94. prevQuestion() {
  95. const { userQuestion } = this.state;
  96. if (userQuestion.no === 1) return;
  97. Question.getDetailByNo(userQuestion.reportId, userQuestion.no - 1).then((r) => {
  98. linkTo(`/paper/question/${r.id}`);
  99. });
  100. }
  101. nextQuestion() {
  102. const { userQuestion } = this.state;
  103. if (userQuestion.questionNumber === userQuestion.no) return;
  104. Question.getDetailByNo(userQuestion.reportId, userQuestion.no + 1).then((r) => {
  105. linkTo(`/paper/question/${r.id}`);
  106. });
  107. }
  108. submitAsk() {
  109. const { userQuestion = {}, ask = {} } = this.state;
  110. if (ask.originContent === '' || ask.content === '' || ask.target === '') return;
  111. My.addQuestionAsk(ask.target, userQuestion.questionModule, ask.originContent, ask.content).then(() => {
  112. this.setState({ askModal: false, askOkModal: true });
  113. }).catch(err => {
  114. this.setState({ askError: err.message });
  115. });
  116. }
  117. submitFeedbackError() {
  118. const { feedback = {}, question = {}, questionNo = {} } = this.state;
  119. if (feedback.originContent === '' || feedback.content === '' || feedback.target === '') return;
  120. My.addFeedbackErrorQuestion(question.id, questionNo.title, feedback.target, feedback.originContent, feedback.content).then(() => {
  121. this.setState({ feedbackModal: false, feedbackOkModal: true });
  122. }).catch(err => {
  123. this.setState({ feedbackError: err.message });
  124. });
  125. }
  126. submitNote(close) {
  127. const { userQuestion = {}, note = {} } = this.state;
  128. My.updateQuestionNote(userQuestion.questionModule, userQuestion.questionNoId, note).then(() => {
  129. if (close) this.setState({ noteModal: false });
  130. }).catch(err => {
  131. this.setState({ noteError: err.message });
  132. });
  133. }
  134. toggleFullscreen() {
  135. const { isFullscreenEnabled } = this.state;
  136. this.setState({ isFullscreenEnabled: !isFullscreenEnabled });
  137. }
  138. toggleCollect() {
  139. const { userQuestion = {} } = this.state;
  140. if (!userQuestion.collect) {
  141. My.addQuestionCollect(userQuestion.questionModule, userQuestion.questionNoId).then(() => {
  142. userQuestion.collect = true;
  143. this.setState({ userQuestion });
  144. });
  145. } else {
  146. My.delQuestionCollect(userQuestion.questionModule, userQuestion.questionNoId).then(() => {
  147. userQuestion.collect = false;
  148. this.setState({ userQuestion });
  149. });
  150. }
  151. }
  152. formatStem(text) {
  153. if (!text) return '';
  154. const { showAnswer, question = { content: {} }, userQuestion } = this.state;
  155. const { table = {}, questions = [] } = question.content;
  156. text = text.replace(/#select#/g, "<span class='#select#' />");
  157. text = text.replace(/#table#/g, "<span class='#table#' />");
  158. setTimeout(() => {
  159. const selectList = document.getElementsByClassName('#select#');
  160. const tableList = document.getElementsByClassName('#table#');
  161. for (let i = 0; i < selectList.length; i += 1) {
  162. if (!questions[i]) break;
  163. ReactDOM.render(
  164. <AnswerSelect
  165. list={questions[i].select}
  166. type={'single'}
  167. selected={(userQuestion.userAnswer || { questions: [] }).questions[i]}
  168. answer={(question.answer || { questions: [] }).questions[i]}
  169. fix
  170. show={showAnswer} />,
  171. selectList[i],
  172. );
  173. }
  174. if (table.row && table.col && table.header) {
  175. const columns = table.header.map((title, index) => {
  176. return { title, key: index };
  177. });
  178. for (let i = 0; i < tableList.length; i += 1) {
  179. ReactDOM.render(<AnswerTable list={columns} columns={columns} data={table.data} />, tableList[i]);
  180. }
  181. }
  182. }, 1);
  183. return text;
  184. }
  185. renderView() {
  186. return (
  187. <Fullscreen
  188. enabled={this.state.isFullscreenEnabled}
  189. onChange={isFullscreenEnabled => this.setState({ isFullscreenEnabled })}
  190. >
  191. {this.renderDetail()}
  192. </Fullscreen>
  193. );
  194. }
  195. renderDetail() {
  196. const { report = {} } = this.state;
  197. switch (report.paperModule) {
  198. case 'sentence':
  199. return <Sentence {...this.state} flow={this} scene='answer' />;
  200. default:
  201. return <div className='base'>{this.renderBase()}</div>;
  202. }
  203. }
  204. renderBase() {
  205. const { questionStatus, userQuestion = {}, questionNo = {}, paper = {}, showIds, questionNos = [] } = this.state;
  206. return <div className="layout" onClick={() => {
  207. if (showIds) this.setState({ showIds: false });
  208. }}>
  209. <div className="layout-header">
  210. <div className="left">
  211. <div className="no">No.{userQuestion.no}</div>
  212. <div className="title"><Assets name='book' />{paper.title}13</div>
  213. </div>
  214. <div className="center">
  215. <div className="menu-wrap">
  216. ID:{questionNo.title}
  217. {questionNos && questionNos.length > 0 && <Icon name="more" onClick={() => {
  218. this.setState({ showIds: true });
  219. }} />}
  220. {showIds && <div className='menu-content'>
  221. <p>题源汇总</p>
  222. {(questionNos || []).map((row) => <p>ID:{row.title}</p>)}
  223. </div>}
  224. </div>
  225. </div>
  226. <div className="right">
  227. <span className="b">
  228. 用时:<span dangerouslySetInnerHTML={{ __html: formatSeconds(userQuestion.userTime).replace(/([0-9]+)([msh])/g, '<span class="s">$1</span>$2') }} />
  229. {/* 用时:<span className="s">1</span>m<span className="s">39</span>s */}
  230. </span>
  231. <span className="b">
  232. 全站:<span dangerouslySetInnerHTML={{ __html: formatSeconds(questionNo.totalTime / questionNo.totalNumber).replace(/([0-9]+)([msh])/g, '<span class="s">$1</span>$2') }} />
  233. {/* 全站:<span className="s">1</span>m<span className="s">39</span>s */}
  234. </span>
  235. <span className="b">
  236. <span className="s">{formatPercent(questionNo.totalCorrect, questionNo.totalNumber)}</span>%
  237. </span>
  238. <Icon name="question" />
  239. <Icon name="star" active={userQuestion.collect} onClick={() => this.toggleCollect()} />
  240. </div>
  241. </div>
  242. <div className="layout-body">{this.renderBody()}</div>
  243. <div className="layout-footer">
  244. <div className="left">
  245. <Icon name={this.state.isFullscreenEnabled ? 'sceen-restore' : 'sceen-full'} onClick={() => this.toggleFullscreen()} />
  246. </div>
  247. <div className="center">
  248. <AnswerButton className="item" onClick={() => this.setState({ noteModal: true })}>笔记</AnswerButton>
  249. <AnswerButton className="item" onClick={() => {
  250. if (questionStatus) {
  251. this.setState({ askModal: true });
  252. } else {
  253. this.setState({ askFailModal: true });
  254. }
  255. }}>提问</AnswerButton>
  256. <AnswerButton className="item" onClick={() => this.setState({ feedbackModal: true })}>纠错</AnswerButton>
  257. </div>
  258. <div className="right">
  259. <Icon name="prev" onClick={() => this.prevQuestion()} />
  260. <Icon name="next" onClick={() => this.nextQuestion()} />
  261. </div>
  262. </div>
  263. {this.state.askModal && this.renderAsk()}
  264. {this.state.askOkModal && this.renderAskOk()}
  265. {this.state.askFailModal && this.renderAskFail()}
  266. {this.state.feedbackModal && this.renderFeedbackError()}
  267. {this.state.feedbackOkModal && this.renderFeedbackErrorOk()}
  268. {this.state.noteModal && this.renderNote()}
  269. </div>;
  270. }
  271. renderBody() {
  272. const { question = { content: {} } } = this.state;
  273. const { typeset = 'one' } = question.content;
  274. const { hideAnalysis } = this.state;
  275. const show = typeset === 'one' ? true : !hideAnalysis;
  276. return (
  277. <div className="layout-content">
  278. <div className='two'>
  279. {this.renderContent()}
  280. {question.questionType !== 'awa' && this.renderAnswer()}
  281. {question.questionType === 'awa' && this.renderAWA()}
  282. </div>
  283. {question.questionType !== 'awa' && this.renderAnalysis()}
  284. {typeset === 'two' && question.questionType !== 'awa' && (
  285. <div className="fixed-analysis" onClick={() => this.setState({ hideAnalysis: !hideAnalysis })}>
  286. {show ? '收起解析 >' : '查看解析 <'}
  287. </div>
  288. )}
  289. </div>
  290. );
  291. }
  292. renderAnalysis() {
  293. const { question = { content: {} }, analysisTab } = this.state;
  294. const { typeset = 'one' } = question.content;
  295. const { hideAnalysis } = this.state;
  296. const show = typeset === 'one' ? true : !hideAnalysis;
  297. return (
  298. <div className={`block block-analysis two-analysis ${show ? 'show' : ''}`}>
  299. <Tabs
  300. type="division"
  301. active={analysisTab}
  302. tabs={[
  303. { key: 'official', name: '官方解析' },
  304. { key: 'qx', name: '千行解析' },
  305. { key: 'association', name: '题源联想' },
  306. { key: 'qa', name: '相关回答' },
  307. ]}
  308. onChange={(key) => {
  309. this.setState({ analysisTab: key });
  310. }}
  311. />
  312. <div className="detail">
  313. {typeset === 'two' && this.renderAnswer()}
  314. {this.renderText()}
  315. </div>
  316. </div>
  317. );
  318. }
  319. renderText() {
  320. const { analysisTab, question = {}, userQuestion = {} } = this.state;
  321. const { asks = [], associations = [] } = userQuestion;
  322. let content;
  323. switch (analysisTab) {
  324. case 'official':
  325. content = <div className="detail-block text-block" dangerouslySetInnerHTML={{ __html: question.officialContent }} />;
  326. break;
  327. case 'qx':
  328. content = <div className="detail-block text-block" dangerouslySetInnerHTML={{ __html: question.qxContent }} />;
  329. break;
  330. case 'association':
  331. content = <div className="detail-block">
  332. <Carousel>
  333. {associations.map(association => {
  334. return <div className="text-block" dangerouslySetInnerHTML={{ __html: association.stem }} />;
  335. })}
  336. </Carousel>
  337. </div>;
  338. break;
  339. case 'qa':
  340. content = <div className="detail-block answer-block">
  341. {asks.map((ask, index) => {
  342. return <OtherAnswer key={index} data={ask} />;
  343. })}
  344. </div>;
  345. break;
  346. default:
  347. break;
  348. }
  349. return content;
  350. }
  351. renderAnswer() {
  352. const { question = { content: {} }, showAnswer, userQuestion = {} } = this.state;
  353. const { questions = [], type, typeset = 'one' } = question.content;
  354. console.log(userQuestion);
  355. return <div className="block block-answer">
  356. {typeset === 'two' ? <Switch checked={showAnswer} onChange={(value) => {
  357. this.setState({ showAnswer: value });
  358. }}>{showAnswer ? '显示答案' : '关闭答案'}</Switch> : ''}
  359. {questions.map((item, index) => {
  360. return (
  361. <div>
  362. <div className="text m-b-2">{item.description}</div>
  363. <AnswerList
  364. show={showAnswer}
  365. selected={(userQuestion.userAnswer || { questions: [] }).questions[index]}
  366. answer={(question.answer || { questions: [] }).questions[index]}
  367. distributed={(question.answerDistributed || { questions: [] }).questions[index]}
  368. list={item.select}
  369. type={type}
  370. first={item.first}
  371. second={item.second}
  372. direction={item.direction}
  373. />
  374. </div>
  375. );
  376. })}
  377. </div>;
  378. }
  379. renderContent() {
  380. const { question = { content: {} }, showAnswer, step } = this.state;
  381. const { typeset = 'one' } = question.content;
  382. const { steps = [] } = question.content;
  383. return (
  384. <div className="block block-content">
  385. {typeset === 'one' && question.questionType !== 'awa' ? <Switch checked={showAnswer} onChange={(value) => {
  386. this.setState({ showAnswer: value });
  387. }}>{showAnswer ? '显示答案' : '关闭答案'}</Switch> : ''}
  388. {question.questionType === 'awa' && <h2>Analytical Writing Assessment</h2>}
  389. {steps.length > 0 && <Navigation theme='detail' list={question.content.steps} active={step} onChange={(v) => this.setState({ step: v })} />}
  390. <div className="text" style={{ height: 2000 }} dangerouslySetInnerHTML={{ __html: this.formatStem(steps.length > 0 ? steps[step].stem : question.stem) }} />
  391. </div>
  392. );
  393. }
  394. renderAWA() {
  395. const { showAnswer, userQuestion = { detail: {}, userAnswer: {} } } = this.state;
  396. return <div className="block block-awa">
  397. <Switch checked={showAnswer} onChange={(value) => {
  398. this.setState({ showAnswer: value });
  399. }}>{showAnswer ? '显示答案' : '关闭答案'}</Switch>
  400. <div className="body">
  401. <h2>Your Response</h2>
  402. {showAnswer && <div className='detail'>
  403. <div className='info'>
  404. <span className="b">
  405. 用时:<span dangerouslySetInnerHTML={{ __html: formatSeconds(userQuestion.userTime).replace(/([0-9]+)([msh])/g, '<span class="s">$1</span>$2') }} />
  406. {/* 用时:<span className="s">1</span>m<span className="s">39</span>s */}
  407. </span>
  408. <span className="b">
  409. 单词数:<span className="s">{Number((userQuestion.detail || {}).words || 0)}</span>词
  410. </span>
  411. </div>
  412. <div className='content-awa' dangerouslySetInnerHTML={{ __html: userQuestion.userAnswer.awa || '' }} />
  413. </div>}
  414. {!showAnswer && <div className='show-awa'>选择「显示答案」查看自己的作文</div>}
  415. </div>
  416. </div>;
  417. }
  418. renderAsk() {
  419. const { ask = {} } = this.state;
  420. return (
  421. <div className="modal ask">
  422. <div className="mask" />
  423. <div className="body">
  424. <div className="title">提问</div>
  425. <div className="desc">
  426. <div className="select-inline">我想对<Select excludeSelf size="small" theme="white" value={ask.target} list={AskTarget} onChange={(item) => {
  427. ask.target = item.value;
  428. this.setState({ ask });
  429. }} />进行提问</div>
  430. <div className="label">有疑问的具体内容是:</div>
  431. <textarea className="textarea" value={ask.originContent} placeholder="请复制粘贴有疑问的内容。" onChange={(e) => {
  432. ask.originContent = e.target.value;
  433. this.setState({ ask });
  434. }} />
  435. <div className="label">针对以上内容的问题是:</div>
  436. <textarea className="textarea" value={ask.content} placeholder="提问频率高的问题会被优先回答哦。" onChange={(e) => {
  437. ask.content = e.target.value;
  438. this.setState({ ask });
  439. }} />
  440. </div>
  441. <div className="bottom">
  442. <AnswerButton theme="cancel" size="lager" onClick={() => this.setState({ askModal: false })}>
  443. 取消
  444. </AnswerButton>
  445. <AnswerButton size="lager" onClick={() => this.submitAsk()}>提交</AnswerButton>
  446. </div>
  447. </div>
  448. </div>
  449. );
  450. }
  451. renderAskOk() {
  452. return (
  453. <div className="modal ask-ok">
  454. <div className="mask" />
  455. <div className="body">
  456. <div className="title">提问</div>
  457. <div className="content">
  458. <div className="left">
  459. <div className="text">已提交成功!</div>
  460. <div className="text">关注公众号,老师回答后会立即收到通知。</div>
  461. <div className="text">我们也会通过站内信的方式通知你。</div>
  462. <div className="small">成为学员享受极速答疑特权。<Link>了解更多</Link></div>
  463. </div>
  464. <div className="right">
  465. <div className="text">扫码关注公众号</div>
  466. <div className="text">千行GMAT</div>
  467. </div>
  468. </div>
  469. <div className="confirm">
  470. <AnswerButton size="lager" theme="confirm" onClick={() => {
  471. this.setState({ askOkModal: false });
  472. }}>
  473. 好的,知道了
  474. </AnswerButton>
  475. </div>
  476. </div>
  477. </div>
  478. );
  479. }
  480. renderAskFail() {
  481. return (
  482. <div className="modal ask-ok">
  483. <div className="mask" />
  484. <div className="body">
  485. <div className="title">提问</div>
  486. <div className="content">
  487. <div className="left">
  488. <div className="text">提问功能正在维护中。</div>
  489. <div className="text">可先查阅“相关问答” 或 成为学员享受极速 答疑特权。</div>
  490. <Link to="/">了解更多></Link>
  491. </div>
  492. <div className="right">
  493. <div className="text">扫码关注公众号</div>
  494. <div className="text">千行GMAT</div>
  495. </div>
  496. </div>
  497. <div className="confirm">
  498. <AnswerButton size="lager" theme="confirm" onClick={() => {
  499. this.setState({ askFailModal: false });
  500. }}>
  501. 好的,知道了
  502. </AnswerButton>
  503. </div>
  504. </div>
  505. </div>
  506. );
  507. }
  508. renderFeedbackError() {
  509. const { feedback = {} } = this.state;
  510. return (
  511. <div className="modal error">
  512. <div className="mask" />
  513. <div className="body">
  514. <div className="title">纠错</div>
  515. <div className="desc">
  516. <div className="select-inline">我想对<Select excludeSelf size="small" theme="white" value={feedback.target} list={AskTarget} onChange={(item) => {
  517. feedback.target = item.value;
  518. this.setState({ feedback });
  519. }} />进行提问</div>
  520. <div className="label">错误内容是:</div>
  521. <textarea className="textarea" value={feedback.originContent} placeholder="你可以适当扩大复制范围以使我们准确定位,感谢。" />
  522. <div className="label">应该改为:</div>
  523. <textarea className="textarea" placeholder="只需提供正确内容即可" />
  524. </div>
  525. <div className="bottom">
  526. <AnswerButton theme="cancel" size="lager" onClick={() => {
  527. this.setState({ feedbackModal: false });
  528. }}>
  529. 取消
  530. </AnswerButton>
  531. <AnswerButton size="lager" onClick={() => {
  532. this.submitFeedbackError();
  533. }}>提交</AnswerButton>
  534. </div>
  535. </div>
  536. </div>
  537. );
  538. }
  539. renderFeedbackErrorOk() {
  540. return (
  541. <div className="modal error-ok">
  542. <div className="mask" />
  543. <div className="body">
  544. <div className="title">纠错</div>
  545. <div className="content">
  546. <div className="left">
  547. <div className="text"><Assets name='right' svg />已提交成功!</div>
  548. <div className="text">感谢您的耐心反馈,我们会尽快核实并以站内信的方式告知结果。</div>
  549. <div className="text">您也可以关注公众号及时获取结果。</div>
  550. </div>
  551. <div className="right">
  552. <div className="text">扫码关注公众号</div>
  553. <div className="text">千行GMAT</div>
  554. </div>
  555. </div>
  556. <div className="confirm">
  557. <AnswerButton size="lager" theme="confirm" onClick={() => {
  558. this.setState({ feedbackOkModal: false });
  559. }}>
  560. 好的,知道了
  561. </AnswerButton>
  562. </div>
  563. </div>
  564. </div>
  565. );
  566. }
  567. renderNote() {
  568. const { noteField, note = {} } = this.state;
  569. return (
  570. <div className="modal note">
  571. <div className="mask" />
  572. <div className="body">
  573. <div className="title">笔记</div>
  574. <div className="content">
  575. <div className="tabs">
  576. {AskTarget.map(item => {
  577. return (
  578. <div className={`tab ${noteField === item.key ? 'active' : ''}`} onClick={() => {
  579. this.setState({ noteField: item.key });
  580. }}>
  581. <div className="text">{item.label}</div>
  582. <div className="date">{note[`${item.key}Time`] ? formatDate(note[`${item.key}Time`]) : ''}</div>
  583. </div>
  584. );
  585. })}
  586. </div>
  587. <div className="input">
  588. <textarea className="textarea" value={note[`${noteField}Content`] || ''} placeholder="记下笔记,方便以后复习" onChange={(e) => {
  589. note[`${noteField}Time`] = new Date();
  590. note[`${noteField}Content`] = e.target.value;
  591. this.setState({ note });
  592. }} />
  593. <div className="bottom">
  594. <AnswerButton theme="cancel" size="lager" onClick={() => {
  595. this.setState({ noteModal: false });
  596. }}>
  597. 取消
  598. </AnswerButton>
  599. <AnswerButton size="lager" onClick={() => {
  600. this.submitNote();
  601. }}>编辑</AnswerButton>
  602. <AnswerButton size="lager" onClick={() => {
  603. this.submitNote(true);
  604. }}>保存</AnswerButton>
  605. </div>
  606. </div>
  607. </div>
  608. </div>
  609. </div>
  610. );
  611. }
  612. }