Explorar el Código

feat:答案导出

zhangjie hace 6 meses
padre
commit
a36dcd0f2e

+ 120 - 178
src/modules/paper-export/components/AnswerTemplateView.vue

@@ -1,70 +1,50 @@
 <template>
   <div class="paper-template-view answer-template-view card-view paper-page">
-    <div v-for="(singlePageData, index) in flatData" :key="index">
-      <div class="page-box page-box-A4 page-box-answer page-answer-flat">
+    <template v-for="(singlePageData, pindex) in pageList">
+      <div
+        class="page-box page-box-A4 page-box-answer page-answer-flat"
+        :key="pindex"
+      >
         <div class="page-main-inner" style="font-size: 14px">
-          <div v-for="(row, i) in singlePageData || []" :key="i">
-            <div v-if="row.type == 'bigTitle'" class="is-detail-title">
-              {{ row.number | numberToChaineseFilter }}、{{ row.name }}
+          <div
+            v-for="(row, rindex) in singlePageData"
+            :key="rindex"
+            :class="['origin-item', { 'is-detail-title': row.isDetail }]"
+          >
+            <template v-if="row.isDetail">
+              {{ row.serialNo | numberToChaineseFilter }}、{{ row.name }}
               {{ row.title }}
-            </div>
-            <div v-else>
-              <span>{{ row.questionSeq + ". " }}</span>
+            </template>
+            <template v-else>
+              <span>{{ row.serialNo + ". " }}</span>
               <question-answer :data="row"></question-answer>
-            </div>
+            </template>
           </div>
           <page-number
             type="text"
-            :rule="getPageNumberCont(index + 1)"
+            :total="pageList.length"
+            :current="pindex + 1"
           ></page-number>
         </div>
       </div>
-    </div>
+    </template>
 
     <div class="page-box page-box-A4 page-box-answer origin-view">
       <div class="page-main-inner">
-        <!-- {{ flatData }} -->
-        <div v-for="(big, index) in paperDetails" :key="index">
-          <div
-            class="is-detail-title"
-            v-domObserver="
-              (top) => {
-                getDomTop(top, index);
-              }
-            "
-          >
-            {{ big.number | numberToChaineseFilter }}、{{ big.name }}
-            {{ big.title }}
-          </div>
-          <div v-for="(small, i) in big.paperDetailUnits" :key="i">
-            <div
-              v-if="!small.question.subQuestions"
-              v-domObserver="
-                (top) => {
-                  getDomTop(top, index, i);
-                }
-              "
-            >
-              <span>{{ small.question.questionSeq + ". " }}</span>
-              <question-answer :data="small.question"></question-answer>
-            </div>
-
-            <template v-if="small.question.subQuestions">
-              <div
-                v-for="(innerQuestion, innerIndex) in small.question
-                  .subQuestions"
-                :key="innerIndex"
-                v-domObserver="
-                  (top) => {
-                    getDomTop(top, index, i, innerIndex);
-                  }
-                "
-              >
-                <span>{{ innerQuestion.questionSeq + ". " }}</span>
-                <question-answer :data="innerQuestion"></question-answer>
-              </div>
-            </template>
-          </div>
+        <div
+          v-for="(row, index) in allList"
+          :key="index"
+          :class="['origin-item', { 'is-detail-title': row.isDetail }]"
+          :id="row.id"
+        >
+          <template v-if="row.isDetail">
+            {{ row.serialNo | numberToChaineseFilter }}、{{ row.name }}
+            {{ row.title }}
+          </template>
+          <template v-else>
+            <span>{{ row.serialNo + ". " }}</span>
+            <question-answer :data="row"></question-answer>
+          </template>
         </div>
       </div>
     </div>
@@ -74,7 +54,7 @@
 <script>
 import PageNumber from "./PageNumber";
 import QuestionAnswer from "../../question/components/QuestionAnswer.vue";
