page.js 8.1 KB

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