Newer
Older
operation_web / src / components / ServiceWatch / components / monitor.vue
<template>
  <div>
    <div class="main">
      <el-card shadow="hover">
        <div class="choice">
          <el-select v-model="choiceRange" @change="selectChange">
            <el-option
              v-for="(item, index) in timeOptions"
              :key="index"
              :label="item.label"
              :value="index"
            >
              <span style="float: left">{{ item.label }}</span>
            </el-option>
          </el-select>
          <el-select v-model="choicePeriod" @change="periodChange">
            <el-option
              v-for="(item, index) in periodOptions"
              :key="index"
              :label="item.label"
              :value="item.value"
            >
              <span style="float: left">{{ item.label }}</span>
            </el-option>
          </el-select>
          <el-date-picker
            v-model="TimeValue"
            :picker-options="pickerOptions"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            id="IndexTime"
            value-format="yyyy-MM-dd HH:mm:ss"
          ></el-date-picker>
          <el-button size="" type="primary"
            ><i class="el-icon-refresh" @click="refresh"></i
          ></el-button>
        </div>
        <p class="describeP">
          <i class="el-icon-info" style="font-size:14px"></i
          >注释:Max、Min和Avg数值统计为当前折线图内所有点的最大值、最小值和平均值<a
            href="javascript:void(0)"
            style="float:right"
            @click="downAll"
            class="export"
            >导出数据</a
          >
        </p>
        <!-- <div class="mian-item">
          <div class="title">
            系统平衡负载
          </div>
          <div class="contentAll">
            <div class="content">
              <div class="describe">
                cpu平衡负载
                <el-tooltip class="item" effect="dark" content="Bottom Left 提示文字" placement="bottom-start">
                  <i class="el-icon-info" style="font-size:14px"></i>
                </el-tooltip>
              </div>
              <div class="echarts" ref="echarts0"></div>
              <div class="smallField"><p>max:</p><p>{{ echartsData1.max === null ? '': echartsData1.max}}%</p></div>
              <div class="smallField"><p>max:</p><p>{{echartsData1.min  === null ? '': echartsData1.min}}%</p></div>
              <div class="smallField"><p>max:</p><p>{{echartsData1.avg}}%</p></div>
              <div class="option">
                <el-button size="mini" icon="el-icon-rank" @click="showBigEcharts"></el-button>
                <el-button size="mini"><i class="el-icon-picture" @click="downImg"></i></el-button>
                <el-button size="mini"><i class="el-icon-download"></i></el-button>
              </div>
            </div>

          </div>
        </div> -->
        <div
          class="mian-item"
          v-for="(member, indexOut) in dataAll"
          :key="indexOut"
        >
          <div class="title">
            {{ member.name }}
          </div>
          <div class="contentAll">
            <div
              class="content"
              v-for="(item, indexInt) in member.data"
              :key="indexInt"
            >
              <div class="describe">
                {{ item.name }}
                <el-tooltip
                  class="item"
                  effect="dark"
                  :content="item.tip"
                  placement="bottom-start"
                >
                  <i class="el-icon-info" style="font-size:14px"></i>
                </el-tooltip>
              </div>
              <div class="echarts" :ref="item.target"></div>
              <div class="smallField">
                <p>max:</p>
                <p>
                  <span v-if="item.echartsData && item.echartsData.max"
                    >{{ item.echartsData && item.echartsData.max
                    }}{{ item.unit }}</span
                  ><span v-if="!(item.echartsData && item.echartsData.max)"
                    >-</span
                  >
                </p>
              </div>
              <div class="smallField">
                <p>min:</p>
                <p>
                  <span v-if="item.echartsData && item.echartsData.min"
                    >{{ item.echartsData && item.echartsData.min
                    }}{{ item.unit }}</span
                  ><span v-if="!(item.echartsData && item.echartsData.min)"
                    >-</span
                  >
                </p>
              </div>
              <div class="smallField">
                <p>avg:</p>
                <p>
                  <span v-if="item.echartsData && item.echartsData.avg"
                    >{{ item.echartsData && item.echartsData.avg
                    }}{{ item.unit }}</span
                  ><span v-if="!(item.echartsData && item.echartsData.avg)"
                    >-</span
                  >
                </p>
              </div>
              <div class="option">
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="展开大图图表"
                  placement="top-end"
                >
                  <el-button
                    type="primary"
                    @click="showBigEcharts(item.target)"
                    class="optionbtn"
                    ><img src="../../../../static/img/zk_icon.png"
                  /></el-button>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="下载图片文件"
                  placement="top-end"
                >
                  <el-button
                    type="primary"
                    class="optionbtn"
                    @click="downImg(item.target)"
                  >
                    <img src="../../../../static/img/tpxz_icon.png" />
                  </el-button>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="下载xls文件"
                  placement="top-end"
                >
                  <el-button
                    type="primary"
                    class="optionbtn"
                    @click="downXls(item.target, item.name)"
                  >
                    <img src="../../../../static/img/wjxz_icon.png" />
                  </el-button>
                </el-tooltip>
              </div>
            </div>
          </div>
        </div>
      </el-card>
      <!-- <el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button> -->

      <el-dialog
        title="详细图表"
        :visible.sync="dialogVisible"
        modal-append-to-body
        width="70%"
      >
        <div id="bigEacharts" ref="bigEacharts"></div>
        <!-- <span slot="footer" class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
        </span> -->
      </el-dialog>
    </div>
  </div>
