完善http模块和日志输出级别
This commit is contained in:
		
							parent
							
								
									91ad9927f2
								
							
						
					
					
						commit
						c61cfa7ee6
					
				| 
						 | 
				
			
			@ -13,6 +13,7 @@
 | 
			
		|||
    "axios": "^1.6.1",
 | 
			
		||||
    "core-js": "^3.25.3",
 | 
			
		||||
    "echarts": "^5.4.3",
 | 
			
		||||
    "loglevel": "^1.9.1",
 | 
			
		||||
    "nuxt": "^2.15.8",
 | 
			
		||||
    "vue": "^2.7.10",
 | 
			
		||||
    "vue-echarts": "^4.1.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										653
									
								
								pages/index.vue
								
								
								
								
							
							
						
						
									
										653
									
								
								pages/index.vue
								
								
								
								
							| 
						 | 
				
			
			@ -1,656 +1,7 @@
 | 
			
		|||
<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>
 | 
			
		||||
  <div>hello world</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()
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
  export default {}
 | 
			
		||||
</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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,11 @@ export default {
 | 
			
		|||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.$log.info('test')
 | 
			
		||||
    this.$log.error('test')
 | 
			
		||||
    this.$log.trace('test')
 | 
			
		||||
    this.$log.info('test')
 | 
			
		||||
    this.$log.warn('test')
 | 
			
		||||
    this.getAutoStyle()
 | 
			
		||||
    window.addEventListener('resize', (e) => {
 | 
			
		||||
      e.stopPropagation()
 | 
			
		||||
| 
						 | 
				
			
			@ -161,11 +166,13 @@ body, html, #__nuxt, #__layout {
 | 
			
		|||
      height: 2721px;
 | 
			
		||||
      background: url("assets/peakCoalImages/left/left-content-bg.png") no-repeat center 60px;
 | 
			
		||||
      padding: 300px 476px 100px 412px;
 | 
			
		||||
      perspective: 500px;
 | 
			
		||||
 | 
			
		||||
      .left-data-panel {
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        transform: rotate(2deg);
 | 
			
		||||
        transform: rotateY(2deg);
 | 
			
		||||
        transform-origin: left center;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -177,11 +184,13 @@ body, html, #__nuxt, #__layout {
 | 
			
		|||
      height: 2721px;
 | 
			
		||||
      background: url("assets/peakCoalImages/right/right-content-bg.png") no-repeat center 60px;
 | 
			
		||||
      padding: 300px 476px 100px 480px;
 | 
			
		||||
      perspective: 500px;
 | 
			
		||||
 | 
			
		||||
      .right-data-panel {
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        transform: rotate(-2deg);
 | 
			
		||||
        transform: rotateY(-2deg);
 | 
			
		||||
        transform-origin: right center;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,11 @@
 | 
			
		|||
import Vue from 'vue'
 | 
			
		||||
import Antd from 'ant-design-vue/lib'
 | 
			
		||||
import log from 'loglevel';
 | 
			
		||||
const logLevel = parseInt(localStorage.getItem('loglevel') || '-1')
 | 
			
		||||
 | 
			
		||||
if (logLevel >= 0) {
 | 
			
		||||
  log.setDefaultLevel(logLevel)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vue.prototype.$log = log
 | 
			
		||||
Vue.use(Antd)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,54 +1,10 @@
 | 
			
		|||
import { get, post } from './axios'
 | 
			
		||||
// 教育资源统计信息
 | 
			
		||||
export const getResourcesStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getResourcesStatistics')
 | 
			
		||||
import { SupportLog, Request, Get, Post, Delete, Log } from './httpModule'
 | 
			
		||||
@SupportLog
 | 
			
		||||
@Request('/aaa')
 | 
			
		||||
class Apis {
 | 
			
		||||
  @Log('test')
 | 
			
		||||
  @Get('test')
 | 
			
		||||
  test () {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 各年级学生分布信息
 | 
			
		||||
export const getStudentGradStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getStudentGradStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 性别分布
 | 
			
		||||
export const getStudentSexStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getStudentSexStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 设备概况
 | 
			
		||||
export const getDeviceStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getDeviceStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 门禁进出人数
 | 
			
		||||
export const getAccessStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getAccessStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 查询班牌统计信息
 | 
			
		||||
export const getClassBrandStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getClassBrandStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 签到记录-最新10条
 | 
			
		||||
export const getAccessInfo = function () {
 | 
			
		||||
  return get('/cloudStatistics/getAccessInfo')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 在校人数与考勤统计
 | 
			
		||||
export const getStudentAttendanceStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getStudentAttendanceStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 各年级人数及出勤分布
 | 
			
		||||
export const getGradeStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getGradeStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 近7日请假统计
 | 
			
		||||
export const getLeaveStatistics = function () {
 | 
			
		||||
  return get('/cloudStatistics/getLeaveStatistics')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default new Apis()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,14 +41,7 @@ service.interceptors.response.use(
 | 
			
		|||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const get = (url, params = {}, config) => {
 | 
			
		||||
  return service.get(url, { params: params || {}, ...(config ||{}) })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const post = (url, params = {}, config) => {
 | 
			
		||||
  return service.post(url, params, config || {})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { get, post }
 | 
			
		||||
export default service
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,175 @@
 | 
			
		|||
 | 
			
		||||
import checkTypes from "@/utils/checkTypes";
 | 
			
		||||
import {urlJoin} from "@/utils/url";
 | 
			
		||||
import {isEmpty} from "@/utils/tools";
 | 
			
		||||
import http from './axios'
 | 
			
		||||
const isDev = process.env.NODE_ENV === 'development'
 | 
			
		||||
 | 
			
		||||
const getUrlByCode = function (url, obj = {}) {
 | 
			
		||||
  const reg = /\{([a-zA-Z0-9]+)\}/g
 | 
			
		||||
  const match = url.match(reg) || []
 | 
			
		||||
  let str = url
 | 
			
		||||
  match.forEach(field => {
 | 
			
		||||
    const _field = field.substr(1, field.length - 2)
 | 
			
		||||
    str = str.replace(field, obj[_field] || field)
 | 
			
		||||
  })
 | 
			
		||||
  return str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获取请求地址
 | 
			
		||||
 * @param prefix
 | 
			
		||||
 * @param url
 | 
			
		||||
 */
 | 
			
		||||
const getUrl = (prefix, url) => {
 | 
			
		||||
  if (url.startsWith('http') || !prefix) return url
 | 
			
		||||
  if (prefix.startsWith('http')) {
 | 
			
		||||
    return urlJoin(`${prefix}/${url}`)
 | 
			
		||||
  }
 | 
			
		||||
  return urlJoin(`/${prefix}/${url}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 请求处理
 | 
			
		||||
 * @param httpMethod  { String } 请求类型
 | 
			
		||||
 * @param fetchUrl { String } 请求地址
 | 
			
		||||
 * @returns {function(...[*]=)}
 | 
			
		||||
 */
 | 
			
		||||
const decoratorHandler = function (httpMethod, fetchUrl) {
 | 
			
		||||
  return function (target, propertyKey, descriptor) {
 | 
			
		||||
    const method = descriptor.value
 | 
			
		||||
    descriptor.value = async function (params = {}, options = {}, $logName) {
 | 
			
		||||
      const res = await method.apply(this, [params, options])
 | 
			
		||||
      let _params = params
 | 
			
		||||
      let _options = options
 | 
			
		||||
      if (!isEmpty(res) && checkTypes.isObject(res) && res.params) {
 | 
			
		||||
        _params = res.params
 | 
			
		||||
        _options = res.options
 | 
			
		||||
      }
 | 
			
		||||
      if (this._commonAxiosOptions) {
 | 
			
		||||
        _options = {
 | 
			
		||||
          ...this._commonAxiosOptions,
 | 
			
		||||
          ..._options
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // 生成请求参数
 | 
			
		||||
      const httpOptions = {
 | 
			
		||||
        method: httpMethod,
 | 
			
		||||
        url: getUrl(this.prefix, getUrlByCode(fetchUrl || propertyKey, _params)),
 | 
			
		||||
        baseURL: '',
 | 
			
		||||
        ..._options
 | 
			
		||||
      }
 | 
			
		||||
      if (httpMethod === 'get') {
 | 
			
		||||
        httpOptions.params = _params
 | 
			
		||||
      } else {
 | 
			
		||||
        httpOptions.data = _params
 | 
			
		||||
      }
 | 
			
		||||
      try {
 | 
			
		||||
        const response = await http(httpOptions)
 | 
			
		||||
        if (this.log) return this.log($logName, httpOptions, response)
 | 
			
		||||
        return response
 | 
			
		||||
      } catch (error) {
 | 
			
		||||
        if (this.log) throw this.log($logName, httpOptions, null, error)
 | 
			
		||||
        throw error
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 根据环境过滤地址
 | 
			
		||||
 * @param devUrl { String }
 | 
			
		||||
 * @param prodUrl { String }
 | 
			
		||||
 * @returns {String}
 | 
			
		||||
 */
 | 
			
		||||
const filterUrl = function (devUrl, prodUrl) {
 | 
			
		||||
  return (isDev ? devUrl : prodUrl || devUrl) || undefined
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 初始化请求接口前缀
 | 
			
		||||
 * @param devPrefix { String } 开发环境请求地址前缀
 | 
			
		||||
 * @param prodPrefix { String } 生产环境请求地址前缀
 | 
			
		||||
 * @returns {function(*): {new(): {prefix: *}, prototype: {prefix: *}}}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const Request = (devPrefix, prodPrefix) => {
 | 
			
		||||
  return function (constructor) {
 | 
			
		||||
    return class extends constructor {
 | 
			
		||||
      prefix = isDev ? devPrefix : prodPrefix || devPrefix
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Post请求
 | 
			
		||||
 * @param devUrl { String }
 | 
			
		||||
 * @param prodUrl { String }
 | 
			
		||||
 * @returns {function(...[*]=)}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const Post = (devUrl, prodUrl) => {
 | 
			
		||||
  let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl
 | 
			
		||||
  return decoratorHandler.call(this, 'post', filterUrl(_devUrl, prodUrl))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get请求
 | 
			
		||||
 * @param devUrl { String }
 | 
			
		||||
 * @param prodUrl { String }
 | 
			
		||||
 * @returns {function(...[*]=)}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const Get = (devUrl, prodUrl) => {
 | 
			
		||||
  let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl
 | 
			
		||||
  return decoratorHandler.call(this, 'get', filterUrl(_devUrl, prodUrl))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Put请求注解
 | 
			
		||||
 * @param devUrl { String }
 | 
			
		||||
 * @param prodUrl { String }
 | 
			
		||||
 * @returns {function(...[*]=)}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const Put = (devUrl, prodUrl) => {
 | 
			
		||||
  let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl
 | 
			
		||||
  return decoratorHandler.call(this, 'put', filterUrl(_devUrl, prodUrl))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Delete请求注解
 | 
			
		||||
 * @param devUrl { String }
 | 
			
		||||
 * @param prodUrl { String }
 | 
			
		||||
 * @returns {function(...[*]=)}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const Delete = (devUrl, prodUrl) => {
 | 
			
		||||
  let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl
 | 
			
		||||
  return decoratorHandler.call(this, 'delete', filterUrl(_devUrl, prodUrl))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 为当前方法添加其他内容
 | 
			
		||||
 * @param _options
 | 
			
		||||
 * @return {function(...[*]=)}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const AxiosOptions = function (_options = {}) {
 | 
			
		||||
  return function (target, propertyKey, descriptor) {
 | 
			
		||||
    // 类
 | 
			
		||||
    if (target.prototype) {
 | 
			
		||||
      return class extends target {
 | 
			
		||||
        _commonAxiosOptions = _options || {}
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      const method = descriptor.value
 | 
			
		||||
      descriptor.value = function (params = {}, options = {}, $logName) {
 | 
			
		||||
        return method.apply(this, [params, {
 | 
			
		||||
          ...options,
 | 
			
		||||
          ..._options
 | 
			
		||||
        }, $logName])
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
import moment from "moment";
 | 
			
		||||
const isDev = process.env.NODE_ENV === 'development'
 | 
			
		||||
// 打印日志
 | 
			
		||||
export const httpLog = function (logName, { method, url, params, data }, response, error) {
 | 
			
		||||
  const logColor = response ? '#0ad554' : '#FF0000'
 | 
			
		||||
  const logLevel = parseInt(localStorage.getItem('loglevel') || '-1')
 | 
			
		||||
  if (logLevel >= 0) {
 | 
			
		||||
    const time = moment().format('YYYY-MM-DD HH:mm:ss')
 | 
			
		||||
    console.groupCollapsed(`%c [DEBUG] HTTP: ${time}-${method.toUpperCase()}@${url}@${logName || ''}`,
 | 
			
		||||
      `color:  #fff;background-color: ${logColor};`
 | 
			
		||||
    )
 | 
			
		||||
    if (data) {
 | 
			
		||||
      console.log('   query: %o', data)
 | 
			
		||||
    }
 | 
			
		||||
    if (params) {
 | 
			
		||||
      console.log('   query: %o', params)
 | 
			
		||||
    }
 | 
			
		||||
    if (response) {
 | 
			
		||||
      console.log('response: %o', response)
 | 
			
		||||
    }
 | 
			
		||||
    if (error) {
 | 
			
		||||
      console.log('   error: %o', error)
 | 
			
		||||
    }
 | 
			
		||||
    console.groupEnd()
 | 
			
		||||
  }
 | 
			
		||||
  if (error) throw error
 | 
			
		||||
  if (response) return response
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 为服务支持日志功能
 | 
			
		||||
 * @param constructor
 | 
			
		||||
 * @return {{new(): {httpLog: *}, prototype: {httpLog: *}}}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
export const SupportLog = function (constructor) {
 | 
			
		||||
  return class extends constructor {
 | 
			
		||||
    log = httpLog
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const Log = function (logName) {
 | 
			
		||||
  return function (target, propertyKey, descriptor) {
 | 
			
		||||
    const method = descriptor.value || target[propertyKey]
 | 
			
		||||
    descriptor.value = function (params = {}, options = {}) {
 | 
			
		||||
      return method && method.apply(this, [params, options, logName])
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
export * from './http'
 | 
			
		||||
export * from './httpLog'
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
const checkTypes = {};
 | 
			
		||||
['Array', 'Object', 'String', 'Number', 'Boolean', 'Null', 'Undefined', 'RegExp', 'Function'].forEach(type => {
 | 
			
		||||
  checkTypes[`is${type}`] = function (data) {
 | 
			
		||||
    return Object.prototype.toString.call(data) === `[object ${type}]`
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default checkTypes
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
/**
 | 
			
		||||
 * @function 将url中的查询字符串转换为obj
 | 
			
		||||
 * @param search { String } 查询字符串,默认为当前url中的查询字符串
 | 
			
		||||
 * @return { Object }
 | 
			
		||||
 */
 | 
			
		||||
export const query2object = (search = location.search.substr(1)) => {
 | 
			
		||||
  if (!search.length) return {}
 | 
			
		||||
  const query = {}
 | 
			
		||||
  for (const queryString of search.split('&')) {
 | 
			
		||||
    const kv = queryString.split('=')
 | 
			
		||||
    query[kv[0]] = kv[1]
 | 
			
		||||
  }
 | 
			
		||||
  return query
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @function 将对象转换为查询字符串,不带#和?
 | 
			
		||||
 * @param object
 | 
			
		||||
 */
 | 
			
		||||
export const object2query = (object) => {
 | 
			
		||||
  if (Object.keys(object).length === 0) return ''
 | 
			
		||||
  let search = ''
 | 
			
		||||
  for (const key in object) {
 | 
			
		||||
    search += `${key}=${object[key]}&`
 | 
			
		||||
  }
 | 
			
		||||
  return search.substr(0, search.length - 1)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
/**
 | 
			
		||||
 * @function 开启全屏方法
 | 
			
		||||
 * @param el { Element } 全屏的dom,默认是document.documentElement
 | 
			
		||||
 */
 | 
			
		||||
function fullScreen(el = document.documentElement) {
 | 
			
		||||
  let rfs = el.requestFullscreen
 | 
			
		||||
    || el.webkitRequestFullScreen
 | 
			
		||||
    || el.mozRequestFullScreen
 | 
			
		||||
    || el.msRequestFullscreen
 | 
			
		||||
  try {
 | 
			
		||||
    if (typeof rfs !== 'undefined' && rfs) rfs.call(el)
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error('fullScreen: %o', e);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @function 监测是否全屏
 | 
			
		||||
 * @return {boolean}
 | 
			
		||||
 */
 | 
			
		||||
function isFullscreen() {
 | 
			
		||||
  return !!(
 | 
			
		||||
    document.webkitIsFullScreen ||
 | 
			
		||||
    document.mozFullScreen ||
 | 
			
		||||
    document.mozFullScreenElement ||
 | 
			
		||||
    document.webkitFullscreenElement ||
 | 
			
		||||
    document.msFullscreenElement ||
 | 
			
		||||
    document.fullscreenElement ||
 | 
			
		||||
    window.fullScreen
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @function 退出全屏
 | 
			
		||||
 */
 | 
			
		||||
function exitScreen() {
 | 
			
		||||
  const exitFn = document.exitFullscreen || document.mozCancelFullScreen || document.webkitCancelFullScreen || document.msExitFullscreen
 | 
			
		||||
  try {
 | 
			
		||||
    if (typeof exitFn !== 'undefined' && exitFn) exitFn.call(document)
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error('exitScreen: %o', e)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  fullScreen,
 | 
			
		||||
  exitScreen,
 | 
			
		||||
  isFullscreen
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
/*
 | 
			
		||||
  开发环境不开启定时器
 | 
			
		||||
 */
 | 
			
		||||
const isStartTimer = process.env.NODE_ENV !== 'development'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @function 定时器
 | 
			
		||||
 * @param fn { function } 执行过程
 | 
			
		||||
 * @param duration { timestamp } 间隔时间
 | 
			
		||||
 * @param immediate { boolean } 是否立即执行
 | 
			
		||||
 * @returns {{stop(): void, restart: restart}}
 | 
			
		||||
 */
 | 
			
		||||
export default function timer(fn, duration = 5 * 1000, immediate = true) {
 | 
			
		||||
  // 执行队列
 | 
			
		||||
  let processes = []
 | 
			
		||||
  let _args = []
 | 
			
		||||
  // 定义定时器
 | 
			
		||||
  let timer = null
 | 
			
		||||
  let _duration = duration
 | 
			
		||||
  // 过程支持list和单一函数
 | 
			
		||||
  if (Array.isArray(fn)) {
 | 
			
		||||
    processes.push.apply(processes, fn)
 | 
			
		||||
  } else {
 | 
			
		||||
    processes.push(fn)
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * @function 过程执行器
 | 
			
		||||
   * @param processes { Array<function> | function }
 | 
			
		||||
   * @param args { any }
 | 
			
		||||
   * @returns {Promise<void>}
 | 
			
		||||
   */
 | 
			
		||||
  const exec = async (processes, ...args) => {
 | 
			
		||||
    _args = args
 | 
			
		||||
    try {
 | 
			
		||||
      if (timer) {
 | 
			
		||||
        clearTimeout(timer)
 | 
			
		||||
        timer = null
 | 
			
		||||
      }
 | 
			
		||||
      for (let process of processes) {
 | 
			
		||||
        if (typeof process === 'function') {
 | 
			
		||||
          await process(..._args)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error('TimerError:', e)
 | 
			
		||||
    } finally {
 | 
			
		||||
      if (!isStartTimer) return false
 | 
			
		||||
      timer = setTimeout(() => {
 | 
			
		||||
        exec(processes, ..._args)
 | 
			
		||||
      }, _duration)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (immediate) {
 | 
			
		||||
    exec(processes)
 | 
			
		||||
  }
 | 
			
		||||
  return {
 | 
			
		||||
    stop () {
 | 
			
		||||
      if (timer) {
 | 
			
		||||
        clearTimeout(timer)
 | 
			
		||||
        timer = null
 | 
			
		||||
        processes = null
 | 
			
		||||
        _args = null
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    clearParams () {
 | 
			
		||||
      _args = []
 | 
			
		||||
    },
 | 
			
		||||
    /**
 | 
			
		||||
     * 定时器重启
 | 
			
		||||
     * @param args { { params: Array<any>, duration: number } } 回调的参数
 | 
			
		||||
     */
 | 
			
		||||
    restart: function (options = {}) {
 | 
			
		||||
      const { params = [], duration } = options
 | 
			
		||||
      // 不能用全等,对象中的undefined 与 undefined 不是全等
 | 
			
		||||
      if (duration != undefined || duration != null) {
 | 
			
		||||
        _duration = duration
 | 
			
		||||
      }
 | 
			
		||||
      exec(processes, ...(params || []))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
import checkTypes from "@/utils/checkTypes";
 | 
			
		||||
export function guid() {
 | 
			
		||||
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
 | 
			
		||||
    const r = (Math.random() * 16) | 0
 | 
			
		||||
    const v = c === 'x' ? r : (r & 0x3) | 0x8
 | 
			
		||||
    return v.toString(16)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getTheTruth = function (data) {
 | 
			
		||||
  if (typeof data !== 'object' && typeof data !== 'string') return data
 | 
			
		||||
  if (typeof data === 'string') {
 | 
			
		||||
    if (data.startsWith('{') || data.startsWith('['))
 | 
			
		||||
      return getTheTruth(JSON.parse(data))
 | 
			
		||||
    return data
 | 
			
		||||
  }
 | 
			
		||||
  if (Array.isArray(data)) return data.map((item) => getTheTruth(item))
 | 
			
		||||
  for (const key in data) data[key] = getTheTruth(data[key])
 | 
			
		||||
  return data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const isEmpty = (data) => {
 | 
			
		||||
  return checkTypes.isUndefined(data) || checkTypes.isNull(data) || data == NaN
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export function isDef(v) {
 | 
			
		||||
  return v !== undefined && v !== null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function isPromise(val) {
 | 
			
		||||
  return (
 | 
			
		||||
    isDef(val) &&
 | 
			
		||||
    typeof val.then === 'function' &&
 | 
			
		||||
    typeof val.catch === 'function'
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const toPromise = (task, data) => {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    let _isPromise = false // 当前任务是不是一个promise
 | 
			
		||||
    try {
 | 
			
		||||
      // 执行任务
 | 
			
		||||
      const results = task(data)
 | 
			
		||||
      // 任务是一个异步函数,执行promise
 | 
			
		||||
      if (isPromise(results)) {
 | 
			
		||||
        _isPromise = true
 | 
			
		||||
        results.then(resolve, reject)
 | 
			
		||||
      } else {
 | 
			
		||||
        // 非异步任务
 | 
			
		||||
        resolve(results)
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (!_isPromise) {
 | 
			
		||||
        reject(e)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getSize(size, defaultValue = undefined) {
 | 
			
		||||
  if (!size) {
 | 
			
		||||
    if (checkTypes.isNumber(size)) return size
 | 
			
		||||
    return defaultValue || undefined
 | 
			
		||||
  }
 | 
			
		||||
  if (/^\-?\d+$/.test(`${size}`)) return `${size}px`
 | 
			
		||||
  if (/(%|px)$/.test(`${size}`)) return size
 | 
			
		||||
  if (/calc/.test(`${size}`)) return size
 | 
			
		||||
  return size
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
export function urlJoin() {
 | 
			
		||||
  return [].slice
 | 
			
		||||
    .call(arguments)
 | 
			
		||||
    .join('/')
 | 
			
		||||
    .replace(/\/+/g, '/')
 | 
			
		||||
    .replace(':/', '://')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5337,6 +5337,11 @@ lodash@^4.15.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.
 | 
			
		|||
  resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
 | 
			
		||||
  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 | 
			
		||||
 | 
			
		||||
loglevel@^1.9.1:
 | 
			
		||||
  version "1.9.1"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/loglevel/-/loglevel-1.9.1.tgz#d63976ac9bcd03c7c873116d41c2a85bafff1be7"
 | 
			
		||||
  integrity sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==
 | 
			
		||||
 | 
			
		||||
loose-envify@^1.0.0:
 | 
			
		||||
  version "1.4.0"
 | 
			
		||||
  resolved "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue