page.js 13 KB

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