zs hai 5 meses
pai
achega
248d20be09

+ 85 - 0
src/components/dataV/mixin/autoResize.js

@@ -0,0 +1,85 @@
+import { debounce, observerDomResize } from '../util/index'
+
+export default {
+  data () {
+    return {
+      dom: '',
+
+      width: 0,
+      height: 0,
+
+      debounceInitWHFun: '',
+
+      domObserver: ''
+    }
+  },
+  methods: {
+    async autoResizeMixinInit () {
+      const { initWH, getDebounceInitWHFun, bindDomResizeCallback, afterAutoResizeMixinInit } = this
+
+      await initWH(false)
+
+      getDebounceInitWHFun()
+
+      bindDomResizeCallback()
+
+      if (typeof afterAutoResizeMixinInit === 'function') afterAutoResizeMixinInit()
+    },
+    initWH (resize = true) {
+      const { $nextTick, $refs, ref, onResize } = this
+
+      return new Promise(resolve => {
+        $nextTick((_) => {
+          const dom = (this.dom = $refs[ref])
+          // this.width = dom ? dom.clientWidth : 0
+          // this.height = dom ? dom.clientHeight : 0
+          this.width = window.innerWidth
+          this.height = window.innerHeight
+
+          if (!dom) {
+            console.warn('DataV: Failed to get dom node, component rendering may be abnormal!')
+          } else if (!this.width || !this.height) {
+            console.warn('DataV: Component width or height is 0px, rendering abnormality may occur!')
+          }
+
+          if (typeof onResize === 'function' && resize) onResize()
+
+          resolve()
+        })
+      })
+    },
+    getDebounceInitWHFun () {
+      const { initWH } = this
+
+      this.debounceInitWHFun = debounce(100, initWH)
+    },
+    bindDomResizeCallback () {
+      const { dom, debounceInitWHFun } = this
+
+      this.domObserver = observerDomResize(dom, debounceInitWHFun)
+
+      window.addEventListener('resize', debounceInitWHFun)
+    },
+    unbindDomResizeCallback () {
+      let { domObserver, debounceInitWHFun } = this
+
+      if (!domObserver) return
+
+      domObserver.disconnect()
+      domObserver.takeRecords()
+      domObserver = null
+
+      window.removeEventListener('resize', debounceInitWHFun)
+    }
+  },
+  mounted () {
+    const { autoResizeMixinInit } = this
+
+    autoResizeMixinInit()
+  },
+  beforeDestroy () {
+    const { unbindDomResizeCallback } = this
+
+    unbindDomResizeCallback()
+  }
+}

+ 60 - 0
src/components/dataV/myMain.vue

@@ -0,0 +1,60 @@
+<template>
+  <div id="dv-full-screen-container" :ref="ref">
+    <template v-if="ready">
+      <slot></slot>
+    </template>
+  </div>
+</template>
+
+<script>
+import autoResize from './mixin/autoResize.js'
+
+export default {
+  name: 'DvFullScreenContainer',
+  mixins: [autoResize],
+  data() {
+    return {
+      ref: 'full-screen-container',
+      allWidth: 0,
+      allHeight: 0,
+      scale: 0,
+      datavRoot: '',
+      ready: false
+    }
+  },
+  methods: {
+    afterAutoResizeMixinInit() {
+      const { initConfig, setAppScale } = this
+
+      initConfig()
+
+      setAppScale()
+
+      this.ready = true
+    },
+    initConfig() {
+      const { dom } = this
+      // const { width } = screen
+      let width = window.innerWidth
+      let height = window.innerHeight
+      this.allWidth = width
+      this.allHeight = height
+
+      dom.style.width = `${width}px`
+      dom.style.height = `${height}px`
+    },
+    setAppScale() {
+      const { allWidth, allHeight, dom } = this
+      const currentWidth = window.innerWidth
+      const currentHeight = window.innerHeight
+      // dom.style.transform = `scale(${currentWidth / allWidth})`
+      dom.style.transform = `scaleY(${currentHeight / allHeight}) scaleX(${currentWidth / allWidth})`
+    },
+    onResize() {
+      const { setAppScale } = this
+
+      setAppScale()
+    }
+  }
+}
+</script>