</template>

<script>
import html2canvas from 'html2canvas'
import { dataAll } from "./monitor01.js";
import fileDownload from 'js-file-download'
import axios from "axios";
// import ExportJsonExcel from "js-export-excel"

export default {
  data() {
    return {
      dataAll,
      timeOptions: [
        {
          label: "实时",
          value: 0,
          mark: 0
        },
        {
          label: "24小时",
          value: 1,
          mark: 1
        },
        {
          label: "7天",
          value: 2,
          mark: 2
        }
      ],
      choiceRange: 0,
      choicePeriod: 10,
      TimeValue: [
        this.moment()
          .subtract(1, "hour")
          .format("YYYY-MM-DD HH:mm:ss"),
        this.moment().format("YYYY-MM-DD HH:mm:ss")
      ], //起止日期
      pickerOptions: {
        shortcuts: [
          {
            text: "实时",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000);
              picker.$emit("pick", [start, end]);
            }
          },
          {
            text: "最近24小时",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24);
              picker.$emit("pick", [start, end]);
            }
          },
          {
            text: "最近7天",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit("pick", [start, end]);
            }
          }
        ]
      }, //时间框的快捷选项
      dialogVisible: false,
      bigEachartsTest: {},
      test: 0,
      echartsData1: {},
      targetAll: [
        "CPUUsage",
        "BaseCpuUsage",
        "CpuLoadavg",
        "MemUsed",
        "MemUsage",
        "LanOuttraffic",
        "LanIntraffic",
        "LanOutpkg",
        "LanInpkg",
        "TcpCurrEstab",
        "WanOuttraffic",
        "WanIntraffic",
        "WanOutpkg",
        "WanInpkg",
        "AccOuttraffic"
      ]
    };
  },
  computed: {
    periodOptions() {
      let arr = [
        {
          label: "10秒",
          value: 10
        },
        {
          label: "1分钟",
          value: 60
        },
        {
          label: "5分钟",
          value: 300
        },
        {
          label: "1小时",
          value: 3600
        },
        {
          label: "1天",
          value: 3600 * 24
        }
      ];
      if (this.choiceRange === 0) return arr.slice(0, 3);
      if (this.choiceRange === 1) return arr.slice(1);
      if (this.choiceRange === 2) return arr.slice(3);
    }
  },

  methods: {
    selectChange(val) {
      if (val === 0)
        this.TimeValue = [
          this.moment()
            .subtract(1, "hour")
            .format("YYYY-MM-DD HH:mm:ss"),
          this.moment().format("YYYY-MM-DD HH:mm:ss")
        ];
      if (val === 1)
        this.TimeValue = [
          this.moment()
            .subtract(24, "hour")
            .format("YYYY-MM-DD HH:mm:ss"),
          this.moment().format("YYYY-MM-DD HH:mm:ss")
        ];
      if (val === 2)
        this.TimeValue = [
          this.moment()
            .subtract(7, "day")
            .format("YYYY-MM-DD HH:mm:ss"),
          this.moment().format("YYYY-MM-DD HH:mm:ss")
        ];
      this.choicePeriod = this.periodOptions[0].value;
    },
    periodChange() {},
    refresh() {
      this.targetAll.forEach(item => {
        this.getInterface(item);
      });
    },
    showBigEcharts(target) {
      this.dialogVisible = true;
      this.getInterface(target);
      // this.test =1
      var echartsObj;
      this.dataAll.forEach(item => {
        item.data.forEach(member => {
          if (member.target === target) {
            echartsObj = member.echartsData;
            setTimeout(() => {
              this.bigEachartsTest = this.$echarts.init(this.$refs.bigEacharts);
              // 指定图表的配置项和数据
              var option = {
                color: ["#3398DB", "red"],
                tooltip: {
                  show: true,
                  trigger: "axis",
                  axisPointer: {
                    type: "line",
                    crossStyle: {
                      color: "#ccc"
                    },
                    snap: true,
                    axis: "x"
                  }
                  // formatter: params => {
                  //   // let axisValue = this.moment(params['axisValueLabel']).format("YYYY-MM-DD HH:mm:ss")
                  //   // return `<p style="color:#333">${axisValue}</p><p style="font-weight:bold;color:black">${params[0].value}%</p>`
                  //   var res = params[0].name;
                  //     for (var i = 0; i < params.length; i++) {
                  //       res +=
                  //         "<br>" +
                  //         params[i].marker +
                  //         params[i].seriesName +
                  //         ":" +
                  //         params[i].data;
                  //     }
                  //     return res;
                  // }
                },
                dataZoom: [
                  {
                    type: "inside"
                  }
                ],
                title: {
                  // text: `${item.instanceId}/${item.name}`
                  text: `${item.name}`
                },
                // legend: {
                //     data:['销量']
                // },
                xAxis: {
                  // show:false,
                  data: echartsObj.timeList,
                  splitLine: {
                    show: false
                  },
                  axisTick: {
                    // alignWithLabel: true
                  }
                },
                yAxis: {
                  axisLine: {
                    show: false
                  },
                  // splitNumber: 1,
                  // minInterval: 10,
                  // maxInterval: 20,
                  splitLine: {
                    show: false
                  },
                  // color: rgb(0, 119, 254)
                  // boundaryGap: [0, '100%']
                  axisLabel: {
                    color: "#3398DB"
                  }
                },
                series: [
                  {
                    // name: '销量1',
                    type: "line",
                    data: echartsObj.valueList,
                    markPoint: {
                      data: [
                        { type: "max", name: "最大值" },
                        { type: "min", name: "最小值" }
                      ],
                      itemStyle: {
                        color: "pink"
                      }
                    },
                    markLine: {
                      data: [{ type: "average", name: "平均值" }],
                      lineStyle: {
                        color: "red"
                      }
                    }
                  }
                  // {
                  //     name: '销量2',
                  //     type: 'bar',
                  //     data: [5, 20, 36, 10, 10, 20,70,200,12,24]
                  // },
                ]
              };
              // 使用刚指定的配置项和数据显示图表。
              this.bigEachartsTest.setOption(option);
            }, 0);
          }
        });
      });
    },
    // 点击导出
    downImg(target) {
      this.showBigEcharts(target);
      // this.bigEachartsTest.on('finished', function () {
      // });
      setTimeout(() => {
        //   var img = new Image();
        //   img.src = this.bigEacharts.getDataURL({
        //       pixelRatio: 2,
        //       backgroundColor: '#fff'
        //   });
        //   // const dataImg = new Image()
        //   // dataImg.src = canvas.toDataURL('image/png')
        //   const alink = document.createElement('a')
        //   alink.href = img.src
        //   alink.download = 'Img.jpg'
        //   alink.click()
        //   this.dialogVisible =false
        window.pageYoffset = 0;
        document.documentElement.scrollTop = 0;
        document.body.scrollTop = 0;
        const targetDom = this.$refs.bigEacharts;
        // console.log(11111)
        html2canvas(targetDom, {
          useCORS: true,
          allowTaint: true,
          height: targetDom.scrollHeight,
          width: targetDom.scrollWidth
        }).then(canvas => {
          const dataImg = new Image();
          dataImg.src = canvas.toDataURL("image/png");
          const alink = document.createElement("a");
          alink.href = dataImg.src;
          alink.download = "Img.jpg";
          alink.click();
          this.dialogVisible = false;
        });
      }, 2000);
      // this.dialogVisible=true
      // this.$nextTick(()=>{

      // })
    },
    downAll() {
      var arr = [];
      this.dataAll.forEach(item => {
        item.data.forEach(element => {
          arr.push({
            id: element.target,
            name: element.name
          });
        });
      });
      // console.log(arr, "arr");
      var param = {
        regionId: "ap-chengdu",
        instanceId: this.$route.query.instanceId,
        period: this.choicePeriod,
        startTime: this.TimeValue[0],
        endTime: this.TimeValue[1],
        metricListStr: JSON.stringify(arr)
      };
      axios
        .post(this.nozzle.downloadMonitor, param, {
          responseType: "blob"
        })
        .then(res => {
          
          fileDownload(res, `${this.$route.query.instanceId}-${name}.xls`);
          // console.log('res', res);
        })
        .catch(err => {
          console.log(err.message);
        });
    },
    downXls(target, name) {
      var param = {
        regionId: "ap-chengdu",
        instanceId: this.$route.query.instanceId,
        // "metricName":target,
        period: this.choicePeriod,
        startTime: this.TimeValue[0],
        endTime: this.TimeValue[1],
        metricListStr: JSON.stringify([{ id: target, name: name }])
      };
      // //   console.log(param,'str')
      //   postDownloadFile(this.nozzle.downloadMonitor, param);

      // 直接导出文件
      // const ExportJsonExcel = require("js-export-excel");

      axios
        .post(this.nozzle.downloadMonitor, param, {
          responseType: "blob"
        })
        .then(res => {
          console.log(121212);
          fileDownload(res, `${this.$route.query.instanceId}-${name}.xls`)
          // var elink = document.createElement("a");
          // elink.download = `${this.$route.query.instanceId}-${name}657.xls`;
          // elink.style.display = "none";
          // var blob = new Blob([res], { type: "application/vnd.ms-excel" });

          // elink.href = URL.createObjectURL(blob);
          // document.body.appendChild(elink);
          // elink.click();
          // document.body.removeChild(elink);
          // console.log('res', res);
        })
        .catch(err => {
          console.log(err.message);
        });
      // var str='?'
      // for(var i in param){
      //   str += i + '=' + param[i] + '&'
      // }
      // str= str.slice(0,-1)
      // window.open(`${this.nozzle.downloadMonitor}?${JSON.stringify(param)}`, '_blank');
      // console.log(this.nozzle.downloadMonitor,'this.nozzle.downloadMonitor')
      // console.log('http://192.168.16.254:8080/download/monitor','this.nozzle.downloadMonitor')
      // postDownloadFile('http://192.168.16.254:8080/download/monitor', {
      //   "regionId":"ap-chengdu",
      //   "instanceId":this.$route.query.instanceId,
      //   "metricName":target,
      //   "period":this.choicePeriod,
      //   "startTime":this.TimeValue.length && this.TimeValue[0],
      //   "endTime":this.TimeValue.length && this.TimeValue[1],
      //   "metricList":[{"id":target,"name":name}]
      // });
      // this.$http.post(this.nozzle.downloadMonitor, {
      //   "regionId":"ap-chengdu",
      //   "instanceId":this.$route.query.instanceId,
      //   "metricName":target,
      //   "period":this.choicePeriod,
      //   "startTime":this.TimeValue.length && this.TimeValue[0],
      //   "endTime":this.TimeValue.length && this.TimeValue[1],
      //   "metricList":[{"id":target,"name":name}]
      // },
      // { responseType: "blob" }
      // ).then(res=>{

      //   console.log(res.data);
      //   // var option = {};

      //   // option.fileName = "excel";

      //   // option.datas = res

      //   // var toExcel = new ExportJsonExcel(option); //new
      //   // toExcel.saveExcel(); //保存
      //   // const blob = res.data;
      //   // const reader = new FileReader();
      //   // reader.readAsDataURL(blob);
      //   // reader.onload = (e) => {
      //   //   const a = document.createElement('a');
      //   //   a.download = `文件名称.xls`;
      //   //   // 后端设置的文件名称在res.headers的 "content-disposition": "form-data; name=\"attachment\"; filename=\"20181211191944.zip\"",
      //   //   a.href = e.target.result;
      //   //   document.body.appendChild(a);
      //   //   a.click();
      //   //   document.body.removeChild(a);
      //   // };
      //   // fileDownload(res.data, `${name}.xls`)
      //   // console.log(res,'resss')
      // })
    },
    createSmallEcharts(target) {
      var echartsObj;
      this.dataAll.forEach(item => {
        item.data.forEach(member => {
          if (member.target === target) {
            echartsObj = member.echartsData;
            // console.log(this.$refs[target],'this.$refs')
            var myChart = this.$echarts.init(this.$refs[target][0]);
            // console.log(document.getElementsByClassName('echarts')[0],'document.getElementsByCl')
            // var myChart = this.$echarts.init(document.getElementsByClassName('echarts')[0]);
            // 指定图表的配置项和数据
            var option = {
              color: ["#3398DB", "red"],
              tooltip: {
                show: true,
                trigger: "axis",
                axisPointer: {
                  type: "line",
                  crossStyle: {
                    color: "#333"
                  },
                  snap: true,
                  axis: "x"
                }
              },
              dataZoom: [
                {
                  type: "inside"
                }
              ],
              title: {
                // text: 'ECharts 入门示例'
              },
              // legend: {
              //     data:['销量']
              // },
              xAxis: {
                show: false,
                data: echartsObj.timeList,
                splitLine: {
                  show: false
                },
                axisTick: {
                  // alignWithLabel: true
                }
              },
              yAxis: {
                axisLine: {
                  show: false
                },
                splitNumber: 2,
                // minInterval: 10,
                // maxInterval: 20,
                splitLine: {
                  show: false
                },
                axisLabel: {
                  color: "#3398DB"
                }
                // boundaryGap: [0, '100%']
              },
              series: [
                {
                  // name: '销量1',
                  type: "line",
                  data: echartsObj.valueList
                }
              ]
            };
            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
          }
        });
      });
    },
    getInterface(target) {
      this.$http
        .post(this.nozzle.monitorInfoList, {
          regionId: "ap-chengdu",
          instanceId: this.$route.query.instanceId,
          metricName: target,
          period: this.choicePeriod,
          startTime: this.TimeValue && this.TimeValue[0],
          endTime: this.TimeValue && this.TimeValue[1]
        })
        .then(res => {
          // console.log(res,'resss')
          var echartsObj;
          this.dataAll.forEach(item => {
            item.data.forEach(member => {
              if (member.target === target) {
                echartsObj = member.echartsData;
                // console.log('target')
              }
            });
          });
          for (var i in echartsObj) {
            delete echartsObj[i];
          }
          for (var i in res.data.data) {
            echartsObj[i] = res.data.data[i];
          }
          // arr.sort(function(a,b){return a - b;})

          function maxCreate(arr) {
            arr = arr.filter(item => !_isNaN(item));
            return arr.length ? Math.max.apply(null, arr) : undefined;
          }

          // var echartsObValueList=  JSON.parse(JSON.stringify(echartsObj.valueList))
          let echartsObValueList = [...echartsObj.valueList];
          // try {

          // } catch(err){
          // }arr.sort(function(a,b){return a - b;});
          // let max = Math.max(echartsObValueList)
          let max = echartsObValueList.sort(function(a, b) {
            return a - b;
          })[echartsObValueList.length - 1];
          let min = echartsObValueList.sort(function(a, b) {
            return a - b;
          })[0];
          // let min = Math.min(echartsObValueList)
          // console.log(echartsObValueList,max,'001')
          const arrayAverage = arr =>
            arr.reduce((acc, val) => acc + val, 0) / arr.length;
          let avg = arrayAverage(echartsObValueList);
          this.$set(echartsObj, "max", max);
          this.$set(echartsObj, "min", min);
          this.$set(echartsObj, "avg", avg.toFixed(3));
          // this.echartsData1['max']=max
          // this.echartsData1['min']=min
          // this.echartsData1['avg']=avg.toFixed(3)
          this.createSmallEcharts(target);
          // console.log(max,min,avg,'res')
        });
    },
    downloadMonitor() {
      console.log(123);
    }
  },
  mounted() {
    // this.createSmallEcharts()
  },
  beforeDestroy() {
    if (this.bigEacharts && Object.keys(this.bigEacharts).length !== 0) {
      this.bigEacharts.dispose();
    }
  },
  beforeCreate() {},
  created() {
    this.$http.post(this.nozzle.monitorMetricInfo).then(res => {
      var arr = res.data.data.map(item => {
        return item.id;
      });
      // this.targetAll = arr
      // console.log(res.data.data,arr,'ress')
      // this.targetAll=res.data.data
    });
    this.refresh();
  }
};
</script>

