Prechádzať zdrojové kódy

模版试卷构建完成

zhangjie 2 rokov pred
rodič
commit
51e4d5e3c6

+ 4 - 0
src/modules/paper-export/assets/styles/paper-temp-design.scss

@@ -18,4 +18,8 @@
       border: 1px dashed #333;
     }
   }
+
+  .page-column-element .element-item::before {
+    border: 1px dashed #333;
+  }
 }

+ 23 - 6
src/modules/paper-export/assets/styles/paper-temp-preview.scss

@@ -1,4 +1,12 @@
 .paper-page {
+  color: #000;
+  &.is-view {
+    .page-box {
+      margin-top: 10px;
+      margin-bottom: 10px;
+    }
+  }
+
   .page-box {
     &-A3 {
       &.page-box-0 {
@@ -18,7 +26,7 @@
           }
         }
         .page-column-side {
-          right: 40px;
+          right: 10px;
           left: auto;
         }
       }
@@ -29,7 +37,7 @@
         top: 40px;
         bottom: 40px;
         width: 110px;
-        left: 20px;
+        left: 10px;
       }
 
       &.page-box-0 {
@@ -48,20 +56,25 @@
           }
         }
         .page-column-side {
-          right: 20px;
+          right: 10px;
           top: 40px;
           left: auto;
         }
       }
     }
+
+    .page-column-body {
+      word-wrap: normal;
+      white-space: normal;
+    }
   }
 
   .page-column-side {
     position: absolute;
     top: 60px;
     bottom: 60px;
-    width: 120px;
-    left: 40px;
+    width: 130px;
+    left: 10px;
     z-index: 10;
 
     .column-side-body {
@@ -79,7 +92,7 @@
   }
 
   .page-column-element .element-item::before {
-    border: 1px dashed #333;
+    border: none;
   }
 }
 
@@ -103,3 +116,7 @@
     }
   }
 }
+.elem-rich-text {
+  display: inline-block;
+  white-space: pre-wrap;
+}

+ 2 - 2
src/modules/paper-export/components/PaperTemplateDesign.vue

@@ -107,7 +107,7 @@
                   <div class="page-column-body">
                     <topic-element-edit
                       v-for="element in column.elements"
-                      :key="element.id"
+                      :key="element.key"
                       class="page-column-element"
                       :data-h="element.h"
                       :data="element"
@@ -155,7 +155,7 @@
                   <!-- topic element -->
                   <topic-element-preview
                     v-for="element in topics"
-                    :key="element.id"
+                    :key="element.key"
                     class="page-column-element"
                     :data="element"
                   ></topic-element-preview>

+ 1 - 1
src/modules/paper-export/components/PaperTemplateView.vue

@@ -5,7 +5,7 @@
         :key="pageNo"
         :class="[
           'page-box',
-          `page-box-${cardConfig.pageSize}`,
+          `page-box-${page.pageSize}`,
           `page-box-${pageNo % 2}`,
         ]"
       >

+ 1 - 1
src/modules/paper-export/components/TopicElementPreview.vue

@@ -6,7 +6,7 @@
       :data-type="data.type"
       :style="styles"
     >
-      <component :is="compName" :data="data" preview></component>
+      <component :is="compName" :data="data"></component>
     </div>
   </div>
 </template>

+ 1 - 1
src/modules/paper-export/elements/page/model.js

@@ -10,7 +10,7 @@ const MODEL = {
   type: "PAGE",
   pageSize: "A3",
   columnNumber: 2,
-  columnGap: 20,
+  columnGap: 40,
   showPageNo: true,
   showSide: true,
   sides: [],

+ 13 - 2
src/modules/paper-export/elements/pane-box/ElemPaneBox.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="elem-pane-box">
-    <div ref="ElemBody" class="elem-body">
+    <div class="elem-body" :style="bodyStyle">
       <!-- 子元件区域 -->
       <div class="elem-pane-box-elements">
         <box-element-preview
@@ -31,7 +31,18 @@ export default {
     },
   },
   data() {
-    return {};
+    return {
+      bodyStyle: {},
+    };
+  },
+  mounted() {
+    let bodyStyle = {
+      height: this.data.h + "px",
+    };
+    if (this.data.borderStyle !== "none") {
+      bodyStyle.border = `1px ${this.data.borderStyle} #333`;
+    }
+    this.bodyStyle = bodyStyle;
   },
   methods: {},
 };

