Browse Source

update: 区级知识点得分率数据导出表格

OnePsycho 2 years ago
parent
commit
c9d44b43db
2 changed files with 291 additions and 129 deletions
  1. 3 0
      TEAMModelOS/ClientApp/src/api/areaArt.js
  2. 288 129
      TEAMModelOS/ClientApp/src/view/art/AreaArt.vue

+ 3 - 0
TEAMModelOS/ClientApp/src/api/areaArt.js

@@ -57,4 +57,7 @@ export default {
     findAreaArtList: function (data) {
         return post('/school/area/find-area-art', data)
     },
+    findKnoPercents: function (data) {
+        return post('/school/area/get-all-knowledge', data)
+    },
 }

+ 288 - 129
TEAMModelOS/ClientApp/src/view/art/AreaArt.vue

@@ -3,131 +3,144 @@
     <vuescroll ref="art-dasboard">
       <Loading v-show="isLoading"></Loading>
       <back-to-top @on-to-top="backToTop"></back-to-top>
-      <div class="export-box"  @click="exportArtTable">
-        <span class="icon iconfont icon-download" style="margin-right:5px;margin-top: 5px;" :title="`下载艺术评测数据表`"></span>
-        <span>下载数据总表</span>
-      </div>
-      <div class="tab-box" style="padding:0px 20px 5px 20px;">
-        <span class="pane" v-for="item in periodList" style="line-height:30px;padding:2px;" @click="tabClick(item.value)" :class="{ active: periodId === item.value }">
-          {{item.label}}
-        </span>
-        <!-- 艺术活动选择 -->
-        <Select v-model="curAreaArtIndex" @on-change="onAcChange" style="margin:15px 0">
-          <Option v-for="(item,index) in areaArtList" :value="index" :key="index">
-            {{ item.name }}
-          </Option>
-        </Select>
-      </div>
-      <TipsInfo v-if="emptyData" msg="暂无数据"></TipsInfo>
-      <template v-else>
-        <!-- 头部统计 -->
-        <div class="top-block-wrap">
-          <div class="content-con-item border-style" v-for="(item,index) in topData" :key="index">
-            <div class="left-area" :style="{background: item.color, width: '36%'}">
-              <Icon :type="item.icon" class="icon" style="font-size: 40px; color: rgb(255, 255, 255);"></Icon>
-            </div>
-            <div class="right-area" style="width: 64%;">
-              <div>
-                <div class="count-to-wrapper">
-                  <p class="content-outer">
-                    <CountTo :decimals="item.type === 'rate' ? 1 : 0" class="count-to-count-text count-style" :endVal="item.number" :duration="600"></CountTo>
-                    <span style="font-size: 28px;" v-if="item.type === 'rate'">%</span>
-                  </p>
-                </div>
-                <p>{{item.text}}</p>
-              </div>
-            </div>
-          </div>
-        </div>
-        <!-- 艺术素质评测概览 -->
-        <div class="online-train-wrap">
-          <h4 class="block-title">艺术素质评测概览</h4>
-          <div class="chart-data-wrap">
-            <Overall :overall="overallData"></Overall>
-          </div>
-        </div>
-        <!-- 知识点得分统计 -->
-        <div class="online-train-wrap">
-          <h4 class="block-title">知识点得分率(音乐)</h4>
-          <div class="chart-line-wrap">
-            <div class="kng-level-wrap chart-data-wrap">
-              <KngLevel :kngData="musicKn"></KngLevel>
-            </div>
-            <div class="kng-point-wrap border-style chart-data-wrap">
-              <KngPoint :kngData="musicKn"></KngPoint>
-            </div>
-          </div>
-        </div>
-        <div class="online-train-wrap">
-          <h4 class="block-title">知识点得分率(美术)</h4>
-          <div class="chart-line-wrap">
-            <div class="kng-level-wrap chart-data-wrap">
-              <KngLevel :kngData="drawKn"></KngLevel>
-            </div>
-            <div class="kng-point-wrap border-style chart-data-wrap">
-              <KngPoint :kngData="drawKn"></KngPoint>
-            </div>
-          </div>
-        </div>
-        <!-- 评测学校情况对比 -->
-        <div class="online-train-wrap">
-          <h4 class="block-title">学校评测情况(音乐)</h4>
-          <div class="chart-data-wrap">
-            <SchoolComp :schools="musicExam"></SchoolComp>
-          </div>
-        </div>
-        <div class="online-train-wrap">
-          <h4 class="block-title">学校评测情况(美术)</h4>
-          <div class="chart-data-wrap">
-            <SchoolComp :schools="drawExam"></SchoolComp>
-          </div>
-        </div>
-        <!-- 艺术特长获奖情况 -->
-        <div class="online-train-wrap">
-          <h4 class="block-title">艺术特长获奖情况</h4>
-          <div class="chart-line-wrap">
-            <div class="award-chart-wrap chart-data-wrap">
-              <!-- <Award :awardData="musicAward" titleText="音乐赛事艺术获奖情况"></Award> -->
-              <EmptyData textContent="暂无音乐获奖情况数据"></EmptyData>
-            </div>
-            <div class="award-chart-wrap chart-data-wrap">
-              <!-- <Award :awardData="drawAward" titleText="美术赛事艺术获奖情况"></Award> -->
-              <EmptyData textContent="暂无美术获奖情况数据"></EmptyData>
-            </div>
-          </div>
-        </div>
-        <!-- 学校列表 -->
-        <div class="online-train-wrap">
-          <div style="height:30px">
-            <h4 class="block-title">学校列表</h4>
-            <Input v-special-char search placeholder="搜索学校" class="school-search" v-model="keyword" />
-          </div>
-          <div class="school-data-wrap">
-            <div class="school-data-item border-style" v-for="(item,index) in schoolListShow" :key="index">
-              <img class="school-img" :src="item.picture || defImg">
-              <div style="margin-left:10px;height:fit-content;">
-                <p class="school-name" :title="item.name">{{item.name}}<span class="to-school-detail" @click="toSchoolDetail(item)">
-                    详情 >
-                  </span></p>
-                <div style="display:flex;margin-top:10px">
-                  <p class="school-value">
-                    <span class="value">{{ parseInt(item.musicPass * 100) || 0}} <span style="font-size:18px">%</span> </span>
-                    <span>音乐及格率</span>
-                  </p>
-                  <p class="school-value">
-                    <span class="value">{{ parseInt(item.drawPass * 100) || 0}} <span style="font-size:18px">%</span> </span>
-                    <span>美术及格率</span>
-                  </p>
-                </div>
+                      <div class="export-box" @click="exportArtTable">
+                        <span class="icon iconfont icon-download" style="margin-right:5px;margin-top: 5px;" :title="`下载艺术评测数据表`"></span>
+                        <span>下载数据总表</span>
+                      </div>
+                      <div class="tab-box" style="padding:0px 20px 5px 20px;">
+                        <span class="pane" v-for="item in periodList" style="line-height:30px;padding:2px;" @click="tabClick(item.value)"
+                          :class="{ active: periodId === item.value }">
+                          {{ item.label }}
+                        </span>
+                        <!-- 艺术活动选择 -->
+                        <Select v-model="curAreaArtIndex" @on-change="onAcChange" style="margin:15px 0">
+                          <Option v-for="(item, index) in areaArtList" :value="index" :key="index">
+                            {{ item.name }}
+                          </Option>
+                        </Select>
+                      </div>
+                      <TipsInfo v-if="emptyData" msg="暂无数据"></TipsInfo>
+                      <template v-else>
+                        <!-- 头部统计 -->
+                        <div class="top-block-wrap">
+                          <div class="content-con-item border-style" v-for="(item, index) in topData" :key="index">
+                            <div class="left-area" :style="{ background: item.color, width: '36%' }">
+                              <Icon :type="item.icon" class="icon" style="font-size: 40px; color: rgb(255, 255, 255);"></Icon>
+                            </div>
+                            <div class="right-area" style="width: 64%;">
+                              <div>
+                                <div class="count-to-wrapper">
+                                  <p class="content-outer">
+                                    <CountTo :decimals="item.type === 'rate' ? 1 : 0" class="count-to-count-text count-style"
+                                      :endVal="item.number" :duration="600"></CountTo>
+                                    <span style="font-size: 28px;" v-if="item.type === 'rate'">%</span>
+                                  </p>
+                                </div>
+                                <p>{{ item.text }}</p>
+                              </div>
+                            </div>
+                          </div>
+                        </div>
+                        <!-- 艺术素质评测概览 -->
+                        <div class="online-train-wrap">
+                          <h4 class="block-title">艺术素质评测概览</h4>
+                          <div class="chart-data-wrap">
+                            <Overall :overall="overallData"></Overall>
+                          </div>
+                        </div>
+                        <!-- 知识点得分统计 -->
+                        <div class="online-train-wrap">
+                          <h4 class="block-title">知识点得分率(音乐)</h4>
+                          <p class="export-btn" @click="exportKnoData('subject_music')">
+                            <span class="icon iconfont icon-download" :title="`下载知识点得分率表格`"></span>
+                            导出数据
+                          </p>
+                          <div class="chart-line-wrap">
+                            <div class="kng-level-wrap chart-data-wrap">
+                              <KngLevel :kngData="musicKn"></KngLevel>
+                            </div>
+                            <div class="kng-point-wrap border-style chart-data-wrap">
+                              <KngPoint :kngData="musicKn"></KngPoint>
+                            </div>
+                          </div>
+                        </div>
+                        <div class="online-train-wrap">
+                          <h4 class="block-title">知识点得分率(美术)</h4>
+                          <p class="export-btn" @click="exportKnoData('subject_painting')">
+                            <span class="icon iconfont icon-download" :title="`下载知识点得分率表格`"></span>
+                            导出数据
+                          </p>
+                          <div class="chart-line-wrap">
+                            <div class="kng-level-wrap chart-data-wrap">
+                              <KngLevel :kngData="drawKn"></KngLevel>
+                            </div>
+                            <div class="kng-point-wrap border-style chart-data-wrap">
+                              <KngPoint :kngData="drawKn"></KngPoint>
+                            </div>
+                          </div>
+                        </div>
+                        <!-- 评测学校情况对比 -->
+                        <div class="online-train-wrap">
+                          <h4 class="block-title">学校评测情况(音乐)</h4>
+                          <div class="chart-data-wrap">
+                            <SchoolComp :schools="musicExam"></SchoolComp>
+                          </div>
+                        </div>
+                        <div class="online-train-wrap">
+                          <h4 class="block-title">学校评测情况(美术)</h4>
+                          <div class="chart-data-wrap">
+                            <SchoolComp :schools="drawExam"></SchoolComp>
+                          </div>
+                        </div>
+                        <!-- 艺术特长获奖情况 -->
+                        <div class="online-train-wrap">
+                          <h4 class="block-title">艺术特长获奖情况</h4>
+                          <div class="chart-line-wrap">
+                            <div class="award-chart-wrap chart-data-wrap">
+                              <!-- <Award :awardData="musicAward" titleText="音乐赛事艺术获奖情况"></Award> -->
+                              <EmptyData textContent="暂无音乐获奖情况数据"></EmptyData>
+                            </div>
+                            <div class="award-chart-wrap chart-data-wrap">
+                              <!-- <Award :awardData="drawAward" titleText="美术赛事艺术获奖情况"></Award> -->
+                              <EmptyData textContent="暂无美术获奖情况数据"></EmptyData>
+                            </div>
+                          </div>
+                        </div>
+                        <!-- 学校列表 -->
+                        <div class="online-train-wrap">
+                          <div style="height:30px">
+                            <h4 class="block-title">学校列表</h4>
+                            <Input v-special-char search placeholder="搜索学校" class="school-search" v-model="keyword" />
+                          </div>
+                          <div class="school-data-wrap">
+                            <div class="school-data-item border-style" v-for="(item, index) in schoolListShow" :key="index">
+                              <img class="school-img" :src="item.picture || defImg">
+                              <div style="margin-left:10px;height:fit-content;">
+                                <p class="school-name" :title="item.name">{{ item.name }}<span class="to-school-detail"
+                                    @click="toSchoolDetail(item)">
+                                    详情 >
+                                  </span></p>
+                                <div style="display:flex;margin-top:10px">
+                                  <p class="school-value">
+                                    <span class="value">{{ parseInt(item.musicPass * 100) || 0 }} <span style="font-size:18px">%</span>
+                                    </span>
+                                    <span>音乐及格率</span>
+                                  </p>
+                                  <p class="school-value">
+                                    <span class="value">{{ parseInt(item.drawPass * 100) || 0 }} <span style="font-size:18px">%</span>
+                                    </span>
+                                    <span>美术及格率</span>
+                                  </p>
+                                </div>
 
