|
@@ -0,0 +1,483 @@
|
|
|
+<template>
|
|
|
+ <HeaderPart ></HeaderPart>
|
|
|
+ <div class="smart-center">
|
|
|
+ <div class="smart-center-cover" id='cover' :style="{'backgroundImage': type == 1 ? `url(${getImageUrl('school-cover')})` : `url(${getImageUrl('clazz-cover')})`}" >
|
|
|
+ <div class="smart-center-name">
|
|
|
+ {{baseCount.schoolName}}
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-date">
|
|
|
+ <div class="smart-center-date-title" >成长阶段:</div>
|
|
|
+ <div class="smart-center-date-value" >{{baseCount.dateRange}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 评估结果与分析 -->
|
|
|
+ <div class="smart-center-analysis">
|
|
|
+ <div class="smart-center-analysis-title">
|
|
|
+ 评估结果与分析
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-1" >
|
|
|
+ <div class="title-2" >
|
|
|
+ 1. 全园基本概况
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-1-content title-3" >
|
|
|
+ {{baseCount.schoolName}}班级{{baseCount.classCount}}个,共有学生{{baseCount.behavior}}名,在本评估周期内共统计到教师的观察记录{{baseCount.behavior}}条,
|
|
|
+ 观察记录到学生{{baseCount.done.length}}名,未观察到的学生{{baseCount.notDone.length}}名。
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- (1)全年级观察记录分布 -->
|
|
|
+ <div class="smart-center-analysis-item-1" >
|
|
|
+ <div class="title-2" >
|
|
|
+ 2. 各年级结果分析
|
|
|
+ </div>
|
|
|
+ <div class="title-4" >
|
|
|
+ (1)全年级观察记录分布
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-2-content" >
|
|
|
+ <div class="base-table" id="capture" >
|
|
|
+ <div class="base-table-item">
|
|
|
+ <div class="title" >记录总数</div>
|
|
|
+ <div class="value" >{{baseCount.records}}篇</div>
|
|
|
+ </div>
|
|
|
+ <div class="base-table-item">
|
|
|
+ <div class="title" >行为记录</div>
|
|
|
+ <div class="value" >{{baseCount.behavior}}次</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- (2)各班级观察记录明细 -->
|
|
|
+ <div class="smart-center-analysis-item-3" >
|
|
|
+ <div class="title-4" >
|
|
|
+ (2)各班级观察记录明细
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-3-content" >
|
|
|
+ <Table ref="tableDom" :columns="classColumns" :data="classRecord" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- (3)各年级记录场景分布 -->
|
|
|
+ <div class="smart-center-analysis-item-3" >
|
|
|
+ <div class="title-4" >
|
|
|
+ (3)各年级记录场景分布
|
|
|
+ </div>
|
|
|
+ <div class="scene" v-for="(item, index) in reportScene" :key="item.levelId" >
|
|
|
+ <div class="picture-title" >
|
|
|
+ {{levelIdMap.get(item.levelId)}}记录场景分布
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-3-content" >
|
|
|
+ <LineCharts :ref="el => reportSceneDom[index]= {title: levelIdMap.get(item.levelId) + '记录场景分布', el}" :datasource="item.scenes" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- (4)各年级观察领域分布 -->
|
|
|
+ <div class="smart-center-analysis-item-3" >
|
|
|
+ <div class="title-4" >
|
|
|
+ (4). 各年级观察领域分布
|
|
|
+ </div>
|
|
|
+ <div class="area" v-for="item in reportDomain" :key="item.levelId" >
|
|
|
+ <div class="picture-title" >
|
|
|
+ {{levelIdMap.get(item.levelId)}}记录领域分布
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-3-content" >
|
|
|
+ <LineCharts
|
|
|
+ :ref="el => reportDomainDom[item.levelId] = {title: levelIdMap.get(item.levelId) + '记录领域分布', el}"
|
|
|
+ :datasource="item.domains"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- (5)各年级各领域能力表现阶段汇总 -->
|
|
|
+ <div class="smart-center-analysis-item-3" >
|
|
|
+ <div class="title-4" >
|
|
|
+ (5). 各年级各领域能力表现阶段汇总
|
|
|
+ </div>
|
|
|
+ <div class="able" v-for="item in gradeDomain" :key="item.classLevelCode" >
|
|
|
+ <div class="picture-title" >
|
|
|
+ {{levelIdMap.get(item.classLevelCode)}}各领域能力表现阶段汇总
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-3-content" >
|
|
|
+ <Table
|
|
|
+ :ref="el => gradeDomainDom[item.classLevelCode] = {title: levelIdMap.get(item.classLevelCode) + '各领域能力表现阶段汇总', el}"
|
|
|
+ :columns="testColumns"
|
|
|
+ :data="item.abilityList"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 3. 全园教师及学生数据分析 -->
|
|
|
+ <div class="smart-center-analysis-item-1" >
|
|
|
+ <div class="title-2" >
|
|
|
+ 3. 全园教师及学生数据分析
|
|
|
+ </div>
|
|
|
+ <div class="title-4" >
|
|
|
+ (1)所有老师观察记录分布明细
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-3-content" >
|
|
|
+ <Table ref="teacherRecordDom" :columns="teacherColumns" :data="teacherRecord" />
|
|
|
+ </div>
|
|
|
+ <div class="title-4" >
|
|
|
+ (2)所有学生各领域表现阶段明细
|
|
|
+ </div>
|
|
|
+ <div class="smart-center-analysis-item-3-content" >
|
|
|
+ <Table ref="studentDomainDom" :columns="studentColumns" :data="studentDomain" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <exportButton :loading="loading" @export="exportReport" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+// @ts-ignore
|
|
|
+import HeaderPart from './components/HeaderPart.vue'
|
|
|
+import exportButton from '@/components/exportButton.vue';
|
|
|
+import LineCharts from '@/components/lineCharts.vue';
|
|
|
+import Table from '@/components/table.vue';
|
|
|
+import { useCenterStore } from "@/store/index.js";
|
|
|
+import { getImageUrl, getAppToken } from "@/utils";
|
|
|
+ // @ts-ignore
|
|
|
+import { exportSmartCenter } from "@/utils/exportPdf.js";
|
|
|
+import { storeToRefs } from "pinia";
|
|
|
+import { onMounted, ref } from 'vue';
|
|
|
+import { useRoute } from "vue-router";
|
|
|
+import html2canvas from 'html2canvas'
|
|
|
+const { p, type } = useRoute().query!;
|
|
|
+console.log('路由参数:', type);
|
|
|
+
|
|
|
+const centerStore = useCenterStore();
|
|
|
+const { baseCount, classRecord, reportDomain, reportScene, levelIdMap, studentDomain, teacherRecord, gradeDomain } = storeToRefs(centerStore);
|
|
|
+const { getCenterBaseCount, getCenteClassRecord, getCenteReportDmain, getCenteReportScene,
|
|
|
+ getCenteStudentDomain, getCenteTeacherRecord, getCenteGradeDomain
|
|
|
+ } = centerStore;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const tableDom = ref()
|
|
|
+
|
|
|
+const reportSceneDom = ref({})
|
|
|
+
|
|
|
+const reportDomainDom = ref({})
|
|
|
+
|
|
|
+const gradeDomainDom = ref({})
|
|
|
+
|
|
|
+const teacherRecordDom = ref()
|
|
|
+
|
|
|
+const studentDomainDom = ref()
|
|
|
+
|
|
|
+const classColumns = ref([
|
|
|
+ {title: '班级', key: 'className'},
|
|
|
+ {title: '教师数量', key: 'teacher'},
|
|
|
+ {title: '记录总数', key: 'records'},
|
|
|
+ {title: '观察学生总数', key: 'done'},
|
|
|
+ {title: '未观察人数', key: 'notDone'},
|
|
|
+])
|
|
|
+ // @ts-ignore
|
|
|
+const gradeDomainColumns = ref([
|
|
|
+ {title: '领域', key: 'domainName'},
|
|
|
+ {title: '能力', key: 'abilityName'},
|
|
|
+ {title: 's1', key: 's1'},
|
|
|
+ {title: 's2', key: 's2'},
|
|
|
+ {title: 's3', key: 's3'},
|
|
|
+ {title: 's4', key: 's4'},
|
|
|
+ {title: 's5', key: 's5'},
|
|
|
+ {title: 's6', key: 's6'},
|
|
|
+ {title: 's7', key: 's7'},
|
|
|
+ {title: 's8', key: 's8'}
|
|
|
+])
|
|
|
+
|
|
|
+const teacherColumns = ref([
|
|
|
+ { title: '教师', key: 'teacherName' },
|
|
|
+ { title: '观察记录数', key: 'education' },
|
|
|
+ { title: '观察学生数量', key: 'students' },
|
|
|
+ { title: '未记录', key: 'tactics' }
|
|
|
+])
|
|
|
+
|
|
|
+const studentColumns = ref(
|
|
|
+ [
|
|
|
+ {title: '姓名', key: 'babyName'},
|
|
|
+ {title: '行为记录', key: 'behavior'},
|
|
|
+ {title: '观察进阶', key: 'up', width: 240,child: [
|
|
|
+ { title: 's1', key: 's1' },
|
|
|
+ { title: 's2', key: 's2' },
|
|
|
+ { title: 's3', key: 's3' },
|
|
|
+ { title: 's4', key: 's4' },
|
|
|
+ { title: 's5', key: 's5' },
|
|
|
+ { title: 's6', key: 's6' },
|
|
|
+ { title: 's7', key: 's7' },
|
|
|
+ { title: 's8', key: 's8' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+)
|
|
|
+
|
|
|
+
|
|
|
+const testColumns = ref(
|
|
|
+ [
|
|
|
+ {title: '领域', key: 'domainName', spanRow: true, width: 70},
|
|
|
+ {title: '能力', key: 'abilityName', width: 70 },
|
|
|
+ { title: 's1', key: 's1'},
|
|
|
+ { title: 's2', key: 's2'},
|
|
|
+ { title: 's3', key: 's3'},
|
|
|
+ { title: 's4', key: 's4'},
|
|
|
+ { title: 's5', key: 's5'},
|
|
|
+ { title: 's6', key: 's6'},
|
|
|
+ { title: 's7', key: 's7'},
|
|
|
+ { title: 's8', key: 's8'}
|
|
|
+ ]
|
|
|
+)
|
|
|
+
|
|
|
+const loading = ref(false)
|
|
|
+
|
|
|
+const htmlToPng = (id: string) => {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ html2canvas(document.querySelector(id)!).then(canvas => {
|
|
|
+ resolve(canvas.toDataURL(''))
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+const exportReport = () => {
|
|
|
+ loading.value = true
|
|
|
+
|
|
|
+ html2canvas(document.querySelector('#cover')!).then(async canvas => {
|
|
|
+
|
|
|
+ const cover = canvas.toDataURL('')
|
|
|
+
|
|
|
+ const record = await htmlToPng('#capture')
|
|
|
+
|
|
|
+
|
|
|
+ const classRecord = await tableDom.value.getChartImg()
|
|
|
+
|
|
|
+ console.log('reportScene:', Object.keys(reportSceneDom.value));
|
|
|
+
|
|
|
+ const reportSceneDomKeys = Object.keys(reportSceneDom.value)
|
|
|
+ const reportDomainDomKeys = Object.keys(reportDomainDom.value)
|
|
|
+ const gradeDomainDomKeys = Object.keys(gradeDomainDom.value).filter(key => key != 'undefined')
|
|
|
+
|
|
|
+ const _reportScene = []
|
|
|
+
|
|
|
+ let _reportDomain = []
|
|
|
+
|
|
|
+ const _gradeDomainDom = []
|
|
|
+
|
|
|
+ for (let index = 0; index < Object.keys(reportSceneDom.value).length; index++) {
|
|
|
+ const key = reportSceneDomKeys[index]
|
|
|
+ if (reportSceneDom.value[key].el) {
|
|
|
+ // @ts-ignore
|
|
|
+ const img = await reportSceneDom.value[key].el.getChartImg()
|
|
|
+
|
|
|
+ // @ts-ignore
|
|
|
+ _reportScene.push({ img: img, title: reportSceneDom.value[key].title })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('reportDomain.value:', reportDomainDom.value);
|
|
|
+
|
|
|
+ for (let index = 0; index < Object.keys(reportDomainDom.value).length; index++) {
|
|
|
+ const key = reportDomainDomKeys[index]
|
|
|
+ console.log('key:', key);
|
|
|
+
|
|
|
+ if (reportDomainDom.value[key].el) {
|
|
|
+ // @ts-ignore
|
|
|
+ const img = await reportDomainDom.value[key].el.getChartImg()
|
|
|
+ console.log('img--over:', key);
|
|
|
+ // @ts-ignore
|
|
|
+ _reportDomain.push({ img: img, title: reportDomainDom.value[key].title })
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('gradeDomainDom.value:', gradeDomainDom.value);
|
|
|
+
|
|
|
+
|
|
|
+ for (let index = 0; index < gradeDomainDomKeys.length; index++) {
|
|
|
+ const key = gradeDomainDomKeys[index]
|
|
|
+ console.log(' gradeDomainDom.value[key].el:', key);
|
|
|
+ // @ts-ignore
|
|
|
+ if (gradeDomainDom.value[key].el) {
|
|
|
+ const img = gradeDomainDom.value[key] && await gradeDomainDom.value[key].el.getChartImg()
|
|
|
+ // @ts-ignore
|
|
|
+ _gradeDomainDom.push({ img: img, title: gradeDomainDom.value[key].title })
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const teacherRecordDomImg = await teacherRecordDom.value.getChartImg()
|
|
|
+ const studentDomainDomImg = await studentDomainDom.value.getChartImg()
|
|
|
+
|
|
|
+ console.log('reportDomain.value:', _gradeDomainDom);
|
|
|
+
|
|
|
+
|
|
|
+ exportSmartCenter({
|
|
|
+ cover,
|
|
|
+ baseInfo: `${baseCount.value.schoolName}班级${baseCount.value.classCount}个, 共有学生${baseCount.value.behavior}名个 ,在本评估周期内共统计到教师的观察记录${baseCount.value.behavior} 条,观察记录到学生${baseCount.value.done.length}名,未观察到的学生${baseCount.value.notDone.length}名。`,
|
|
|
+ record,
|
|
|
+ classRecord,
|
|
|
+ _reportScene,
|
|
|
+ _reportDomain,
|
|
|
+ _gradeDomainDom,
|
|
|
+ teacherRecordDomImg,
|
|
|
+ studentDomainDomImg
|
|
|
+ }, async (progress: number) => {
|
|
|
+ const r = (progress * 100).toFixed(0)
|
|
|
+ if (r === '100') {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ await getAppToken()
|
|
|
+ // @ts-ignore
|
|
|
+ const $par = JSON.parse(decodeURIComponent(atob(p!)))
|
|
|
+
|
|
|
+ // @ts-ignore
|
|
|
+ // type.value = typeAs === 1 ? 'school' : 'class'
|
|
|
+
|
|
|
+
|
|
|
+ getCenterBaseCount( $par)
|
|
|
+ getCenteClassRecord( $par)
|
|
|
+ getCenteReportDmain( $par)
|
|
|
+ getCenteReportScene( $par)
|
|
|
+ getCenteStudentDomain( $par)
|
|
|
+ getCenteTeacherRecord( $par)
|
|
|
+ getCenteGradeDomain( $par)
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+
|
|
|
+$font-size-H1: 26px;
|
|
|
+$font-size-H2: 20px;
|
|
|
+$font-size-H3: 18px;
|
|
|
+$font-size-H4: 16px;
|
|
|
+$font-size-H5: 14px;
|
|
|
+
|
|
|
+.smart-center {
|
|
|
+ padding-bottom: 160px;
|
|
|
+ .smart-center-cover {
|
|
|
+ width: 100vw;
|
|
|
+ height: 667px;
|
|
|
+ background-size: contain;
|
|
|
+ position: relative;
|
|
|
+ .smart-center-name {
|
|
|
+ position: absolute;
|
|
|
+ left: 20px;
|
|
|
+ top: 240px;
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ .smart-center-date {
|
|
|
+ position: absolute;
|
|
|
+ left: 20px;
|
|
|
+ top: 270px;
|
|
|
+ display: flex;
|
|
|
+ font-size: 14px;
|
|
|
+ .smart-center-date-title {
|
|
|
+ margin-right: 6px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .smart-center-analysis {
|
|
|
+ // margin-top: 20px;
|
|
|
+ padding: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ .smart-center-analysis-title {
|
|
|
+ font-size: $font-size-H1;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ }
|
|
|
+ .smart-center-analysis-item-1 {
|
|
|
+ .smart-center-analysis-item-1-title {
|
|
|
+ font-size: $font-size-H2;
|
|
|
+ }
|
|
|
+ .smart-center-analysis-item-1-content {
|
|
|
+ font-size: $font-size-H4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .smart-center-analysis-item-2 {
|
|
|
+ margin-top: 20px;
|
|
|
+ .smart-center-analysis-item-1-title {
|
|
|
+ font-size: $font-size-H2;
|
|
|
+ }
|
|
|
+ .smart-center-analysis-item-1-subtitle {
|
|
|
+ font-size: $font-size-H3;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ .smart-center-analysis-item-2-content {
|
|
|
+ .base-table {
|
|
|
+ margin-top: 12px;
|
|
|
+ .base-table-item {
|
|
|
+ width: 100%;
|
|
|
+ height: 40px;
|
|
|
+ display: flex;
|
|
|
+ background-color: rgb(113, 207, 224);
|
|
|
+ font-size: 12px;
|
|
|
+ color: #fff;
|
|
|
+ .title {
|
|
|
+ width: 50%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ border-bottom: 1px solid #fff;
|
|
|
+ border-right: 1px solid #fff;
|
|
|
+ }
|
|
|
+ .value {
|
|
|
+ width: 50%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ border-bottom: 1px solid #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .smart-center-analysis-item-3 {
|
|
|
+ .smart-center-analysis-item-3-subtitle {
|
|
|
+ margin-top: 20px;
|
|
|
+ font-size: $font-size-H4;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .title-1 {
|
|
|
+ font-size: $font-size-H1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title-2 {
|
|
|
+ font-size: $font-size-H2;
|
|
|
+ margin: 24px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title-3 {
|
|
|
+ font-size: $font-size-H3;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title-4 {
|
|
|
+ font-size: $font-size-H4;
|
|
|
+ margin: 12px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title-5 {
|
|
|
+ font-size: $font-size-H5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picture-title {
|
|
|
+ font-size: $font-size-H5;
|
|
|
+ margin-top: 20px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ text-align: center;
|
|
|
+ color: #5c5b5b;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+</style>
|