CardRulePreview.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <template>
  2. <div :class="classes">
  3. <div class="preview-body">
  4. <template v-for="(page, pageNo) in pages">
  5. <div
  6. :class="[
  7. 'page-box',
  8. `page-box-${cardConfig.pageSize}`,
  9. `page-box-${pageNo % 2}`
  10. ]"
  11. :key="pageNo"
  12. >
  13. <div
  14. :class="['page-locators', `page-locators-${page.locators.length}`]"
  15. >
  16. <ul
  17. class="page-locator-group"
  18. v-for="(locator, iind) in page.locators"
  19. :key="iind"
  20. >
  21. <li
  22. v-for="(elem, eindex) in locator"
  23. :key="eindex"
  24. :id="elem.id"
  25. ></li>
  26. </ul>
  27. </div>
  28. <!-- inner edit area -->
  29. <div class="page-main-inner">
  30. <div
  31. :class="['page-main', `page-main-${page.columns.length}`]"
  32. :style="{ margin: `0 -${page.columnGap / 2}px` }"
  33. >
  34. <div
  35. class="page-column"
  36. v-for="(column, columnNo) in page.columns"
  37. :key="columnNo"
  38. :style="{ padding: `0 ${page.columnGap / 2}px` }"
  39. >
  40. <div
  41. class="page-column-main"
  42. :id="[`column-${pageNo}-${columnNo}`]"
  43. >
  44. <div class="page-column-body" v-if="column.elements.length">
  45. <topic-element-preview
  46. class="page-column-element"
  47. v-for="element in column.elements"
  48. :key="element.id"
  49. :data="element"
  50. ></topic-element-preview>
  51. </div>
  52. <div class="page-column-body" v-else>
  53. <div
  54. class="page-column-forbid-area"
  55. v-if="cardConfig.showForbidArea"
  56. >
  57. <p>该区域严禁作答</p>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. <!-- outer edit area -->
  65. <div class="page-main-outer">
  66. <page-number
  67. type="rect"
  68. :total="pages.length"
  69. :current="pageNo + 1"
  70. ></page-number>
  71. <page-number
  72. type="text"
  73. :total="pages.length"
  74. :current="pageNo + 1"
  75. ></page-number>
  76. </div>
  77. </div>
  78. </template>
  79. </div>
  80. </div>
  81. </template>
  82. <script>
  83. import TopicElementPreview from "../components/TopicElementPreview";
  84. import PageNumber from "../components/PageNumber";
  85. import { cardConfigInfos } from "../api";
  86. const JsBarcode = require("jsbarcode");
  87. import { getCardHeadModel } from "../elementModel";
  88. const pages = [
  89. {
  90. type: "PAGE",
  91. columnGap: 20,
  92. locators: [
  93. [
  94. {
  95. type: "LOCATOR",
  96. id: "locator-0-00"
  97. },
  98. {
  99. type: "LOCATOR",
  100. id: "locator-0-01"
  101. }
  102. ],
  103. [
  104. {
  105. type: "LOCATOR",
  106. id: "locator-0-10"
  107. },
  108. {
  109. type: "LOCATOR",
  110. id: "locator-0-11"
  111. }
  112. ],
  113. [
  114. {
  115. type: "LOCATOR",
  116. id: "locator-0-20"
  117. },
  118. {
  119. type: "LOCATOR",
  120. id: "locator-0-21"
  121. }
  122. ]
  123. ],
  124. columns: [
  125. {
  126. type: "COLUMN",
  127. elements: []
  128. },
  129. {
  130. type: "COLUMN",
  131. elements: []
  132. }
  133. ]
  134. }
  135. ];
  136. export default {
  137. name: "card-preview",
  138. components: { TopicElementPreview, PageNumber },
  139. data() {
  140. return {
  141. cardRuleId: this.$route.params.cardRuleId,
  142. cardConfig: {},
  143. pages
  144. };
  145. },
  146. computed: {
  147. classes() {
  148. return ["card-preview"];
  149. }
  150. },
  151. mounted() {
  152. if (!this.cardRuleId) {
  153. this.$message.error("题卡规则id缺失!");
  154. return;
  155. }
  156. this.init();
  157. },
  158. methods: {
  159. async init() {
  160. const data = await cardConfigInfos(this.cardRuleId);
  161. if (!data) {
  162. this.$message.error("找不到题卡规则!");
  163. return;
  164. }
  165. let config = {
  166. ...data,
  167. ...{
  168. pageSize: "A3",
  169. columnNumber: 2,
  170. columnGap: 20,
  171. showForbidArea: true,
  172. cardDesc: ""
  173. }
  174. };
  175. config.aOrB = true; // 默认开启A/B卷型
  176. config.requiredFields = JSON.parse(config.requiredFields);
  177. config.extendFields = JSON.parse(config.extendFields);
  178. config.cardTitle = config.titleRule;
  179. this.cardConfig = config;
  180. let cardHeadElement = getCardHeadModel(this.cardConfig);
  181. cardHeadElement.fieldInfos = this.fetchFieldInfos(config, {});
  182. this.pages[0].columns[0].elements.push(cardHeadElement);
  183. },
  184. fetchFieldInfos(cardConfig, stdInfo) {
  185. let fieldInfos = {};
  186. const defContent = "相关信息";
  187. const defNumber = "123456789";
  188. [...cardConfig.requiredFields, ...cardConfig.extendFields]
  189. .filter(item => item.enable)
  190. .map(item => {
  191. console.log(item);
  192. fieldInfos[item.code] = stdInfo[item.code] || defContent;
  193. });
  194. if (cardConfig.examNumberStyle === "PRINT") {
  195. fieldInfos.examNumber = this.getBase64Barcode(
  196. stdInfo["examNumber"] || defNumber
  197. );
  198. fieldInfos.examNumberStr = stdInfo["examNumber"] || defNumber;
  199. }
  200. if (cardConfig.aOrB && cardConfig.paperType === "PRINT") {
  201. fieldInfos.paperType = this.getBase64Barcode(
  202. stdInfo["paperType"] || defNumber
  203. );
  204. fieldInfos.paperTypeName = stdInfo["paperTypeName"] || "A";
  205. }
  206. return fieldInfos;
  207. },
  208. getBase64Barcode(str) {
  209. const canvas = document.createElement("CANVAS");
  210. JsBarcode(canvas, str, {
  211. width: 2,
  212. height: 30,
  213. displayValue: false,
  214. marginLeft: 20,
  215. marginRight: 20,
  216. marginTop: 0,
  217. marginBottom: 0
  218. });
  219. return canvas.toDataURL();
  220. }
  221. }
  222. };
  223. </script>