page.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. import React from 'react';
  2. import Fullscreen from 'react-fullscreen-crossbrowser';
  3. import './index.less';
  4. import Page from '@src/containers/Page';
  5. import { randomList, sortListWithOrder, resortListWithOrder } from '@src/services/Tools';
  6. import { Question } from '../../../stores/question';
  7. import Base from './base';
  8. import Sentence from './sentence';
  9. import { ExaminationOrder } from '../../../../Constant';
  10. import { Main } from '../../../stores/main';
  11. import { My } from '../../../stores/my';
  12. export default class extends Page {
  13. init() {
  14. this.singleTime = null;
  15. this.singleInterval = null;
  16. this.stages = {};
  17. this.stage = '';
  18. this.stageInterval = null;
  19. this.stageTime = 0;
  20. this.stageNumber = 0;
  21. this.stageProcess = { number: 0, time: 0 };
  22. this.relaxProcess = { time: 0 };
  23. this.startInterval = null;
  24. this.startTime = 0;
  25. }
  26. initState() {
  27. return {
  28. setting: {},
  29. report: {},
  30. question: {},
  31. userQuestion: {},
  32. paper: {},
  33. scene: null,
  34. };
  35. }
  36. initData() {
  37. const { type, id } = this.params;
  38. // type 是获取基础paper的表信息
  39. // 等同于PaperOrigin
  40. Question.getPaper(type, id).then(paper => {
  41. this.setState({ paper });
  42. let handler = null;
  43. if (paper.paperModule === 'examination') {
  44. // 模考获取配置信息
  45. handler = Main.getExaminationNumber().then(result => {
  46. Object.keys(result).forEach(key => {
  47. result[key].time = Number(result[key].time);
  48. result[key].number = Number(result[key].number);
  49. });
  50. this.stages = result;
  51. this.relaxProcess = { time: 8 * 60 };
  52. });
  53. } else {
  54. handler = Promise.resolve();
  55. }
  56. const { r } = this.state.search;
  57. if (r) {
  58. handler.then(() => {
  59. this.continue(r);
  60. });
  61. } else if (paper.paperModule === 'sentence') {
  62. // 长难句没有设置,直接开始
  63. handler.then(() => {
  64. this.start({});
  65. });
  66. } else {
  67. this.setState({ scene: 'start' });
  68. // 模考cat1分钟自动开始
  69. if (paper.isAdapt > 1) {
  70. this.startWaitTime();
  71. }
  72. }
  73. handler.catch(() => {
  74. goBack();
  75. });
  76. });
  77. }
  78. setSetting(newSetting) {
  79. const { setting } = this.state;
  80. this.setState({ setting: Object.assign(setting, newSetting) });
  81. }
  82. start(setting) {
  83. const { type, id } = this.params;
  84. return Question.start(type, id, setting).then(report => {
  85. if (report.isFinish) {
  86. return this.finish();
  87. }
  88. this.setState({ report, scene: 'question' });
  89. // 开始统计做题进度
  90. if (report.paperModule === 'examination') {
  91. const { order } = setting;
  92. this.initStage(order[0], 0, 0);
  93. }
  94. return this.next();
  95. });
  96. }
  97. continue(reportId) {
  98. return Question.continue(reportId)
  99. .then(report => {
  100. if (report.isFinish) {
  101. throw new Error('做题结束,请先重置');
  102. }
  103. this.setState({ report, scene: 'questionn' });
  104. // 更新当前做题进度
  105. if (report.paperModule === 'examination') {
  106. const { stage, time, number } = report.setting;
  107. this.initStage(stage, time[stage], number[stage]);
  108. }
  109. return this.next();
  110. })
  111. .catch(() => {
  112. Question.reportLink({ report: { id: reportId } }, false);
  113. });
  114. }
  115. next() {
  116. const { report, scene } = this.state;
  117. const { setting = {} } = report;
  118. if (scene === 'relax') {
  119. this.nextStage();
  120. }
  121. return Question.next(report.id)
  122. .then(userQuestion => {
  123. const questionSetting = {};
  124. if (setting.disorder) {
  125. const { questions } = userQuestion.question.content;
  126. if (questions) {
  127. // 乱序显示选项
  128. questionSetting.questions = [];
  129. questions.forEach(q => {
  130. const order = randomList(q.select.length);
  131. q.select = sortListWithOrder(q.select, order);
  132. questionSetting.questions.push(order);
  133. });
  134. }
  135. }
  136. this.setState({
  137. userQuestion,
  138. question: userQuestion.question,
  139. questionSetting,
  140. scene: 'question',
  141. });
  142. this.singleQuestionTime();
  143. return true;
  144. })
  145. .catch(err => {
  146. if (err.message === 'finish') {
  147. // 考试结束
  148. return this.finish();
  149. }
  150. return false;
  151. });
  152. }
  153. submit(answer) {
  154. const { report, userQuestion, questionSetting, singleTime } = this.state;
  155. const { setting = {} } = report;
  156. if (setting.disorder) {
  157. const { questions } = answer;
  158. if (questions) {
  159. // 还原乱序选项
  160. questions.forEach((q, index) => {
  161. const order = questionSetting.questions[index];
  162. Object.keys(q).forEach(k => {
  163. if (q[k]) q[k] = resortListWithOrder(q[k], order);
  164. });
  165. });
  166. }
  167. }
  168. return Question.submit(userQuestion.id, answer, singleTime, questionSetting).then(() => {
  169. this.singleQuestionTime(true);
  170. // 更新模考做题进度
  171. if (report.paperModule === 'examination') {
  172. this.stageNumber += 1;
  173. if (this.stageNumber >= this.stageProcess.number) {
  174. // 进入休息
  175. this.relaxStage();
  176. }
  177. }
  178. });
  179. }
  180. // 主动进入下一阶段
  181. stage() {
  182. const { report } = this.state;
  183. return Question.stage(report.id)
  184. .then(() => {
  185. return this.relaxStage();
  186. });
  187. }
  188. finish() {
  189. const { report } = this.state;
  190. return Question.finish(report.id)
  191. .then(() => {
  192. // 跳转到报告页
  193. Question.reportLink({ report }, false);
  194. // this.setState({ scene: 'finish' });
  195. })
  196. .catch(() => {
  197. Question.reportLink({ report }, false);
  198. });
  199. }
  200. singleQuestionTime(stop) {
  201. if (this.singleInterval) {
  202. clearInterval(this.singleInterval);
  203. this.singleInterval = null;
  204. }
  205. if (!stop) {
  206. this.singleTime = 0;
  207. this.singleInterval = setInterval(() => {
  208. this.singleTime += 1;
  209. this.setState({ singleTime: this.singleTime });
  210. }, 1000);
  211. }
  212. }
  213. stageQuestionTime(initTime, stop) {
  214. if (this.stageInterval) {
  215. clearInterval(this.stageInterval);
  216. this.stageInterval = null;
  217. this.stageTime = initTime;
  218. }
  219. if (!stop) {
  220. this.stageInterval = setInterval(() => {
  221. this.stageTime += 1;
  222. if (this.stageTime >= this.stageProcess.time) {
  223. const { scene } = this.state;
  224. if (scene === 'relax') {
  225. // 进入下一阶段,获取下一题
  226. this.next();
  227. } else {
  228. // 提交当前阶段
  229. this.stage();
  230. }
  231. }
  232. this.setState({ stageTime: this.targetProcess.time - this.stageTime });
  233. }, 1000);
  234. }
  235. }
  236. startWaitTime() {
  237. if (this.startInterval) {
  238. clearInterval(this.startInterval);
  239. this.startInterval = null;
  240. }
  241. this.startInterval = setInterval(() => {
  242. this.startTime += 1;
  243. // 1分钟等待: 自动提交第一选择
  244. const { scene } = this.state;
  245. if (scene !== 'start') {
  246. clearInterval(this.startInterval);
  247. this.startInterval = null;
  248. } else if (this.startTime >= 60) {
  249. clearInterval(this.startInterval);
  250. this.startInterval = null;
  251. this.start(Object.assign({ order: ExaminationOrder[0].value }, this.state.setting));
  252. }
  253. this.setState({ startTime: 60 - this.startTime });
  254. }, 1000);
  255. }
  256. nextStage() {
  257. const { report } = this.state;
  258. // 进入下一阶段
  259. const { order } = report.setting;
  260. this.stage = order[order.indexOf(this.stage) + 1];
  261. this.stageProcess = this.stages[this.stage];
  262. this.stageNumber = 0;
  263. this.stageQuestionTime(0);
  264. }
  265. relaxStage() {
  266. this.stageProcess = this.relaxProcess;
  267. this.stageNumber = 0;
  268. this.stageQuestionTime(0);
  269. this.setState({
  270. scene: 'relax',
  271. });
  272. }
  273. initStage(stage, time, number) {
  274. this.stage = stage;
  275. this.stageProcess = this.stages[stage];
  276. this.stageTime = time;
  277. this.stageNumber = number;
  278. this.stageQuestionTime(time);
  279. }
  280. toggleFullscreen() {
  281. const { isFullscreenEnabled } = this.state;
  282. this.setState({ isFullscreenEnabled: !isFullscreenEnabled });
  283. }
  284. toggleCollect() {
  285. const { userQuestion = {} } = this.state;
  286. if (!userQuestion.collect) {
  287. My.addQuestionCollect(userQuestion.questionNoId).then(() => {
  288. userQuestion.collect = true;
  289. this.setState({ userQuestion });
  290. });
  291. } else {
  292. My.delQuestionCollect(userQuestion.questionNoId).then(() => {
  293. userQuestion.collect = false;
  294. this.setState({ userQuestion });
  295. });
  296. }
  297. }
  298. renderView() {
  299. return (
  300. <Fullscreen
  301. enabled={this.state.isFullscreenEnabled}
  302. onChange={isFullscreenEnabled => this.setState({ isFullscreenEnabled })}
  303. >
  304. {this.renderDetail()}
  305. </Fullscreen>
  306. );
  307. }
  308. renderDetail() {
  309. const { scene, paper, userQuestion } = this.state;
  310. if (!paper.id || !scene) return null;
  311. switch (paper.paperModule) {
  312. case 'sentence':
  313. return <Sentence key={userQuestion.id} {...this.state} flow={this} mode='process' />;
  314. default:
  315. return <Base key={userQuestion.id} {...this.state} flow={this} mode='process' />;
  316. }
  317. }
  318. }