page.js 24 KB

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