+ 47 - 0
src/components/dataV/util/index.js

@@ -0,0 +1,47 @@
+export function randomExtend(minNum, maxNum) {
+  if (arguments.length === 1) {
+    return parseInt(Math.random() * minNum + 1, 10)
+  } else {
+    return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
+  }
+}
+
+export function debounce(delay, callback) {
+  let lastTime
+
+  return function () {
+    clearTimeout(lastTime)
+
+    const [that, args] = [this, arguments]
+
+    lastTime = setTimeout(() => {
+      callback.apply(that, args)
+    }, delay)
+  }
+}
+
+export function observerDomResize(dom, callback) {
+  const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
+
+  const observer = new MutationObserver(callback)
+
+  observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })
+
+  return observer
+}
+
+export function getPointDistance(pointOne, pointTwo) {
+  const minusX = Math.abs(pointOne[0] - pointTwo[0])
+
+  const minusY = Math.abs(pointOne[1] - pointTwo[1])
+
+  return Math.sqrt(minusX * minusX + minusY * minusY)
+}
+
+export function uuid(hasHyphen) {
+  return (hasHyphen ? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' : 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx').replace(/[xy]/g, function (c) {
+    const r = (Math.random() * 16) | 0
+    const v = c == 'x' ? r : (r & 0x3) | 0x8
+    return v.toString(16)
+  })
+}

+ 1 - 1
src/router/guard.js

@@ -5,7 +5,7 @@ import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 import { ElMessageBox } from 'element-plus'
 import i18n from '@/lang'
-const whiteList = ['/redirect', '/login', '/401', '/404']
+const whiteList = ['/redirect', '/login', 'screen', '/401', '/404']
 NProgress.configure({ showSpinner: false }) // 进度条
 // 获取用户信息,返回菜单
 const getUserMeta = async (token) => {

+ 6 - 0
src/router/index.js

@@ -61,6 +61,12 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/screen',
+    name: 'Screen',
+    meta: { title: '智慧大屏' },
+    component: () => import('@/views/screen/index.vue')
+  },
   {
     path: '/401',
     name: '401',

+ 94 - 0
src/views/screen/echarts/echarts1.vue

@@ -0,0 +1,94 @@
+<template>
+  <div ref="echarts1" class="echarts1"></div>
+</template>
+<style scoped lang="scss">
+.echarts1 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts1 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts1()
+  if (res.errcode == '0') await echarts1View(res.data)
+})
+function echarts1View(info) {
+  const nameList = get(info, 'nameList')
+  const data = get(info, 'data')
+  const myChart1 = echarts.init(echarts1.value)
+  const option1 = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    grid: {
+      left: '10%',
+      top: '10%',
+      right: '10%',
+      bottom: '10%',
+      containLabel: true
+    },
+    xAxis: {
+      data: nameList,
+      axisLine: { show: false },
+      axisLabel: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 12
+      }
+    },
+    yAxis: {
+      axisLine: { show: false },
+      axisLabel: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 12
+      },
+      splitLine: {
+        lineStyle: {
+          color: 'rgba(255,255,255,0.5)',
+          type: 'dotted'
+        }
+      }
+    },
+    series: [
+      {
+        type: 'bar',
+        barWidth: '15%',
+        itemStyle: {
+          normal: {
+            barBorderRadius: 50,
+            color: new echarts.graphic.LinearGradient(
+              0,
+              0,
+              0,
+              1,
+              [
+                {
+                  offset: 0,
+                  color: '#01fdcc'
+                },
+                {
+                  offset: 0.8,
+                  color: '#11a1d8'
+                }
+              ],
+              false
+            )
+          }
+        },
+        data
+      }
+    ]
+  }
+  myChart1.setOption(option1)
+  window.addEventListener('resize', function () {
+    myChart1.resize()
+  })
+}
+</script>

