rightPage.vue 8.56 KB
<template>
  <div class="pd20">
    <div class="chartCard">
      <div class="title">开票计划与执行</div>
      <div class="po_right">
        <el-radio-group v-model="radioA" size="small" @change="radioAChange">
          <el-radio-button label="本月" value="month"/>
          <el-radio-button label="本季度" value="quarter"/>
          <el-radio-button label="本年" value="year"/>
        </el-radio-group>
      </div>

      <div ref="zhuRef" style="width: 100%; height: 24vh;"></div>
    </div>

    <div class="chartCard mt30">
      <div class="title">回款</div>
      <div class="po_right">
        <!--        <el-radio-group v-model="radioB" size="small" @change="radioBChange">-->
        <!--          <el-radio-button label="本月" value="month" />-->
        <!--          <el-radio-button label="本季度" value="quarter" />-->
        <!--          <el-radio-button label="本年" value="year" />-->
        <!--        </el-radio-group>-->
      </div>

      <div ref="lineRef" style="width: 100%; height: 24vh;"></div>
    </div>
    <div class="chartCard mt30">
      <div class="title">逾期360天以上未开票</div>
      <div ref="overdueRef" style="width: 100%; height: 25vh;"></div>
    </div>
  </div>
</template>

<script setup>
import {onMounted, onUnmounted, ref} from 'vue'
import _ from 'lodash'
import {autoToolTip} from "@/plugins/auto-toolTip";
import * as echarts from "echarts";
import * as api from "@/apiPc/common"

const zhuRef = ref(null)
const lineRef = ref(null)
const overdueRef = ref(null)
const kindList = ref(['文书', '婚姻', '图书', '档案', '司法', '环保', '音频', '视频', '会计', '其他'])
const dataA = ref([80, 60, 55, 62, 50, 55, 60, 62, 48, 53])
const radioA = ref('month')
let chartA
let chartB
let chartC
let intervalA = null
onMounted(() => {
  // init()
  window.addEventListener('resize', handleResize);
  setA()
  setB()
  setC()
})
const init = () => {
  clear()
  if (!intervalA) {
    getdata()
  }
  intervalA = setInterval(getdata, 1000 * 60 * 60);
}
const getdata = () => {
  getA()
  getB()
}
const getA = () => {
  //定时更新
  api.getJieYue({type: radioA.value}).then(res => {
    dataA.value = []
    kindList.value = []
    for (let n of res.data) {
      if (n.count > 0) {
        kindList.value.push(n.name)
        dataA.value.push(n.count)
      }
    }
    setA()
  })
}

const setA = () => {
  chartA = echarts.init(zhuRef.value)
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        // Use axis to trigger tooltip
        type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
      }
    },
    legend: {
      top: "3%"
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'value'
    },
    yAxis: {
      type: 'category',
      data: ['塘沽', '深圳', '漳江', '上海', '海南', '山西', '陕西', '新疆', '伊拉克']
    },
    series: [
      {
        name: 'Direct',
        type: 'bar',
        label: {
          show: true
        },
        emphasis: {
          focus: 'series'
        },
        data: [320, 302, 301, 334, 390, 330, 320, 330, 320]
      },
      {
        name: 'Direct',
        type: 'bar',
        label: {
          show: true
        },
        emphasis: {
          focus: 'series'
        },
        data: [320, 302, 301, 334, 390, 330, 320, 330, 320]
      }
    ]
  }
  chartA.setOption(option)
  autoHover(chartA, option, 0, 2000)
}