-              </div>
-            </div>
-            <EmptyData textContent="暂无学校数据" v-show="!schoolListShow.length"></EmptyData>
-          </div>
-        </div>
-      </template>
-    </vuescroll>
-  </div>
+                              </div>
+                            </div>
+                            <EmptyData textContent="暂无学校数据" v-show="!schoolListShow.length"></EmptyData>
+                          </div>
+                        </div>
+                      </template>
+                    </vuescroll>
+                  </div>
 </template>
 <script>
 import excel from '@/utils/excel.js'
@@ -146,6 +159,7 @@ export default {
   },
   data() {
     return {
+      areaKnoJson: null,
       emptyData: false,
       isLoading: false,
       keyword: '',
@@ -177,7 +191,7 @@ export default {
     topData() {
       let { scCount, classCount, stuCount, subjectCount } = this.curPeriodData.areaSchool
       let { classJoinCount, stuJoinCount } = this.curPeriodData
-      let totalStandard = (+(this.curPeriodData.knData.map(i => i.stand).reduce((a, b) => a + b, 0)) / 2).toFixed(2)
+      let totalStandard = parseInt(+(this.curPeriodData.knData.map(i => i.stand).reduce((a, b) => a + b, 0)) / 2)
       let joinCount = this.curPeriodData.periodAll ? this.curPeriodData.periodAll.schoolScore?.length : 0
       let topData = [
         {
@@ -318,6 +332,113 @@ export default {
     this.getAreaArtList()
   },
   methods: {
+    exportKnoData(subjectId) {
+      console.error(subjectId, this.areaKnoJson)
+      let sheets = []
+      // 区级概况
+      let area_knoHeaders = ['知识点名称', '知识块名称', '知识块配分', '知识块维度', '知识点得分率']
+      let area_knoKeys = ['pointName', 'blockName', 'blockScore', 'dim', 'pointScoreRate']
+      let subjectBlocks = this.areaKnoJson.blocks.find(i => i.subjectId === subjectId).dim
+      let area_knoData = this.areaKnoJson.areaSubjectPersent.find(i => i.subjectId === subjectId).psersent.map(item => {
+        let blockInfo = subjectBlocks.find(i => i.name === item.block[0])
+        return {
+          pointName: item.know,
+          blockName: item.block.length ? item.block[0] : '-',
+          blockScore: blockInfo ? blockInfo.score : 0,
+          dim: blockInfo ? blockInfo.dim[0] : '-',
+          pointScoreRate: parseInt(item.score * 100) + '%'
+        }
+      })
+      const areaSheet = {
+        title: area_knoHeaders,
+        key: area_knoKeys,
+        data: area_knoData,
+        filename: '区级概况',
+        autoWidth: true
+      }
+      sheets.push(areaSheet)
+      // 校级概况
+      let sch_knoHeaders = ['学校名称', '知识点名称', '知识块名称', '知识块配分', '知识块维度', '知识点得分率']
+      let sch_knoKeys = ['schoolName', 'pointName', 'blockName', 'blockScore', 'dim', 'pointScoreRate']
+      let sch_knoData = []
+      this.areaKnoJson.schoolSubjectPersent.forEach(school => {
+        school.subject.find(i => i.subjectId === subjectId).psersent.forEach(item => {
+          let blockInfo = subjectBlocks.find(i => i.name === item.block[0])
+          sch_knoData.push({
+            schoolName: school.schoolName,
+            pointName: item.know,
+            blockName: item.block.length ? item.block[0] : '-',
+            blockScore: blockInfo ? blockInfo.score : 0,
+            dim: blockInfo ? blockInfo.dim[0] : '-',
+            pointScoreRate: parseInt(item.score * 100) + '%'
+          })
+        })
+      })
+      const schSheet = {
+        title: sch_knoHeaders,
+        key: sch_knoKeys,
+        data: sch_knoData,
+        filename: '校级概况',
+        autoWidth: true
+      }
+      sheets.push(schSheet)
+      // 年级概况
+      let grade_knoHeaders = ['年级名称', '知识点名称', '知识块名称', '知识块配分', '知识块维度', '知识点得分率']
+      let grade_knoKeys = ['gradeName', 'pointName', 'blockName', 'blockScore', 'dim', 'pointScoreRate']
+      let grade_knoData = []
+      this.areaKnoJson.gradeSubjectPersent.find(i => i.subjectId === subjectId).psersent.forEach(grade => {
+        grade.knowledge.forEach(item => {
+          let blockInfo = subjectBlocks.find(i => i.name === item.block[0])
+          grade_knoData.push({
+            gradeName: grade.gradeName,
+            pointName: item.know,
+            blockName: item.block.length ? item.block[0] : '-',
+            blockScore: blockInfo ? blockInfo.score : 0,
+            dim: blockInfo ? blockInfo.dim[0] : '-',
+            pointScoreRate: parseInt(item.score * 100) + '%'
+          })
+        })
+      })
+      const gradeSheet = {
+        title: grade_knoHeaders,
+        key: grade_knoKeys,
+        data: grade_knoData,
+        filename: '年级概况',
+        autoWidth: true
+      }
+      sheets.push(gradeSheet)
+      // 班级概况
+      let class_knoHeaders = ['学校名称', '年级名称', '班级名称', '知识点名称', '知识块名称', '知识块配分', '知识块维度', '知识点得分率']
+      let class_knoKeys = ['schoolName', 'gradeName', 'className', 'pointName', 'blockName', 'blockScore', 'dim', 'pointScoreRate']
+      let class_knoData = []
+      this.areaKnoJson.classPersent.filter(i => i.subjectId === subjectId).forEach(classItem => {
+        classItem.know.forEach(item => {
+          let blockInfo = subjectBlocks.find(i => i.name === item.block[0])
+          class_knoData.push({
+            schoolName: classItem.schoolName,
+            gradeName: item.gradeName,
+            className: item.className,
+            pointName: item.knowledgeName,
+            blockName: item.block.length ? item.block[0] : '-',
+            blockScore: blockInfo ? blockInfo.score : 0,
+            dim: blockInfo ? blockInfo.dim[0] : '-',
+            pointScoreRate: parseInt(item.score * 100) + '%'
+          })
+        })
+      })
+      const classSheet = {
+        title: class_knoHeaders,
+        key: class_knoKeys,
+        data: class_knoData,
+        filename: '班级概况',
+        autoWidth: true
+      }
+      sheets.push(classSheet)
+      // 合并导出
+      let curPeriodName = this.periodList.find(i => i.value === this.periodId).label
+      let subjectName = subjectId === 'subject_music' ? '音乐' : '美术'
+      excel.export_array_to_sheet(sheets, `${sessionStorage.getItem('areaName')} - 知识点得分率报告(${curPeriodName}-${subjectName})`)
+    },
     exportArtTable() {
       let sheets = []
       // 区级概况
@@ -338,7 +459,7 @@ export default {
           m_min: mScore.min,
           m_average: mScore.average,
           m_excellent: parseInt(mScore.excellent * 100) + '%',
-          m_pass:  parseInt(mScore.pass * 100) + '%',
+          m_pass: parseInt(mScore.pass * 100) + '%',
           m_stan: this.curPeriodData.knData.find(i => i.key === 'subject_music').stand,
           p_max: pScore.max,
           p_min: pScore.min,
@@ -358,7 +479,7 @@ export default {
       sheets.push(areaSheet)
       // 各学校数据
       let schoolHeaders = ['学校名称', '音乐最高分', '音乐平均分', '音乐优秀率', '音乐合格率', '美术最高分', '美术平均分', '美术优秀率', '美术合格率']
-      let schoolKeys = ['name', 'm_max','m_average','m_excellent','m_pass', 'p_max',  'p_average', 'p_excellent', 'p_pass']
+      let schoolKeys = ['name', 'm_max', 'm_average', 'm_excellent', 'm_pass', 'p_max', 'p_average', 'p_excellent', 'p_pass']
       let schoolDatas = []
       this.allData.periodAll.schoolScore.forEach(school => {
         let sch_music_score = school.scores.find(i => i.subjectId === 'subject_music')
@@ -438,7 +559,7 @@ export default {
       console.log(this.periodList);
       console.log(this.periodId);
       let curPeriodName = this.periodList.find(i => i.value === this.periodId).label
-      excel.export_array_to_sheet(sheets, `${sessionStorage.getItem('areaName')} - 艺术评测报告(${ curPeriodName })`)
+      excel.export_array_to_sheet(sheets, `${sessionStorage.getItem('areaName')} - 艺术评测报告(${curPeriodName})`)
     },
     getAreaArtList() {
       this.$api.areaArt.findAreaArtList({
@@ -451,6 +572,13 @@ export default {
           this.onAcChange()
         }
       })
+      // 获取区级当前学段汇总知识点得分率数据
+      this.$api.areaArt.findKnoPercents({
+        id: sessionStorage.getItem('areaId'),
+        periodType: this.periodId,
+      }).then(res => {
+        this.areaKnoJson = res
+      })
     },
     onAcChange() {
       this.getAreaArtAnalysis()
@@ -597,12 +725,14 @@ export default {
   border-radius: 20px;
   // margin-right: 20px;
 }
+
 .school-img {
   width: 90px;
   height: 90px;
   margin-right: 20px;
   border-radius: 10px;
 }
+
 .school-data-item {
   position: relative;
   display: flex;
@@ -615,10 +745,12 @@ export default {
   min-width: 360px;
   border-radius: 5px;
   transition: all 0.2s ease 0s;
+
   &:hover {
     box-shadow: 0 26px 40px -24px #aaa;
     transform: translateY(-4px);
   }
+
   .school-name {
     // width: 158px;
     // text-overflow: ellipsis;
@@ -629,6 +761,7 @@ export default {
     // font-weight: 600;
     font-size: 16px;
   }
+
   .school-value {
     margin-top: 5px;
     font-size: 12px;
@@ -647,6 +780,7 @@ export default {
       font-size: 24px;
     }
   }
+
   .to-school-detail {
     margin-left: 8px;
     color: #2d8cf0;
@@ -654,6 +788,7 @@ export default {
     cursor: pointer;
   }
 }
+
 .school-data-wrap {
   margin-bottom: 20px;
   display: flex;
@@ -662,25 +797,31 @@ export default {
   margin-top: 20px;
   justify-content: start;
 }
+
 .award-chart-wrap {
   width: 49%;
 }
+
 .kng-point-wrap {
   width: ~"calc(100% - 420px)";
 }
+
 .chart-line-wrap {
   display: flex;
   justify-content: space-between;
 }
+
 .kng-level-wrap {
   width: fit-content;
   margin-right: 30px;
 }
+
 .chart-data-wrap {
   background: #ffffff;
   margin-top: 10px;
   padding: 40px 20px;
 }
+
 .block-title {
   border-left: 4px solid #1cc0f3;
   padding-left: 10px;
@@ -690,18 +831,30 @@ export default {
   color: #414749;
   margin-bottom: 20px;
 }
+
 .online-train-wrap {
+  position: relative;
   border-radius: 5px;
   width: 100%;
   // background: white;
   padding: 0px 20px;
   // box-shadow: 0px 4px 4px 1px #f0f0f0;
   margin-top: 35px;
+
+  .export-btn {
+    position: absolute;
+    right: 20px;
+    top: 10px;
+    cursor: pointer;
+  }
 }
+
+
 .border-style {
   box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
   border-radius: 4px;
 }
+
 .content-con-item {
   width: 24%;
   height: 110px;
@@ -709,27 +862,32 @@ export default {
   border-radius: 2px;
   margin-bottom: 20px;
   overflow: hidden;
+
   .left-area {
     float: left;
     height: 100%;
     display: table;
     text-align: center;
+
     .icon {
       display: table-cell;
       vertical-align: middle;
     }
   }
+
   .right-area {
     background: white;
     float: left;
     height: 100%;
     display: table;
     text-align: center;
+
     .count-style {
       font-size: 50px;
     }
   }
 }
+
 .top-block-wrap {
   width: 100%;
   display: flex;
@@ -738,13 +896,14 @@ export default {
   margin-top: 10px;
   padding: 0px 20px 0px 20px;
 }
+
 .area-data-container {
   position: relative;
   width: 100%;
   height: 100%;
   background: #ededed;
 
-  .export-box{
+  .export-box {
     position: absolute;
     right: 20px;
     top: 20px;