+ 100 - 0
src/views/screen/echarts/echarts2.vue

@@ -0,0 +1,100 @@
+<template>
+  <div ref="echarts2" class="echarts2"></div>
+</template>
+<style scoped lang="scss">
+.echarts2 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts2 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts2()
+  if (res.errcode == '0') await echarts2View(res.data)
+})
+function echarts2View(info) {
+  const data = get(info, 'data')
+  const nameList = data.map((i) => {
+    return i.name
+  })
+  const myChart2 = echarts.init(echarts2.value)
+  const option2 = {
+    legend: {
+      left: 'left',
+      itemWidth: 10,
+      itemHeight: 10,
+      data: nameList,
+      textStyle: {
+        color: 'rgba(255,255,255,.5)',
+        fontSize: '12'
+      }
+    },
+    tooltip: {
+      trigger: 'item',
+      formatter: '{b} : {c} ({d}%)'
+    },
+
+    visualMap: {
+      show: false,
+      min: 500,
+      max: 600,
+      inRange: {}
+    },
+    series: [
+      {
+        name: '分布',
+        type: 'pie',
+        radius: ['30%', '60%'],
+        center: ['50%', '50%'],
+        color: ['#30c5ed', '#9fe7b8', '#fb7293', '#e7bcf2', '#0086e5', '#fedb5b', '#ff9f7d'],
+        data: data.sort(function (a, b) {
+          return a.value - b.value
+        }),
+        roseType: 'radius',
+
+        label: {
+          normal: {
+            formatter: ['{d|{d}%}', '{b|{b}}'].join('\n'),
+            rich: {
+              d: {
+                color: 'rgb(241,246,104)',
+                fontSize: 14,
+                fontWeight: 'bold'
+              },
+              b: {
+                color: 'rgb(98,137,169)',
+                fontSize: 12
+              }
+            }
+          }
+        },
+        labelLine: {
+          normal: {
+            lineStyle: {
+              color: 'rgb(98,137,169)'
+            },
+            smooth: 0.2,
+            length: 5,
+            length2: 9
+          }
+        },
+        itemStyle: {
+          normal: {
+            shadowColor: 'rgba(0, 0, 0, 0.1)',
+            shadowBlur: 50
+          }
+        }
+      }
+    ]
+  }
+  myChart2.setOption(option2)
+  window.addEventListener('resize', function () {
+    myChart2.resize()
+  })
+}
+</script>

+ 127 - 0
src/views/screen/echarts/echarts3.vue

@@ -0,0 +1,127 @@
+<template>
+  <div ref="echarts3" class="echarts3"></div>
+</template>
+<style scoped lang="scss">
+.echarts3 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts3 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts3()
+  if (res.errcode == '0') await echarts3View(res.data)
+})
+function echarts3View(info) {
+  const nameList = get(info, 'nameList')
+  const data = get(info, 'data')
+  const myChart3 = echarts.init(echarts3.value)
+  const option3 = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        lineStyle: {
+          color: '#57617B'
+        }
+      },
+      formatter: '{b}日	:<br/> 生产情况{c}'
+    },
+
+    grid: {
+      left: '0%',
+      right: '0%',
+      top: '5%',
+      bottom: '5%',
+      containLabel: true
+    },
+    xAxis: [
+      {
+        type: 'category',
+        boundaryGap: false,
+        axisLine: {
+          show: false,
+          lineStyle: {
+            color: 'rgba(255,255,255,.6)'
+          }
+        },
+        data: nameList
+      }
+    ],
+    yAxis: [
+      {
+        axisLabel: {
+          show: true,
+          textStyle: {
+            color: 'rgba(255,255,255,.6)'
+          }
+        },
+        axisLine: {
+          show: false
+        },
+        splitLine: {
+          lineStyle: {
+            type: 'dotted',
+            color: 'rgba(255,255,255,.1)'
+          }
+        }
+      }
+    ],
+    series: [
+      {
+        name: '生产情况',
+        type: 'line',
+        smooth: true,
+        symbol: 'circle',
+        symbolSize: 5,
+        showSymbol: false,
+        lineStyle: {
+          normal: {
+            width: 2
+          }
+        },
+
+        areaStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(
+              0,
+              0,
+              0,
+              1,
+              [
+                {
+                  offset: 0,
+                  color: 'rgba(98, 201, 141, 0.5)'
+                },
+                {
+                  offset: 1,
+                  color: 'rgba(98, 201, 141, 0.1)'
+                }
+              ],
+              false
+            ),
+            shadowColor: 'rgba(0, 0, 0, 0.1)',
+            shadowBlur: 10
+          }
+        },
+        itemStyle: {
+          normal: {
+            color: '#4cb9cf',
+            borderColor: 'rgba(98, 201, 141,0.27)',
+            borderWidth: 12
+          }
+        },
+        data
+      }
+    ]
+  }
+  myChart3.setOption(option3)
+  window.addEventListener('resize', function () {
+    myChart3.resize()
+  })
+}
+</script>