-import { cloneDeep } from "lodash";
+
 export default {
   name: "AnswerTemplateView",
   components: {
@@ -82,12 +62,6 @@ export default {
     QuestionAnswer,
   },
   props: {
-    pageConfig: {
-      type: Object,
-      default() {
-        return {};
-      },
-    },
     answerData: {
       type: Object,
       default() {
@@ -98,135 +72,103 @@ export default {
       type: String,
     },
   },
-  computed: {
-    paperDetails() {
-      return this.answerData?.paperDetails || [];
-    },
-    //数据扁平化,便于高度计算
-    flatData() {
-      let arr = [[]];
-      const limitHeight = 976;
-      let usedPageIndex = 0;
-      let computedHeight = 0;
-      let paperDetailsWithTop = cloneDeep(this.paperDetailsWithTop);
-      for (let i = 0; i < paperDetailsWithTop.length; i++) {
-        let cloneBig = cloneDeep(paperDetailsWithTop[i]);
-        let { top, height } = cloneBig; //大题标题的尺寸数据
-        if (computedHeight + top + height > limitHeight) {
-          usedPageIndex++;
-          arr[usedPageIndex] = [];
-          computedHeight = top + height;
-        } else {
-          computedHeight += top + height;
-        }
-        arr[usedPageIndex].push({
-          type: "bigTitle",
-          name: cloneBig.name,
-          title: cloneBig.title,
-          number: cloneBig.number,
-        });
-        if (cloneBig.paperDetailUnits?.length) {
-          for (let j = 0; j < cloneBig.paperDetailUnits.length; j++) {
-            let unit = cloneBig.paperDetailUnits[j];
-            let question = unit.question;
-            let { top, height } = unit; //大题标题的尺寸数据
-            if (!question.subQuestions) {
-              //无套题的小题尺寸数据
-              if (computedHeight + top + height > limitHeight) {
-                usedPageIndex++;
-                arr[usedPageIndex] = [];
-                computedHeight = top + height;
-              } else {
-                computedHeight += top + height;
-              }
-              arr[usedPageIndex].push({
-                type: "subQuestion",
-                ...cloneDeep(question),
-              });
-            } else {
-              for (let x = 0; x < question.subQuestions.length; x++) {
-                let innerQuestion = question.subQuestions[x];
-                let { top, height } = innerQuestion;
-                if (computedHeight + top + height > limitHeight) {
-                  usedPageIndex++;
-                  arr[usedPageIndex] = [];
-                  computedHeight = top + height;
-                } else {
-                  computedHeight += top + height;
-                }
-                arr[usedPageIndex].push({
-                  type: "innerQuestion",
-                  ...cloneDeep(innerQuestion),
-                });
-              }
-            }
-          }
-        }
-      }
-      if (arr.length % 2 != 0 && this.pageCountMode === "DOUBLE") {
-        arr.push([]);
-      }
-      return arr;
-    },
-  },
   data() {
     return {
-      paperDetailsWithTop: [],
-      // computedPages: [],
+      pageList: [],
+      allList: [],
     };
   },
   watch: {
-    answerData(val) {
-      let arr = cloneDeep(val?.paperDetails || []);
-      this.paperDetailsWithTop = arr.map((detail) => {
-        detail.position = { top: 0, height: 0 };
-        if (detail.paperDetailUnits?.length) {
-          detail.paperDetailUnits = detail.paperDetailUnits.map((unit) => {
-            unit.position = { top: 0, height: 0 };
-            let question = unit.question;
-            if (question.subQuestions?.length) {
-              question.subQuestions = question.subQuestions.map((subQues) => {
-                subQues.position = { top: 0, height: 0 };
-                return subQues;
-              });
-            }
-            return unit;
-          });
-        }
-        return detail;
-      });
+    answerData() {
+      this.initData();
     },
   },
+  mounted() {
+    this.initData();
+  },
   methods: {
-    created() {},
-    mounted() {},
-    getDomTop(position, index, subIndex, innerIndex) {
-      let arr = cloneDeep(this.paperDetailsWithTop);
-      if (subIndex == undefined && innerIndex == undefined) {
-        arr[index].position = {
-          top: position.top - 40,
-          height: position.height,
-        };
+    initData() {
+      if (!this.answerData) return;
+
+      this.updateAllList();
+      this.$nextTick(() => {
+        this.autoPage();
+        this.$nextTick(() => {
+          this.$emit("rend-finished");
+        });
+      });
+    },
+    updateAllList() {
+      const paperDetails = this.answerData?.paperDetails || [];
+      if (!paperDetails.length) {
+        this.allList = [];
+        return;
       }
-      if (subIndex) {
-        if (innerIndex == undefined) {
-          arr[index]["paperDetailUnits"][subIndex].position = {
-            top: position.top - 40,
-            height: position.height,
-          };
-        } else {
-          arr[index]["paperDetailUnits"][subIndex]["question"]["subQuestions"][
-            innerIndex
-          ].position = {
-            top: position.top - 40,
-            height: position.height,
-          };
+
+      const allList = [];
+      paperDetails.forEach((detail) => {
+        if (!detail.paperDetailUnits?.length) {
+          return;
         }
-      }
-      this.paperDetailsWithTop = arr;
+
+        allList.push({
+          id: `detail-${detail.number}`,
+          isDetail: true,
+          serialNo: detail.number,
+          name: detail.name,
+          title: detail.title,
+        });
+
+        detail.paperDetailUnits.forEach((unit) => {
+          const question = unit.question;
+          if (question.subQuestions?.length) {
+            question.subQuestions.forEach((subQues) => {
+              allList.push({
+                id: `question-${detail.number}-${question.questionSeq}-${subQues.questionSeq}`,
+                isDetail: false,
+                serialNo: subQues.questionSeq,
+                questionType: subQues.questionType,
+                quesAnswer: subQues.quesAnswer,
+              });
+            });
+            return;
+          }
+
+          allList.push({
+            id: `question-${detail.number}-${question.questionSeq}`,
+            isDetail: false,
+            serialNo: question.questionSeq,
+            questionType: question.questionType,
+            quesAnswer: question.quesAnswer,
+          });
+        });
+      });
+
+      this.allList = allList;
+      // console.log(allList);
     },
-    getPageNumberCont(pageNo) {
-      return `第${pageNo}页 共${this.flatData.length}页`;
+    autoPage() {
+      const pageList = [[]];
+      const limitHeight = 976;
+      let usedPageIndex = 0;
+      let computedHeight = 0;
+      this.allList.forEach((item) => {
+        const itemDom = document.getElementById(item.id);
+        const height = itemDom.offsetHeight;
+        if (computedHeight + height > limitHeight) {
+          usedPageIndex++;
+          pageList[usedPageIndex] = [];
+          computedHeight = 0;
+        }
+        computedHeight += height;
+        pageList[usedPageIndex].push(item);
+      });
+      if (pageList.length % 2 !== 0 && this.pageCountMode === "DOUBLE") {
+        pageList.push([]);
+      }
+      // console.log(pageList);
+
+      this.pageList = pageList;
     },
   },
 };

+ 21 - 20
src/modules/paper-export/views/AnswerTemplateBuild.vue

@@ -2,11 +2,13 @@
   <div class="paper-template-build">
     <div class="paper-template-build-body">
       <answer-template-view
+        v-if="paperJson"
         ref="AnswerTemplateView"
         id="answer-template-view"
         class="preview-body"
         :answerData="paperJson"
         :pageCountMode="pageCountMode"
+        @rend-finished="rendFinished"
       ></answer-template-view>
     </div>
   </div>
@@ -25,7 +27,7 @@ export default {
       paperId: this.$route.params.paperId,
       viewType: this.$route.params.viewType,
       seqMode: "MODE3",
-      paperJson: {},
+      paperJson: null,
       maxColumnWidth: 200,
       maxColumnHeight: 200,
       curPaperTemp: {},
@@ -59,26 +61,25 @@ export default {
       } catch (error) {
         this.emitFrameResult(false, "数据错误");
       }
-
-      this.$nextTick(async () => {
-        const answerBlob = await buildPdf(
-          {
-            elements: document
-              .getElementById("answer-template-view")
-              .querySelectorAll(".page-answer-flat"),
-            pageSize: "A4",
-          },
-          true
-        ).catch((error) => {
-          console.error(error);
-        });
-        if (!answerBlob) {
-          this.emitFrameResult(false, "生成答案pdf错误");
-          return;
-        }
-
-        this.emitFrameResult(true, "", answerBlob);
+    },
+    async rendFinished() {
+      const answerBlob = await buildPdf(
+        {
+          elements: document
+            .getElementById("answer-template-view")
+            .querySelectorAll(".page-answer-flat"),
+          pageSize: "A4",
+        },
+        true
+      ).catch((error) => {
+        console.error(error);
       });
+      if (!answerBlob) {
+        this.emitFrameResult(false, "生成答案pdf错误");
+        return;
+      }
+
+      this.emitFrameResult(true, "", answerBlob);
     },
     emitFrameResult(success = true, errorMsg = "", blobCont = null) {
       // console.log("htmlC", htmlCont);