Browse Source

fix: 班级报告

lvkun996 9 months ago
parent
commit
3ddbcbd82c

+ 23 - 7
src/components/exportButton.vue

@@ -1,17 +1,18 @@
 <template>
   <div  class="export-button" v-if="!scrollState" @click="exportHandel" >
-    {{progress === '' ? '导出' : progress + '%'}}
+    <van-icon name="replay" class="ani" v-if="loading" />
+    <div>{{ loading ? '导出中' : '导出'}}</div>
   </div>
 </template>
 <script lang='ts'  setup >
 // @ts-nocheck
  import { withDefaults, ref } from 'vue'
  export interface IProps {
-  progress: string
+  loading: boolance
  }
 
  const props = withDefaults(defineProps<IProps>(), {
-  progress: ''
+  loading: false
  }) 
 
  const emits = defineEmits(['export'])
@@ -43,17 +44,32 @@
 </script>
 <style lang='scss' scoped >
  .export-button {
-    width: 48px;
-    height: 48px;
+ 
+    padding: 8px 10px;
+    padding-left: 20px;
     display: flex;
     justify-content: center;
     align-items: center;
     position: fixed;
-    right: 30px;
+    right: 0px;
     bottom: 100px;
-    border-radius: 50%;
     background-color: #2A69FD;
     color: #fff;
     z-index: 10;
+    box-sizing: border-box;
+    border-top-left-radius: 12px;
+    border-bottom-left-radius: 12px;
+    .ani {
+      animation: ani-rotate 1s infinite;
+      margin-right: 4px;
+    }
+    @keyframes ani-rotate {
+      0% {
+        rotate: 0;
+      }
+      100% {
+        rotate:  360deg;
+      }
+    }
  }
 </style>

+ 6 - 6
src/utils/exportPdf.js