<style lang="scss" scoped>
.mian {
  margin-bottom: -10px;
}
.describeP {
  text-align: left;
  margin: 30px 0 10px 0;
  font-size: 12px;
  color: var(--white);
}
.mian-item {
  /* height: 150px; */
  display: flex;
  text-align: left;
  /* margin: 30px 0 0 0; */
  border-bottom: 1px solid var(--white);
}
.mian-item .title {
  /* text-align: left; */
  font-weight: bold;
  font-size: 14px;
  color: var(--white);
  padding: 10px;
  width: 10%;
}
.mian-item .contentAll {
  flex: 1;
  /* display: flex; */
  /* position: relative; */
}
.mian-item .contentAll .content {
  border-top: 1px solid var(--white);
}
.mian-item .contentAll > :first-child {
  border-top: initial;
}
.mian-item .content {
  /* flex: 1; */
  display: flex;
  position: relative;
}
.mian-item .content .describe {
  height: 78px;
  width: 10%;
  font-size: 12px;
  font-weight: 700;
  padding: 10px;
  color: var(--white);
}
.tooltip {
  display: inline;
}
.mian-item .content .echarts {
  height: 78px;
  flex: 1;
  /* padding: 10px; */
}
.mian-item .content .smallField {
  height: 78px;
  width: 10%;
  padding: 10px;
}
.mian-item .content .smallField p {
  height: 18px;
  line-height: 18px;
}
.mian-item .content .smallField p:nth-child(1) {
  font-size: 14px;
  color: var(--white);
}
.mian-item .content .smallField p:nth-child(2) {
  margin: 10px 0 0 0;
  font-size: 14px;
  color: var(--white);
}
.mian-item .content .option {
  height: 78px;
  width: 10%;
  padding: 10px;
}
.choice {
  text-align: left;
}
#bigEacharts {
  width: 100%;
  height: 400px;
}
/* /deep/.el-select .el-input__inner{
  color: black !important;
}
/deep/.el-date-editor .el-range-input{
  color: black !important;
}
/deep/.el-date-editor .el-range-separator{
  color: black !important;
} */
/* /deep/.el-button { */
/* margin-top: 2px; */
/* } */
/deep/.el-button + .el-button {
  margin-left: 0;
}

.export {
  color: var(--yellow);
}

.optionbtn {
  position: relative;
  // background-color: rgb(2, 120, 254) !important;
  // border: 1px solid rgb(2, 120, 254) !important;
  padding: 12px 20px;
}
.optionbtn img {
  position: absolute;
  top: calc(50% - 10px);
  left: calc(50% - 10px);
}
</style>