paperCard.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import { numberToChinese } from "../plugins/utils";
  2. import {
  3. getModel as createFillQuestion,
  4. getFullModel as getFillQuesitonElements,
  5. } from "../elements/fill-question/model";
  6. import {
  7. getModel as createFillLine,
  8. getFullModel as getFillLineElements,
  9. } from "../elements/fill-line/model";
  10. import {
  11. getModel as createExplain,
  12. getFullModel as getExplainElements,
  13. } from "../elements/explain/model";
  14. const COMMON_QUESTION_TYPES = [
  15. "SINGLE_ANSWER_QUESTION",
  16. "MULTIPLE_ANSWER_QUESTION",
  17. "BOOL_ANSWER_QUESTION",
  18. "FILL_BLANK_QUESTION",
  19. "TEXT_ANSWER_QUESTION",
  20. ];
  21. // TODO: READING_COMPREHENSION,LISTENING_QUESTION,CLOZE,PARAGRAPH_MATCHING,BANKED_CLOZE
  22. const structTypeToCardElementType = {
  23. SINGLE_ANSWER_QUESTION: "FILL_QUESTION",
  24. MULTIPLE_ANSWER_QUESTION: "FILL_QUESTION",
  25. BOOL_ANSWER_QUESTION: "FILL_QUESTION",
  26. FILL_BLANK_QUESTION: "FILL_LINE",
  27. TEXT_ANSWER_QUESTION: "EXPLAIN",
  28. };
  29. const elementModel = {
  30. FILL_QUESTION: (presetData) => {
  31. const model = createFillQuestion(presetData);
  32. return getFillQuesitonElements(model, { pageSize: "A3", columnNumber: 2 });
  33. },
  34. FILL_LINE: (presetData) => {
  35. const model = createFillLine(presetData);
  36. return getFillLineElements(model, presetData.questions);
  37. },
  38. EXPLAIN: (presetData) => {
  39. const model = createExplain(presetData);
  40. return getExplainElements(model);
  41. },
  42. };
  43. function parseCommonPaperStruct(paperJson) {
  44. let structList = [];
  45. paperJson.paperDetails.forEach((detail) => {
  46. const commonQuestions = detail.paperDetailUnits.filter((q) =>
  47. COMMON_QUESTION_TYPES.includes(q.questionType)
  48. );
  49. if (commonQuestions.length) {
  50. const commonStructList = getCommonQuestionStructList(
  51. detail,
  52. commonQuestions,
  53. true,
  54. 0
  55. );
  56. structList.push(...commonStructList);
  57. }
  58. const nestedQuestions = detail.paperDetailUnits.filter(
  59. (q) => !COMMON_QUESTION_TYPES.includes(q.questionType)
  60. );
  61. if (nestedQuestions.length) {
  62. const nestedStructList = getNestedQuestionStructList(
  63. detail,
  64. nestedQuestions
  65. );
  66. structList.push(...nestedStructList);
  67. }
  68. });
  69. structList.sort((a, b) => a.sortNo - b.sortNo);
  70. console.log(structList);
  71. return structList;
  72. }
  73. function getCommonQuestionStructList(
  74. detail,
  75. questions,
  76. isCommon,
  77. nestedQNo = 0
  78. ) {
  79. let structList = [];
  80. let structs = {};
  81. const qTypeNum = isCommon ? 1 : 2;
  82. questions.forEach((question) => {
  83. if (!structs[question.questionType]) structs[question.questionType] = [];
  84. structs[question.questionType].push(question);
  85. });
  86. Object.keys(structs).forEach((structType) => {
  87. const typeNo = COMMON_QUESTION_TYPES.indexOf(structType);
  88. const questions = parseCommonTypeQuestions(structType, structs[structType]);
  89. structList.push({
  90. detailName: detail.name,
  91. detailNo: detail.number,
  92. structType,
  93. isCommon,
  94. nestedQNo,
  95. sortNo:
  96. typeNo * 10000 + detail.number * 1000 + qTypeNum * 100 + nestedQNo,
  97. questions,
  98. });
  99. });
  100. return structList;
  101. }
  102. function getNestedQuestionStructList(detail, questions) {
  103. let structList = [];
  104. questions.forEach((question) => {
  105. const qStructList = getCommonQuestionStructList(
  106. detail,
  107. question.subQuestions,
  108. false,
  109. question.number
  110. );
  111. structList.push(...qStructList);
  112. });
  113. return structList;
  114. }
  115. function parseCommonTypeQuestions(structType, dataList) {
  116. const choiceQs = [
  117. "SINGLE_ANSWER_QUESTION",
  118. "MULTIPLE_ANSWER_QUESTION",
  119. "BOOL_ANSWER_QUESTION",
  120. ];
  121. let questions = [];
  122. if (choiceQs.includes(structType)) {
  123. questions = dataList.map((item) => {
  124. return {
  125. questionNo: item.number,
  126. optionCount:
  127. structType === "BOOL_ANSWER_QUESTION"
  128. ? 2
  129. : item.question.quesOptions.length,
  130. };
  131. });
  132. } else if (structType === "FILL_BLANK_QUESTION") {
  133. questions = dataList.map((item) => {
  134. return {
  135. questionNo: item.number,
  136. fillCount: getFillBackClozeCount(item.question.quesBody),
  137. };
  138. });
  139. } else {
  140. questions = dataList.map((item) => item.number);
  141. }
  142. return questions;
  143. }
  144. function getFillBackClozeCount(questionBodyContent) {
  145. // TODO:
  146. let questionBody = null;
  147. let num = 0;
  148. try {
  149. questionBody = JSON.parse(questionBodyContent);
  150. questionBody.sections.forEach((section) => {
  151. section.blocks.forEach((block) => {
  152. if (block.type === "cloze") num++;
  153. });
  154. });
  155. } catch (error) {
  156. num = 1;
  157. }
  158. return num;
  159. }
  160. function buildCardElements(structList) {
  161. let cardElements = [];
  162. structList.forEach((struct) => {
  163. const detailChineseNumber = numberToChinese(struct.detailNo);
  164. let topicName = struct.isCommon
  165. ? `${detailChineseNumber}、${struct.detailName}`
  166. : `${detailChineseNumber}(${struct.nestedQNo})`;
  167. const modelType = structTypeToCardElementType[struct.structType];
  168. if (!struct.isCommon && struct.structType === "TEXT_ANSWER_QUESTION") {
  169. struct.questions.forEach((qno) => {
  170. const tname = `${topicName}、${qno}`;
  171. const elements = elementModel[modelType]({
  172. questions: [""],
  173. topicName: tname,
  174. });
  175. cardElements.push(...elements);
  176. });
  177. return;
  178. }
  179. let presetData = {
  180. questions: struct.questions,
  181. topicName,
  182. };
  183. if (struct.structType === "MULTIPLE_ANSWER_QUESTION")
  184. presetData.isMultiply = true;
  185. if (struct.structType === "BOOL_ANSWER_QUESTION")
  186. presetData.isBoolean = true;
  187. const elements = elementModel[modelType](presetData);
  188. cardElements.push(...elements);
  189. });
  190. return cardElements;
  191. }
  192. export function buildPaperCard(paperJson) {
  193. const structList = parseCommonPaperStruct(paperJson);
  194. const cardElements = buildCardElements(structList);
  195. console.log(cardElements);
  196. return cardElements;
  197. }
  198. // const paperStruct = {
  199. // paperName: "",
  200. // structList: [
  201. // {
  202. // detailName: "",
  203. // detailNo: 1,
  204. // structType: 1,
  205. // questions: [
  206. // { questionNo: "1", optionCount: 4 },
  207. // { questionNo: "2", optionCount: 4 },
  208. // ],
  209. // },
  210. // {
  211. // detailName: "",
  212. // detailNo: 1,
  213. // structType: 2,
  214. // questions: [
  215. // { questionNo: "3", optionCount: 4 },
  216. // { questionNo: "4", optionCount: 4 },
  217. // ],
  218. // },
  219. // {
  220. // detailName: "",
  221. // detailNo: 1,
  222. // structType: 3,
  223. // questions: [
  224. // { questionNo: "5", optionCount: 2 },
  225. // { questionNo: "6", optionCount: 2 },
  226. // ],
  227. // },
  228. // {
  229. // detailName: "",
  230. // detailNo: 1,
  231. // structType: 4,
  232. // questions: [
  233. // { questionNo: "7", fillCount: 1 },
  234. // { questionNo: "8", fillCount: 2 },
  235. // ],
  236. // },
  237. // {
  238. // detailName: "",
  239. // detailNo: 1,
  240. // structType: 5,
  241. // questions: ["11", "12"],
  242. // },
  243. // ],
  244. // };