|
@@ -0,0 +1,582 @@
|
|
|
+<template>
|
|
|
+ <div class="area-data-container">
|
|
|
+ <Loading v-show="isLoading"></Loading>
|
|
|
+ <vuescroll>
|
|
|
+ <!-- 头部统计 -->
|
|
|
+ <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 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="online-data-wrap">
|
|
|
+ <div class="percent-wrap border-style">
|
|
|
+ <Percent :count="dimension"></Percent>
|
|
|
+ </div>
|
|
|
+ <div class="point-wrap border-style">
|
|
|
+ <AbilityPoint :count="abilityPoint"></AbilityPoint>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 校本研修数据统计 -->
|
|
|
+ <div class="online-train-wrap">
|
|
|
+ <h4 class="block-title">校本研修统计</h4>
|
|
|
+ <div class="offline-data-wrap">
|
|
|
+ <div class="offline-data-item border-style" v-for="(item,index) in trainType" :key="index">
|
|
|
+ <img class="offline-img" :src="trainImgs[index]">
|
|
|
+ <div style="margin-left:20px;height:fit-content;">
|
|
|
+ <p class="offline-label" :title="item.label">{{item.label}}</p>
|
|
|
+ <p class="offline-value"><b>{{item.count || 0}}</b></p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 学时数据统计 -->
|
|
|
+ <div class="online-train-wrap" style="margin-bottom:40px">
|
|
|
+
|
|
|
+ <h4 class="block-title">学时统计</h4>
|
|
|
+ <div class="hour-data-wrap">
|
|
|
+ <div class="hour-data-item border-style" v-for="(item,index) in hourData" :key="index">
|
|
|
+ <p class="hour-data-title">
|
|
|
+ {{item.name}}
|
|
|
+ <span class="hour-value">({{item.total}}学时)</span>
|
|
|
+ </p>
|
|
|
+ <div class="hour-chart">
|
|
|
+ <HourProg :count="[item.complete,item.going,item.uncomplete]"></HourProg>
|
|
|
+ <p class="legend-item">
|
|
|
+ <span>
|
|
|
+ 未开始:{{item.uncomplete}}人
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ <p class="legend-item">
|
|
|
+ <span>
|
|
|
+ 进行中:{{item.going}}人
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ <p class="legend-item">
|
|
|
+ <span>
|
|
|
+ 已完成:{{item.complete}}人
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 学校概览 -->
|
|
|
+ <div class="online-train-wrap" style="margin-bottom:40px">
|
|
|
+ <div>
|
|
|
+ <h4 class="block-title">学校总览</h4>
|
|
|
+ <Button class="export-data-wrap" type="primary" icon="md-cloud-download">
|
|
|
+ 导出数据
|
|
|
+ </Button>
|
|
|
+ <Input search placeholder="搜索学校" class="school-search" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="school-data-wrap">
|
|
|
+ <div class="school-data-item border-style" v-for="(item,index) in schoolList" :key="index">
|
|
|
+ <img class="school-img" :src="item.picture">
|
|
|
+ <div style="margin-left:20px;height:fit-content;">
|
|
|
+ <p class="school-name" :title="item.label">{{item.name}}</p>
|
|
|
+ <p class="school-value">
|
|
|
+ <span>参训人数:</span>
|
|
|
+ <span>68人</span>
|
|
|
+ </p>
|
|
|
+ <p class="school-value">
|
|
|
+ <span>完成人数:</span>
|
|
|
+ <span>48人</span>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ <span class="to-school-detail">
|
|
|
+ 更多>>>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </vuescroll>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import Percent from '@/view/statistics/Percent.vue'
|
|
|
+import AbilityPoint from '@/view/statistics/AbilityPoint.vue'
|
|
|
+import HourProg from './HourProg.vue'
|
|
|
+import CountTo from 'vue-count-to'
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ Percent, AbilityPoint, HourProg, CountTo
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ schoolList: [],
|
|
|
+ topData: [
|
|
|
+ {
|
|
|
+ icon: 'ios-people',
|
|
|
+ color: '#2d8cf0',
|
|
|
+ number: 281,
|
|
|
+ text: '学校数量',
|
|
|
+ type: 'num'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ icon: 'md-cube',
|
|
|
+ color: '#2db7f5',
|
|
|
+ number: 3021,
|
|
|
+ text: '教师人数',
|
|
|
+ type: 'num'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ icon: 'md-bookmark',
|
|
|
+ color: '#5cadff',
|
|
|
+ number: 2890,
|
|
|
+ text: '参训人数',
|
|
|
+ type: 'num'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ icon: 'md-thumbs-up',
|
|
|
+ color: '#ff9900',
|
|
|
+ number: 83,
|
|
|
+ text: '参训率',
|
|
|
+ type: 'rate'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ icon: 'md-checkmark-circle',
|
|
|
+ color: '#19be6b',
|
|
|
+ number: 13,
|
|
|
+ text: '完成率',
|
|
|
+ type: 'rate'
|
|
|
+ }
|
|
|
+
|
|
|
+ ],
|
|
|
+ schoolInfo: undefined,
|
|
|
+ isLoading: false,
|
|
|
+ dimension: [],
|
|
|
+ abilityPoint: [],
|
|
|
+ offlineData: [
|
|
|
+ {
|
|
|
+ label: '教研组',
|
|
|
+ value: 0
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ trainType: [],
|
|
|
+ trainImgs: [
|
|
|
+ 'https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/image/%E4%BF%A1%E6%81%AF%E5%8C%96%E6%95%99%E5%AD%A6%E6%A1%88%E4%BE%8B.png',
|
|
|
+ 'https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/image/%E4%B8%93%E5%AE%B6%E4%B8%93%E9%A2%98%E5%9F%B9%E8%AE%AD.png',
|
|
|
+ 'https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/image/%E5%90%8C%E8%AF%BE%E5%BC%82%E6%9E%84.png',
|
|
|
+ 'https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/image/%E5%90%8C%E8%AF%BE%E5%90%8C%E6%9E%84.png',
|
|
|
+ 'https://teammodelstorage.blob.core.chinacloudapi.cn/0-public/image/%E6%A0%A1%E6%9C%AC2.0%E5%9F%B9%E8%AE%AD.png'
|
|
|
+ ],
|
|
|
+ hourData: [
|
|
|
+ {
|
|
|
+ name: '线上研修',
|
|
|
+ total: 20,
|
|
|
+ complete: 0,
|
|
|
+ going: 0,
|
|
|
+ uncomplete: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '校本研修',
|
|
|
+ total: 10,
|
|
|
+ complete: 0,
|
|
|
+ going: 0,
|
|
|
+ uncomplete: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '应用考核',
|
|
|
+ total: 15,
|
|
|
+ complete: 0,
|
|
|
+ going: 0,
|
|
|
+ uncomplete: 0
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '课堂实录',
|
|
|
+ total: 5,
|
|
|
+ complete: 0,
|
|
|
+ going: 0,
|
|
|
+ uncomplete: 0
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ returnList() {
|
|
|
+ this.$router.push({
|
|
|
+ name: 'areaMgmt'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ findTotalData() {
|
|
|
+ this.isLoading = true
|
|
|
+ let params = {
|
|
|
+ school: this.schoolInfo.id
|
|
|
+ }
|
|
|
+ this.$api.ability.FindTotalData(params).then(
|
|
|
+ res => {
|
|
|
+ if (!res.error) {
|
|
|
+ let deData = this.$GLOBAL.DIMENSIONS()
|
|
|
+ // 能力点统计
|
|
|
+ res.abilityCount.forEach(item => {
|
|
|
+ item.percent = (item.count * 100 / res.subCount).toFixed(1) + '%'
|
|
|
+ let d = deData.find(i => {
|
|
|
+ return i.code == item.dimension
|
|
|
+ })
|
|
|
+ if (d) {
|
|
|
+ item.dimensionName = d.val
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.abilityPoint = res.abilityCount
|
|
|
+
|
|
|
+ // 能力维度统计
|
|
|
+ res.dimensionCount.forEach(item => {
|
|
|
+ let d = deData.find(i => {
|
|
|
+ return i.code == item.dimension
|
|
|
+ })
|
|
|
+ if (d) {
|
|
|
+ item.name = d.val
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.dimension = res.dimensionCount
|
|
|
+
|
|
|
+ //学时数据统计
|
|
|
+ res.groupMembers.forEach(item => {
|
|
|
+ // 线上研修
|
|
|
+ if (item.onlineTime == 0) {
|
|
|
+ this.hourData[0].uncomplete++
|
|
|
+ } else if (item.onlineTime >= 20) {
|
|
|
+ this.hourData[0].complete++
|
|
|
+ } else {
|
|
|
+ this.hourData[0].going++
|
|
|
+ }
|
|
|
+ // 校本研修
|
|
|
+ if (item.offlinelTime == 0) {
|
|
|
+ this.hourData[1].uncomplete++
|
|
|
+ } else if (item.onlineTime >= 10) {
|
|
|
+ this.hourData[1].complete++
|
|
|
+ } else {
|
|
|
+ this.hourData[1].going++
|
|
|
+ }
|
|
|
+ // 应用考核
|
|
|
+ if (item.schoolScoreTime == 0) {
|
|
|
+ this.hourData[2].uncomplete++
|
|
|
+ } else if (item.onlineTime >= 15) {
|
|
|
+ this.hourData[2].complete++
|
|
|
+ } else {
|
|
|
+ this.hourData[2].going++
|
|
|
+ }
|
|
|
+ // 课堂实录
|
|
|
+ if (item.classVideoTime == 0) {
|
|
|
+ this.hourData[3].uncomplete++
|
|
|
+ } else if (item.onlineTime >= 5) {
|
|
|
+ this.hourData[3].complete++
|
|
|
+ } else {
|
|
|
+ this.hourData[3].going++
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ err => {
|
|
|
+
|
|
|
+ }
|
|
|
+ ).finally(() => {
|
|
|
+ this.isLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ findTrainList() {
|
|
|
+ let params = {
|
|
|
+ code: this.schoolInfo.id
|
|
|
+ }
|
|
|
+ this.$api.train.findTrainList(params).then(
|
|
|
+ res => {
|
|
|
+ console.log(res)
|
|
|
+ this.trainType = this.$GLOBAL.TRAIN_TYPE()
|
|
|
+ res.studies.forEach(item => {
|
|
|
+ this.trainType[item.type - 1].count = this.trainType[item.type - 1].count || 0
|
|
|
+ this.trainType[item.type - 1].count++
|
|
|
+ })
|
|
|
+ this.trainType.splice(this.trainType.length - 1, 1)
|
|
|
+ },
|
|
|
+ err => {
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.schoolInfo = {}
|
|
|
+ this.schoolInfo.id = 'hbcn'
|
|
|
+ this.findTotalData()
|
|
|
+ this.findTrainList()
|
|
|
+ this.schoolList = this.$store.state.user.userProfile.schools
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+.export-data-wrap {
|
|
|
+ float: right;
|
|
|
+ // margin-top: 8px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.school-search {
|
|
|
+ float: right;
|
|
|
+ width: 240px;
|
|
|
+ border-radius: 20px;
|
|
|
+ margin-right: 20px;
|
|
|
+}
|
|
|
+.border-style {
|
|
|
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+.hour-chart {
|
|
|
+ // height: 200px;
|
|
|
+ text-align: center;
|
|
|
+ .legend-item {
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 5px;
|
|
|
+ &::before {
|
|
|
+ content: " ";
|
|
|
+ display: inline-block;
|
|
|
+ width: 15px;
|
|
|
+ height: 8px;
|
|
|
+ // background: red;
|
|
|
+ border-radius: 2px;
|
|
|
+ margin-right: 10px;
|
|
|
+ margin-left: 15px;
|
|
|
+ }
|
|
|
+ &:nth-child(2)::before {
|
|
|
+ background: #ed4014;
|
|
|
+ }
|
|
|
+ &:nth-child(3)::before {
|
|
|
+ background: #ff9900;
|
|
|
+ }
|
|
|
+ &:nth-child(4)::before {
|
|
|
+ background: #19be6b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.hour-data-item {
|
|
|
+ width: 23%;
|
|
|
+ background: white;
|
|
|
+ padding-bottom: 20px;
|
|
|
+}
|
|
|
+.hour-data-wrap {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-top: 20px;
|
|
|
+ font-size: 16px;
|
|
|
+ .hour-value {
|
|
|
+ font-weight: bold;
|
|
|
+ color: #1e1f24;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+ .hour-data-title {
|
|
|
+ text-align: center;
|
|
|
+ // background: #f9f9f9;
|
|
|
+ padding: 10px 0px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.offline-data-wrap {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+.offline-data-item {
|
|
|
+ // margin: 10px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: white;
|
|
|
+ padding: 15px 30px;
|
|
|
+ border-radius: 5px;
|
|
|
+ .offline-label {
|
|
|
+ width: 120px;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ color: #1e1f24;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .offline-value {
|
|
|
+ margin-top: 5px;
|
|
|
+ font-size: 30px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #1e1f24;
|
|
|
+ }
|
|
|
+}
|
|
|
+.school-data-wrap {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ display: flex;
|
|
|
+ // justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+.school-data-item {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: white;
|
|
|
+ padding: 20px 40px 20px 30px;
|
|
|
+ margin-right: 30px;
|
|
|
+ border-radius: 5px;
|
|
|
+ transition: all 0.2s ease 0s;
|
|
|
+ &:hover {
|
|
|
+ box-shadow: 0 26px 40px -24px #aaa;
|
|
|
+ transform: translateY(-4px);
|
|
|
+ }
|
|
|
+ .school-name {
|
|
|
+ width: 120px;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ color: #17233d;
|
|
|
+ cursor: pointer;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 15px;
|
|
|
+ }
|
|
|
+ .school-value {
|
|
|
+ margin-top: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #808695;
|
|
|
+ }
|
|
|
+ .to-school-detail {
|
|
|
+ position: absolute;
|
|
|
+ right: 5px;
|
|
|
+ bottom: 5px;
|
|
|
+ color: #2d8cf0;
|
|
|
+ font-size: 12px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+}
|
|
|
+.offline-img {
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+ border-radius: 10px;
|
|
|
+}
|
|
|
+.school-img {
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+ border-radius: 10px;
|
|
|
+}
|
|
|
+.area-data-container {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ padding: 15px;
|
|
|
+ background: #f7f7f7;
|
|
|
+}
|
|
|
+.school-base-info {
|
|
|
+ border-radius: 5px;
|
|
|
+ width: 100%;
|
|
|
+ background: white;
|
|
|
+ padding: 25px 15px;
|
|
|
+ // box-shadow: 0px 4px 4px 1px #f0f0f0;
|
|
|
+ display: flex;
|
|
|
+ position: relative;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.return-list {
|
|
|
+ position: absolute;
|
|
|
+ right: 80px;
|
|
|
+ top: 35px;
|
|
|
+ color: #1cc0f3;
|
|
|
+ font-weight: bold;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.school-info-item {
|
|
|
+ margin-top: 10px;
|
|
|
+ .info-label {
|
|
|
+ color: #a0a0a0;
|
|
|
+ }
|
|
|
+ .info-value {
|
|
|
+ color: #5cadff;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+}
|
|
|
+.online-train-wrap {
|
|
|
+ border-radius: 5px;
|
|
|
+ width: 100%;
|
|
|
+ // background: white;
|
|
|
+ padding: 0px 20px;
|
|
|
+ // box-shadow: 0px 4px 4px 1px #f0f0f0;
|
|
|
+ margin-top: 50px;
|
|
|
+}
|
|
|
+.block-title {
|
|
|
+ border-left: 6px solid #1cc0f3;
|
|
|
+ padding-left: 15px;
|
|
|
+ font-size: 18px;
|
|
|
+ line-height: 16px;
|
|
|
+ color: #414749;
|
|
|
+ margin-bottom: 0px;
|
|
|
+}
|
|
|
+.online-data-wrap {
|
|
|
+ display: flex;
|
|
|
+ margin-top: 15px;
|
|
|
+}
|
|
|
+.percent-wrap {
|
|
|
+ width: fit-content;
|
|
|
+ padding: 30px 0px;
|
|
|
+ background: white;
|
|
|
+ // margin-left: 30px;
|
|
|
+}
|
|
|
+.point-wrap {
|
|
|
+ width: fit-content;
|
|
|
+ padding: 30px 0px;
|
|
|
+ background: white;
|
|
|
+ margin-left: 20px;
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+.top-block-wrap {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-top: 10px;
|
|
|
+ padding: 0px 20px 0px 20px;
|
|
|
+ // background: white;
|
|
|
+ // border-radius: 5px;
|
|
|
+}
|
|
|
+.content-con-item {
|
|
|
+ width: 18%;
|
|
|
+ height: 110px;
|
|
|
+ position: relative;
|
|
|
+ border-radius: 2px;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="less">
|
|
|
+.school-search .ivu-input {
|
|
|
+ // border-radius: 20px;
|
|
|
+}
|
|
|
+</style>
|