+ 119 - 0
src/views/screen/echarts/echarts4.vue

@@ -0,0 +1,119 @@
+<template>
+  <div ref="echarts4" class="echarts4"></div>
+</template>
+<style scoped lang="scss">
+.echarts4 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts4 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts4()
+  if (res.errcode == '0') await echarts4View(res.data)
+})
+function echarts4View(info) {
+  const nameList = get(info, 'nameList')
+  const data = get(info, 'data')
+  const myChart4 = echarts.init(echarts4.value)
+  const option4 = {
+    tooltip: {
+      trigger: 'axis'
+    },
+    grid: {
+      left: '8%',
+      right: '0%',
+      bottom: '15%',
+      top: '5%'
+    },
+    legend: {
+      orient: 'horizontal',
+      x: '20px',
+      y: '10px',
+      itemGap: 50, //图例之间间距
+      itemWidth: 12, //图例宽
+      itemHeight: 12, //图例高
+      icon: 'circle',
+      textStyle: {
+        fontSize: 14 //更改坐标轴文字大小
+      }
+    },
+    xAxis: {
+      type: 'category',
+      axisLine: {
+        show: false,
+        lineStyle: {
+          color: 'rgba(255,255,255,.6)'
+        }
+      },
+      axisLabel: {
+        //x轴文字倾斜
+        show: true,
+        textStyle: {
+          color: 'rgba(255,255,255,.6)', //更改坐标轴文字颜色
+          fontSize: 14 //更改坐标轴文字大小
+        }
+      },
+      data: nameList
+    },
+    yAxis: {
+      type: 'value',
+      name: '',
+      nameTextStyle: {
+        padding: [0, 30, 5, 0], // y轴name位置
+        color: 'rgba(255,255,255,.6)', //更改坐标轴文字颜色
+        fontSize: 14 //更改坐标轴文字大小
+      },
+      axisLabel: {
+        show: true,
+        textStyle: {
+          color: 'rgba(255,255,255,.6)'
+        }
+      },
+      axisLine: {
+        show: false
+      },
+      splitLine: {
+        lineStyle: {
+          type: 'dotted',
+          color: 'rgba(255,255,255,.1)'
+        }
+      }
+    },
+    series: [
+      {
+        type: 'line',
+        stack: 'Total',
+        symbolSize: 8, //设定实心点的大小
+        smooth: true, //面积图改成弧形状
+        lineStyle: {
+          normal: {
+            color: '#168eff', //外边线颜色
+            width: 3, //外边线宽度
+            shadowColor: '#168eff', //线阴影颜色
+            shadowOffsetY: 10, //阴影大小
+            shadowBlur: 15
+          }
+        },
+        itemStyle: {
+          normal: {
+            //节点颜色
+            color: '#168eff'
+          }
+        },
+        showSymbol: true, //去除面积图节点圆
+        data
+      }
+    ]
+  }
+  myChart4.setOption(option4)
+  window.addEventListener('resize', function () {
+    myChart4.resize()
+  })
+}
+</script>