const getB = () => {
  api.getJieShou().then(res => {
    dataA.value = []
    kindList.value = []
    for (let n of res.data) {
      if (n.count > 0) {
        kindList.value.push(n.name)
        dataA.value.push(n.count)
      }
    }
    setB()
  })
}
const setB = () => {
  chartB = echarts.init(lineRef.value)
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        // Use axis to trigger tooltip
        type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
      }
    },
    legend: {
      top: "3%"
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'value'
    },
    yAxis: {
      type: 'category',
      data: ['塘沽', '深圳', '漳江', '上海', '海南', '山西', '陕西', '新疆', '伊拉克']
    },
    series: [
      {
        name: 'Direct',
        type: 'bar',
        label: {
          show: true
        },
        emphasis: {
          focus: 'series'
        },
        data: [320, 302, 301, 334, 390, 330, 320, 330, 320]
      }
    ]
  }
  chartB.setOption(option)
  autoHover(chartB, option, 0, 2000)
}
const setC = () => {
  chartC = echarts.init(overdueRef.value)
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      top: '10%',
      textStyle: {
        color: '#FFF'
      },
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        stack: 'Ad',
        data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '金额(万元)',
      }
    ],
    series: [
      {
        name: '0-180天未开票',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: [320, 332, 301, 334, 390, 330, 320, 320, 332, 301, 334, 390]
      },
      {
        name: '180-360天未开票',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: [120, 132, 101, 134, 90, 230, 210, 101, 134, 90, 230, 210]
      },
      {
        name: '逾期360天以上',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: [220, 182, 191, 234, 290, 330, 310, 220, 182, 191, 234, 290,]
      },
    ]
  }
  chartC.setOption(option)
  autoHover(chartC, option, 0, 2000)
}
const radioAChange = (e) => {
  getA()
}
const radioBChange = (e) => {
  getB()
}

const clear = () => {
  if (autoToolTip) {
    clearTimeout(autoToolTip);
  }
}

function autoHover(myChart, option, index, time) {
  autoToolTip(myChart, option, {
    interval: time,// 轮播间隔时间 默认2s
    loopSeries: false,// 是否循环轮播所有序列
    seriesIndex: index, // 第1个被轮播的序列下标
  });
}

function handleResize() {
  chartA?.resize()
  chartB?.resize()
  chartC?.resize()
}

onUnmounted(() => {
  if (intervalA) {
    clearInterval(intervalA);
  }
})
</script>

<style lang="scss" scoped>
:deep(.el-radio-button--small .el-radio-button__inner) {
  font-size: calc(12 * 100vw / 1920);
  padding: calc(5 * 100vw / 1920) calc(11 * 100vw / 1920);
}

.title {
  padding: calc(12 * 100vw / 1920) calc(50 * 100vw / 1920) 0;
  font-family: 'YouSheBiaoTiHei';
  color: #FFFFFF;
  //text-shadow: 0px 4px 3px #003F85;
  background: linear-gradient(180deg, #fff 50%, #9CD2FF 100%);
  -webkit-background-clip: text;
  font-size: calc(17 * 100vw / 1920);
  -webkit-text-fill-color: transparent;
  position: relative;

  &::after {
    content: '';
    width: 100%;
    height: 100%;
    background: url("@/assets/img/line2.png") no-repeat;
    background-size: contain;
    position: absolute;
    top: calc(20 * 100vw / 1920);
    left: 0;
    animation: movelr 4s ease-in infinite;
  }
}

@keyframes movelr {
  0% {
    left: 0;
    opacity: 1;
  }
  100% {
    left: calc(220 * 100vw / 1920);
    opacity: 0;
  }
}

.chartCard {
  background: url("@/assets/image/box01@2x.png") no-repeat top left;
  background-size: 100% 100%;
  position: relative;
  overflow: hidden;

  .po_right {
    position: absolute;
    right: calc(20 * 100vw / 1920);
    top: calc(40 * 100vw / 1920);
    z-index: 1;

    :deep(.el-radio-button) {
      --el-radio-button-checked-bg-color: linear-gradient(0deg, #2C67B7, #40A5F4);
      --el-radio-button-checked-text-color: #fff;
      --el-radio-button-disabled-checked-fill: #03DAFD;
      --el-radio-button-checked-border-color: #0D599A;

      .el-radio-button__inner {
        color: #7ECEF4;
        background: transparent;
        border-color: #0D599A;
      }

      .el-radio-button__original-radio:checked + .el-radio-button__inner {
        color: #fff;
        background: linear-gradient(0deg, #2C67B7, #40A5F4);
      }
    }
  }
}

.downDot {
  position: relative;

  &::after {
    content: '';
    width: calc(6 * 100vw / 1920);
    height: calc(6 * 100vw / 1920);
    background: #fff;
    border-radius: 50%;
    position: absolute;
    bottom: 0;
  }
}
</style>