page.js 7.9 KB

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