+ 97 - 0
src/views/screen/echarts/echarts5.vue

@@ -0,0 +1,97 @@
+<template>
+  <div ref="echarts5" class="echarts5"></div>
+</template>
+<style scoped lang="scss">
+.echarts5 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts5 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts5()
+  if (res.errcode == '0') await echarts5View(res.data)
+})
+function echarts5View(info) {
+  const nameList = get(info, 'nameList')
+  const data = get(info, 'data')
+  const myChart5 = echarts.init(echarts5.value)
+  const option5 = {
+    color: ['#1aa1ff', '#31c17b', '#ff6535'],
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    grid: {
+      left: '0%',
+      top: '15px',
+      right: '0%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      data: nameList,
+      axisLine: { show: false },
+      axisLabel: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 12
+      }
+    },
+    yAxis: {
+      name: '(人)',
+      splitNumber: 4,
+      nameTextStyle: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 12
+      },
+      axisLine: { show: false },
+      axisLabel: {
+        color: 'rgba(255,255,255,.6)',
+        fontSize: 12
+      },
+      splitLine: {
+        lineStyle: {
+          color: 'rgba(255,255,255,.1)',
+          type: 'dotted'
+        }
+      }
+    },
+    series: [
+      {
+        type: 'bar',
+        barWidth: '25%',
+        itemStyle: {
+          normal: {
+            barBorderRadius: 50,
+            color: function (params) {
+              var colorList = ['#4591e3', '#04b8e5', '#04dde5', '#04e5bd', '#04e57e', '#fedb5b', '#e59e04', '#ff632d', '#ff639e', '#ff82e9', '#b562e4', '#4591e3']
+
+              return colorList[params.dataIndex]
+            },
+
+            label: {
+              show: true,
+              position: 'top',
+              formatter: '{c}',
+              color: 'rgba(255,255,255,.4)',
+              fontSize: 12
+            }
+          }
+        },
+        data
+      }
+    ]
+  }
+  myChart5.setOption(option5)
+  window.addEventListener('resize', function () {
+    myChart5.resize()
+  })
+}
+</script>

+ 155 - 0
src/views/screen/echarts/echarts6.vue

