page.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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.totalTime = null;
  17. this.totalInterval = null;
  18. this.stages = {};
  19. this.stage = '';
  20. this.stageInterval = null;
  21. this.stageTime = 0;
  22. this.stageProcess = { number: 0, time: 0 };
  23. this.relaxProcess = { time: 0 };
  24. this.startInterval = null;
  25. this.startTime = 0;
  26. this.baseRef = null;
  27. this.sentenceRef = null;
  28. this.accTime = 0;
  29. }
  30. outPage() {
  31. if (this.stageInterval) {
  32. clearInterval(this.stageInterval);
  33. this.stageInterval = null;
  34. }
  35. if (this.totalInterval) {
  36. clearInterval(this.totalInterval);
  37. this.totalInterval = null;
  38. }
  39. if (this.singleInterval) {
  40. clearInterval(this.singleInterval);
  41. this.singleInterval = null;
  42. }
  43. }
  44. initState() {
  45. return {
  46. showTime: true,
  47. showNo: true,
  48. setting: {},
  49. report: {},
  50. question: {},
  51. userQuestion: {},
  52. paper: {},
  53. scene: null,
  54. };
  55. }
  56. switchTime() {
  57. this.setState({ showTime: !this.state.showTime });
  58. }
  59. switchNo() {
  60. this.setState({ showNo: !this.state.showNo });
  61. }
  62. initData() {
  63. const { type, id } = this.params;
  64. // type 是获取基础paper的表信息
  65. // 等同于PaperOrigin
  66. Question.getPaper(type, id).then(paper => {
  67. let totalNumber = paper.questionNumber;
  68. let handler = null;
  69. if (paper.paperModule === 'examination') {
  70. // 模考获取配置信息
  71. handler = Main.getExaminationNumber().then(result => {
  72. totalNumber = 0;
  73. Object.keys(result).forEach(key => {
  74. result[key].time = Number(result[key].time);
  75. result[key].number = Number(result[key].number);
  76. totalNumber += result[key].number;
  77. });
  78. this.stages = result;
  79. this.relaxProcess = { time: 8 * 60 };
  80. });
  81. } else {
  82. handler = Promise.resolve();
  83. }
  84. this.setState({ paper, totalNumber });
  85. const { r } = this.state.search;
  86. if (r) {
  87. handler.then(() => {
  88. this.continue(r);
  89. });
  90. } else if (paper.paperModule === 'sentence') {
  91. // 长难句没有设置,直接开始
  92. handler.then(() => {
  93. this.start({});
  94. });
  95. } else {
  96. this.setState({ scene: 'start' });
  97. // 模考cat1分钟自动开始
  98. if (paper.paperModule === 'examination') {
  99. this.startWaitTime();
  100. }
  101. }
  102. handler.catch(() => {
  103. goBack();
  104. });
  105. });
  106. }
  107. setSetting(newSetting) {
  108. const { setting } = this.state;
  109. this.setState({ setting: Object.assign(setting, newSetting) });
  110. }
  111. start(setting) {
  112. const { type, id } = this.params;
  113. return Question.start(type, id, setting).then(report => {
  114. if (report.isFinish) {
  115. return this.finish();
  116. }
  117. this.changeQuery({ r: report.id });
  118. this.setState({ report, scene: 'question' });
  119. // 开始统计做题进度
  120. if (report.paperModule === 'examination') {
  121. const { order } = setting;
  122. this.initStage(order[0], 0, 0);
  123. }
  124. this.totalQuestionTime();
  125. return this.next();
  126. });
  127. }
  128. continue(reportId) {
  129. return Question.continue(reportId)
  130. .then(report => {
  131. if (report.isFinish) {
  132. throw new Error('做题结束,请先重置');
  133. }
  134. this.setState({ report, scene: 'questionn' });
  135. // 更新当前做题进度
  136. if (report.paperModule === 'examination') {
  137. const { stage, time, number } = report.setting;
  138. this.initStage(stage, time[stage], number[stage]);
  139. }
  140. this.totalQuestionTime(report.userTime || 0);
  141. return this.next();
  142. })
  143. .catch(() => {
  144. Question.reportLink({ report: { id: reportId } }, false);
  145. });
  146. }
  147. next() {
  148. const { report } = this.state;
  149. const { setting = {} } = report;
  150. return Question.next(report.id)
  151. .then(userQuestion => {
  152. const questionSetting = {};
  153. if (setting.disorder && userQuestion.questionType !== 'ds') {
  154. const { questions } = userQuestion.question.content;
  155. if (questions) {
  156. // 乱序显示选项
  157. questionSetting.questions = [];
  158. questions.forEach(q => {
  159. const order = randomList(q.select.length);
  160. q.select = sortListWithOrder(q.select, order);
  161. questionSetting.questions.push(order);
  162. });
  163. }
  164. }
  165. this.setState({
  166. userQuestion,
  167. question: userQuestion.question,
  168. questionSetting,
  169. scene: 'question',
  170. });
  171. this.singleQuestionTime();
  172. return true;
  173. })
  174. .catch(err => {
  175. if (err.message === 'finish') {
  176. // 考试结束
  177. return this.finish();
  178. }
  179. return false;
  180. });
  181. }
  182. submit(answer) {
  183. const { report, userQuestion, questionSetting, singleTime } = this.state;
  184. const { setting = {} } = report;
  185. if (setting.disorder && userQuestion.questionType !== 'ds') {
  186. const { questions } = answer;
  187. if (questions) {
  188. // 还原乱序选项
  189. questions.forEach((q, index) => {
  190. const order = questionSetting.questions[index];
  191. Object.keys(q).forEach(k => {
  192. if (q[k]) q[k] = resortListWithOrder(q[k], order);
  193. });
  194. });
  195. }
  196. }
  197. return Question.submit(userQuestion.id, answer, singleTime, questionSetting).then(() => {
  198. this.singleQuestionTime(true);
  199. if (report.paperModule === 'examination') {
  200. // 更新模考做题进度
  201. this.stageNumber = userQuestion.stageNo;
  202. if (this.stageNumber >= this.stageProcess.number) {
  203. const { order } = report.setting;
  204. // 进入休息
  205. if (order.indexOf(this.stage) < order.length - 1) {
  206. this.stageToRelax();
  207. return Promise.reject();
  208. }
  209. }
  210. }
  211. return Promise.resolve();
  212. });
  213. }
  214. // 主动进入下一阶段
  215. nextStage() {
  216. const { report } = this.state;
  217. return Question.stage(report.id)
  218. .then(() => {
  219. this.baseRef.timeOut(() => {
  220. this.stageToRelax();
  221. });
  222. })
  223. .catch(err => {
  224. if (err.message === 'finish') {
  225. // 考试结束
  226. return this.finish();
  227. }
  228. return false;
  229. });
  230. }
  231. relaxToNextStage() {
  232. this.stageQuestionTime(0, true);
  233. // 进入下一阶段
  234. this.initNextStage();
  235. this.next();
  236. }
  237. stageToRelax() {
  238. if (this.accTime > 55 * 60) {
  239. this.relaxStage();
  240. this.accTime = 0;
  241. } else {
  242. this.relaxToNextStage();
  243. }
  244. }
  245. finish() {
  246. const { report } = this.state;
  247. return Question.finish(report.id)
  248. .then(() => {
  249. // 跳转到报告页
  250. Question.reportLink({ report }, false);
  251. // this.setState({ scene: 'finish' });
  252. })
  253. .catch(() => {
  254. Question.reportLink({ report }, false);
  255. });
  256. }
  257. singleQuestionTime(stop) {
  258. if (this.singleInterval) {
  259. clearInterval(this.singleInterval);
  260. this.singleInterval = null;
  261. }
  262. if (!stop) {
  263. this.singleTime = 0;
  264. this.singleInterval = setInterval(() => {
  265. this.singleTime += 1;
  266. this.setState({ singleTime: this.singleTime });
  267. }, 1000);
  268. }
  269. }
  270. totalQuestionTime(initTime, stop) {
  271. if (initTime) {
  272. this.totalTime = initTime;
  273. }
  274. if (this.totalInterval) {
  275. clearInterval(this.totalInterval);
  276. this.totalInterval = null;
  277. }
  278. if (!stop) {
  279. this.totalInterval = setInterval(() => {
  280. this.totalTime += 1;
  281. this.setState({ totalTime: this.totalTime });
  282. }, 1000);
  283. }
  284. }
  285. stageQuestionTime(initTime, stop) {
  286. if (this.stageInterval) {
  287. clearInterval(this.stageInterval);
  288. this.stageInterval = null;
  289. this.stageTime = initTime;
  290. }
  291. if (!stop) {
  292. this.stageInterval = setInterval(() => {
  293. this.stageTime += 1;
  294. if (this.stageTime >= this.stageProcess.time) {
  295. clearInterval(this.stageInterval);
  296. const { scene } = this.state;
  297. if (scene === 'relax') {
  298. // 进入下一阶段,获取下一题
  299. this.relaxToNextStage();
  300. } else {
  301. // 提交当前阶段
  302. this.nextStage();
  303. }
  304. return;
  305. }
  306. this.setState({ stageTime: this.stageProcess.time - this.stageTime });
  307. }, 1000);
  308. this.setState({ stageTime: this.stageProcess.time - this.stageTime });
  309. }
  310. }
  311. startWaitTime() {
  312. if (this.startInterval) {
  313. clearInterval(this.startInterval);
  314. this.startInterval = null;
  315. }
  316. this.startInterval = setInterval(() => {
  317. this.startTime += 1;
  318. // 1分钟等待: 自动提交第一选择
  319. const { scene } = this.state;
  320. const { paper, setting } = this.state;
  321. const { disorder = true, order = [] } = setting;
  322. if (scene !== 'start') {
  323. clearInterval(this.startInterval);
  324. this.startInterval = null;
  325. } else if (this.startTime >= 60) {
  326. clearInterval(this.startInterval);
  327. this.startInterval = null;
  328. this.start({
  329. disorder: paper.finishTimes > 0 ? disorder : false,
  330. order: order.length > 0 ? order.filter(row => row) : ExaminationOrder[0].value,
  331. });
  332. }
  333. this.setState({ startTime: 60 - this.startTime });
  334. }, 1000);
  335. }
  336. initNextStage() {
  337. const { report } = this.state;
  338. // 进入下一阶段
  339. const { order } = report.setting;
  340. this.stage = order[order.indexOf(this.stage) + 1];
  341. this.stageProcess = this.stages[this.stage];
  342. this.stageQuestionTime(0);
  343. this.setState({ totalNumber: this.stageProcess.number });
  344. this.accTime += this.stageProcess.time;
  345. }
  346. relaxStage() {
  347. this.stageProcess = this.relaxProcess;
  348. this.stageQuestionTime(0);
  349. this.setState({
  350. scene: 'relax',
  351. });
  352. return true;
  353. }
  354. initStage(stage, time) {
  355. this.stage = stage;
  356. this.stageProcess = this.stages[stage];
  357. this.stageTime = time;
  358. this.stageQuestionTime(time);
  359. this.setState({ totalNumber: this.stageProcess.number });
  360. this.accTime += this.stageProcess.time;
  361. }
  362. toggleFullscreen() {
  363. const { isFullscreenEnabled } = this.state;
  364. this.setState({ isFullscreenEnabled: !isFullscreenEnabled });
  365. }
  366. toggleCollect() {
  367. const { userQuestion = {} } = this.state;
  368. if (!userQuestion.collect) {
  369. My.addQuestionCollect(userQuestion.questionNoId).then(() => {
  370. userQuestion.collect = true;
  371. this.setState({ userQuestion });
  372. });
  373. } else {
  374. My.delQuestionCollect(userQuestion.questionNoId).then(() => {
  375. userQuestion.collect = false;
  376. this.setState({ userQuestion });
  377. });
  378. }
  379. }
  380. renderView() {
  381. return (
  382. <Fullscreen
  383. enabled={this.state.isFullscreenEnabled}
  384. onChange={isFullscreenEnabled => this.setState({ isFullscreenEnabled })}
  385. >
  386. {this.renderDetail()}
  387. </Fullscreen>
  388. );
  389. }
  390. renderDetail() {
  391. const { scene, paper, userQuestion } = this.state;
  392. if (!paper.id || !scene) return null;
  393. switch (paper.paperModule) {
  394. case 'sentence':
  395. return <Sentence ref={(ref) => { this.sentenceRef = ref; }} key={userQuestion.id} {...this.state} flow={this} mode='process' />;
  396. default:
  397. return <Base ref={(ref) => { this.baseRef = ref; }} key={userQuestion.id} {...this.state} flow={this} mode='process' />;
  398. }
  399. }
  400. }