fix: 测试
							
								
								
									
										956
									
								
								pnpm-lock.yaml
								
								
								
								
							
							
						
						| 
						 | 
				
			
			@ -1,119 +0,0 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="center-container">
 | 
			
		||||
    <div class="item" :style="getItemStyle(index)" v-for="(item, index) in dcList" :key="item.type">
 | 
			
		||||
      <dv-decoration-9 class="active" v-if="!dcId || dcId === item.id"></dv-decoration-9>
 | 
			
		||||
      <span class="dc-name" @click="select(index)">{{item.name}}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import { ref, onUnmounted } from '@vue/composition-api'
 | 
			
		||||
import { getDcs } from 'services/screen/outside'
 | 
			
		||||
export default {
 | 
			
		||||
  setup(props, context) {
 | 
			
		||||
    const dcId = ref('');
 | 
			
		||||
    let currentIndex = -1;
 | 
			
		||||
    let timer = null;
 | 
			
		||||
    const startTimer = () => {
 | 
			
		||||
      // 如果timer存在先清除
 | 
			
		||||
      if (timer) clearTimer();
 | 
			
		||||
      timer = setInterval(() => {
 | 
			
		||||
        currentIndex++;
 | 
			
		||||
        select(currentIndex, 'auto');
 | 
			
		||||
        if (currentIndex === dcList.value.length - 1) currentIndex = -1;
 | 
			
		||||
      }, 1000 * 20)
 | 
			
		||||
    }
 | 
			
		||||
    const clearTimer = () => {
 | 
			
		||||
      clearInterval(timer);
 | 
			
		||||
      timer = null;
 | 
			
		||||
    }
 | 
			
		||||
    onUnmounted(() => {
 | 
			
		||||
      clearTimer();
 | 
			
		||||
    })
 | 
			
		||||
    const select = (index, way) => {
 | 
			
		||||
      // 手动触发重置定时器
 | 
			
		||||
      if (way !== 'auto') startTimer();
 | 
			
		||||
      currentIndex = index;
 | 
			
		||||
      // -1时为全部
 | 
			
		||||
      const id = currentIndex === -1 ? '' : dcList.value[index].id;
 | 
			
		||||
      dcId.value = id;
 | 
			
		||||
      context.emit('changeDc', id)
 | 
			
		||||
    };
 | 
			
		||||
    // 获取数据中心
 | 
			
		||||
    const dcList = ref([]);
 | 
			
		||||
    (async function() {
 | 
			
		||||
      const res = await getDcs();
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        dcList.value = res.data.rows;
 | 
			
		||||
        select(currentIndex);
 | 
			
		||||
      }
 | 
			
		||||
    })();
 | 
			
		||||
    // 获取每个数据中心的样式 横向每个加400,大于3个折行
 | 
			
		||||
    function getItemStyle(index) {
 | 
			
		||||
      const rows = Math.floor(index / 2);
 | 
			
		||||
      const style = {
 | 
			
		||||
        // left: `${index % 2 * 400 + 50}px`,
 | 
			
		||||
        // top: `${rows * 400}px`
 | 
			
		||||
      }
 | 
			
		||||
      return style
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      dcList,
 | 
			
		||||
      dcId,
 | 
			
		||||
      select,
 | 
			
		||||
      getItemStyle
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.center-container {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  justify-content: space-around;
 | 
			
		||||
}
 | 
			
		||||
@keyframes item-animate {
 | 
			
		||||
  0% {
 | 
			
		||||
    top: 100px;
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
  }
 | 
			
		||||
  50% {
 | 
			
		||||
    opacity: 0.8;
 | 
			
		||||
    top: 80px;
 | 
			
		||||
  }
 | 
			
		||||
  100% {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    top: 100px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.item {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  width: 430px;
 | 
			
		||||
  height: 430px;
 | 
			
		||||
  background: url('/scr-web/static/img/sip/bg_bottom.png');
 | 
			
		||||
  background-size: 100% 100% ;
 | 
			
		||||
  .active{
 | 
			
		||||
    width: 350px;
 | 
			
		||||
    height: 350px;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    bottom: -78px;
 | 
			
		||||
    left: 38px;
 | 
			
		||||
    transform: rotateX(115deg);
 | 
			
		||||
  }
 | 
			
		||||
  .dc-name {
 | 
			
		||||
    animation: item-animate 1.2s infinite linear;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 110px;
 | 
			
		||||
    top: 100px;
 | 
			
		||||
    width: 50%;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    font-size: 30px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,327 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div id="RealTimeUsed"></div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import * as echarts from 'echarts'
 | 
			
		||||
import { getRealTimeUtilization } from './api.js'
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'UsedTrend',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      myChart: null,
 | 
			
		||||
      used: 25.7,
 | 
			
		||||
      timer: null
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    const chartDom = document.getElementById('RealTimeUsed')
 | 
			
		||||
    this.myChart = echarts.init(chartDom)
 | 
			
		||||
    this.getRealTimeUesdView()
 | 
			
		||||
    this.timer = setInterval(() => {
 | 
			
		||||
      this.getRealTimeData()
 | 
			
		||||
    }, 1000)
 | 
			
		||||
  },
 | 
			
		||||
  unmounted() {
 | 
			
		||||
    clearInterval(this.timer)
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    // 平台实用利用率
 | 
			
		||||
    async getRealTimeData() {
 | 
			
		||||
      const res = await getRealTimeUtilization()
 | 
			
		||||
      if (res.status !== 'success') return
 | 
			
		||||
      this.used = (res.data?.result?.[0]?.value[1] || 25.7).toFixed(2)
 | 
			
		||||
    },
 | 
			
		||||
    getRealTimeUesdView() {
 | 
			
		||||
      let angle = 0
 | 
			
		||||
      const value = this.used
 | 
			
		||||
      const option = {
 | 
			
		||||
        title: {
 | 
			
		||||
          text: '{a|' + value + '}{c|%}',
 | 
			
		||||
          x: 'center',
 | 
			
		||||
          y: 'center',
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            rich: {
 | 
			
		||||
              a: {
 | 
			
		||||
                fontSize: 20,
 | 
			
		||||
                color: '#29EEF3'
 | 
			
		||||
              },
 | 
			
		||||
 | 
			
		||||
              c: {
 | 
			
		||||
                fontSize: 18,
 | 
			
		||||
                color: '#ffffff'
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        series: [
 | 
			
		||||
          {
 | 
			
		||||
            name: 'ring5',
 | 
			
		||||
            type: 'custom',
 | 
			
		||||
            coordinateSystem: 'none',
 | 
			
		||||
            renderItem: function(params, api) {
 | 
			
		||||
              return {
 | 
			
		||||
                type: 'arc',
 | 
			
		||||
                shape: {
 | 
			
		||||
                  cx: api.getWidth() / 2,
 | 
			
		||||
                  cy: api.getHeight() / 2,
 | 
			
		||||
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.6,
 | 
			
		||||
                  startAngle: ((0 + angle) * Math.PI) / 180,
 | 
			
		||||
                  endAngle: ((90 + angle) * Math.PI) / 180
 | 
			
		||||
                },
 | 
			
		||||
                style: {
 | 
			
		||||
                  stroke: '#0CD3DB',
 | 
			
		||||
                  fill: 'transparent',
 | 
			
		||||
                  lineWidth: 1.5
 | 
			
		||||
                },
 | 
			
		||||
                silent: true
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [0]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'ring5',
 | 
			
		||||
            type: 'custom',
 | 
			
		||||
            coordinateSystem: 'none',
 | 
			
		||||
            renderItem: function(params, api) {
 | 
			
		||||
              return {
 | 
			
		||||
                type: 'arc',
 | 
			
		||||
                shape: {
 | 
			
		||||
                  cx: api.getWidth() / 2,
 | 
			
		||||
                  cy: api.getHeight() / 2,
 | 
			
		||||
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.6,
 | 
			
		||||
                  startAngle: ((180 + angle) * Math.PI) / 180,
 | 
			
		||||
                  endAngle: ((270 + angle) * Math.PI) / 180
 | 
			
		||||
                },
 | 
			
		||||
                style: {
 | 
			
		||||
                  stroke: '#0CD3DB',
 | 
			
		||||
                  fill: 'transparent',
 | 
			
		||||
                  lineWidth: 1.5
 | 
			
		||||
                },
 | 
			
		||||
                silent: true
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [0]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'ring5',
 | 
			
		||||
            type: 'custom',
 | 
			
		||||
            coordinateSystem: 'none',
 | 
			
		||||
            renderItem: function(params, api) {
 | 
			
		||||
              return {
 | 
			
		||||
                type: 'arc',
 | 
			
		||||
                shape: {
 | 
			
		||||
                  cx: api.getWidth() / 2,
 | 
			
		||||
                  cy: api.getHeight() / 2,
 | 
			
		||||
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.65,
 | 
			
		||||
                  startAngle: ((270 + -angle) * Math.PI) / 180,
 | 
			
		||||
                  endAngle: ((40 + -angle) * Math.PI) / 180
 | 
			
		||||
                },
 | 
			
		||||
                style: {
 | 
			
		||||
                  stroke: '#0CD3DB',
 | 
			
		||||
                  fill: 'transparent',
 | 
			
		||||
                  lineWidth: 1.5
 | 
			
		||||
                },
 | 
			
		||||
                silent: true
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [0]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'ring5',
 | 
			
		||||
            type: 'custom',
 | 
			
		||||
            coordinateSystem: 'none',
 | 
			
		||||
            renderItem: function(params, api) {
 | 
			
		||||
              return {
 | 
			
		||||
                type: 'arc',
 | 
			
		||||
                shape: {
 | 
			
		||||
                  cx: api.getWidth() / 2,
 | 
			
		||||
                  cy: api.getHeight() / 2,
 | 
			
		||||
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.65,
 | 
			
		||||
                  startAngle: ((90 + -angle) * Math.PI) / 180,
 | 
			
		||||
                  endAngle: ((220 + -angle) * Math.PI) / 180
 | 
			
		||||
                },
 | 
			
		||||
                style: {
 | 
			
		||||
                  stroke: '#0CD3DB',
 | 
			
		||||
                  fill: 'transparent',
 | 
			
		||||
                  lineWidth: 1.5
 | 
			
		||||
                },
 | 
			
		||||
                silent: true
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [0]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'ring5',
 | 
			
		||||
            type: 'custom',
 | 
			
		||||
            coordinateSystem: 'none',
 | 
			
		||||
            renderItem: function(params, api) {
 | 
			
		||||
              const x0 = api.getWidth() / 2
 | 
			
		||||
              const y0 = api.getHeight() / 2
 | 
			
		||||
              const r = (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.65
 | 
			
		||||
              const point = getCirlPoint(x0, y0, r, 90 + -angle)
 | 
			
		||||
              return {
 | 
			
		||||
                type: 'circle',
 | 
			
		||||
                shape: {
 | 
			
		||||
                  cx: point.x,
 | 
			
		||||
                  cy: point.y,
 | 
			
		||||
                  r: 4
 | 
			
		||||
                },
 | 
			
		||||
                style: {
 | 
			
		||||
                  stroke: '#0CD3DB', // 粉
 | 
			
		||||
                  fill: '#0CD3DB'
 | 
			
		||||
                },
 | 
			
		||||
                silent: true
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [0]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'ring5', // 绿点
 | 
			
		||||
            type: 'custom',
 | 
			
		||||
            coordinateSystem: 'none',
 | 
			
		||||
            renderItem: function(params, api) {
 | 
			
		||||
              const x0 = api.getWidth() / 2
 | 
			
		||||
              const y0 = api.getHeight() / 2
 | 
			
		||||
              const r = (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.65
 | 
			
		||||
              const point = getCirlPoint(x0, y0, r, 270 + -angle)
 | 
			
		||||
              return {
 | 
			
		||||
                type: 'circle',
 | 
			
		||||
                shape: {
 | 
			
		||||
                  cx: point.x,
 | 
			
		||||
                  cy: point.y,
 | 
			
		||||
                  r: 4
 | 
			
		||||
                },
 | 
			
		||||
                style: {
 | 
			
		||||
                  stroke: '#0CD3DB', // 绿
 | 
			
		||||
                  fill: '#0CD3DB'
 | 
			
		||||
                },
 | 
			
		||||
                silent: true
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [0]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'pie',
 | 
			
		||||
            radius: ['58%', '45%'],
 | 
			
		||||
            silent: true,
 | 
			
		||||
            clockwise: true,
 | 
			
		||||
            startAngle: 90,
 | 
			
		||||
            z: 0,
 | 
			
		||||
            zlevel: 0,
 | 
			
		||||
            label: {
 | 
			
		||||
              normal: {
 | 
			
		||||
                position: 'center'
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            data: [
 | 
			
		||||
              {
 | 
			
		||||
                value: value,
 | 
			
		||||
                name: '',
 | 
			
		||||
                itemStyle: {
 | 
			
		||||
                  normal: {
 | 
			
		||||
                    color: {
 | 
			
		||||
                      //  完成的圆环的颜色
 | 
			
		||||
                      colorStops: [
 | 
			
		||||
                        {
 | 
			
		||||
                          offset: 0,
 | 
			
		||||
                          color: '#4FADFD' // 0% 处的颜色
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                          offset: 1,
 | 
			
		||||
                          color: '#28E8FA' // 100% 处的颜色
 | 
			
		||||
                        }
 | 
			
		||||
                      ]
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                value: 100 - value,
 | 
			
		||||
                name: '',
 | 
			
		||||
                label: {
 | 
			
		||||
                  normal: {
 | 
			
		||||
                    show: false
 | 
			
		||||
                  }
 | 
			
		||||
                },
 | 
			
		||||
                itemStyle: {
 | 
			
		||||
                  normal: {
 | 
			
		||||
                    color: '#173164'
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '',
 | 
			
		||||
            type: 'gauge',
 | 
			
		||||
            radius: '58%',
 | 
			
		||||
            center: ['50%', '50%'],
 | 
			
		||||
            startAngle: 0,
 | 
			
		||||
            endAngle: 359.9,
 | 
			
		||||
            splitNumber: 8,
 | 
			
		||||
            hoverAnimation: true,
 | 
			
		||||
            axisTick: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            splitLine: {
 | 
			
		||||
              length: 12,
 | 
			
		||||
              lineStyle: {
 | 
			
		||||
                width: 5,
 | 
			
		||||
                color: '#061740'
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            pointer: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLine: {
 | 
			
		||||
              lineStyle: {
 | 
			
		||||
                opacity: 0
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            detail: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            data: [
 | 
			
		||||
              {
 | 
			
		||||
                value: 0,
 | 
			
		||||
                name: ''
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 获取圆上面某点的坐标(x0,y0表示坐标,r半径,angle角度)
 | 
			
		||||
      function getCirlPoint(x0, y0, r, angle) {
 | 
			
		||||
        const x1 = x0 + r * Math.cos((angle * Math.PI) / 180)
 | 
			
		||||
        const y1 = y0 + r * Math.sin((angle * Math.PI) / 180)
 | 
			
		||||
        return {
 | 
			
		||||
          x: x1,
 | 
			
		||||
          y: y1
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      setInterval(() => {
 | 
			
		||||
        angle = angle + 3
 | 
			
		||||
        option.title.text = `{a|${this.used}}{c|%}`
 | 
			
		||||
        option.series[6].data[0].value = this.used
 | 
			
		||||
        option.series[6].data[1].value = 100 - parseFloat(this.used)
 | 
			
		||||
        this.myChart.setOption(option, true)
 | 
			
		||||
      }, 100)
 | 
			
		||||
 | 
			
		||||
      window.addEventListener('resize', () => {
 | 
			
		||||
        this.myChart.resize()
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
#RealTimeUsed {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,264 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div id="UsedTrend"></div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import * as echarts from 'echarts'
 | 
			
		||||
import { getAverageUtilizationTrend } from './api.js'
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'UsedTrend',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      myChart: null,
 | 
			
		||||
      timer: null,
 | 
			
		||||
      tableData7: [
 | 
			
		||||
        {
 | 
			
		||||
          data: 50,
 | 
			
		||||
          name: 1621300392
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
          data: 90,
 | 
			
		||||
          name: 1691300392
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          data: 70,
 | 
			
		||||
          name: 1729300392
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    const chartDom = document.getElementById('UsedTrend')
 | 
			
		||||
    this.myChart = echarts.init(chartDom)
 | 
			
		||||
    this.getQueryRangeData()
 | 
			
		||||
    this.getQueryRangeView()
 | 
			
		||||
  },
 | 
			
		||||
  unmounted() {
 | 
			
		||||
    clearInterval(this.timer)
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    // 平台实用利用率
 | 
			
		||||
    async getQueryRangeData() {
 | 
			
		||||
      const res = await getAverageUtilizationTrend()
 | 
			
		||||
      if (res.status !== 'success') return
 | 
			
		||||
      this.tableData7 = res.data?.result?.[0]?.values?.map(v => {
 | 
			
		||||
        return {
 | 
			
		||||
          name: v[0],
 | 
			
		||||
          data: v[1]
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      this.getQueryRangeView()
 | 
			
		||||
    },
 | 
			
		||||
    getQueryRangeView() {
 | 
			
		||||
      const ydata = this.tableData7.map(v => parseFloat(v.data).toFixed(2))
 | 
			
		||||
      const xdata = this.tableData7.map(v => {
 | 
			
		||||
        const date = new Date(v.name * 1000)
 | 
			
		||||
        const year = date.getFullYear()
 | 
			
		||||
        const month = String(date.getMonth() + 1).padStart(2, '0')
 | 
			
		||||
        const day = String(date.getDate()).padStart(2, '0')
 | 
			
		||||
        const hours = String(date.getHours()).padStart(2, '0')
 | 
			
		||||
        const minutes = String(date.getMinutes()).padStart(2, '0')
 | 
			
		||||
        const seconds = String(date.getSeconds()).padStart(2, '0')
 | 
			
		||||
        return `${year}-${month}-${day}`
 | 
			
		||||
      })
 | 
			
		||||
      const option = {
 | 
			
		||||
        grid: {
 | 
			
		||||
          left: '0%', // 将 left 设置为 0 确保左边没有留白
 | 
			
		||||
          right: '0%',
 | 
			
		||||
          top: '20%',
 | 
			
		||||
          bottom: '0%',
 | 
			
		||||
          containLabel: true, // 确保标签不会被裁剪
 | 
			
		||||
          show: false
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          formatter: '{b}: {c}',
 | 
			
		||||
          trigger: 'axis',
 | 
			
		||||
          axisPointer: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0, 82, 212,0.3)',
 | 
			
		||||
              type: 'dashed'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          backgroundColor: 'rgba(0, 82, 212,0.3)',
 | 
			
		||||
          padding: [5, 10],
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            color: '#fff',
 | 
			
		||||
            fontSize: 12
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
          right: 20,
 | 
			
		||||
          orient: 'vertical'
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          type: 'category',
 | 
			
		||||
          data: xdata,
 | 
			
		||||
          boundaryGap: false,
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            show: false
 | 
			
		||||
          },
 | 
			
		||||
          splitLine: {
 | 
			
		||||
            show: true,
 | 
			
		||||
            interval: 'auto',
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0,0,0,0.06)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0,0,0,0.06)'
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          // axisLabel: {
 | 
			
		||||
          //   rotate: 45,
 | 
			
		||||
          //   textStyle: {
 | 
			
		||||
          //     color: '#fff'
 | 
			
		||||
          //   }
 | 
			
		||||
          // }
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: {
 | 
			
		||||
          // name: '出勤人数',
 | 
			
		||||
          nameTextStyle: {
 | 
			
		||||
            color: '#666'
 | 
			
		||||
          },
 | 
			
		||||
          type: 'value',
 | 
			
		||||
          min: 0,
 | 
			
		||||
          max: 100,
 | 
			
		||||
          minInterval: 1, // 横坐标值为整数
 | 
			
		||||
          splitLine: {
 | 
			
		||||
            show: true,
 | 
			
		||||
            interval: 'auto',
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0,0,0,0.06)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            show: false
 | 
			
		||||
          },
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0,0,0,0.06)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            margin: 1,
 | 
			
		||||
            textStyle: {
 | 
			
		||||
              fontSize: 10,
 | 
			
		||||
              color: '#FFF'
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        series: [
 | 
			
		||||
          {
 | 
			
		||||
            type: 'line',
 | 
			
		||||
            showSymbol: false,
 | 
			
		||||
            symbol: 'emptyCircle',
 | 
			
		||||
            symbolSize: 2,
 | 
			
		||||
            data: ydata,
 | 
			
		||||
            areaStyle: {
 | 
			
		||||
              normal: {
 | 
			
		||||
                color: new echarts.graphic.LinearGradient(
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  1,
 | 
			
		||||
                  [
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 0,
 | 
			
		||||
                      color: 'rgb(128, 255, 165)'
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 1,
 | 
			
		||||
                      color: 'rgb(1, 191, 236, 0)'
 | 
			
		||||
                    }
 | 
			
		||||
                  ],
 | 
			
		||||
                  false
 | 
			
		||||
                )
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            itemStyle: {
 | 
			
		||||
              normal: {
 | 
			
		||||
                borderWidth: 2,
 | 
			
		||||
                color: new echarts.graphic.LinearGradient(
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  1,
 | 
			
		||||
                  [
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 0,
 | 
			
		||||
                      color: 'rgba(0, 82, 212,0.7)'
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 1,
 | 
			
		||||
                      color: 'rgba(0, 82, 212,0.4)'
 | 
			
		||||
                    }
 | 
			
		||||
                  ],
 | 
			
		||||
                  false
 | 
			
		||||
                )
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              globalCoord: false, // 缺省为 false
 | 
			
		||||
              normal: {
 | 
			
		||||
                width: 2,
 | 
			
		||||
                color: new echarts.graphic.LinearGradient(
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  1,
 | 
			
		||||
                  [
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 0,
 | 
			
		||||
                      color: 'rgba(0, 82, 212,0.7)'
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 1,
 | 
			
		||||
                      color: 'rgba(0, 82, 212,0.4)'
 | 
			
		||||
                    }
 | 
			
		||||
                  ],
 | 
			
		||||
                  false
 | 
			
		||||
                )
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            emphasis: {
 | 
			
		||||
              itemStyle: {
 | 
			
		||||
                borderWidth: 2,
 | 
			
		||||
                borderColor: new echarts.graphic.LinearGradient(
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  0,
 | 
			
		||||
                  1,
 | 
			
		||||
                  [
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 0,
 | 
			
		||||
                      color: 'rgba(245,166,35,1)'
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                      offset: 1,
 | 
			
		||||
                      color: 'rgba(245,166,35,0.8)'
 | 
			
		||||
                    }
 | 
			
		||||
                  ],
 | 
			
		||||
                  false
 | 
			
		||||
                )
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      option && this.myChart.setOption(option)
 | 
			
		||||
      window.addEventListener('resize', () => {
 | 
			
		||||
        this.myChart.resize()
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped>
 | 
			
		||||
#UsedTrend {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,98 @@
 | 
			
		|||
import axios from 'axios'
 | 
			
		||||
 | 
			
		||||
// 单位机时统计
 | 
			
		||||
export const getDepartDuration = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/findTopByOrg?startDate=2024-05-01&endDate=2024-06-30')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
// 软件机时统计
 | 
			
		||||
export const getSoftwareDuration = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/findTopBySoft?startDate=2024-05-01&endDate=2024-06-30')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
// 当前在用软件
 | 
			
		||||
export const getInUseSoftware = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/findTopSoftList?startDate=2024-05-01&endDate=2024-06-30')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
// 用户机时用量
 | 
			
		||||
export const getUserUseTrend = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/findTopByUser?startDate=2024-05-01&endDate=2024-06-30')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
// 软件集成数量
 | 
			
		||||
export const getSoftwareIntegrate = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/findSoftCount?startDate=2024-05-01&endDate=2024-06-30')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
// 查看帮助
 | 
			
		||||
export const getHelp = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/help/query')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
// 实时利用率
 | 
			
		||||
export const getRealTimeUtilization = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .get('/prometheus/api/v1/query?query=avg(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[2m])) by (instance)) * 100')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
// 平均利用率趋势
 | 
			
		||||
export const getAverageUtilizationTrend = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .get('/prometheus/api/v1/query_range')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
// 查询平台统计数据
 | 
			
		||||
export const getPlateformSum = () =>
 | 
			
		||||
  axios
 | 
			
		||||
    .post('/screen_server/hpc/findSum')
 | 
			
		||||
    .then(function(response) {
 | 
			
		||||
      return response.data
 | 
			
		||||
    })
 | 
			
		||||
    .catch(function(error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    })
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="full-screen-container" :style="style">
 | 
			
		||||
    <slot></slot>
 | 
			
		||||
    <div class="loading" v-if="loading">
 | 
			
		||||
      <dv-decoration-9 style="width:300px;height:300px;">数据加载中</dv-decoration-9>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { computed, onMounted, onUnmounted, reactive, toRefs } from '@vue/composition-api'
 | 
			
		||||
import { debounce } from 'lodash-es'
 | 
			
		||||
// import 'utils/rem'
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    width: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 1920
 | 
			
		||||
    },
 | 
			
		||||
    height: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 1080
 | 
			
		||||
    },
 | 
			
		||||
    loading: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup(props, context) {
 | 
			
		||||
    const state = reactive({
 | 
			
		||||
      scale: null
 | 
			
		||||
    })
 | 
			
		||||
    const style = computed(() => {
 | 
			
		||||
      return {
 | 
			
		||||
        width: `${props.width}px`,
 | 
			
		||||
        height: `${props.height}px`,
 | 
			
		||||
        transform: `scale(${state.scale})`
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    function getScale() {
 | 
			
		||||
      const { width, height } = props
 | 
			
		||||
      const wRatio = window.innerWidth / width
 | 
			
		||||
      const hRatio = window.innerHeight / height
 | 
			
		||||
      // return 1;
 | 
			
		||||
      return wRatio < hRatio ? wRatio : hRatio
 | 
			
		||||
    }
 | 
			
		||||
    function setScale() {
 | 
			
		||||
      state.scale = getScale()
 | 
			
		||||
      context.emit('getScale', state.scale)
 | 
			
		||||
    }
 | 
			
		||||
    const onResize = debounce(setScale, 10)
 | 
			
		||||
    onMounted(() => {
 | 
			
		||||
      setScale()
 | 
			
		||||
      window.addEventListener('resize', onResize)
 | 
			
		||||
    })
 | 
			
		||||
    onUnmounted(() => {
 | 
			
		||||
      window.removeEventListener('resize', onResize)
 | 
			
		||||
    })
 | 
			
		||||
    return {
 | 
			
		||||
      style
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.full-screen-container {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 0px;
 | 
			
		||||
  left: 0px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  transform-origin: left top;
 | 
			
		||||
  z-index: 999;
 | 
			
		||||
  .loading {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    background: rgba(0, 0, 0, 0.8);
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    color: rgba(255, 255, 255, 0.8);
 | 
			
		||||
    font-size: 20px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="outside-header">
 | 
			
		||||
    <span class="pull-left">
 | 
			
		||||
      <img class="logo m-r" :src="logo" />
 | 
			
		||||
      <img class="m-r" :src="logo2" />
 | 
			
		||||
      <div class="inline-block left-title text-center sub-title">
 | 
			
		||||
        <div>国家能源集团科学技术研究院有限公司</div>
 | 
			
		||||
        <div>重点实验室</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </span>
 | 
			
		||||
    <span class="screen-title" @click="operateScreen">
 | 
			
		||||
      {{ title }}
 | 
			
		||||
    </span>
 | 
			
		||||
    <span class="pull-right">
 | 
			
		||||
      <span class="m-r-lg tips">系统使用手册下载</span>
 | 
			
		||||
      <span class="btn m-r">登录入口</span>
 | 
			
		||||
    </span>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import useHeader from './useHeader.js'
 | 
			
		||||
export default {
 | 
			
		||||
  setup() {
 | 
			
		||||
    const { operateScreen, logo, logo2, title } = useHeader()
 | 
			
		||||
    return {
 | 
			
		||||
      logo,
 | 
			
		||||
      logo2,
 | 
			
		||||
      title,
 | 
			
		||||
      operateScreen
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.m-r {
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
}
 | 
			
		||||
.m-r-lg {
 | 
			
		||||
  margin-right: 35px;
 | 
			
		||||
}
 | 
			
		||||
.text-center {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pull-left {
 | 
			
		||||
  text-align: left;
 | 
			
		||||
}
 | 
			
		||||
.inline-block {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pull-right {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
}
 | 
			
		||||
.outside-header {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 73px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  & > span {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .left-title {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
  }
 | 
			
		||||
  .logo {
 | 
			
		||||
    margin: 0 0 0 20px;
 | 
			
		||||
    width: 54px;
 | 
			
		||||
  }
 | 
			
		||||
  .sub-title {
 | 
			
		||||
    font-size: 20px;
 | 
			
		||||
  }
 | 
			
		||||
  .screen-title {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
    line-height: 42px;
 | 
			
		||||
    font-style: normal;
 | 
			
		||||
    text-transform: none;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
  }
 | 
			
		||||
  .tips {
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    color: #b7b7b7;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
  }
 | 
			
		||||
  .btn {
 | 
			
		||||
    padding: 5px;
 | 
			
		||||
    width: 30px;
 | 
			
		||||
    height: 20px;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    color: #03a9f4;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    background: url('../images/card_bg.png');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="table-td" :title="value" :style="style">
 | 
			
		||||
    <slot :value=value>
 | 
			
		||||
      <el-tooltip class="item" effect="dark" :content="value.toString()" placement="top-start">
 | 
			
		||||
        <span>{{value}}</span>
 | 
			
		||||
      </el-tooltip>
 | 
			
		||||
    </slot>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import { computed } from '@vue/composition-api'
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    value: {
 | 
			
		||||
      type: [String, Number],
 | 
			
		||||
      default: ''
 | 
			
		||||
    },
 | 
			
		||||
    width: {
 | 
			
		||||
      type: String
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    return {
 | 
			
		||||
      style: props.width ? { width: props.width, flex: 'none' } : {}
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
div.table-td {
 | 
			
		||||
  flex: 1;
 | 
			
		||||
  // width: calc(100% / 7);
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  text-overflow: ellipsis;
 | 
			
		||||
  padding: 8px 5px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <ul class="scroll-table">
 | 
			
		||||
    <li class="table-header">
 | 
			
		||||
      <div v-for="(item, index) in columns" :key="item" :title="item" :style="getStyle(index)">
 | 
			
		||||
        <span>{{ item }}</span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </li>
 | 
			
		||||
    <div class="table-body">
 | 
			
		||||
      <li class="table-tr" v-for="(item, index) in data" :key="index">
 | 
			
		||||
        <slot :row="item"></slot>
 | 
			
		||||
      </li>
 | 
			
		||||
      <div v-if="!data.length"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ul>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    options: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: function() {
 | 
			
		||||
        return {}
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    columns: {
 | 
			
		||||
      type: Array
 | 
			
		||||
    },
 | 
			
		||||
    columnWidth: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: function() {
 | 
			
		||||
        return []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    data: {
 | 
			
		||||
      type: Array
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    const getStyle = index => {
 | 
			
		||||
      const width = props.columnWidth[index]
 | 
			
		||||
      return width ? { width: width, flex: 'none' } : {}
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      getStyle
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.scroll-table {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  padding: 0 10px;
 | 
			
		||||
  list-style: none;
 | 
			
		||||
  .table-header {
 | 
			
		||||
    background: #152e6a;
 | 
			
		||||
    background: url('../../images/table-header.png');
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    div {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      // width: calc(100% / 7);
 | 
			
		||||
      padding: 10px 5px;
 | 
			
		||||
      white-space: nowrap;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      text-overflow: ellipsis;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .table-body {
 | 
			
		||||
    height: calc(100% - 50px);
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
 | 
			
		||||
    .table-tr {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      background: url('../../images/table-row.png');
 | 
			
		||||
      background-repeat: no-repeat;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .table-body::-webkit-scrollbar {
 | 
			
		||||
    width: 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
import logo from '../images/logo.png'
 | 
			
		||||
import logo2 from '../images/logo2.png'
 | 
			
		||||
export default function() {
 | 
			
		||||
  const title = '高性能数值模拟实验平台'
 | 
			
		||||
 | 
			
		||||
  let isFull = false
 | 
			
		||||
  function operateScreen() {
 | 
			
		||||
    if (isFull) {
 | 
			
		||||
      disableFullScreen()
 | 
			
		||||
    } else {
 | 
			
		||||
      enableFullScreen()
 | 
			
		||||
    }
 | 
			
		||||
    isFull = !isFull
 | 
			
		||||
  }
 | 
			
		||||
  return {
 | 
			
		||||
    logo,
 | 
			
		||||
    logo2,
 | 
			
		||||
    title,
 | 
			
		||||
    operateScreen
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function enableFullScreen() {
 | 
			
		||||
  const docElm = document.documentElement
 | 
			
		||||
  // W3C
 | 
			
		||||
  if (docElm.requestFullscreen) {
 | 
			
		||||
    docElm.requestFullscreen()
 | 
			
		||||
  } else if (docElm.mozRequestFullScreen) {
 | 
			
		||||
    // FireFox
 | 
			
		||||
    docElm.mozRequestFullScreen()
 | 
			
		||||
  } else if (docElm.webkitRequestFullScreen) {
 | 
			
		||||
    // Chrome等
 | 
			
		||||
    docElm.webkitRequestFullScreen()
 | 
			
		||||
  } else if (docElm.msRequestFullscreen) {
 | 
			
		||||
    // IE11
 | 
			
		||||
    document.body.msRequestFullscreen()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
export function disableFullScreen() {
 | 
			
		||||
  if (document.exitFullscreen) {
 | 
			
		||||
    document.exitFullscreen()
 | 
			
		||||
  } else if (document.mozCancelFullScreen) {
 | 
			
		||||
    document.mozCancelFullScreen()
 | 
			
		||||
  } else if (document.webkitCancelFullScreen) {
 | 
			
		||||
    document.webkitCancelFullScreen()
 | 
			
		||||
  } else if (document.msExitFullscreen) {
 | 
			
		||||
    document.msExitFullscreen()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.9 MiB  | 
| 
		 After Width: | Height: | Size: 2.1 KiB  | 
| 
		 After Width: | Height: | Size: 4.5 KiB  | 
| 
		 After Width: | Height: | Size: 3.6 KiB  | 
| 
		 After Width: | Height: | Size: 4.5 KiB  | 
| 
		 After Width: | Height: | Size: 3.5 KiB  | 
| 
		 After Width: | Height: | Size: 11 KiB  | 
| 
		 After Width: | Height: | Size: 4.9 KiB  | 
| 
		 After Width: | Height: | Size: 15 KiB  | 
| 
		 After Width: | Height: | Size: 17 KiB  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 4.5 KiB  | 
| 
		 After Width: | Height: | Size: 333 KiB  | 
| 
		 After Width: | Height: | Size: 24 KiB  | 
| 
		 After Width: | Height: | Size: 24 KiB  | 
| 
		 After Width: | Height: | Size: 24 KiB  | 
| 
		 After Width: | Height: | Size: 24 KiB  | 
| 
		 After Width: | Height: | Size: 3.3 KiB  | 
| 
		 After Width: | Height: | Size: 649 B  | 
| 
						 | 
				
			
			@ -1,201 +1,264 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <full-screen-container :width="1920" :height="1080" :loading="loading">
 | 
			
		||||
    <Header code="COUNT_SCREEN"></Header>
 | 
			
		||||
  <FullScreenContainer :width="1920" :height="1080" :loading="loading">
 | 
			
		||||
    <Header> </Header>
 | 
			
		||||
    <div class="container">
 | 
			
		||||
      <el-row class="full">
 | 
			
		||||
        <el-col :span="8" class="left">
 | 
			
		||||
          <div class="card">
 | 
			
		||||
            <div class="card-title">资源总览</div>
 | 
			
		||||
      <el-row class="full" :gutter="10">
 | 
			
		||||
        <el-col :span="7" class="left">
 | 
			
		||||
          <div class="card mini-card card-border1">
 | 
			
		||||
            <div class="card-title card-title-border1">平台实时利用率</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <el-row :gutter="15">
 | 
			
		||||
                <el-col :span="12">
 | 
			
		||||
                  <ResourceCount title="云主机总数(台)" :value="overviewData.vms" color=""></ResourceCount>
 | 
			
		||||
                </el-col>
 | 
			
		||||
                <el-col :span="12">
 | 
			
		||||
                  <ResourceCount title="CPU总量(核)" :value="overviewData.cpu" color="#18BE6A" icon="/scr-web/static/img/sip/cpu.png"></ResourceCount>
 | 
			
		||||
                </el-col>
 | 
			
		||||
                <el-col :span="12">
 | 
			
		||||
                  <ResourceCount title="内存总量(TB)" :value="overviewData.mem" color="#1890FF" icon="/scr-web/static/img/sip/mem.png"></ResourceCount>
 | 
			
		||||
                </el-col>
 | 
			
		||||
                <el-col :span="12">
 | 
			
		||||
                  <ResourceCount title="存储总量(TB)" :value="overviewData.disk" color="#FF6600" icon="/scr-web/static/img/sip/storage.png"></ResourceCount>
 | 
			
		||||
              <RealTimeUsed></RealTimeUsed>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="card card-border2">
 | 
			
		||||
            <div class="card-title card-title-border1">单位使用排名</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <ScrollTable :data="departTrend" :column-width="['80px']" :columns="['排名', '单位名称', '机时']" :options="{ singleHeight: 32 }">
 | 
			
		||||
                <template v-slot="scope">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.rank" width="80px">
 | 
			
		||||
                    <template slot-scope="scope">
 | 
			
		||||
                      <div class="square" :style="{ 'background-color': colorMap[scope.value - 1] || 'gray' }">{{ scope.value }}</div>
 | 
			
		||||
                    </template>
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.org_name"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.calc_time"> </scroll-table-column>
 | 
			
		||||
                </template>
 | 
			
		||||
              </ScrollTable>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="card mini-card card-border3">
 | 
			
		||||
            <div class="card-title card-title-border1">应用软件使用排名</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <ScrollTable :data="appTrend" :column-width="['80px']" :columns="['排名', '软件名称', '机时']" :options="{ singleHeight: 32 }">
 | 
			
		||||
                <template v-slot="scope">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.rank" width="80px">
 | 
			
		||||
                    <template slot-scope="scope">
 | 
			
		||||
                      <div class="square" :style="{ 'background-color': colorMap[scope.value - 1] || 'gray' }">{{ scope.value }}</div>
 | 
			
		||||
                    </template>
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.app_name"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.calc_time"> </scroll-table-column>
 | 
			
		||||
                </template>
 | 
			
		||||
              </ScrollTable>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </el-col>
 | 
			
		||||
        <el-col :span="10" class="center">
 | 
			
		||||
          <div class="card intro-card card-border4">
 | 
			
		||||
            <div class="card-title card-title-border2">平台简介</div>
 | 
			
		||||
            <div class="card-body ">
 | 
			
		||||
              <img class="intro-img m-t" src="./images/plateform.png" />
 | 
			
		||||
              <div class="intro-text">
 | 
			
		||||
                <div>
 | 
			
		||||
                  中科院高性能数值模拟实验平台是低碳智能燃煤发电与超净排放全国重点实验室的核心实验平台之-,以设计标准化、部署模块化,管理可视化,运维智能化为依托,打造满足中国机房设计标准、美国机房设计标准和Uptime
 | 
			
		||||
                  Institue的创新性平台,致力于拓展科研手段、深化生产服务,为火力发电、新能源等领域的关键技术、核心装备、系统集成等相关科技研发提供有力支撑。
 | 
			
		||||
                </div>
 | 
			
		||||
                <br />
 | 
			
		||||
                <div>
 | 
			
		||||
                  平台建筑面积200余平方米,硬件设施智能完善、软件系统高效便捷,主要开展火力发电固体燃料热解与燃烧、气体燃料燃烧、污染物生成与脱除、物质流能量流、全过程控制优化的数值模拟,以及综合能源系统仿真研究等八大研究方向。
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <el-row :gutter="32">
 | 
			
		||||
                <el-col :span="6" v-for="(item, index) in introItems" :key="index">
 | 
			
		||||
                  <div class="intro-item text-right m-r " :style="{ 'background-image': `url(${item.img})` }">
 | 
			
		||||
                    <div>
 | 
			
		||||
                      <span class="intro-item-value" :style="{ color: introColorMap[index] }">{{ item.value }}</span>
 | 
			
		||||
                      <span>{{ item.unit }}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div>{{ item.text }}</div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </el-col>
 | 
			
		||||
              </el-row>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="card">
 | 
			
		||||
            <div class="card-title">近30天云主机申请趋势</div>
 | 
			
		||||
          <div class="card mini-card card-border5">
 | 
			
		||||
            <div class="card-title card-title-border2">当前在用软件清单</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <line-charts :data="vmApplyTrend" width="100%" height="100%">
 | 
			
		||||
              </line-charts>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="card">
 | 
			
		||||
            <div class="card-title">近30天云资源申请趋势</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <line-charts  :data="resourceApplyTrend" width="100%" height="100%">
 | 
			
		||||
              </line-charts>
 | 
			
		||||
              <ScrollTable :data="inUseApps" :column-width="['80px']" :columns="['序号', '软件名称', '使用人员', '单位名称']" :options="{ singleHeight: 32 }">
 | 
			
		||||
                <template v-slot="scope">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.rank" width="80px"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.app_name"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.combined_info"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.departName"> </scroll-table-column>
 | 
			
		||||
                </template>
 | 
			
		||||
              </ScrollTable>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </el-col>
 | 
			
		||||
        <el-col :span="8" class="center">
 | 
			
		||||
          <OneCenter @changeDc="change"></OneCenter>
 | 
			
		||||
        </el-col>
 | 
			
		||||
        <el-col :span="8" class="right">
 | 
			
		||||
          <div class="card">
 | 
			
		||||
            <div class="card-title">租户云资源统计</div>
 | 
			
		||||
        <el-col :span="7" class="right">
 | 
			
		||||
          <div class="card mini-card card-border1">
 | 
			
		||||
            <div class="card-title card-title-border1">平台利用率趋势</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <scroll-table :data="tenantCount" :column-width="['80px']" :columns="['租户',  'CPU(核)' , '内存(GB)' , '存储(GB)']" :options="{singleHeight: 40}">
 | 
			
		||||
                <template v-slot="scope">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.name" width="80px">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.cpu">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.mem">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.disk">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                </template>
 | 
			
		||||
              </scroll-table>
 | 
			
		||||
              <UsedTrend></UsedTrend>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="card">
 | 
			
		||||
            <div class="card-title">项目云资源统计</div>
 | 
			
		||||
          <div class="card card-border2">
 | 
			
		||||
            <div class="card-title card-title-border1">用户使用排名</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <scroll-table :data="projectCount" :column-width="['80px']" :columns="['项目', 'CPU(核)' , '内存(GB)' , '存储(GB)']" :options="{singleHeight: 40}">
 | 
			
		||||
              <ScrollTable :data="userUseTrend" :column-width="['80px']" :columns="['排名', '人员姓名', '单位名称', '机时']" :options="{ singleHeight: 32 }">
 | 
			
		||||
                <template v-slot="scope">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.name" width="80px">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.cpu">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.mem">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.disk">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.rank" width="80px">
 | 
			
		||||
                    <template slot-scope="scope">
 | 
			
		||||
                      <div class="square" :style="{ 'background-color': colorMap[scope.value - 1] || 'gray' }">{{ scope.value }}</div>
 | 
			
		||||
                    </template>
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.full_name"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.org_name"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.calc_time"> </scroll-table-column>
 | 
			
		||||
                </template>
 | 
			
		||||
              </scroll-table>
 | 
			
		||||
              </ScrollTable>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="card">
 | 
			
		||||
            <div class="card-title">业务云资源统计</div>
 | 
			
		||||
          <div class="card mini-card card-border3">
 | 
			
		||||
            <div class="card-title card-title-border1">应用软件集成需求</div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <scroll-table :data="businessCount" :column-width="['80px']" :columns="['业务', 'CPU(核)' , '内存(GB)' , '存储(GB)']" :options="{singleHeight: 40}">
 | 
			
		||||
              <ScrollTable :data="appDemandList" :column-width="['80px']" :columns="['排名', '软件名称', '需求频次']" :options="{ singleHeight: 32 }">
 | 
			
		||||
                <template v-slot="scope">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.name" width="80px">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.cpu">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.mem">
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.disk">
 | 
			
		||||
                  <scroll-table-column :value="scope.row.rank" width="80px">
 | 
			
		||||
                    <template slot-scope="scope">
 | 
			
		||||
                      <div class="square" :style="{ 'background-color': colorMap[scope.value - 1] || 'gray' }">{{ scope.value }}</div>
 | 
			
		||||
                    </template>
 | 
			
		||||
                  </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.app_name"> </scroll-table-column>
 | 
			
		||||
                  <scroll-table-column :value="scope.row.cnum"> </scroll-table-column>
 | 
			
		||||
                </template>
 | 
			
		||||
              </scroll-table>
 | 
			
		||||
              </ScrollTable>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </el-col>
 | 
			
		||||
      </el-row>
 | 
			
		||||
    </div>
 | 
			
		||||
  </full-screen-container>
 | 
			
		||||
  </FullScreenContainer>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Header from 'components/ScreenWrapper/Header'
 | 
			
		||||
import FullScreenContainer from './components/FullScreenContainer.vue'
 | 
			
		||||
import Header from './components/Header.vue'
 | 
			
		||||
import ScrollTable from './components/ScrollTable/index.vue'
 | 
			
		||||
import ScrollTableColumn from './components/ScrollTable/TableColumn.vue'
 | 
			
		||||
import { reactive, toRefs } from '@vue/composition-api'
 | 
			
		||||
import OneCenter from './OneCenter'
 | 
			
		||||
import ResourceCount from './ResourceCount'
 | 
			
		||||
import {
 | 
			
		||||
  getOverview,
 | 
			
		||||
  getVmApplyTrend,
 | 
			
		||||
  getResourceApplyTrend,
 | 
			
		||||
  getTenantResource,
 | 
			
		||||
  getProjectResource,
 | 
			
		||||
  getBusinessResource
 | 
			
		||||
} from 'services/screen/outside'
 | 
			
		||||
 | 
			
		||||
import subIcon1 from './images/sub-icon1.png'
 | 
			
		||||
import subIcon2 from './images/sub-icon2.png'
 | 
			
		||||
import subIcon3 from './images/sub-icon3.png'
 | 
			
		||||
import subIcon4 from './images/sub-icon4.png'
 | 
			
		||||
import RealTimeUsed from './RealTimeUsed'
 | 
			
		||||
import UsedTrend from './UsedTrend.vue'
 | 
			
		||||
import { getDepartDuration, getSoftwareDuration, getInUseSoftware, getUserUseTrend, getSoftwareIntegrate, getPlateformSum } from './api'
 | 
			
		||||
export default {
 | 
			
		||||
  components: { Header, ResourceCount, OneCenter },
 | 
			
		||||
  components: { FullScreenContainer, Header, ScrollTable, ScrollTableColumn, RealTimeUsed, UsedTrend },
 | 
			
		||||
  setup() {
 | 
			
		||||
    const state = reactive({
 | 
			
		||||
      loading: true,
 | 
			
		||||
      overviewData: {},
 | 
			
		||||
      vmApplyTrend: {},
 | 
			
		||||
      resourceApplyTrend: {},
 | 
			
		||||
      tenantCount: [],
 | 
			
		||||
      projectCount: [],
 | 
			
		||||
      businessCount: []
 | 
			
		||||
      colorMap: ['red', '#ffc107', 'blue'],
 | 
			
		||||
      introColorMap: ['#6be6f5', '#489ef1', '#6ce2bb', '#d09154'],
 | 
			
		||||
      loading: false,
 | 
			
		||||
      departTrend: [],
 | 
			
		||||
      appTrend: [],
 | 
			
		||||
      inUseApps: [],
 | 
			
		||||
      introItems: [
 | 
			
		||||
        {
 | 
			
		||||
          value: 0,
 | 
			
		||||
          unit: '人',
 | 
			
		||||
          text: '注册人数',
 | 
			
		||||
          img: subIcon1
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          value: 0,
 | 
			
		||||
          unit: '家',
 | 
			
		||||
          text: '注册单位',
 | 
			
		||||
          img: subIcon2
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          value: 0,
 | 
			
		||||
          unit: '个',
 | 
			
		||||
          text: '软件数量',
 | 
			
		||||
          img: subIcon3
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          value: 0,
 | 
			
		||||
          unit: '小 时',
 | 
			
		||||
          text: '使用总时长',
 | 
			
		||||
          img: subIcon4
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      userUseTrend: [],
 | 
			
		||||
      appDemandList: []
 | 
			
		||||
    })
 | 
			
		||||
    let dcId = ''
 | 
			
		||||
    // 资源概览
 | 
			
		||||
    const getOverviewData = async () => {
 | 
			
		||||
      const res = await getOverview(dcId)
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        state.overviewData = res.data
 | 
			
		||||
      }
 | 
			
		||||
    const getDepartDurationList = async () => {
 | 
			
		||||
      const res = await getDepartDuration()
 | 
			
		||||
      state.departTrend = res.data.map((item, index) => {
 | 
			
		||||
        return { ...item, rank: index + 1 }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    // 云主机申请趋势
 | 
			
		||||
    const getVmTrend = async () => {
 | 
			
		||||
      const res = await getVmApplyTrend(dcId)
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        state.vmApplyTrend = res.data
 | 
			
		||||
      }
 | 
			
		||||
    const getSoftwareDurationList = async () => {
 | 
			
		||||
      const res = await getSoftwareDuration()
 | 
			
		||||
      state.appTrend = res.data.map((item, index) => {
 | 
			
		||||
        return { ...item, rank: index + 1 }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    // 云资源申请趋势
 | 
			
		||||
    const getResourceTrend = async () => {
 | 
			
		||||
      const res = await getResourceApplyTrend(dcId)
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        state.resourceApplyTrend = res.data
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    const getInUseSoftwareList = async () => {
 | 
			
		||||
      const res = await getInUseSoftware()
 | 
			
		||||
      state.inUseApps = res.data.map((item, index) => {
 | 
			
		||||
        return { ...item, rank: index + 1 }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    // 租户资源统计
 | 
			
		||||
    const getTenantCount = async () => {
 | 
			
		||||
      const res = await getTenantResource(dcId)
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        state.tenantCount = res.data
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    const getUserUseTrendList = async () => {
 | 
			
		||||
      const res = await getUserUseTrend()
 | 
			
		||||
      state.userUseTrend = res.data.map((item, index) => {
 | 
			
		||||
        return { ...item, rank: index + 1 }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    // 项目资源统计
 | 
			
		||||
    const getProjectCount = async () => {
 | 
			
		||||
      const res = await getProjectResource(dcId)
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        state.projectCount = res.data
 | 
			
		||||
      }
 | 
			
		||||
    const getDemandList = async () => {
 | 
			
		||||
      const res = await getSoftwareIntegrate()
 | 
			
		||||
      state.appDemandList = res.data.map((item, index) => {
 | 
			
		||||
        return { ...item, rank: index + 1 }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    // 业务资源
 | 
			
		||||
    const getBusinessCount = async () => {
 | 
			
		||||
      const res = await getBusinessResource(dcId)
 | 
			
		||||
      if (res.success) {
 | 
			
		||||
        state.businessCount = res.data
 | 
			
		||||
      }
 | 
			
		||||
    const getPlateformSumList = async () => {
 | 
			
		||||
      const res = await getPlateformSum()
 | 
			
		||||
 | 
			
		||||
      res.data.map(item => {
 | 
			
		||||
        if (item.keyName === 'userNum') {
 | 
			
		||||
          state.introItems[0].value = item.numValue
 | 
			
		||||
        }
 | 
			
		||||
        if (item.keyName === 'softNum') {
 | 
			
		||||
          state.introItems[1].value = item.numValue
 | 
			
		||||
        }
 | 
			
		||||
        if (item.keyName === 'orgNum') {
 | 
			
		||||
          state.introItems[2].value = item.numValue
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (item.keyName === 'timeSum') {
 | 
			
		||||
          state.introItems[3].value = item.numValue
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    const change = async (id) => {
 | 
			
		||||
      dcId = id
 | 
			
		||||
 | 
			
		||||
    const initData = async () => {
 | 
			
		||||
      try {
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          getOverviewData(),
 | 
			
		||||
          getVmTrend(),
 | 
			
		||||
          getResourceTrend(),
 | 
			
		||||
          getTenantCount(),
 | 
			
		||||
          getProjectCount(),
 | 
			
		||||
          getBusinessCount()
 | 
			
		||||
        ])
 | 
			
		||||
        await Promise.all([getDepartDurationList(), getSoftwareDurationList(), getInUseSoftwareList(), getUserUseTrendList(), getDemandList(), getPlateformSumList()])
 | 
			
		||||
      } catch (error) {}
 | 
			
		||||
      state.loading = false
 | 
			
		||||
    }
 | 
			
		||||
    initData()
 | 
			
		||||
    return {
 | 
			
		||||
      ...toRefs(state),
 | 
			
		||||
      change
 | 
			
		||||
      ...toRefs(state)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.text-right {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
}
 | 
			
		||||
.container {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background: url('/scr-web/static/img/sip/bg.png') no-repeat;
 | 
			
		||||
  padding: 100px 20px 20px 20px;
 | 
			
		||||
  background: url('./images/bg.png') no-repeat;
 | 
			
		||||
  padding: 90px 20px 20px 20px;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
}
 | 
			
		||||
.full {
 | 
			
		||||
  height: 100%;
 | 
			
		||||
| 
						 | 
				
			
			@ -209,30 +272,108 @@ export default {
 | 
			
		|||
  width: 48%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
}
 | 
			
		||||
.loop-card {
 | 
			
		||||
  display: flex;
 | 
			
		||||
.mini-card {
 | 
			
		||||
  height: 280px !important;
 | 
			
		||||
}
 | 
			
		||||
.card-border1 {
 | 
			
		||||
  background: url('./images/item-border1.png');
 | 
			
		||||
  background-size: 100% 85%;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position-y: 43px;
 | 
			
		||||
}
 | 
			
		||||
.card-border2 {
 | 
			
		||||
  background: url('./images/item-border2.png');
 | 
			
		||||
  background-size: 100% 85%;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position-y: 43px;
 | 
			
		||||
}
 | 
			
		||||
.card-border3 {
 | 
			
		||||
  background: url('./images/item-border3.png');
 | 
			
		||||
  background-size: 100% 85%;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position-y: 43px;
 | 
			
		||||
}
 | 
			
		||||
.card-border4 {
 | 
			
		||||
  background: url('./images/item-border4.png');
 | 
			
		||||
  background-size: 100% 92%;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position-y: 43px;
 | 
			
		||||
}
 | 
			
		||||
.card-border5 {
 | 
			
		||||
  background: url('./images/item-border5.png');
 | 
			
		||||
  background-size: 100% 85%;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position-y: 43px;
 | 
			
		||||
}
 | 
			
		||||
.card-title-border1 {
 | 
			
		||||
  background: url('./images/item-header1.png');
 | 
			
		||||
}
 | 
			
		||||
.card-title-border2 {
 | 
			
		||||
  background: url('./images/item-header1.png');
 | 
			
		||||
  background-position-x: -33px !important;
 | 
			
		||||
}
 | 
			
		||||
.card {
 | 
			
		||||
  // height: calc((100% - 200px) / 3 - 20px);
 | 
			
		||||
  height: 310px;
 | 
			
		||||
  height: 350px;
 | 
			
		||||
  padding: 15px;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
  background: url('/scr-web/static/img/sip/card_bg.png');
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
 | 
			
		||||
  &:not(:last-child) {
 | 
			
		||||
    margin-bottom: 20px;
 | 
			
		||||
  }
 | 
			
		||||
  .card-title {
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    border-left: 3px solid #0089ff;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: #bbefff;
 | 
			
		||||
    padding-left: 5px;
 | 
			
		||||
    margin-bottom: 10px;
 | 
			
		||||
    padding-left: 70px;
 | 
			
		||||
    background-position-x: -40px;
 | 
			
		||||
    height: 60px;
 | 
			
		||||
    line-height: 75px;
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
  }
 | 
			
		||||
  .card-body {
 | 
			
		||||
    height: calc(100% - 35px);
 | 
			
		||||
    height: calc(100% - 56px);
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.intro-card {
 | 
			
		||||
  height: 650px;
 | 
			
		||||
  .intro-img {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 280px;
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
  }
 | 
			
		||||
  .intro-text {
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    background-color: rgba(0, 0, 0, 0.5);
 | 
			
		||||
    text-indent: 2em;
 | 
			
		||||
  }
 | 
			
		||||
  .intro-item {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 120px;
 | 
			
		||||
    background-position: center;
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    background-size: contain;
 | 
			
		||||
    padding-top: 15px;
 | 
			
		||||
    & > div {
 | 
			
		||||
      padding-right: 20%;
 | 
			
		||||
    }
 | 
			
		||||
    .intro-item-value {
 | 
			
		||||
      margin-right: 10px;
 | 
			
		||||
      font-size: 32px;
 | 
			
		||||
      -webkit-text-stroke: 1px #fff;
 | 
			
		||||
      text-shadow: 0 0 2px #fff, 0 0 2px #fff, 0 0 2px #fff;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.square {
 | 
			
		||||
  width: 20px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
  background-color: gray;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  line-height: 20px;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  border-radius: 5px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,16 @@ module.exports = {
 | 
			
		|||
        pathRewrite: {
 | 
			
		||||
          '^/scr-web/static/img': '/static/img' // rewrite path
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      '/screen_server': {
 | 
			
		||||
        target: 'http://gn.api.aipow.cn:8080',
 | 
			
		||||
        changeOrigin: true,
 | 
			
		||||
        pathRewrite: { '^/screen_server': '/screen_server' }
 | 
			
		||||
      },
 | 
			
		||||
      '/prometheus': {
 | 
			
		||||
        target: 'http://gn.api.aipow.cn:8080',
 | 
			
		||||
        changeOrigin: true,
 | 
			
		||||
        pathRewrite: { '^/prometheus': '/prometheus' }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||