@@ -33,7 +33,7 @@ export const exportPDF = async (_semesterReport, progressCb) => {
     const H1Template = (text) => (
         { text: `${text}`, 
         fontSize: H1, 
-        margin: [0, 40, 0, 4], 
+        margin: [0, 40, 0, 40], 
         color: "blue",  
         bold: true, 
         font: 'STXINGKA.TTF', 
@@ -518,7 +518,7 @@ export const exportTable = (_semesterReport) => {
 }
 
 
-export const exportClazzPDF = async (clazzData) => {
+export const exportClazzPDF = async (clazzData, cb) => {
     const _clazzData = JSON.parse(JSON.stringify(clazzData))
     console.log(_clazzData);
 
@@ -711,17 +711,17 @@ export const exportClazzPDF = async (clazzData) => {
           pdfContent.content = createPdfContent()
 
   
-          // 下载进度回调函数
-        //   const progressCallback = (progress) => progressCb(progress)
+        // 下载进度回调函数
+          const progressCallback = (progress) => cb(progress)
   
-        //   pdfMake.setProgressCallback(progressCallback);
+          pdfMake.setProgressCallback(progressCallback);
   
           if (getRunPlatform() === 'app') {
               pdfMake.createPdf(pdfContent).getBase64().then(data => {
                   callAppFc('saveFile', {
                       fileName: _clazzData.baseData.schoolName + new Date().getTime() + '.pdf', 
                       data: `data:application/pdf;base64,` + data, 
-                      callback: () => { }}
+                      callback: () => {}}
                   )
               })
           } else {

+ 37 - 85
src/views/customize/ClazzReport.vue

@@ -119,18 +119,21 @@
                 :class="['total-table-item-cell', index === 0 ? 'total-table-item-title border-white' : '']"
                 v-for="(item, index) in tableData.record.data" 
                 :key="index"
-                style="padding: 8px;"
               >
                 {{item}}
               </div>
             </div>
             <div  class="total-table-item"  >
-              <div class="performances-title border-white">
+              <div class="performances-title">
                 观察进阶
               </div>
               <div class="performances-item-content" >
                 <div class="performances-item-conten-card" v-for="(item, index) in  tableData.performances.data" :key="index">
-                  <div :style="{height: index === 0 ? '20px' : '40px'}" :class="['total-table-item-cell-small', index === 0 ? 'border-white performances-subtitle': '']"  v-for="(_, index) in item" :key="index"  >
+                  <div 
+                    :class="['total-table-item-cell-small', index === 0 ? 'border-white performances-subtitle first-cell': '']"  
+                    v-for="(_, index) in item" 
+                    :key="index"
+                    >
                     {{_}}
                   </div>
                 </div>
@@ -150,7 +153,7 @@
     </div>
 
     <!-- 导出 -->
-    <export-button  @export="exportReport" />
+    <export-button  @export="exportReport"  :loading="loading" />
   </div>
 </template>
 <script lang='ts'  setup >
@@ -233,7 +236,13 @@ const { p } = useRoute().query;
   },
   xAxis: {
     type: 'value',
-    boundaryGap: [0, 0.01]
+    boundaryGap: [0, 0.01],
+    interval: 1,
+    axisLabel: {
+      formatter: function (value) {
+          return value.toFixed(0); // 保证显示整数
+      }
+    }
   },
   yAxis: {
     type: 'category',
@@ -282,33 +291,37 @@ const { p } = useRoute().query;
 
  
 
+ const loading = ref(false)
 
  const exportReport = () => {
   nextTick(async () => {
+    loading.value = true
     console.log('recordChart:', recordChart);
-
-
     const $par = {
       baseData: baseData.value,
       clazzDomainData: clazzDomainData.value, 
-      clazzSceneData: clazzSceneData.value, 
+      clazzSceneData: clazzSceneData.value,
       studentDomainData: studentDomainData.value,
       clazzDomainChart: recordChart.value.getDataURL(),
       clazzSceneChart: observeChart.value.getDataURL(),
       basePng: await htmlToPng(),
       studentPng: await studentChartHtmlToPng(),
     }
-    exportClazzPDF($par)
+    exportClazzPDF($par, async (progress: number) => {
+      const r = (progress * 100).toFixed(0) 
+      if (r === '100') {
+        loading.value = false
+      }
+    })
   })
 
 }
 
-
  onMounted( async () => {
-  await getAppToken()
-  // await getTestTeachToken()
-  const $par = JSON.parse(decodeURIComponent(atob(p)))
-  // const $par = {"classIds":["1655822889577734146"],"gradeSemesterIds":["00","11","01","-10","-11","20","10","21"],"schoolId":"1304705665728421889","teacherIds":["1450638512771702786","1436187006844682241","1304705367924449281","1711187837184294914","1800414891962654721","1778693522847088641"]}
+  // await getAppToken()
+  await getTestTeachToken()
+  // const $par = JSON.parse(decodeURIComponent(atob(p)))
+  const $par = {"classIds":["1655822889577734146"],"gradeSemesterIds":["00","11","01","-10","-11","20","10","21"],"schoolId":"1304705665728421889","teacherIds":["1450638512771702786","1436187006844682241","1304705367924449281","1711187837184294914","1800414891962654721","1778693522847088641"]}
   getClazzBase($par)
   getClazzDomain($par).then(() => {
 
@@ -477,70 +490,6 @@ const { p } = useRoute().query;
       }
       .total-scene {
         display: flex;
-        .total-table {
-          width: 100%;
-          overflow: hidden;
-          overflow-x: scroll;
-           display: flex;
-           .total-table-item {
-            .performances-title {
-              width: 100%;
-              height: 20px;
-              background-color: rgb(51, 179, 92);
-              color: #fff;
-              display: flex;
-              justify-content: center;
-              align-items: center;
-              border-bottom: 1px solid #fff !important;
-            }
-            .performances-item-content {
-              display: flex;
-              border-top: 1px solid #fff !important;
-              .performances-item-conten-card:last-child {
-                .total-table-item-cell {
-                  border-right: 1px solid #a19d9d;
-                }
-              }
-            }
-            .performances-subtitle {
-              width: 100%;
-              background-color: rgb(51, 179, 92);
-              height: 20px !important;
-              color: #fff;
-              box-sizing: border-box;
-            }
-            .total-table-item-cell {
-              width: 100px;
-              height: 40px;
-              display: flex;
-              flex-direction: column;
-              justify-content: center;
-              align-items: center;
-              border-bottom: 1px solid #a19d9d;
-              border-left: 1px solid #a19d9d;
-              box-sizing: border-box;
-              margin-top: -1px;
-            }
-            .total-table-item-title {
-              width: 100px;
-              height: 40px;
-              background-color: rgb(51, 179, 92);
-              color: #fff;
-              display: flex;
-              justify-content: center;
-              align-items: center;
-              box-sizing: border-box;
-            }
-            .border-white {
-              border-left: 1px solid #fff;
-              border-bottom: 1px solid #fff;
-              border-top: none;
-              box-sizing: border-box;
-              margin-top: 0px;
-            }
-          }
-          
-        }
         .total-table-small {
           width: 100%;
           overflow: hidden;
@@ -556,22 +505,26 @@ const { p } = useRoute().query;
               display: flex;
               justify-content: center;
               align-items: center;
+              border-bottom: 1px solid #fff;
+              border-left: 1px solid #fff;
+              box-sizing: border-box
             }
             .performances-item-content {
               display: flex;
               .performances-item-conten-card {
-                margin-top: 1px;
+                .first-cell {
+                  height: 20px !important;
+                }
                 .total-table-item-cell-small {
                   width: 31px;
-                  // height: 40px;
+                  height: 40px;
                   display: flex;
                   flex-direction: column;
                   justify-content: center;
                   align-items: center;
                   border-bottom: 1px solid #a19d9d;
                   border-left: 1px solid #a19d9d;
-                  box-sizing: border-box;
-                  margin-top: -1px;
+                  box-sizing: border-box !important;
                   text-align: center;
                 }
 
@@ -597,8 +550,8 @@ const { p } = useRoute().query;
               align-items: center;
               border-bottom: 1px solid #a19d9d;
               border-left: 1px solid #a19d9d;
-              box-sizing: border-box;
-              margin-top: -1px;
+              box-sizing: border-box !important;
+              // margin-top: -1px;
               text-align: center;
             }
 
@@ -619,7 +572,6 @@ const { p } = useRoute().query;
               border-bottom: 1px solid #fff !important;
               border-top: none;
               box-sizing: border-box;
-              margin-top: 0px;
             }
           }
           

+ 4 - 6
src/views/customize/SemesterReport.vue

@@ -310,7 +310,7 @@
   <ShareModal :show="shareShow" @close="shareShow = false" />
 
   <!-- 导出 -->
-  <export-button @export="exportReport" :progress="progressRef" :key="progressRef" />
+  <export-button @export="exportReport" :loading="loading"  />
 
 </template>
 
@@ -472,10 +472,10 @@ function getTargetStyle(index: number) {
   return style;
 }
 
-const progressRef = ref('')
+const loading = ref(false)
 
 const exportReport = () => {
-  progressRef.value = '0'
+  loading.value = true
   nextTick(() => {
     // @ts-ignore
     semesterReport.value.radarChartBase64 = radarListDom.value[-1].getDataURL()
@@ -485,13 +485,11 @@ const exportReport = () => {
     })
 
     exportPDF(semesterReport.value, async (progress: number) => {
-
       const r = (progress * 100).toFixed(0) 
       if (r === '100') {
-        progressRef.value = ''
+        loading.value = false
         return
       }
-      progressRef.value  = r
     })
   })
 

+ 23 - 8
src/views/customize/SingleReport.vue

@@ -117,7 +117,11 @@
   <exprotWord ref="exprotWordDom" />
 
    <!-- 导出 -->
-  <export-button v-if="(getIsApp() || getMobileOperatingSystem() === 'iOS')" @export="exportWord" :progress="progressRef"  />
+  <export-button 
+    v-if="(getIsApp() || getMobileOperatingSystem() === 'iOS')" 
+    @export="exportWord" 
+    :loading="loading" 
+  />
 
 </template>
 
@@ -133,7 +137,6 @@ import exportButton from '@/components/exportButton.vue'
 import exprotWord from '@/views/test.vue'
 import { getIsApp } from "@/utils/index.js";
 
-
 const { b: babyId, i: id, p: isParent, o: isMyRoute } = useRoute().query;
 
 const customizeStore = useCustomizeStore();
@@ -143,7 +146,7 @@ const { getSingleRecord, sendSingleRecord, joinSemesterReport } = customizeStore
 const showConfirm = ref(false);
 
 const singleRecord = computed<ISingleRecord>(() => {
-  // return customizeStore.singleRecord;
+  return customizeStore.singleRecord;
   return  {
         "recordId": "1825715384938938369",
         "babyId": "1778357748956053505",
@@ -312,11 +315,12 @@ function getMobileOperatingSystem() {
 
 const exprotWordDom = ref()
 
-const progressRef = ref('')
+const loading = ref(false)
 
 const exportWord = () => {
-    // progressRef.value = '0'
-  exprotWordDom.value.exportWordDocx({
+  loading.value = true
+  exprotWordDom.value.exportWordDocx(
+    {
     ...singleRecord.value,
     //@ts-ignore
     babyNames: singleRecord.value.babyNames.map(item => ({name: item})),
@@ -343,8 +347,19 @@ const exportWord = () => {
     //@ts-ignore 
     tactics:  singleRecord.value!.domainList.map(item => item.abilityList.map(_ => ({tactic: _.description.tactics.split('\n').map(_ => ({key: _}))}))).flat(Infinity),
     //@ts-ignore
-    educations: singleRecord.value.domainList.map(item => item.abilityList.map(_ => ({education: _.description.education.split('\n').map(_ => ({key: _}))}))).flat(Infinity)
-  }, singleRecord.value!.babyNames[0] + '宝贝的观察评估')
+    educations: singleRecord.value.domainList.map(item => item.abilityList.map(_ => ({education: _.description.education.split('\n').map(_ => ({key: _}))}))).flat(Infinity),
+      //@ts-ignore
+    abilitys: singleRecord.value.domainList.map(item => {
+      return item.abilityList.map(_ => {
+        return {
+          name: _.abilityName + '\n',
+          behave: _.descriptionExtra?.behave
+        }
+      })
+    }).flat(Infinity)
+  }, singleRecord.value!.babyNames[0] + '宝贝的观察评估', () => {
+    loading.value = false
+  })
 }
 
 

BIN
src/views/termplate.docx


+ 4 - 22
src/views/test.vue

@@ -23,7 +23,7 @@ const termplateDocxPath = new URL('./termplate.docx', import.meta.url).href
 
 let file = ref(null);
 
-const  exportWordDocx = async  (tempDocxPath: any, dataObj: any, fileName: any) =>  {
+const  exportWordDocx = async  (tempDocxPath: any, dataObj: any, fileName: any, cb: Function) =>  {
 
   const storyVideos = dataObj.storyVideo ? [{url: await generateQRCode(dataObj.storyVideo), desc: '(扫码查看视频)'}] : []
  
@@ -68,30 +68,12 @@ const  exportWordDocx = async  (tempDocxPath: any, dataObj: any, fileName: any)
             } else {
               saveAs(out, fileName)
             }
+            cb()
+
         })
     })
 }
 
-// function isWeChatBrowser() {
-//   const userAgent = navigator.userAgent.toLowerCase();
-//   return false;
-// }
-
-// function getMobileOperatingSystem() {
-//   // @ts-ignore
-//     var userAgent = navigator.userAgent || navigator.vendor || window.opera;
-
-//     // @ts-ignore
-//     if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
-//         return 'iOS';
-//     }
-//     // 检查Android设备
-//     else if (/android/i.test(userAgent)) {
-//         return 'Android';
-//     }
-//     return 'unknown';
-// }
-
 function blobToBase64(blob: Blob, callback: (result: string | ArrayBuffer | null) => void) {
     const reader = new FileReader();
     reader.onloadend = function() {
@@ -180,7 +162,7 @@ const generateQRCode = (content: string) => {
 //     //this.file = file;
 //   }
 defineExpose({
-  exportWordDocx: (record: any, fileName: string) => exportWordDocx(termplateDocxPath, {...dataObj, ...record}, fileName)
+  exportWordDocx: (record: any, fileName: string, cb: Function) => exportWordDocx(termplateDocxPath, {...dataObj, ...record}, fileName, cb)
 })
 
 </script>