lg_frontend/pages/index.vue

657 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>