AnswerTemplateBuild.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <template>
  2. <div class="paper-template-build">
  3. <div class="paper-template-build-body">
  4. <!-- <paper-template-view
  5. ref="PaperTemplateView"
  6. class="preview-body"
  7. :pages="pages"
  8. :page-config="paperTempJson.pageConfig"
  9. >
  10. </paper-template-view> -->
  11. <!-- process dom -->
  12. <!-- <div v-if="elementList.length" class="element-list">
  13. <elem-rich-text
  14. v-for="elem in elementList"
  15. :id="elem.id"
  16. :key="elem.id"
  17. :data="elem"
  18. ></elem-rich-text>
  19. </div> -->
  20. <answer-template-view
  21. ref="AnswerTemplateView"
  22. class="preview-body"
  23. :answerData="paperJson"
  24. :pageCountMode="pageCountMode"
  25. ></answer-template-view>
  26. </div>
  27. </div>
  28. </template>
  29. <script>
  30. // import ElemRichText from "../elements/rich-text/ElemRichText.vue";
  31. // import PaperTemplateView from "../components/PaperTemplateView.vue";
  32. import AnswerTemplateView from "../components/AnswerTemplateView.vue";
  33. // import { deepCopy } from "../../card/plugins/utils";
  34. // import previewTemp from "../previewTemp";
  35. import previewTemp from "../previewAnswer";
  36. import { paperDetailInfoApi } from "../../paper/api";
  37. // import { paperTemplateListApi, paperPdfDownloadApi } from "../api";
  38. import { paperPdfDownloadApi } from "../api";
  39. import { downloadByApi } from "@/plugins/download";
  40. import paperTemplateBuildMixins from "./paperTemplateBuildMixins";
  41. export default {
  42. name: "AnswerTemplateBuild",
  43. components: { AnswerTemplateView },
  44. mixins: [paperTemplateBuildMixins],
  45. data() {
  46. return {
  47. paperId: this.$route.params.paperId,
  48. viewType: this.$route.params.viewType,
  49. seqMode: "MODE3",
  50. paperJson: {},
  51. paperTempJson: {
  52. pages: [],
  53. pageConfig: {},
  54. },
  55. maxColumnWidth: 200,
  56. maxColumnHeight: 200,
  57. paperTempList: [],
  58. curPaperTemp: {},
  59. downloading: false,
  60. fieldData: {},
  61. paperStructs: [],
  62. configModalForm: {
  63. showDetailNo: true,
  64. showDetailScoreInfo: true,
  65. showDetailScoreTable: false,
  66. pageCountMode: "SIMPLE",
  67. },
  68. configSources: [],
  69. prepareDownloadPdf: false,
  70. pageCountMode: "SIMPLE",
  71. };
  72. },
  73. mounted() {
  74. if (this.viewType === "frame") {
  75. this.initFrame();
  76. return;
  77. }
  78. },
  79. methods: {
  80. async initFrame() {
  81. try {
  82. const answerSet = window.parent.answerSet;
  83. if (!answerSet) {
  84. this.emitFrameResult(false, "数据缺失");
  85. return;
  86. }
  87. this.seqMode = answerSet.seqMode;
  88. this.pageCountMode = answerSet.pageCountMode;
  89. // this.curPaperTemp = answerSet.paperTemp;
  90. // this.configModalForm = answerSet.configModalForm;
  91. await this.getPaperJson();
  92. } catch (error) {
  93. this.emitFrameResult(false, "数据错误");
  94. }
  95. this.$nextTick(() => {
  96. this.emitFrameResult(true, "", this.getPreviewTemp());
  97. });
  98. },
  99. emitFrameResult(success = true, errorMsg = "", htmlCont = "") {
  100. // console.log("htmlC", htmlCont);
  101. window.parent &&
  102. window.parent.submitPaperTemp &&
  103. window.parent.submitPaperTemp({
  104. success,
  105. errorMsg,
  106. htmlCont,
  107. // templateId: this.curPaperTemp.id,
  108. templateId: null,
  109. });
  110. },
  111. async getPaperJson() {
  112. const res = await paperDetailInfoApi({
  113. paperId: this.paperId,
  114. seqMode: this.seqMode,
  115. });
  116. this.paperJson = res.data;
  117. this.resetClozeSerialNo(this.paperJson);
  118. this.fieldData = {
  119. paperName: res.data.name,
  120. courseName: res.data.course.name,
  121. courseCode: res.data.course.code,
  122. totalScore: res.data.totalScore,
  123. rootOrgName: res.data.rootOrgName,
  124. };
  125. this.paperStructs = this.paperJson.paperDetails.map((detail) => {
  126. return {
  127. detailName: detail.name,
  128. questionCount: detail.unitCount,
  129. totalScore: detail.score,
  130. };
  131. });
  132. },
  133. resetClozeSerialNo(paperData) {
  134. const clozeQuestionTypes = ["CLOZE", "BANKED_CLOZE"];
  135. paperData.paperDetails.forEach((detail) => {
  136. detail.paperDetailUnits.forEach((question) => {
  137. if (!clozeQuestionTypes.includes(question.questionType)) return;
  138. question.question.quesBody.sections.forEach((section) => {
  139. section.blocks.forEach((block) => {
  140. if (block.type !== "cloze") return;
  141. block.value =
  142. question.question.subQuestions[block.value - 1].questionSeq;
  143. });
  144. });
  145. });
  146. });
  147. },
  148. // img ------ start >
  149. loadImg(url) {
  150. return new Promise((resolve, reject) => {
  151. const img = new Image();
  152. img.onload = function () {
  153. resolve(true);
  154. };
  155. img.onerror = function () {
  156. reject();
  157. };
  158. img.src = url;
  159. });
  160. },
  161. getRichJsonImgUrls(richJson) {
  162. let urls = [];
  163. if (!richJson) return urls;
  164. richJson.sections.forEach((section) => {
  165. section.blocks.forEach((elem) => {
  166. if (elem.type === "image" && elem.value.startsWith("http")) {
  167. urls.push(elem.value);
  168. }
  169. });
  170. });
  171. return urls;
  172. },
  173. async waitAllImgLoaded() {
  174. let imgUrls = [];
  175. this.elementList.forEach((item) => {
  176. imgUrls.push(...this.getRichJsonImgUrls(item.content));
  177. });
  178. // console.log(imgUrls);
  179. if (!imgUrls.length) return Promise.resolve(true);
  180. const imgLoads = imgUrls.map((item) => this.loadImg(item));
  181. const imgLoadResult = await Promise.all(imgLoads).catch(() => {});
  182. if (imgLoadResult && imgLoadResult.length) {
  183. return Promise.resolve(true);
  184. } else {
  185. return Promise.reject();
  186. }
  187. },
  188. // img ------ end >
  189. // download ------ start >
  190. getPreviewTemp() {
  191. return previewTemp(this.$refs.AnswerTemplateView.$el.outerHTML);
  192. },
  193. async downloadPaperPdf() {
  194. const htmlCont = this.getPreviewTemp();
  195. if (this.downloading) return;
  196. this.downloading = true;
  197. const res = await downloadByApi(() => {
  198. return paperPdfDownloadApi({
  199. content: htmlCont,
  200. templateId: this.curPaperTemp.id,
  201. paperId: this.paperId,
  202. });
  203. }).catch((e) => {
  204. this.$message.error(e || "下载失败,请重新尝试!");
  205. });
  206. this.downloading = false;
  207. if (!res) return;
  208. this.$message.success("下载成功!");
  209. },
  210. },
  211. };
  212. </script>
  213. <style>
  214. .paper-template-build {
  215. text-align: center;
  216. }
  217. .paper-template-build-body {
  218. display: inline-block;
  219. text-align: initial;
  220. }
  221. .paper-template-build .page-box {
  222. margin-top: 10px;
  223. margin-bottom: 10px;
  224. }
  225. .paper-template-build .paper-build-config {
  226. padding: 10px 15px 2px;
  227. margin-top: 5px;
  228. background: #fff;
  229. border-radius: 10px;
  230. }
  231. .paper-build-config .el-form-item {
  232. margin-bottom: 16px;
  233. margin-right: 30px;
  234. }
  235. .paper-template-build .element-list {
  236. visibility: hidden;
  237. position: absolute;
  238. width: 1200px;
  239. height: 600px;
  240. overflow: hidden;
  241. left: -9999px;
  242. top: 0;
  243. z-index: 1;
  244. }
  245. </style>