import React, { Component } from 'react'; import './index.less'; import Assets from '@src/components/Assets'; import { formatSecond, formatPercent } from '@src/services/Tools'; import Icon from '../../../../components/Icon'; import Button from '../../../../components/Button'; import Tabs from '../../../../components/Tabs'; import Progress from '../../../../components/Progress'; import HardInput from '../../../../components/HardInput'; import AnswerCheckbox from '../../../../components/AnswerCheckbox'; import { SentenceOption } from '../../../../../Constant'; import { Question } from '../../../../stores/question'; export default class extends Component { constructor(props) { super(props); // 确保可以自身进行答案显示,外部也可以直接显示答案 // 将props转入state this.state = { analysisTab: 'qx', focusKey: 'subject', scene: this.props.scene || 'answer', userQuestion: this.props.userQuestion, question: this.props.question, }; const { question, userQuestion } = this.props; if (this.state.scene === 'answer') { this.state.stem = this.formatStem(question.stem, userQuestion.userAnswer, question.answer); } else { this.state.stem = question.stem; } } showAnswer() { const { userQuestion } = this.state; Question.getDetailById(userQuestion.id).then(result => { const { question } = result; this.setState({ userQuestion: result, question: result.question, scene: 'answer', stem: this.formatStem(question.stem, result.userAnswer, question.answer), }); }); } addTarget(target) { const uuid = target.getAttribute('uuid'); if (!uuid) return; const text = target.innerText; const { focusKey, answer = {}, question } = this.state; if (!answer[focusKey]) answer[focusKey] = []; if (answer[focusKey].filter(row => row.uuid === uuid).length > 0) return; answer[focusKey].push({ text, uuid, }); this.setState({ answer, stem: this.formatStem(question.stem, answer), }); } removeTarget(key, target) { const { answer = {}, question } = this.state; if (!answer[key]) return; answer[key] = answer[key].filter(row => row.uuid !== target.uuid); this.setState({ answer, stem: this.formatStem(question.stem, answer), }); } next() { const { flow } = this.props; const { scene } = this.state; if (scene === 'question') { const { answer } = this.state; flow.submit(answer).then(() => { this.showAnswer(); }); } else if (scene === 'answer') { flow.next(); } } formatStem(stem, userAnswer, answer) { // userAnswer 添加蓝色字, 错误的添加红色背景 // answer 添加绿色背景 const uuidMap = {}; const show = !!answer; answer = answer || {}; userAnswer = userAnswer || {}; Object.keys(userAnswer).forEach((key) => { if (key === 'options') return; const u = userAnswer[key]; const a = answer[key] && answer[key].length > 0 ? answer[key][0] : []; const map = {}; a.forEach((row) => { if (!uuidMap[row.uuid]) uuidMap[row.uuid] = []; uuidMap[row.uuid].push('true'); map[row.uuid] = row; }); u.forEach((row) => { if (!uuidMap[row.uuid]) uuidMap[row.uuid] = []; uuidMap[row.uuid].push('user'); if (show && !map[row.uuid]) uuidMap[row.uuid].push('false'); }); }); Object.keys(uuidMap).forEach(uuid => { stem = stem.replace(`uuid='${uuid}'`, `uuid='${uuid}' class='${uuidMap[uuid].join(' ')}'`); }); return stem; } render() { const { flow, paper, userQuestion, singleTime } = this.props; return ( <div id='paper-process-sentence'> <div className="layout"> <div className="layout-header"> <div className="left"> <div className="title">{paper.title}</div> </div> <div className="right"> <div className="text"><Assets name='timecost_icon' />Time cost {formatSecond(userQuestion.userTime || singleTime)}</div> <Icon name="star" active={userQuestion.collect} onClick={() => flow.toggleCollect()} /> </div> </div> {this.renderBody()} <div className="layout-footer"> <div className="left"> <Icon name={this.props.isFullscreenEnabled ? 'sceen-restore' : 'sceen-full'} onClick={() => flow.toggleFullscreen()} /> </div> <div className="center"> <div className="p"> <Progress theme="theme" progress={formatPercent(userQuestion.no, paper.questionNumber)} /> </div> <div className="t">{userQuestion.no}/{paper.questionNumber}</div> </div> <div className="right"> <Button size="lager" radius onClick={() => { this.next(); }}> Next <Assets name="next_icon" /> </Button> </div> </div> </div> </div> ); } renderBody() { const { scene } = this.state; switch (scene) { case 'question': return this.renderQuestion(); case 'answer': return this.renderAnswer(); default: return null; } } renderQuestion() { const { focusKey, answer = {}, stem } = this.state; return ( <div className="layout-body"> <div className="title"><Icon name="question" />请分别找出句子中的主语,谓语和宾语,并做出逻辑关系判断。</div> <div className="desc" dangerouslySetInnerHTML={{ __html: stem }} onClick={(e) => { this.addTarget(e.target); }} /> <div className="label">主语</div> <div className="input"> <HardInput focus={focusKey === 'subject'} list={answer.subject || []} onClick={() => { this.setState({ focusKey: 'subject' }); }} onDelete={(item) => { this.removeTarget('subject', item); }} /> </div> <div className="label">谓语</div> <div className="input"> <HardInput focus={focusKey === 'predicate'} list={answer.predicate || []} onClick={() => { this.setState({ focusKey: 'predicate' }); }} onDelete={(item) => { this.removeTarget('predicate', item); }} /> </div> <div className="label">宾语</div> <div className="input"> <HardInput focus={focusKey === 'object'} list={answer.object || []} onClick={() => { this.setState({ focusKey: 'object' }); }} onDelete={(item) => { this.removeTarget('object', item); }} /> </div> <div className="select"> <div className="select-title">本句存在以下哪种逻辑关系?(可多选)</div> <AnswerCheckbox list={SentenceOption} selected={answer.options} onChange={(values) => { answer.options = values; this.setState({ answer }); }} /> </div> </div> ); } renderAnswer() { const { analysisTab, question, userQuestion, stem } = this.state; const { userAnswer = {} } = userQuestion; const { answer } = question; return <div className="layout-body"> <div className="title"><Icon name="question" />请分别找出句子中的主语,谓语和宾语,并做出逻辑关系判断。</div> <div className="desc" dangerouslySetInnerHTML={{ __html: stem }} /> <div className="label">主语</div> <div className="input"> <HardInput show list={userAnswer.subject || []} answer={answer.subject} /> </div> <div className="label">谓语</div> <div className="input"> <HardInput show list={userAnswer.predicate || []} answer={answer.predicate} /> </div> <div className="label">宾语</div> <div className="input"> <HardInput show list={userAnswer.object || []} answer={answer.object} /> </div> <div className="select"> <div className="select-title">本句存在以下哪种逻辑关系?(可多选)</div> <AnswerCheckbox show list={SentenceOption} selected={userAnswer.options} answer={answer.options} /> </div> <div className="analysis"> <Tabs type="division" active={analysisTab} tabs={[{ key: 'qx', name: '解析详情' }, { key: 'chinese', name: '中文语意' }]} onChange={(key) => { this.setState({ analysisTab: key }); }} /> {this.renderText()} </div> </div>; } renderText() { const { analysisTab, question = {}, questionNo = {} } = this.state; let content; switch (analysisTab) { case 'chinese': content = <div className="detail-block text-block" dangerouslySetInnerHTML={{ __html: questionNo.chineseContent }} />; break; case 'qx': content = <div className="detail-block text-block" dangerouslySetInnerHTML={{ __html: question.qxContent }} />; break; default: break; } return content; } }