657 lines
20 KiB
Vue
657 lines
20 KiB
Vue
<template>
|
||
<div class="visual-container" :style="autoStyle">
|
||
<div class="header">
|
||
<div class="date">
|
||
{{ date }}
|
||
</div>
|
||
<div class="time">
|
||
{{ time }}
|
||
</div>
|
||
<div class="title">
|
||
{{ title }}
|
||
</div>
|
||
</div>
|
||
<div class="body">
|
||
<div class="left-panel">
|
||
<CustomTitle>教育资源</CustomTitle>
|
||
<Split num="10"></Split>
|
||
<div class="jyzy">
|
||
<div class="jyzy-t">
|
||
<a-row>
|
||
<a-col :span="12">
|
||
<CustomDesc title="年级数" :num="resourcesStatistics.gradeNumber || 0" :icon="njs" />
|
||
</a-col>
|
||
<a-col :span="12" style="padding-left: 23px;">
|
||
<CustomDesc title="班级数" :num="resourcesStatistics.classNumber || 0" :icon="bjs" />
|
||
</a-col>
|
||
</a-row>
|
||
</div>
|
||
<div class="jyzy-b">
|
||
<a-row>
|
||
<a-col :span="12">
|
||
<CustomDesc title="教职工数" :num="resourcesStatistics.staffNumber || 0" :icon="jzgs" />
|
||
</a-col>
|
||
<a-col :span="12" style="padding-left: 23px;">
|
||
<CustomDesc title="学生总数(人)" :num="resourcesStatistics.studentNumber || 0" :icon="xszs" />
|
||
</a-col>
|
||
</a-row>
|
||
</div>
|
||
|
||
</div>
|
||
<CustomLine />
|
||
<Split num="23"></Split>
|
||
<CustomSubTitle>各年级学生分布</CustomSubTitle>
|
||
<Split num="12">
|
||
|
||
</Split>
|
||
<div style="height: 190px;">
|
||
<Pie :data="studentGradStatistics" name="学生总数" :total="resourcesStatistics.studentNumber || 0"></Pie>
|
||
</div>
|
||
<Split num="12"></Split>
|
||
<CustomSubTitle>性别分布</CustomSubTitle>
|
||
<div style="height: 126px;">
|
||
<Split num="8"></Split>
|
||
<a-row class="xbfb" :gutter="30">
|
||
<a-col :span="12">
|
||
<div class="tp">
|
||
<div class="sex">男</div>
|
||
<div class="info">
|
||
<span class="num">{{ studentSexStatistics.men.total }}</span>
|
||
<div class="info-line"></div>
|
||
<span class="num">{{ studentSexStatistics.men.percent }}%</span>
|
||
</div>
|
||
</div>
|
||
<div class="process">
|
||
<div class="persen men" v-for="num in personArr" :key="num.value" :class="{ select: studentSexStatistics.men.percent >= num.value }"></div>
|
||
</div>
|
||
</a-col>
|
||
<a-col :span="12" style="padding-left: 23px;">
|
||
<div class="tp">
|
||
<div class="sex">女</div>
|
||
<div class="info">
|
||
<span class="num">{{ studentSexStatistics.women.total }}</span>
|
||
<div class="info-line"></div>
|
||
<span class="num">{{ studentSexStatistics.women.percent }}%</span>
|
||
</div>
|
||
</div>
|
||
<div class="process">
|
||
<div class="persen women" v-for="num in personArr" :key="num.value" :class="{ select: studentSexStatistics.women.percent >= num.value }"></div>
|
||
</div>
|
||
</a-col>
|
||
</a-row>
|
||
<Split num="23"></Split>
|
||
</div>
|
||
<CustomTitle>电子班牌概况</CustomTitle>
|
||
<div style="height: 106px; box-sizing: border-box;padding: 13px 0;">
|
||
<div class="jkdgk">
|
||
<CustomDesc title="总数(个)" :num="deviceStatistics.deviceTotalNumber || 0" color="#08EBF5" />
|
||
<CustomDesc title="在线(个)" :num="deviceStatistics.deviceOnlineNumber || 0" color="#2DFBC4" />
|
||
<CustomDesc title="离线(个)" :num="deviceStatistics.deviceOfflineNumber || 0" color="#FF7011" />
|
||
<CustomDesc title="待检测(个)" :num="deviceStatistics.deviceOtherNumber || 0" color="#E6F6FF" />
|
||
</div>
|
||
</div>
|
||
<CustomTitle>今日门禁进出</CustomTitle>
|
||
<div style="height: 217px;padding-top: 14px;">
|
||
<div class="mjjc">
|
||
<div class="mjjc-item-1 mjjc-item">
|
||
<CustomDesc2 title="教职工" :num="accessStatistics.staffNumber || 0"></CustomDesc2>
|
||
</div>
|
||
<div class="mjjc-item-2 mjjc-item">
|
||
<CustomDesc2 title="学生" :num="accessStatistics.studentNumber || 0"></CustomDesc2>
|
||
</div>
|
||
<div class="mjjc-item-3 mjjc-item">
|
||
<CustomDesc2 title="校外人员" :num="accessStatistics.otherNumber || 0"></CustomDesc2>
|
||
</div>
|
||
<div class="mjjc-item-4 mjjc-item">
|
||
<CustomDesc2 title="出入总数" :num="accessStatistics.atSchoolNumber || 0" color="#E6F6FF" font-size="24"></CustomDesc2>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="right-panel">
|
||
<CustomTitle>今日在校人数</CustomTitle>
|
||
<div style="height: 98px;padding: 15px 0;box-sizing: border-box">
|
||
<div class="zxrs-main">
|
||
<NumCon :num="studentAttendanceStatistics.atSchoolNumber || 0"></NumCon>
|
||
</div>
|
||
</div>
|
||
<CustomTitle>考勤统计</CustomTitle>
|
||
<div style="height: 258px;" class="kqtj">
|
||
<div class="kqtj-t">
|
||
<div class="top-info">
|
||
<CustomDesc titleColor="#08EBF5" paddingLeft="0" align="center" title="可打卡学生总数" :num="studentAttendanceStatistics.studentTotalNumber || 0" />
|
||
<CustomDesc titleColor="#08EBF5" paddingLeft="0" align="center" title="出勤人数" :num="studentAttendanceStatistics.studentAttendanceNumber || 0" />
|
||
<CustomDesc titleColor="#08EBF5" paddingLeft="0" align="center" title="出勤率" :num="(studentAttendanceStatistics.studentAttendanceProportion || 0) + '%'" />
|
||
</div>
|
||
</div>
|
||
<div style="height: 160px;">
|
||
<Pie :data="studentAttendanceStatisticsPie" name="出勤率" :total="(studentAttendanceStatistics.studentAttendanceProportion || 0) + '%'"></Pie>
|
||
</div>
|
||
</div>
|
||
<CustomTitle>各年级数人分布</CustomTitle>
|
||
<div style="height: 222px;">
|
||
<div class="tabs">
|
||
<TabItem @click="classClickHandler(1)" :selected="cls === 1">一年级</TabItem>
|
||
<TabItem @click="classClickHandler(2)" :selected="cls === 2">二年级</TabItem>
|
||
<TabItem @click="classClickHandler(3)" :selected="cls === 3">三年级</TabItem>
|
||
<TabItem @click="classClickHandler(4)" :selected="cls === 4">四年级</TabItem>
|
||
<TabItem @click="classClickHandler(5)" :selected="cls === 5">五年级</TabItem>
|
||
<TabItem @click="classClickHandler(6)" :selected="cls === 6">六年级</TabItem>
|
||
</div>
|
||
|
||
<div style="height: 169px;">
|
||
<Pie :data="gradeStatistics"></Pie>
|
||
|
||
</div>
|
||
</div>
|
||
<CustomTitle>近7日请假统计</CustomTitle>
|
||
<div style="height: 303px;">
|
||
<Bar :colors="barColors" :data="leaveStatistics"></Bar>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="center">
|
||
<div class="center-img">
|
||
<img :src="schSrc" alt="">
|
||
</div>
|
||
<CustomTitle type="2" style="margin-top: 12px;">电子班牌使用情况</CustomTitle>
|
||
<Split num="22"></Split>
|
||
<div style="height: 94px;">
|
||
<a-row type="flex" justify="center">
|
||
<a-col :span="8" class="fc">
|
||
<a-row type="flex" justify="center">
|
||
<a-col :span="12">
|
||
<CustomDesc title="信息发布数" :num="classBrandStatistics.releaseNumber || 0" :icon="xxfbs"></CustomDesc>
|
||
</a-col>
|
||
<a-col :span="12">
|
||
<CustomDesc title="刷脸数" :num="classBrandStatistics.brushFaceNumber || 0" :icon="sls"></CustomDesc>
|
||
</a-col>
|
||
</a-row>
|
||
|
||
<CustomLine type="2" />
|
||
</a-col>
|
||
<a-col :span="16" style="padding-left: 32px;">
|
||
<a-row :gutter="16">
|
||
<a-col :span="12">
|
||
<div class="dzbpboard b1">
|
||
<div class="board-main">
|
||
<CustomDesc title="留言数量" :num="classBrandStatistics.brandMessageCount || 0" padding-left="0"></CustomDesc>
|
||
<CustomDesc title="发言人数" :num="classBrandStatistics.brandMessagePersonCount || 0" color="#34FF66" padding-left="0"></CustomDesc>
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
<a-col :span="12">
|
||
<div class="dzbpboard b2">
|
||
<div class="board-main">
|
||
<CustomDesc title="照片数量" :num="classBrandStatistics.photoNumber || 0" padding-left="0"></CustomDesc>
|
||
<CustomDesc title="视频数量" :num="classBrandStatistics.videoNumber || 0" color="#34FF66" padding-left="0"></CustomDesc>
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
</a-row>
|
||
</a-col>
|
||
</a-row>
|
||
</div>
|
||
<CustomTitle type="2" >签到记录</CustomTitle>
|
||
<div style="height: 278px;">
|
||
<Split num="12"></Split>
|
||
<div style="height: 213px;overflow: hidden">
|
||
<vue-seamless-scroll
|
||
:data="accessInfo"
|
||
:class-option="classOption"
|
||
class="warp"
|
||
>
|
||
<SwiperCard v-for="item in accessInfo" :key="item.uuid" :card-info="item"></SwiperCard>
|
||
</vue-seamless-scroll>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import moment from 'moment'
|
||
import schSrc from 'assets/images/学校全景.jpg'
|
||
import njs from 'assets/images/编组 20 2.png'
|
||
import bjs from 'assets/images/编组 20.png'
|
||
import jzgs from 'assets/images/图标.png'
|
||
import xszs from 'assets/images/图标 2.png'
|
||
import xxfbs from 'assets/images/编组 11备份 2.png'
|
||
import sls from 'assets/images/编组 11备份 2 2.png'
|
||
import { raf, caf } from '@/utils/animate'
|
||
import https from '@/mixins/https'
|
||
import vueSeamlessScroll from 'vue-seamless-scroll'
|
||
const nowDate = moment().format('YYYY-MM-DD')
|
||
const nowTime = moment().format('HH:mm:ss')
|
||
export default {
|
||
name: 'IndexPage',
|
||
mixins: [https],
|
||
components: {
|
||
vueSeamlessScroll
|
||
},
|
||
data () {
|
||
return {
|
||
autoStyle: {},
|
||
classOption: {
|
||
step: 1, // 数值越大速度滚动越快
|
||
limitMoveNum: 6, // 开始无缝滚动的数据量 this.dataList.length
|
||
hoverStop: true, // 是否开启鼠标悬停stop
|
||
direction: 2, // 0向下 1向上 2向左 3向右
|
||
openWatch: true, // 开启数据实时监控刷新dom
|
||
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
|
||
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
|
||
waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
|
||
},
|
||
rate: 50,
|
||
personArr: [
|
||
{ value: 12.5 },
|
||
{ value: 25 },
|
||
{ value: 37.5 },
|
||
{ value: 50 },
|
||
{ value: 62.5 },
|
||
{ value: 75 },
|
||
{ value: 87.5 },
|
||
{ value: 100 },
|
||
],
|
||
sls,
|
||
xxfbs,
|
||
xszs,
|
||
jzgs,
|
||
njs,
|
||
bjs,
|
||
schSrc,
|
||
date: nowDate,
|
||
time: nowTime,
|
||
title: '西乌旗第三小学智慧校园可视化管理平台',
|
||
barColors: [
|
||
[ '#8AFFE2', '#00BFFF' ],
|
||
[ '#FF7313', '#EFD351' ],
|
||
],
|
||
cls: 1
|
||
}
|
||
},
|
||
mounted() {
|
||
this.getTime()
|
||
this.getAutoStyle()
|
||
window.addEventListener('resize', (e) => {
|
||
e.stopPropagation()
|
||
this.getAutoStyle()
|
||
}, false)
|
||
|
||
},
|
||
computed: {
|
||
|
||
},
|
||
methods: {
|
||
getAutoStyle () {
|
||
const { scale, origin } = this.getScale()
|
||
this.autoStyle = {
|
||
transform: `scale(${scale})`,
|
||
transformOrigin: origin
|
||
}
|
||
},
|
||
getScale () {
|
||
let scale = 1
|
||
let origin = 'top center'
|
||
const baseWidth = 1920
|
||
const baseHeight = 1080
|
||
const innerWidth = window.innerWidth
|
||
const innerHeight = window.innerHeight
|
||
const widthScale = innerWidth / baseWidth
|
||
const scaleHeight = baseHeight * widthScale
|
||
if (scaleHeight <= innerHeight) {
|
||
origin = 'left center'
|
||
scale = widthScale
|
||
if (scale > 1) {
|
||
origin = 'left top'
|
||
}
|
||
} else {
|
||
scale = innerHeight / baseHeight
|
||
}
|
||
return { scale, origin }
|
||
},
|
||
classClickHandler (cls) {
|
||
this.cls = cls
|
||
this.getGradeStatisticsPieData()
|
||
},
|
||
getTime () {
|
||
this.date = moment().format('YYYY-MM-DD')
|
||
this.time = moment().format('HH:mm:ss')
|
||
if (this.raf) {
|
||
caf(this.raf)
|
||
}
|
||
this.raf = raf(() => {
|
||
this.getTime()
|
||
})
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
<style>
|
||
body, html, #__nuxt, #__layout {
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: #000;
|
||
overflow: hidden;
|
||
}
|
||
.list-enter-active, .list-leave-active {
|
||
transition: all 0.5s;
|
||
}
|
||
.list-enter, .list-leave-to
|
||
/* .list-leave-active for below version 2.1.8 */ {
|
||
opacity: 0;
|
||
transform: translateY(30px);
|
||
}
|
||
</style>
|
||
<style scoped lang="less">
|
||
@import "assets/styles/mixin";
|
||
|
||
.warp {
|
||
width: 100%;
|
||
.swiper-con {
|
||
.clear-fix;
|
||
}
|
||
}
|
||
.visual-container {
|
||
width: 1920px;
|
||
height: 1080px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
background: url("assets/images/bg.png") left top no-repeat;
|
||
background-size: 100% 100%;
|
||
user-select: none;
|
||
.header {
|
||
height: 56px;
|
||
width: 100%;
|
||
background-color: #333;
|
||
line-height: 56px;
|
||
box-sizing: border-box;
|
||
padding: 0 32px;
|
||
background: url("assets/images/顶部导航.png") left 4px no-repeat;
|
||
background-size: 100% 100%;
|
||
.clear-fix;
|
||
.date, .time {
|
||
width: 100px;
|
||
font-family: HIKLDH-Number-CondensedMedium;
|
||
font-size: 16px;
|
||
color: #08EBF5;
|
||
letter-spacing: 0;
|
||
font-weight: 500;
|
||
}
|
||
.date {
|
||
.float(left)
|
||
}
|
||
.time {
|
||
.float(right);
|
||
text-align: right;
|
||
}
|
||
.title {
|
||
overflow: hidden;
|
||
font-family: HYHeiFangJ;
|
||
font-size: 30px;
|
||
color: #fff;
|
||
text-align: center;
|
||
text-shadow: 3px 3px 3px rgba(2,36,40,0.25);
|
||
font-weight: 700;
|
||
}
|
||
|
||
}
|
||
.body {
|
||
height: calc(100% - 56px);
|
||
box-sizing: border-box;
|
||
padding: 16px 32px;
|
||
.clear-fix;
|
||
.left-panel {
|
||
height: 100%;
|
||
width: 488px;
|
||
.float(left);
|
||
padding-right: 27px;
|
||
box-sizing: border-box;
|
||
.xbfb {
|
||
position: relative;
|
||
height: 103px;
|
||
.tp {
|
||
height: 33px;
|
||
line-height: 33px;
|
||
.clear-fix;
|
||
.sex {
|
||
float: left;
|
||
font-family: PingFangSC-Regular;
|
||
font-size: 14px;
|
||
color: #9FF7FF;
|
||
letter-spacing: 0;
|
||
font-weight: 400;
|
||
}
|
||
.info {
|
||
float: right;
|
||
font-family: HIKLDH-Number-CondensedMedium;
|
||
font-size: 24px;
|
||
color: #08EBF5;
|
||
letter-spacing: 0;
|
||
line-height: 33px;
|
||
font-weight: 500;
|
||
.clear-fix;
|
||
.num, .info-line {
|
||
float: left;
|
||
}
|
||
.info-line {
|
||
width: 2px;
|
||
height: 33px;
|
||
background-color: #08EBF5;
|
||
margin: 0 11px;
|
||
}
|
||
}
|
||
}
|
||
.process {
|
||
.clear-fix;
|
||
padding-top: 13px;
|
||
.persen {
|
||
float: left;
|
||
margin-left: 4px;
|
||
width: 22px;
|
||
height: 50px;
|
||
|
||
&:first-child {
|
||
margin-left: 0;
|
||
}
|
||
&.men {
|
||
background: url('assets/images/形状结合备份 16.png') left top no-repeat;
|
||
background-size: 100% 100%;
|
||
&.select {
|
||
background: url('assets/images/男性(亮).png') left top no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
}
|
||
&.women {
|
||
background: url('assets/images/形状备份 3.png') left top no-repeat;
|
||
background-size: 100% 100%;
|
||
&.select {
|
||
background: url('assets/images/女性(亮).png') left top no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
&:after {
|
||
position: absolute;
|
||
content: " ";
|
||
display: table;
|
||
top: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
height: 100%;
|
||
width: 1px;
|
||
background: linear-gradient(to top, transparent, rgba(255, 255, 255, 0.5), #08EBF5, rgba(255, 255, 255, 0.5), transparent);//从下到上
|
||
}
|
||
}
|
||
.jyzy {
|
||
position: relative;
|
||
&:after {
|
||
position: absolute;
|
||
content: " ";
|
||
display: table;
|
||
top: 0;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
height: 100%;
|
||
width: 1px;
|
||
background: linear-gradient(to top, transparent, rgba(255, 255, 255, 0.5), #08EBF5, rgba(255, 255, 255, 0.5), transparent);//从下到上
|
||
}
|
||
}
|
||
.jyzy-t {
|
||
position: relative;
|
||
padding: 15px;
|
||
box-sizing: border-box;
|
||
&:after {
|
||
position: absolute;
|
||
content: " ";
|
||
display: table;
|
||
bottom: 0;
|
||
left: 0;
|
||
height: 1px;
|
||
width: 100%;
|
||
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.5), #08EBF5, rgba(255, 255, 255, 0.5), transparent);//从下到上
|
||
}
|
||
}
|
||
.jyzy-b {
|
||
position: relative;
|
||
padding: 15px;
|
||
box-sizing: border-box;
|
||
}
|
||
.jkdgk {
|
||
height: 80px;
|
||
background: url('assets/images/1状态数量统计.png') left top no-repeat;
|
||
background-size: 100% 100%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
.mjjc {
|
||
height: 176px;
|
||
background: url('assets/images/编组 18.png') left top no-repeat;
|
||
background-size: 100% 100%;
|
||
position: relative;
|
||
.mjjc-item {
|
||
position: absolute;
|
||
width: 96px;
|
||
height: 64px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
&.mjjc-item-1 {
|
||
top: 0;
|
||
left: 0;
|
||
}
|
||
&.mjjc-item-2 {
|
||
right: 0px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
&.mjjc-item-3 {
|
||
bottom: 5px;
|
||
left: 0;
|
||
}
|
||
&.mjjc-item-4 {
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
.right-panel {
|
||
height: 100%;
|
||
width: 488px;
|
||
.float(right);
|
||
padding-left: 27px;
|
||
box-sizing: border-box;
|
||
.zxrs-main {
|
||
height: 67px;
|
||
background: url("assets/images/编组 4.png") left 4px no-repeat;
|
||
background-size: 100% 100%;
|
||
padding-left: 130px;
|
||
padding-top: 13px;
|
||
|
||
}
|
||
}
|
||
.center {
|
||
height: 100%;
|
||
overflow: hidden;
|
||
.center-img {
|
||
width: 100%;
|
||
height: 538px;
|
||
padding: 10px;
|
||
background: url("assets/images/编组212.png") left 4px no-repeat;
|
||
background-size: 100% 535px;
|
||
> img {
|
||
width: 100%;
|
||
display: block;
|
||
height: 518px;
|
||
}
|
||
}
|
||
.board-main {
|
||
width: 214px;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding-right: 37px;
|
||
box-sizing: border-box;
|
||
padding-top: 10px;
|
||
}
|
||
.fc {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
> div:nth-child(1) {
|
||
width: 100% ;
|
||
};
|
||
}
|
||
.dzbpboard {
|
||
height: 72px;
|
||
box-sizing: border-box;
|
||
padding-left: 70px;
|
||
&.b1 {
|
||
background: url("assets/images/顶部本月的粉 2.png") left 4px no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
&.b2 {
|
||
background: url("assets/images/顶部本月的粉.png") left 4px no-repeat;
|
||
background-size: 100% 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.kqtj-t {
|
||
padding: 10px 16px 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.top-info {
|
||
background: url("assets/images/编组 21.png") center 22px no-repeat;
|
||
background-size: 100% 50%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
height: 64px;
|
||
box-sizing: border-box;
|
||
padding: 0 20px;
|
||
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 15px;
|
||
width: 100%;
|
||
}
|
||
|
||
}
|
||
</style>
|