PaperTemplateDesign.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <template>
  2. <div class="paper-template-design">
  3. <!-- actions -->
  4. <div class="design-action">
  5. <div class="design-logo">
  6. <h1>
  7. <i class="el-icon-d-arrow-left" title="退出" @click="toExit"></i>
  8. 试卷模板制作
  9. </h1>
  10. </div>
  11. <div class="action-part">
  12. <div class="action-part-title"><h2>基本设置</h2></div>
  13. <div class="action-part-body">
  14. <page-prop-edit @init-page="initPageData"></page-prop-edit>
  15. </div>
  16. </div>
  17. <div class="action-part">
  18. <div class="action-part-title"><h2>编辑结构</h2></div>
  19. <div class="action-part-body">
  20. <div class="type-list">
  21. <div class="type-item">
  22. <el-button @click="addNewTopic('PANE_BOX')"
  23. ><i class="el-icon-plus"></i>编辑框</el-button
  24. >
  25. </div>
  26. </div>
  27. <p class="tips-info">提示:点击创建编辑框</p>
  28. </div>
  29. </div>
  30. <div class="action-part">
  31. <div class="action-part-title"><h2>插入元素</h2></div>
  32. <div class="action-part-body">
  33. <div class="type-list">
  34. <div
  35. v-for="(item, index) in ELEMENT_LIST"
  36. :key="index"
  37. class="type-item"
  38. draggable="true"
  39. @dragstart="dragstart(item)"
  40. >
  41. <el-button><i class="el-icon-plus"></i>{{ item.name }}</el-button>
  42. </div>
  43. </div>
  44. <p class="tips-info">提示:拖动插入元素</p>
  45. </div>
  46. </div>
  47. </div>
  48. <div class="design-main">
  49. <!-- menus -->
  50. <div class="design-control">
  51. <div class="control-left tab-btns">
  52. <el-button
  53. v-for="(page, pageNo) in pages"
  54. :key="pageNo"
  55. :type="curPageNo === pageNo ? 'primary' : 'default'"
  56. @click="swithPage(pageNo)"
  57. >{{ pageNo ? "正面" : "反面" }}</el-button
  58. >
  59. </div>
  60. <div class="control-right">
  61. <el-button type="primary" :loading="isSubmit" @click="toSubmit"
  62. >提交</el-button
  63. >
  64. </div>
  65. </div>
  66. <!-- edit body -->
  67. <div class="design-body">
  68. <div
  69. :class="[
  70. 'page-box',
  71. `page-box-${curPage.pageSize}`,
  72. `page-box-${curPageNo % 2}`,
  73. ]"
  74. >
  75. <!-- inner edit area -->
  76. <div class="page-main-inner">
  77. <div
  78. :class="['page-main', `page-main-${curPage.columns.length}`]"
  79. :style="{ margin: `0 -${curPage.columnGap / 2}px` }"
  80. >
  81. <div
  82. v-for="(column, columnNo) in curPage.columns"
  83. :key="columnNo"
  84. class="page-column"
  85. :style="{ padding: `0 ${curPage.columnGap / 2}px` }"
  86. >
  87. <div
  88. :id="[`column-${curPageNo}-${columnNo}`]"
  89. class="page-column-main"
  90. >
  91. <div class="page-column-body">
  92. <topic-element-edit
  93. v-for="element in column.elements"
  94. :key="element.id"
  95. class="page-column-element"
  96. :data-h="element.h"
  97. :data="element"
  98. ></topic-element-edit>
  99. </div>
  100. </div>
  101. <page-number
  102. v-if="curPage.showPageNo"
  103. type="text"
  104. :total="pages.length * 2"
  105. :current="curPageNo * 2 + columnNo + 1"
  106. ></page-number>
  107. </div>
  108. </div>
  109. </div>
  110. <!-- side edit -->
  111. <paper-side-edit class="page-main-side"></paper-side-edit>
  112. </div>
  113. </div>
  114. </div>
  115. <!-- all topics -->
  116. <div class="topic-list">
  117. <div :class="['page-box', `page-box-${curPage.pageSize}`]">
  118. <div class="page-main-inner">
  119. <div
  120. :class="['page-main', `page-main-${curPage.columnNumber}`]"
  121. :style="{ margin: `0 -${curPage.columnGap / 2}px` }"
  122. >
  123. <div
  124. class="page-column"
  125. :style="{ padding: `0 ${curPage.columnGap / 2}px` }"
  126. >
  127. <div id="topic-column" class="page-column-main">
  128. <div class="page-column-body">
  129. <!-- topic element -->
  130. <topic-element-preview
  131. v-for="element in topics"
  132. :key="element.id"
  133. class="page-column-element"
  134. :data="element"
  135. ></topic-element-preview>
  136. </div>
  137. </div>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. <!-- element-prop-edit -->
  144. <element-prop-edit ref="ElementPropEdit"></element-prop-edit>
  145. <!-- right-click-menu -->
  146. <right-click-menu></right-click-menu>
  147. </div>
  148. </template>
  149. <script>
  150. import { mapState, mapMutations, mapActions } from "vuex";
  151. import { getElementModel, ELEMENT_LIST } from "../elementModel";
  152. import { getModel as getPageModel } from "../elements/page/model";
  153. import PagePropEdit from "./PagePropEdit";
  154. import ElementPropEdit from "./ElementPropEdit";
  155. import RightClickMenu from "./RightClickMenu";
  156. import PageNumber from "./PageNumber";
  157. import TopicElementEdit from "./TopicElementEdit.vue";
  158. import TopicElementPreview from "./TopicElementPreview.vue";
  159. import PaperSideEdit from "./PaperSideEdit.vue";
  160. export default {
  161. name: "PaperTemplateDesign",
  162. components: {
  163. PagePropEdit,
  164. ElementPropEdit,
  165. RightClickMenu,
  166. PageNumber,
  167. TopicElementEdit,
  168. TopicElementPreview,
  169. PaperSideEdit,
  170. },
  171. props: {
  172. content: {
  173. type: Object,
  174. default() {
  175. return {
  176. pages: [],
  177. };
  178. },
  179. },
  180. },
  181. data() {
  182. return {
  183. ELEMENT_LIST,
  184. isSubmit: false,
  185. };
  186. },
  187. computed: {
  188. ...mapState("paper-export", [
  189. "topics",
  190. "pages",
  191. "curElement",
  192. "curPage",
  193. "curPageNo",
  194. ]),
  195. },
  196. mounted() {
  197. this.initCard();
  198. },
  199. beforeDestroy() {
  200. this.initState();
  201. },
  202. methods: {
  203. ...mapMutations("paper-export", [
  204. "addPage",
  205. "setCurPage",
  206. "setCurElement",
  207. "setOpenElementEditDialog",
  208. "setCurDragElement",
  209. "setPages",
  210. "setTopics",
  211. "initState",
  212. ]),
  213. ...mapActions("paper-export", [
  214. "addElement",
  215. "modifyElement",
  216. "rebuildPages",
  217. "initTopicsFromPages",
  218. ]),
  219. initCard() {
  220. const { pages } = this.content;
  221. if (pages && pages.length) {
  222. this.setPages(pages);
  223. this.initTopicsFromPages();
  224. this.setCurPage(0);
  225. } else {
  226. this.initPageData();
  227. }
  228. },
  229. initPageData() {
  230. this.setPages([getPageModel(), getPageModel()]);
  231. this.setCurPageNo(0);
  232. },
  233. addNewTopic(type) {
  234. let element = getElementModel(type);
  235. element.w = document.getElementById("topic-column").offsetWidth;
  236. this.addElement(element);
  237. },
  238. // 元件编辑
  239. dragstart(element) {
  240. this.setCurDragElement(getElementModel(element.type));
  241. },
  242. // 切换正反页
  243. swithPage(pindex) {
  244. if (this.curPageNo === pindex) return;
  245. this.setCurPage(pindex);
  246. this.setCurElement({});
  247. },
  248. getTemplateJson() {
  249. return new Promise((resolve) => {
  250. setTimeout(() => {
  251. const data = JSON.stringify(
  252. {
  253. pages: this.pages,
  254. },
  255. (k, v) => (k.startsWith("_") ? undefined : v)
  256. );
  257. resolve(data);
  258. }, 100);
  259. });
  260. },
  261. toSubmit() {
  262. if (this.isSubmit) return;
  263. this.$emit("on-submit", {
  264. pages: this.pages,
  265. });
  266. },
  267. toExit() {
  268. this.$emit("on-exit");
  269. },
  270. loading() {
  271. this.isSubmit = true;
  272. },
  273. unloading() {
  274. this.isSubmit = false;
  275. },
  276. },
  277. };
  278. </script>