+ 5 - 1
src/modules/paper-export/elements/pane-box/ElemPaneBoxEdit.vue

@@ -77,9 +77,13 @@ export default {
     ...mapActions("paper-export", ["rebuildPages", "modifyElementChild"]),
     modifyBodyStyle() {
       this.$nextTick(() => {
-        this.bodyStyle = {
+        let bodyStyle = {
           height: this.data.h + "px",
         };
+        if (this.data.borderStyle !== "none") {
+          bodyStyle.border = `1px ${this.data.borderStyle} #333`;
+        }
+        this.bodyStyle = bodyStyle;
       });
     },
     dropInnerElement(e) {

+ 89 - 34
src/modules/paper-export/views/PaperTemplateBuild.vue

@@ -1,8 +1,8 @@
 <template>
-  <div class="paper-template-build card-view paper-page">
+  <div class="paper-template-build">
     <paper-template-view
       ref="PaperTemplateView"
-      class="preview-body"
+      :class="['preview-body', { 'is-view': isViewMode }]"
       :pages="pages"
     ></paper-template-view>
   </div>
@@ -28,6 +28,7 @@ const checkRichTextHasCont = function (data) {
   if (!data.sections || !data.sections.length) return false;
 
   if (!data.sections[0].blocks || !data.sections[0].blocks.length) return false;
+
   return true;
 };
 
@@ -37,6 +38,8 @@ export default {
   data() {
     return {
       paperId: this.$route.params.paperId,
+      viewType: this.$route.params.viewType || "view",
+      renderStructList: [],
       pages: [],
       paperJson: {},
       paperTempJson: [],
@@ -44,12 +47,20 @@ export default {
       maxColumnHeight: 200,
     };
   },
+  computed: {
+    isViewMode() {
+      return this.viewType === "view";
+    },
+  },
+  mounted() {
+    this.initData();
+  },
   methods: {
     async initData() {
       // todo: get data
       this.paperJson = paperJson;
       this.paperTempJson = paperTempJson;
-      this.pages = paperTempJson.papes;
+      this.pages = paperTempJson.pages;
       this.$nextTick(() => {
         this.buildData();
       });
@@ -60,8 +71,8 @@ export default {
       this.parseRenderStructList();
       this.buildPrePages();
 
-      const loadres = await this.waitAllImgLoaded().catch(() => {});
-      if (!loadres) {
+      const loadRes = await this.waitAllImgLoaded().catch(() => {});
+      if (!loadRes) {
         this.$message.error("图片加载有误!");
         return;
       }
@@ -81,18 +92,18 @@ export default {
         detail.paperDetailUnits.forEach((question) => {
           let questionInfo = question.question;
           if (questionInfo.subQuestions && questionInfo.subQuestions.length) {
-            const bodys = this.parseTitleOption(question.quesBody, "");
+            const bodys = this.parseTitleOption(questionInfo.quesBody, "");
             renderStructList.push(...bodys);
 
-            const isMatches = this.checkIsMatches(question.questionType);
+            const isMatches = this.checkIsMatches(questionInfo.questionType);
             if (
               isMatches &&
               questionInfo.quesOptions &&
               questionInfo.quesOptions.length
             ) {
-              question.quesOptions.forEach((op) => {
+              questionInfo.quesOptions.forEach((op) => {
                 const obodys = this.parseTitleOption(
-                  op.body,
+                  op.optionBody,
                   `${numberToUpperCase(op.number)}、`,
                   "option"
                 );
@@ -100,8 +111,14 @@ export default {
               });
             }
 
+            // 选词填空不展示小题
+            if (questionInfo.questionType === "BANKED_CLOZE") {
+              renderStructList.push(this.parseLineGap());
+              return;
+            }
+
             questionInfo.subQuestions.forEach((sq) => {
-              if (isMatches) sq.quesOptions = [];
+              if (isMatches) sq.quesOptions = []; // 选词填空、段落匹配小题中不展示选项
               const contents = this.parseSimpleQuestion(sq, false);
               renderStructList.push(...contents);
               if (!isMatches) renderStructList.push(this.parseLineGap());
@@ -110,8 +127,8 @@ export default {
             questionInfo.number = question.number;
             const datas = this.parseSimpleQuestion(questionInfo, true);
             renderStructList.push(...datas);
-            renderStructList.push(this.parseLineGap());
           }
+          renderStructList.push(this.parseLineGap());
         });
       });
 
@@ -162,15 +179,15 @@ export default {
       let contents = [];
 
       const tbodys = this.parseTitleOption(
-        question.body,
-        isCommon ? `${question.number}、` : `${question.subNumber}`
+        question.quesBody,
+        isCommon ? `${question.number}、` : `${question.subNumber}`
       );
       contents.push(...tbodys);
 
       if (question.quesOptions && question.quesOptions.length) {
         question.quesOptions.forEach((op) => {
           const obodys = this.parseTitleOption(
-            op.body,
+            op.optionBody,
             `${numberToUpperCase(op.number)}、`,
             "option"
           );
@@ -180,10 +197,12 @@ export default {
       return contents;
     },
     parseDetailTitle(data) {
-      let content = this.getRichStruct({
-        type: "text",
-        value: `${data.cnNum}、${data.name}`,
-      });
+      let content = this.getRichStruct([
+        {
+          type: "text",
+          value: `${data.cnNum}、${data.name}`,
+        },
+      ]);
       return getRichTextModel({
         styles: { width: "100%", fontWeight: 600 },
         content,
@@ -193,7 +212,7 @@ export default {
       if (!richJson) return [];
       const bodys = this.transformRichJson(richJson);
 
-      return bodys.forEach((body, index) => {
+      return bodys.map((body, index) => {
         if (index === 0 && noVal) {
           body.sections[0].blocks.unshift({
             type: "text",
@@ -201,18 +220,18 @@ export default {
           });
         }
 
-        return this.getRichTextModel({
+        return getRichTextModel({
           contType,
-          styles: { width: "100%" },
+          styles: { width: contType !== "option" ? "100%" : "auto" },
           content: body,
         });
       });
     },
     parseLineGap() {
-      return this.getRichTextModel({
+      return getRichTextModel({
         contType: "gap",
         styles: { width: "100%", height: "20px" },
-        content: this.getRichStruct({ type: "text", value: "" }),
+        content: this.getRichStruct([{ type: "text", value: "" }]),
       });
     },
     checkIsMatches(structType) {
@@ -220,14 +239,15 @@ export default {
       return matchesTypes.includes(structType);
     },
     buildPrePages() {
-      let pages = deepCopy(this.paperTempJson);
-      pages[0].columns[0].elements.push(...this.renderStructList);
+      let pages = deepCopy(this.paperTempJson.pages);
+      pages[0].columns[0].texts = [];
+      pages[0].columns[0].texts.push(...this.renderStructList);
       this.pages = pages;
     },
 
     buildReleasePages() {
       this.resetRenderStructSize();
-      this.autoPage();
+      this.buildPageAutoPage();
     },
     resetRenderStructSize() {
       let curOptions = [];
@@ -278,7 +298,7 @@ export default {
         curOptions = [];
       });
     },
-    autoPage() {
+    buildPageAutoPage() {
       let pages = [];
       let curPage = null,
         curElem = null;
@@ -306,34 +326,61 @@ export default {
           curElem.contType !== "option" ||
           (curElem.contType === "option" && curElem._percent === 1)
         ) {
+          // 非选项,单独占整行
           curLinePercent = 1;
           if (curElem.h + curColumnHeight > this.maxColumnHeight) {
             // 当前栏满了
+            if (curColumnNo >= curPage.columnNumber) {
+              // 当前页满了
+              pages.push(curPage);
+              curPage = null;
+              curColumnNo = null;
+            }
+            curColumn = null;
+            curColumnHeight = 0;
           } else {
-            // 未满
-            curColumn.push(curElem);
+            // 当前栏未满
+            curColumnHeight += curElem.h;
+            curColumn.texts.push(curElem);
             curElem = getNextElem();
           }
         } else {
+          // 选项的处理
           if (curLinePercent + curElem._percent > 1) {
-            // 放下一行
+            // 行满了,放下一行
             if (curElem.h + curColumnHeight > this.maxColumnHeight) {
               curLinePercent = 1;
               // 当前栏满了
+              if (curColumnNo >= curPage.columnNumber) {
+                // 当前页满了
+                pages.push(curPage);
+                curPage = null;
+                curColumnNo = null;
+              }
+              curColumn = null;
+              curColumnHeight = 0;
             } else {
-              // 未满
+              // 当前栏未满,放下一行
               curLinePercent = curElem._percent;
-              curColumn.push(curElem);
+              curColumnHeight += curElem.h;
+              curColumn.texts.push(curElem);
               curElem = getNextElem();
             }
           } else {
-            // 放当前行
+            // 行未满,放当前行
             curLinePercent += curElem._percent;
-            curColumn.push(curElem);
+            curColumn.texts.push(curElem);
             curElem = getNextElem();
           }
         }
       }
+
+      if (curPage) {
+        pages.push(curPage);
+        curPage = null;
+      }
+
+      this.pages = pages;
     },
     getNewPageModel(pageNo) {
       let pNo = pageNo % 2;
@@ -349,8 +396,15 @@ export default {
         let nelem = deepCopy(elem);
         nelem.id = getElementId();
         nelem.key = randomCode();
+
+        if (pNo === 1 && nelem.type === "GUTTER") {
+          nelem.direction = "right";
+        }
         return nelem;
       });
+      newPage.columns.forEach((column) => {
+        column.texts = [];
+      });
 
       if (pageNo > 1) return newPage;
 
@@ -367,6 +421,7 @@ export default {
           }
           return nelem;
         });
+        column.texts = [];
       });
       return newPage;
     },

+ 94 - 72
src/modules/paper-export/views/data/paper-temp.json

@@ -4,67 +4,70 @@
       "type": "PAGE",
       "pageSize": "A3",
       "columnNumber": 2,
-      "columnGap": 20,
+      "columnGap": 40,
       "showPageNo": true,
       "showSide": true,
       "sides": [
         {
-          "id": "element-as3e4kr8eru0qki8",
-          "key": "r63thvagbn0k3kh8",
+          "id": "element-r947rqn8jbjlf988",
+          "key": "4qrj0nto89sptfco",
           "type": "TEXT",
-          "x": 18,
-          "y": 7,
-          "w": 63,
-          "h": 192,
+          "x": 13,
+          "y": 19,
+          "w": 87,
+          "h": 179,
           "sign": "",
           "fontWeight": 400,
           "fontFamily": "宋体",
           "fontSize": "14px",
           "color": "#000",
           "mode": "side",
-          "content": [{ "type": "text", "content": "样例内容请注意内容衔接" }],
+          "content": [
+            {
+              "type": "text",
+              "content": "样例内容阿斯加德发觉阿帆卡拉胶金卡价啊发卡机咖啡机啊咖啡机啊氪金大佬咖啡机阿拉基发卡送达方"
+            }
+          ],
+          "contentStr": "样例内容阿斯加德发觉阿帆卡拉胶金卡价啊发卡机咖啡机啊咖啡机啊氪金大佬咖啡机阿拉基发卡送达方",
           "zindex": 9,
-          "init": false,
-          "_edit": true,
-          "_side": true,
-          "contentStr": "样例内容请注意内容衔接"
+          "init": false
+        },
+        {
+          "type": "GUTTER",
+          "x": 98,
+          "y": 0,
+          "w": 32,
+          "h": 1002,
+          "content": "装订线",
+          "direction": "left",
+          "id": "element-fkqshn2o31aj2028",
+          "key": "vuq63d6ga12erp1f",
+          "zindex": 9,
+          "init": false
         },
         {
           "type": "FILL_FIELD",
-          "x": 0,
-          "y": 497,
-          "w": 40,
-          "h": 489,
+          "x": 7,
+          "y": 465,
+          "w": 30,
+          "h": 522,
           "sign": "",
           "fieldCountPerLine": 2,
           "lineSpacing": 30,
           "nameIsJustify": false,
           "fields": "姓名,学号",
           "mode": "side",
-          "id": "element-1lm51osihtdhnc1o",
-          "key": "o10dn2n8br85kjdo",
+          "id": "element-ph34uhqosel71k9g",
+          "key": "4i9082r8tk5nnpb8",
           "zindex": 9,
           "init": false,
           "_edit": true,
           "_side": true
-        },
-        {
-          "type": "GUTTER",
-          "x": 85,
-          "y": 0,
-          "w": 35,
-          "h": 1002,
-          "content": "装订线",
-          "direction": "left",
-          "id": "element-j63lg138d65iaua8",
-          "key": "baklghqog0pnofl3",
-          "zindex": 9,
-          "init": false
         }
       ],
       "columns": [
         {
-          "id": "column-o4funrkole78hur8",
+          "id": "column-un4g3pbgfrm9t0a8",
           "type": "COLUMN",
           "x": "",
           "y": "",
@@ -73,22 +76,22 @@
           "isFull": false,
           "elements": [
             {
-              "id": "element-2q6h0lcoi8k0uc3g",
-              "key": "hvlqujgt0hvtn4eo",
+              "id": "element-branch1o2tea17i8",
+              "key": "ci36kgrosn17qvr8",
               "type": "PANE_BOX",
               "x": 0,
               "y": 0,
               "w": 683,
-              "h": 273,
+              "h": 200,
               "borderStyle": "none",
               "elements": [
                 {
-                  "id": "element-ijdkepug1v4e8alg",
-                  "key": "qhtuu8bnhbrjjm7g",
+                  "id": "element-rt95tr755q772638",
+                  "key": "vou1hs9guci381ug",
                   "type": "TEXT",
-                  "x": 246,
-                  "y": 3,
-                  "w": 170,
+                  "x": 272,
+                  "y": 154,
+                  "w": 144,
                   "h": 30,
                   "sign": "",
                   "fontWeight": 400,
@@ -97,23 +100,24 @@
                   "color": "#000",
                   "mode": "normal",
                   "content": [
-                    { "type": "text", "content": "2023学年期末考试-数学" }
+                    { "type": "text", "content": "样例内容很 阿打发" }
                   ],
                   "container": {
-                    "id": "element-2q6h0lcoi8k0uc3g",
+                    "id": "element-branch1o2tea17i8",
                     "type": "PANE_BOX"
                   },
                   "zindex": 9,
                   "init": false,
-                  "contentStr": "2023学年期末考试-数学"
+                  "_edit": true,
+                  "_side": false,
+                  "contentStr": "样例内容很 阿打发"
                 }
               ],
-              "isCovered": false,
-              "init": false
+              "isCovered": false
             },
             {
-              "id": "element-pfd0g4tgbjm4mn38",
-              "key": "cvc3k59o0pq1tfvg",
+              "id": "element-oq0h1ps8ufp37et8",
+              "key": "i0cnu0dgonga6q0o",
               "type": "PANE_BOX",
               "x": 0,
               "y": 0,
@@ -122,13 +126,13 @@
               "borderStyle": "none",
               "elements": [
                 {
-                  "id": "element-hr6lqsdgtpl5r4gk",
-                  "key": "9948sdfg87b3nlio",
+                  "id": "element-82jbqhcgtc1coq1g",
+                  "key": "e8ed5h78j15e372o",
                   "type": "TEXT",
-                  "x": 192,
-                  "y": 160,
-                  "w": 320,
-                  "h": 30,
+                  "x": 249,
+                  "y": 18,
+                  "w": 200,
+                  "h": 50,
                   "sign": "",
                   "fontWeight": 400,
                   "fontFamily": "宋体",
@@ -136,27 +140,45 @@
                   "color": "#000",
                   "mode": "normal",
                   "content": [
-                    {
-                      "type": "text",
-                      "content": "样例内容很长的问题自动卡达克看看风景啊咖啡机"
-                    }
+                    { "type": "text", "content": "样例内容剪短发康师傅" }
                   ],
                   "container": {
-                    "id": "element-pfd0g4tgbjm4mn38",
+                    "id": "element-oq0h1ps8ufp37et8",
                     "type": "PANE_BOX"
                   },
                   "zindex": 9,
                   "init": false,
-                  "contentStr": "样例内容很长的问题自动卡达克看看风景啊咖啡机"
+                  "contentStr": "样例内容剪短发康师傅"
+                },
+                {
+                  "id": "element-9c7l69p88dpliud8",
+                  "key": "ffun4p7og54bvi1o",
+                  "type": "LINES",
+                  "x": 249,
+                  "y": 122,
+                  "w": 200,
+                  "h": 59,
+                  "sign": "",
+                  "lineCount": 3,
+                  "lineSpacing": 20,
+                  "margin": 0,
+                  "bold": "1px",
+                  "color": "#000000",
+                  "style": "solid",
+                  "container": {
+                    "id": "element-oq0h1ps8ufp37et8",
+                    "type": "PANE_BOX"
+                  },
+                  "zindex": 9,
+                  "init": false
                 }
               ],
-              "isCovered": false,
-              "init": false
+              "isCovered": false
             }
           ]
         },
         {
-          "id": "column-msg772k5uap0253o",
+          "id": "column-n8plgn7oodmt0iro",
           "type": "COLUMN",
           "x": "",
           "y": "",
@@ -166,33 +188,33 @@
           "elements": []
         }
       ],
-      "id": "element-4fo8hdl8a4rcere1"
+      "id": "element-4rbh6g7jvnta8f8o"
     },
     {
       "type": "PAGE",
       "pageSize": "A3",
       "columnNumber": 2,
-      "columnGap": 20,
+      "columnGap": 40,
       "showPageNo": true,
       "showSide": true,
       "sides": [
         {
           "type": "GUTTER",
-          "x": 0,
+          "x": 1,
           "y": 0,
-          "w": 34,
-          "h": 1002,
+          "w": 30,
+          "h": 999,
           "content": "装订线",
           "direction": "left",
-          "id": "element-hkvqv2fbkk88nato",
-          "key": "b6107ianogg9qqmo",
+          "id": "element-afafmegrb2ugbkug",
+          "key": "r24k6ii8jagsct78",
           "zindex": 9,
           "init": false
         }
       ],
       "columns": [
         {
-          "id": "column-89ihnbt8q4e4chkg",
+          "id": "column-qj04p96ggo1j4spg",
           "type": "COLUMN",
           "x": "",
           "y": "",
@@ -202,7 +224,7 @@
           "elements": []
         },
         {
-          "id": "column-tlfhl6d8ilhdsee6",
+          "id": "column-aikvo5eo2k893c18",
           "type": "COLUMN",
           "x": "",
           "y": "",
@@ -212,7 +234,7 @@
           "elements": []
         }
       ],
-      "id": "element-q14jm8gljpitt4mg"
+      "id": "element-q6kkciuoabbfjbig"
     }
   ]
 }