Jelajahi Sumber

答题统计导出

曹冬冬 5 tahun lalu
induk
melakukan
444ee1459b

+ 4 - 1
src/components/HeaderData.vue

@@ -5,7 +5,7 @@
         <span @click="home" style="cursor: pointer;">首页</span> > 数据
       </div>
       <div class="right">
-        <div class="operational-data">下载PDF</div>
+        <div class="operational-data" @click="handleExport">下载PDF</div>
       </div>
     </div>
   </div>
@@ -19,6 +19,9 @@ export default {
   methods: {
     home() {
       this.$router.push({ path: "/" });
+    },
+    handleExport() {
+      this.$parent.goToPreviewPage();
     }
   }
 };

+ 4 - 0
src/routers.js

@@ -49,6 +49,10 @@ const router = new Router({
     path: '/testData',
     name: "testData",
     component: require('./views/testData/testData.vue')
+  }, {
+    path: '/previewPage',
+    name: "previewPage",
+    component: require('./views/previewPage/previewPage.vue')
   }]
 })
 router.beforeEach((to, from, next) => {

+ 2 - 1
src/util/htmlToPdf.js

@@ -3,7 +3,8 @@ import html2Canvas from 'html2canvas'
 import JsPDF from 'jspdf'
 export default {
   install(Vue, options) {
-    Vue.prototype.getPdf = function () {
+    Vue.prototype.$appName = 'My App';
+    Vue.prototype.$getPdf = function () {
       let title = this.htmlTitle
       html2Canvas(document.querySelector('#pdfDom'), {
         allowTaint: true

+ 64 - 0
src/views/previewPage/previewPage.html

@@ -0,0 +1,64 @@
+<div class="content">
+  <div @click="xxxxx" class="dowload"> 下载到本地 </div>
+  <div id="pdfDom" class="pdfContent">
+    <div class="pHeader">
+      <div class="projectTitle">项目答题数据</div>
+      <div class="testList"> <span v-for="(item, index) in options" :key="index">【{{item.label}}】</span></div>
+      <div class="tip">截止到{{currentDate}},问卷共{{answerData.answerJoin || 0}}人参与,完成全部题目的有{{answerData.answerAll || 0}}人。
+      </div>
+    </div>
+    <div class="filterResult" v-if="filterStr">已为您筛选出【{{filterStr}}】共{{answerData.answerAll}}人,此条件下的用户题目答题情况如下:</div>
+    <!-- 答题统计->表格 -->
+    <div class="result" v-if="isShowTable">
+      <div class="resultItem" v-for="(item, index) in answerData.questionList" :key="index">
+        <div class="testLable"
+          v-if="index == 0 || answerData.questionList[index-1].belongTestOrder != answerData.questionList[index].belongTestOrder">
+          测试{{item.belongTestOrder}}:{{item.lable}}</div>
+        <div class="resultTitle"><img v-if="item.isFilter" style="width: 32px;height: 17px;margin-right: 5px;"
+            src="https://dm.static.elab-plus.com/diaoyanbao/%E6%9D%A1%E4%BB%B6%E6%A0%87%E8%AE%B0@2x.png" alt="">
+          题目{{index+1}}:{{item.content}}[{{item.chooseType == '1'? '单选':'多选'}}]<span
+            v-if="item.testOrderList.length">(包含测试<span v-for="(testOrder,textIndex) in item.testOrderList"
+              :key="index">{{testOrder}}<span
+                v-if="textIndex!=(item.testOrderList.length-1)">、</span></span>中的数据)</span></div>
+        <div class="resultTable">
+          <div class="tableHeader">
+            <div class="option">选项</div>
+            <div class="numbers">答题人数</div>
+            <div class="percent">占该题总答题人数百分比</div>
+          </div>
+          <div class="tableRow" v-for="(optionItem, optionIndex) in item.optionList" :key="optionIndex">
+            <div class="option">{{optionItem.content}}</div>
+            <div class="numbers">{{optionItem.answerCount}}</div>
+            <div class="percent">
+              <div style="width: 100%;">
+                <el-progress
+                  :percentage="item.answerTotal==0?0:((optionItem.answerCount/item.answerTotal)*100).toFixed(0)"
+                  color="#4E5DFF" :stroke-width="8">
+                </el-progress>
+              </div>
+            </div>
+          </div>
+          <div class="tableRow">
+            <div class="option">总计</div>
+            <div class="numbers">{{item.answerTotal}}</div>
+            <div class="percent">_ _</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="chart" v-if="!isShowTable">
+      <div class="chartItem" v-for="(item, index) in chartData" :key="index">
+        <div class="chartTitle"><span v-if="item.isFilter"
+            class="filterTag">条件</span>题目{{index+1}}:{{item.content}}[{{item.chooseType == '1'? '单选':'多选'}}]<span
+            v-if="item.testOrderList.length">(包含测试<span v-for="(testOrder,textIndex) in item.testOrderList"
+              :key="index">{{testOrder}}<span
+                v-if="textIndex!=(item.testOrderList.length-1)">、</span></span>中的数据)</span>
+        </div>
+        <div class="chartData">
+          <HistogramHorizontal :id="'c1'" :chartId="'c'+item.questionId" :chart-data="item.data">
+          </HistogramHorizontal>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 32 - 0
src/views/previewPage/previewPage.js

@@ -0,0 +1,32 @@
+import timeFormat from '../../util/time'
+import HistogramHorizontal from "../../components/HistogramHorizontal";
+export default {
+  components: {
+    HistogramHorizontal
+  },
+
+  data() {
+    return {
+      currentDate: null,
+      answerData: null,
+      chartData: null,
+      options: null,
+      filterStr: null,
+      isShowTable: null
+    }
+  },
+  created() {
+    this.chartData = this.$route.params.chartData
+    this.currentDate = this.$route.params.currentDate
+    this.answerData = this.$route.params.answerData
+    this.options = this.$route.params.options
+    this.filterStr = this.$route.params.filterStr
+    this.isShowTable = this.$route.params.isShowTable
+    console.log("xXXXX", this.$route.params);
+  },
+  methods: {
+    xxxxx() {
+      this.$getPdf('exportBox', '测试截屏');
+    }
+  },
+}

+ 218 - 0
src/views/previewPage/previewPage.scss

@@ -0,0 +1,218 @@
+.content {
+  background: #edeff7;
+  padding: 0px;
+}
+.dowload {
+  width:100px;
+  height:30px;
+  background:rgba(78,93,255,1);
+  border-radius:15px;
+  font-size:12px;
+  font-family:STYuanti-SC-Regular,STYuanti-SC;
+  font-weight:400;
+  color:rgba(255,255,255,1);
+  line-height:30px;
+  text-align: center;
+  margin: 0 auto;
+  cursor: pointer;
+  position: fixed;
+  top: 20px;
+  right: 20px;
+}
+.pdfContent {
+  width: 1180px;
+  margin: 0 auto;
+  background: white;
+  .pHeader{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    border-bottom: 1px solid #E8E8E8;
+    .projectTitle {
+      margin-top: 86px;
+      margin-bottom: 16px;
+      font-size:36px;
+      font-family:PingFangSC-Medium,PingFang SC;
+      font-weight:500;
+      color:rgba(51,51,51,1);
+      line-height:50px;
+    }
+    .testList {
+      font-size:18px;
+      font-family:PingFangSC-Regular,PingFang SC;
+      font-weight:400;
+      color:rgba(51,51,51,1);
+      line-height:25px;
+    }
+    .tip {
+      font-size:18px;
+      font-family:PingFangSC-Medium,PingFang SC;
+      font-weight:500;
+      color:rgba(51,51,51,1);
+      line-height:25px;
+      margin-bottom: 23px;
+    }
+  }
+  .filterResult {
+    width: 960px;
+    margin: 0 auto;
+    font-size:14px;
+    font-family:PingFangSC-Regular,PingFang SC;
+    font-weight:400;
+    color:rgba(51,51,51,1);
+    line-height:20px;
+    border-bottom: 1px dashed #E8E8E8;
+    padding-top: 23px;
+    padding-bottom: 15px;
+  }
+  .result {
+    margin-top: 30px;
+    padding: 0px 120px;
+    box-sizing: border-box;
+    .resultItem {
+      margin-top: 36px;
+      padding-bottom: 20px;
+      border-bottom:1px dashed rgba(202,204,210,1);
+      .testLable {
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(78,93,255,1);
+        line-height:25px;
+        margin-bottom: 10px;
+        padding-bottom: 10px;
+        width: 100%;
+        border-bottom: 1px dashed #E8E8E8;
+      }
+      .resultTitle {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:25px;
+      }
+      .resultTable {
+
+        border-radius:4px;
+        border:1px solid rgba(232,232,232,1);
+        margin-top: 8px;
+      }
+      .tableHeader {
+        display: flex;
+        flex-direction: row;
+        height: 32px;
+        background:rgba(250,250,250,1);
+        border-radius:4px 0px 0px 0px;
+        font-size:14px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(0,0,0,0.85);
+        line-height:21px;
+        align-items:flex-end;
+        .option {
+         flex-grow: 2;
+         padding-left: 25px;
+         box-sizing: border-box;
+        }
+        .numbers {
+          width:236px;
+          height: 100%;
+          padding-top: 8px;
+          padding-left: 25px;
+          box-sizing: border-box;
+          border-left:1px solid rgba(232,232,232,1);
+          border-right:1px solid rgba(232,232,232,1);
+        }
+        .percent {
+          width: 408px;
+          padding-left: 25px;
+          box-sizing: border-box;
+        }
+      }
+      .tableRow {
+        display: flex;
+        flex-direction: row;
+        min-height: 32px;
+        font-size:14px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(0,0,0,0.65);
+        line-height:21px;
+        .option {
+         flex-grow: 2;
+         height: 100%;
+         padding-top: 8px;
+         padding-left: 25px;
+         box-sizing: border-box;
+         border-top:1px solid rgba(232,232,232,1);
+        padding: 8px 15px;
+        }
+        .numbers {
+          width:236px;
+          min-height: 100%;
+          padding: 0px 15px;
+          padding-left: 25px;
+          box-sizing: border-box;
+          border-left:1px solid rgba(232,232,232,1);
+          border-right:1px solid rgba(232,232,232,1);
+          border-top:1px solid rgba(232,232,232,1);
+          flex-shrink: 0;
+          display: flex;
+          align-items: center;
+        }
+        .percent {
+          width: 408px;
+          min-height: 100%;
+          padding-left: 25px;
+          box-sizing: border-box;
+          border-top:1px solid rgba(232,232,232,1);
+          flex-shrink: 0;
+          display: flex;
+          align-items: center;
+        }
+      }
+    }
+  }
+  .chart {
+    display: flex;
+    flex-direction: column;
+    margin-top: 30px;
+    padding: 0px 120px;
+    box-sizing: border-box;
+    .chartItem {
+      display: flex;
+      flex-direction: column;
+      .chartTitle {
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:25px;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        .filterTag{
+          display: block;
+          width: 32px;
+          height: 16px;
+          background:rgba(255,106,106,1);
+          border-radius:8px;
+          font-size:12px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(255,255,255,1);
+          line-height:16px;
+          text-align: center;
+          margin-right: 5px;
+        }
+      }
+      .chartData {
+        width: 100%;
+        margin: 10px 0px;
+      }
+    }
+  }
+}

+ 7 - 0
src/views/previewPage/previewPage.vue

@@ -0,0 +1,7 @@
+<template src='./previewPage.html'>
+</template>
+<script src="./previewPage.js">
+</script>
+<style lang="scss">
+@import "./previewPage.scss";
+</style>

+ 18 - 0
src/views/testData/testData.js

@@ -723,6 +723,24 @@ export default {
           console.log("error");
         }
       });
+    },
+    goToPreviewPage() {
+      // let routeUrl = this.$router.resolve({
+      //   name: "previewPage",
+      //   params: { id: 0 }
+      // });
+      // window.open(routeUrl.href, "_blank");
+      this.$router.push({
+        name: 'previewPage',
+        params: {
+          chartData: this.chartData,
+          answerData: this.answerData,
+          currentDate: this.currentDate,
+          options: this.options,
+          filterStr: this.filterStr,
+          isShowTable: this.isShowTable
+        }
+      })
     }