CardBuildDialog.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <el-dialog
  3. class="card-build-dialog opacity-dialog"
  4. :visible.sync="modalIsShow"
  5. :close-on-click-modal="false"
  6. :close-on-press-escape="false"
  7. :show-close="false"
  8. append-to-body
  9. fullscreen
  10. @opened="initData"
  11. >
  12. <div slot="title"></div>
  13. <div slot="footer"></div>
  14. <div
  15. class="loading-tips"
  16. v-loading="loading"
  17. element-loading-text="生成题卡中"
  18. ></div>
  19. <div
  20. v-if="modalIsShow"
  21. id="card-build"
  22. class="card-build card-preview card-print"
  23. >
  24. <card-view
  25. v-if="pages.length"
  26. ref="CardView"
  27. class="preview-body"
  28. :pages="pages"
  29. :card-config="cardConfig"
  30. ></card-view>
  31. <!-- all topics -->
  32. <div v-else class="topic-list">
  33. <div :class="['page-box', `page-box-${cardConfig.pageSize}`]">
  34. <div class="page-main-inner">
  35. <div
  36. :class="['page-main', `page-main-${cardConfig.columnNumber}`]"
  37. :style="{ margin: `0 -${cardConfig.columnGap / 2}px` }"
  38. >
  39. <div
  40. class="page-column"
  41. :style="{ padding: `0 ${cardConfig.columnGap / 2}px` }"
  42. >
  43. <div class="page-column-main" id="topic-column">
  44. <div class="page-column-body">
  45. <!-- card-head-sample -->
  46. <card-head-sample
  47. :data="cardHeadSampleData"
  48. id="simple-card-head"
  49. v-if="topics.length && cardHeadSampleData"
  50. ></card-head-sample>
  51. <!-- topic element -->
  52. <topic-element-preview
  53. class="page-column-element"
  54. v-for="element in topics"
  55. :key="element.id"
  56. :data="element"
  57. ></topic-element-preview>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. </el-dialog>
  67. </template>
  68. <script>
  69. import { mapState, mapMutations, mapActions } from "vuex";
  70. import { saveCard, cardConfigInfos } from "../api";
  71. import { tikuPaperDetail } from "../../exam/api";
  72. import { getPaperJsonSimpleStructInfo } from "../autoBuild/paperStruct";
  73. import { buildCardFromPaperSimpleStruct } from "../autoBuild/simplePaperCard";
  74. // card components
  75. import { getCardHeadModel } from "../../../../card/elementModel";
  76. import TopicElementPreview from "../../../../card/components/TopicElementPreview";
  77. import CardView from "../../../../card/components/CardView";
  78. import CardHeadSample from "../../../../card/elements/card-head/CardHead";
  79. // ceshi
  80. // import paperData from "./paper.json";
  81. export default {
  82. name: "CardBuild",
  83. components: { CardView, TopicElementPreview, CardHeadSample },
  84. props: {
  85. presetData: {
  86. type: Object,
  87. default() {
  88. return {
  89. paperId: "",
  90. };
  91. },
  92. },
  93. },
  94. data() {
  95. return {
  96. cardId: "",
  97. loading: false,
  98. modalIsShow: false,
  99. paperInfo: {},
  100. };
  101. },
  102. computed: {
  103. ...mapState("card", ["cardConfig", "topics", "pages"]),
  104. cardHeadSampleData() {
  105. if (!this.cardConfig["pageSize"]) return;
  106. const data = getCardHeadModel(this.cardConfig);
  107. data.isSimple = true;
  108. return data;
  109. },
  110. },
  111. methods: {
  112. ...mapMutations("card", ["setCardConfig", "setTopics", "initState"]),
  113. ...mapActions("card", ["resetTopicSeries", "rebuildPages"]),
  114. async initData() {
  115. this.loading = true;
  116. this.initState();
  117. // 题卡规则
  118. const cardConfig = await this.getCardConfig(
  119. this.presetData.cardRuleId
  120. ).catch(() => {});
  121. if (!cardConfig) {
  122. this.emitResult({ success: false, message: "题卡规则获取失败" });
  123. return;
  124. }
  125. this.setCardConfig(cardConfig);
  126. // 试卷信息
  127. const res = await tikuPaperDetail({
  128. examId: this.presetData.examId,
  129. paperId: this.presetData.paperId,
  130. uuid: this.presetData.uuid,
  131. }).catch(() => {});
  132. if (!res) {
  133. this.emitResult({ success: false, message: "试卷内容获取失败" });
  134. return;
  135. }
  136. // const res = paperData;
  137. // 构建题卡
  138. try {
  139. this.paperInfo = {
  140. uuid: this.presetData.uuid,
  141. attachmentId: res.attachmentId,
  142. };
  143. const paperJson = res.paperJson ? JSON.parse(res.paperJson) : {};
  144. const paperSimpleStruct = getPaperJsonSimpleStructInfo(paperJson);
  145. const elementTypePreSetInfo = {
  146. FILL_QUESTION: {
  147. pageSize: "A3",
  148. columnNumber: 2,
  149. },
  150. };
  151. const elements = buildCardFromPaperSimpleStruct(
  152. paperSimpleStruct,
  153. elementTypePreSetInfo
  154. );
  155. this.setTopics([getCardHeadModel(this.cardConfig), ...elements]);
  156. this.resetTopicSeries();
  157. } catch (error) {
  158. console.dir(error);
  159. this.emitResult({
  160. success: false,
  161. message: error.message || "数据构建错误",
  162. });
  163. return;
  164. }
  165. this.$nextTick(() => {
  166. this.rebuildPages();
  167. this.$nextTick(() => {
  168. this.buildData();
  169. });
  170. });
  171. },
  172. async getCardConfig(cardRuleId) {
  173. const data = await cardConfigInfos(cardRuleId);
  174. if (!data) {
  175. this.$message.error("找不到题卡规则!");
  176. return Promise.reject();
  177. }
  178. let config = {
  179. ...data,
  180. ...{
  181. pageSize: "A3",
  182. columnNumber: 2,
  183. columnGap: 20,
  184. showForbidArea: false,
  185. makeMethod: "SELF",
  186. },
  187. };
  188. config.fillNumber = data.examNumberDigit;
  189. config.aOrB = false;
  190. config.requiredFields = JSON.parse(config.requiredFields);
  191. config.extendFields = JSON.parse(config.extendFields);
  192. config.cardTitle = this.getCardTitle(config.titleRule);
  193. return config;
  194. },
  195. getCardTitle(titleRule) {
  196. const fieldMap = {
  197. courseCode: this.presetData.courseCode,
  198. courseName: this.presetData.courseName,
  199. schoolName: this.presetData.schoolName,
  200. };
  201. Object.entries(fieldMap).forEach(([key, val]) => {
  202. titleRule = titleRule.replace("${" + key + "}", val);
  203. });
  204. return titleRule;
  205. },
  206. async buildData() {
  207. const model = this.$refs.CardView.getPageModel({
  208. cardConfig: this.cardConfig,
  209. pages: this.pages,
  210. });
  211. const htmlContent = this.$refs.CardView.getPreviewTemp(
  212. document.getElementById("card-build").outerHTML
  213. );
  214. const datas = {
  215. content: model,
  216. htmlContent,
  217. title: this.presetData.paperName,
  218. status: "SUBMIT",
  219. ...this.presetData,
  220. };
  221. const result = await saveCard(datas).catch((error) => {
  222. this.emitResult({
  223. success: false,
  224. message: error.message || "保存题卡错误",
  225. });
  226. });
  227. if (!result) return;
  228. this.emitResult({
  229. success: true,
  230. data: { ...result, ...this.paperInfo },
  231. });
  232. },
  233. emitResult(data) {
  234. // console.log(data);
  235. this.loading = false;
  236. this.$emit("confirm", data);
  237. this.cancel();
  238. },
  239. cancel() {
  240. this.modalIsShow = false;
  241. },
  242. open() {
  243. this.modalIsShow = true;
  244. },
  245. },
  246. };
  247. </script>