@@ -0,0 +1,155 @@
+<template>
+  <div ref="echarts6" class="echarts6"></div>
+</template>
+<style scoped lang="scss">
+.echarts6 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts6 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts6()
+  if (res.errcode == '0') await echarts6View(res.data)
+})
+function echarts6View(info) {
+  let xdata = get(info, 'xdata')
+  let ydata = get(info, 'ydata')
+  const myChart6 = echarts.init(echarts6.value)
+  const option6 = {
+    tooltip: {
+      trigger: 'axis'
+    },
+    grid: {
+      left: '20%',
+      right: '5%',
+      bottom: '0%',
+      top: '0%',
+      containLabel: false
+    },
+    xAxis: {
+      type: 'value',
+      show: false
+    },
+    yAxis: {
+      type: 'category',
+      data: ydata,
+      axisLine: {
+        show: false
+      },
+      axisTick: {
+        show: false
+      },
+      axisLabel: {
+        margin: 70,
+        width: 60,
+        align: 'left',
+        overflow: 'truncate',
+        formatter: function (value, index) {
+          let ind = index + 1
+          if (ind == ydata.length) {
+            return '{one|' + (ydata.length - index) + '} {a|' + value + '}'
+          } else if (ind + 1 == ydata.length) {
+            return '{two|' + (ydata.length - index) + '} {b|' + value + '}'
+          } else if (ind + 2 == ydata.length) {
+            return '{three|' + (ydata.length - index) + '} {c|' + value + '}'
+          }
+          if (ydata.length - index > 9) {
+            return '{five|' + (ydata.length - index) + '} {d|' + value + '}'
+          }
+          return '{four|' + (ydata.length - index) + '} {d|' + value + '}'
+        },
+        rich: {
+          a: {
+            color: '#59c9f9'
+          },
+          b: {
+            color: '#59c9f9'
+          },
+          c: {
+            color: '#59c9f9'
+          },
+          d: {
+            color: '#59c9f9'
+          },
+          // 第一名
+          one: {
+            backgroundColor: '#E86452',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 第二名
+          two: {
+            backgroundColor: '#FF9845',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 第三名
+          three: {
+            backgroundColor: '#F6BD16',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 一位数
+          four: {
+            backgroundColor: 'rgba(0,0,0,0.15)',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 两位数
+          five: {
+            backgroundColor: 'rgba(0,0,0,0.15)',
+            color: 'white',
+            width: 16,
+            height: 16,
+            padding: [1, 0, 0, 1],
+            borderRadius: 10,
+            fontSize: 11
+          }
+        }
+      }
+    },
+    series: [
+      {
+        type: 'bar',
+        showBackground: true,
+        label: {
+          show: true,
+          position: 'right',
+          color: 'rgba(255,255,255,.6)'
+        },
+        barWidth: 20,
+        itemStyle: {
+          color: '#5B8FF9'
+        },
+        data: xdata
+      }
+    ]
+  }
+  myChart6.setOption(option6)
+  window.addEventListener('resize', function () {
+    myChart6.resize()
+  })
+}
+</script>

+ 155 - 0
src/views/screen/echarts/echarts7.vue

@@ -0,0 +1,155 @@
+<template>
+  <div ref="echarts7" class="echarts7"></div>
+</template>
+<style scoped lang="scss">
+.echarts7 {
+  height: 100%;
+  width: 100%;
+}
+</style>
+<script setup>
+import * as echarts from 'echarts'
+import { get } from 'lodash-es'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+const echarts7 = ref()
+onMounted(async () => {
+  const res = await statisticsStore.echarts7()
+  if (res.errcode == '0') await echarts7View(res.data)
+})
+function echarts7View(info) {
+  let xdata = get(info, 'xdata')
+  let ydata = get(info, 'ydata')
+  const myChart7 = echarts.init(echarts7.value)
+  const option7 = {
+    tooltip: {
+      trigger: 'axis'
+    },
+    grid: {
+      left: '20%',
+      right: '5%',
+      bottom: '0%',
+      top: '0%',
+      containLabel: false
+    },
+    xAxis: {
+      type: 'value',
+      show: false
+    },
+    yAxis: {
+      type: 'category',
+      data: ydata,
+      axisLine: {
+        show: false
+      },
+      axisTick: {
+        show: false
+      },
+      axisLabel: {
+        margin: 70,
+        width: 60,
+        align: 'left',
+        overflow: 'truncate',
+        formatter: function (value, index) {
+          let ind = index + 1
+          if (ind == ydata.length) {
+            return '{one|' + (ydata.length - index) + '} {a|' + value + '}'
+          } else if (ind + 1 == ydata.length) {
+            return '{two|' + (ydata.length - index) + '} {b|' + value + '}'
+          } else if (ind + 2 == ydata.length) {
+            return '{three|' + (ydata.length - index) + '} {c|' + value + '}'
+          }
+          if (ydata.length - index > 9) {
+            return '{five|' + (ydata.length - index) + '} {d|' + value + '}'
+          }
+          return '{four|' + (ydata.length - index) + '} {d|' + value + '}'
+        },
+        rich: {
+          a: {
+            color: '#59c9f9'
+          },
+          b: {
+            color: '#59c9f9'
+          },
+          c: {
+            color: '#59c9f9'
+          },
+          d: {
+            color: '#59c9f9'
+          },
+          // 第一名
+          one: {
+            backgroundColor: '#E86452',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 第二名
+          two: {
+            backgroundColor: '#FF9845',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 第三名
+          three: {
+            backgroundColor: '#F6BD16',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 一位数
+          four: {
+            backgroundColor: 'rgba(0,0,0,0.15)',
+            color: 'white',
+            width: 12,
+            height: 16,
+            padding: [1, 0, 0, 5],
+            borderRadius: 10,
+            fontSize: 11
+          },
+          // 两位数
+          five: {
+            backgroundColor: 'rgba(0,0,0,0.15)',
+            color: 'white',
+            width: 16,
+            height: 16,
+            padding: [1, 0, 0, 1],
+            borderRadius: 10,
+            fontSize: 11
+          }
+        }
+      }
+    },
+    series: [
+      {
+        type: 'bar',
+        showBackground: true,
+        label: {
+          show: true,
+          position: 'right',
+          color: 'rgba(255,255,255,.6)'
+        },
+        barWidth: 20,
+        itemStyle: {
+          color: '#5B8FF9'
+        },
+        data: xdata
+      }
+    ]
+  }
+  myChart7.setOption(option7)
+  window.addEventListener('resize', function () {
+    myChart7.resize()
+  })
+}
+</script>

+ 248 - 0
src/views/screen/index.vue

@@ -0,0 +1,248 @@
+<template>
+  <myMain>
+    <div class="main animate__animated animate__backInRight" v-loading="loading">
+      <div class="one">
+        <span>{{ $t('login.title') }}</span>
+      </div>
+      <div class="two">
+        <div class="two_1" style="width: 25%">
+          <div class="boxall boxall_1">
+            <div class="title">分区节点数</div>
+            <div class="echarts">
+              <echarts1></echarts1>
+            </div>
+          </div>
+          <div class="boxall boxall_2">
+            <div class="title">CPU资源利用率(%)</div>
+            <div class="echarts">
+              <echarts4></echarts4>
+            </div>
+          </div>
+          <div class="boxall boxall_3">
+            <div class="title">存储利用率(%)</div>
+            <div class="echarts">
+              <echarts3></echarts3>
+            </div>
+          </div>
+        </div>
+        <div class="two_1" style="width: 45%">
+          <div class="boxall boxall_8">
+            <div class="item">
+              <h4>{{ nodeList[0]?.num || 0 }}</h4>
+              <div class="itemTilte">
+                <el-icon color="#006cff"><Grid /></el-icon>
+                <span>节点总数</span>
+              </div>
+            </div>
+            <div class="item">
+              <h4>{{ cpuList[0]?.num || 0 }}</h4>
+              <div class="itemTilte">
+                <el-icon color="#ed3f35"><Histogram /></el-icon>
+                <span>CPU(核)总数</span>
+              </div>
+            </div>
+            <div class="item">
+              <h4>{{ userList[0]?.num || 0 }}</h4>
+              <div class="itemTilte">
+                <el-icon color="#6acca3"><UserFilled /></el-icon>
+                <span>用户总数</span>
+              </div>
+            </div>
+            <div class="item">
+              <h4>{{ userList[1]?.num || 0 }}</h4>
+              <div class="itemTilte">
+                <el-icon color="#6acca3"><UserFilled /></el-icon>
+                <span>在线人数</span>
+              </div>
+            </div>
+          </div>
+          <div class="boxall boxall_4">
+            <div class="title">实时状态作业数(总数:{{ work_total || 0 }})</div>
+            <div class="echarts">
+              <echarts2></echarts2>
+            </div>
+          </div>
+          <div class="boxall boxall_5">
+            <div class="title">作业提交数</div>
+            <div class="echarts">
+              <echarts5></echarts5>
+            </div>
+          </div>
+        </div>
+        <div class="two_1" style="width: 25%">
+          <div class="boxall boxall_6">
+            <div class="title">组织提交作业TOP5(30天)</div>
+            <div class="echarts">
+              <echarts6></echarts6>
+            </div>
+          </div>
+          <div class="boxall boxall_7">
+            <div class="title">用户提交作业TOP5(30天)</div>
+            <div class="echarts">
+              <echarts7></echarts7>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </myMain>
+</template>
+
+<script setup>
+import myMain from '@/components/dataV/myMain.vue'
+// 组件
+import echarts1 from './echarts/echarts1.vue'
+import echarts2 from './echarts/echarts2.vue'
+import echarts3 from './echarts/echarts3.vue'
+import echarts4 from './echarts/echarts4.vue'
+import echarts5 from './echarts/echarts5.vue'
+import echarts6 from './echarts/echarts6.vue'
+import echarts7 from './echarts/echarts7.vue'
+import { StatisticsStore } from '@/store/api/core/statistics'
+const statisticsStore = StatisticsStore()
+// 加载中
+const loading = ref(false)
+// 节点情况
+const nodeList = ref([])
+// CPU情况
+const cpuList = ref([])
+// 用户数量
+const userList = ref([])
+// 作业总数
+const work_total = ref(0)
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await search()
+  loading.value = false
+})
+const search = async () => {
+  const res = await statisticsStore.total()
+  if (res.errcode == '0') {
+    nodeList.value = res.data.nodeList
+    cpuList.value = res.data.cpuList
+    userList.value = res.data.userList
+    work_total.value = res.data.work_total
+  }
+}
+</script>
+<style scoped lang="scss">
+.main {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  background: linear-gradient(25deg, #0f2249, #182e5a 20%, #0f2249 40%, #182e5a 60%, #0f2249 80%, #182e5a 100%);
+  padding: 0rem;
+  margin: 0rem;
+  color: #ffffff;
+  font-family: '微软雅黑';
+  cursor: default; /* 将鼠标样式更改为箭头 */
+
+  .one {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 8%;
+    background: url(/images/head_bg.png);
+    background-size: 100% 100%;
+    font-size: 2.4rem;
+    font-weight: 600;
+    color: #53befe;
+    span {
+      letter-spacing: 0.2em;
+    }
+  }
+  .two {
+    display: flex;
+    justify-content: space-evenly;
+    width: 100%;
+    height: 88%;
+    margin: 1rem 0 0 0;
+    .two_1 {
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      .boxall {
+        border: 1px solid #3486da;
+        background: rgba(0, 70, 190, 0.1);
+        position: relative;
+        padding: 1rem;
+        z-index: 10;
+        .title {
+          background: linear-gradient(to right, rgba(48, 82, 174, 1), rgba(48, 82, 174, 0));
+          color: #fff;
+          font-size: 1rem;
+          padding: 0.5rem 0.6rem;
+          margin: 0 0 1rem 0;
+        }
+        .echarts {
+          height: 85%;
+        }
+      }
+      .boxall:before,
+      .boxall:after {
+        position: absolute;
+        content: '';
+        border-top: 3px solid #3486da;
+        top: -2px;
+      }
+      .boxall:before,
+      .boxfoot:before {
+        border-left: 3px solid #3486da;
+        left: -2px;
+      }
+      .boxall:after,
+      .boxfoot:after {
+        border-right: 3px solid #3486da;
+        right: -2px;
+      }
+      .boxall_1 {
+        height: 28%;
+      }
+      .boxall_2 {
+        height: 28%;
+      }
+      .boxall_3 {
+        height: 28%;
+      }
+      .boxall_4 {
+        height: 30%;
+      }
+      .boxall_5 {
+        height: 35%;
+      }
+      .boxall_6 {
+        height: 45%;
+      }
+      .boxall_7 {
+        height: 45%;
+      }
+      .boxall_8 {
+        height: 23%;
+        padding: 0 2rem;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        h4 {
+          font-size: 2rem;
+          padding-left: 1rem;
+          color: #20dbfd;
+          text-shadow: 0 0 25px #00d8ff;
+          margin: 1rem 0;
+        }
+        .itemTilte {
+          display: flex;
+          align-items: center;
+          span {
+            margin: 0 0 0.1rem 0.5rem;
+            font-size: 1rem;
+            color: rgba(255, 255, 255, 0.6);
+          }
+        }
+      }
+    }
+  }
+}
+</style>