<template>
  <div>
    <div class="app-container">
      <el-form
        :model="queryParams"
        ref="queryForm"
        :inline="true"
        v-show="showSearch"
        size="small"
      >
<!--        <el-form-item prop="domainName">-->
<!--          <el-select-->
<!--            v-model="queryParams.domainName"-->
<!--            placeholder="请选择域名"-->
<!--            clearable-->
<!--            style="width: 150px"-->
<!--          >-->
<!--            <el-option-->
<!--              v-for="item in options"-->
<!--              :key="item.label"-->
<!--              :label="item.label"-->
<!--              :value="item.label"-->
<!--            >-->
<!--            </el-option>-->
<!--          </el-select>-->
<!--        </el-form-item>-->
        <el-form-item>
          <span :class="timeType == 0 ? 'type active' : 'type'" @click="handleTimeType(0)">今日</span>
          <span :class="timeType == 1 ? 'type active' : 'type'" @click="handleTimeType(1)">昨日</span>
          <span :class="timeType == 2 ? 'type active' : 'type'" @click="handleTimeType(2)">7天内</span>
          <span :class="timeType == 3 ? 'type active' : 'type'" @click="handleTimeType(3)">30天内</span>
          <el-date-picker
            v-model="datetime"
            type="datetimerange"
            value-format="yyyy-MM-dd HH:mm:ss"
            range-separator="至"
            start-placeholder="开始日时间"
            end-placeholder="结束时间"
            :clearable="false"
            :picker-options="pickerOptions"
            @change="timePickerchange"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="粒度" prop="interval">
          <el-select v-model="queryParams.interval" placeholder="请选择粒度" >
                <el-option label="5分钟" :value="0"></el-option>
                <el-option label="1小时" :value="1"></el-option>
                <el-option label="1天" :value="2"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="getChartData">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
<!--      <el-row>-->
<!--        <right-toolbar-->
<!--          :showSearch.sync="showSearch"-->
<!--          @queryTable="getChartData"-->
<!--        ></right-toolbar>-->
<!--      </el-row>-->
    </div>
    <div class="app-container" >
      <div class="chart-title">流量趋势<span>总量：{{ summary.flux }} MB</span></div>
      <div ref="trafficTrends" style="width: 100%; height: 400px;"></div>
    </div>
    <!-- 带宽趋势图 -->
    <div class="app-container">
      <div class="chart-title">峰值带宽趋势 <span>峰值：{{ summary.bw }} Mbps</span></div>
      <div ref="bwTrends" style="width: 100%; height: 400px;"></div>
    </div>
    <!-- 请求数量趋势图 -->
    <div class="app-container">
      <div class="chart-title">请求数量 <span>总量：{{ summary.req_num }} 次</span></div>
      <div ref="reqNumTrends" style="width: 100%; height: 400px;"></div>
    </div>
    <!-- 请求命中率趋势图 -->
    <div class="app-container">
      <div class="chart-title">请求命中率
        <span>命中率：{{ summary.hit_rate }} %</span>
        <span>命中次数：{{ summary.hit_num }} 次</span>
      </div>
      <div ref="hitRateTrends" style="width: 100%; height: 400px;"></div>
    </div>
  </div>
</template>

<script>
import {parseTime} from "@/utils/common";
import {cdnStatistics} from "@/api/common";
import * as echarts from "echarts";
export default {
  data() {
    return {
      flux:[],
      bw: [],
      reqNum:[],
      hitRate:[],
      summary: {
        flux:null,
        req_num:null,
        bw:null,
        hit_num:null,
        hit_rate:null,
      },
      statTypeOptions:[
        { value:'bw',
          label:"带宽"
        },
        { value:'flux',
          label:"流量"
        }
      ],
      options: [{
        label:"obs.shouzhujue.com"
      }],
      today: new Date(),
      tomorrow: new Date().setDate(new Date().getDate() + 1),
      yesterday: new Date().setDate(new Date().getDate() - 1),
      weekday: new Date().setDate(new Date().getDate() - 6),
      thirtyDaysAgo: new Date().setDate(new Date().getDate() - 29),
      // 查询参数
      queryParams: {
        startTime: undefined,
        endTime: undefined,
        domainName: "obs.jy.cc",
        statType: "flux,bw,req_num,hit_num",
        interval: 0,
      },
      // 时间范围类型
      timeType: 0,
      datetime: [],
      // 显示搜索条件
      showSearch: true,
      chart: null,
      bwChart: null,
      reqNumChart: null,
      hitRateChart: null,
      chartOptions: {
        tooltip: {
          trigger: "axis",
        },
        grid: {
          bottom: "10%",
          left: "5%",
          top: "15%",
          right: "5%",
        },
        xAxis: {
          name: "时间",
          axisLine: {
            show: true,
          },
          axisTick: {
            show: true,
          },
          splitLine: {
            show: false,
          },
          axisLabel: {
            formatter: (value) => {
              return this.parseTime(value, "{h}:{i}");
            },
          },
        },
        yAxis: {
          name: "流量(MB)",
          type: "value",
          axisLine: {
            show: false,
          },
          splitLine: {
            show: true,
            lineStyle: {
              type: "dashed",
            },
          },
          axisTick: {
            show: true,
          },
        },
        series: [
          {
            data: [],
            name: "流量",
            type: "line",
            smooth: true,
            symbol: "none",
            lineStyle: {
              color: "#409eff", //改变折线颜色
            },
            emphasis: {
              focus: "series",
            },
          },
        ],
      },
      bwChartOptions: {
        tooltip: {
          trigger: "axis",
        },
        grid: {
          bottom: "10%",
          left: "5%",
          top: "15%",
          right: "5%",
        },
        xAxis: {
          name: "时间",
          axisLine: {
            show: true,
          },
          axisTick: {
            show: true,
          },
          splitLine: {
            show: false,
          },
          axisLabel: {
            formatter: (value) => {
              return this.parseTime(value, "{h}:{i}");
            },
          },
        },
        yAxis: {
          name: "带宽(Mbps)",
          type: "value",
          axisLine: {
            show: false,
          },
          splitLine: {
            show: true,
            lineStyle: {
              type: "dashed",
            },
          },
          axisTick: {
            show: true,
          },
        },
        series: [
          {
            data: [],
            name: "峰值带宽",
            type: "line",
            smooth: true,
            symbol: "none",
            lineStyle: {
              color: "#409eff", //改变折线颜色
            },
            emphasis: {
              focus: "series",
            },
          },
        ],
      },
      reqNumChartOptions: {
        tooltip: {
          trigger: "axis",
        },
        grid: {
          bottom: "10%",
          left: "5%",
          top: "15%",
          right: "5%",
        },
        xAxis: {
          name: "时间",
          axisLine: {
            show: true,
          },
          axisTick: {
            show: true,
          },
          splitLine: {
            show: false,
          },
          axisLabel: {
            formatter: (value) => {
              return this.parseTime(value, "{h}:{i}");
            },
          },
        },
        yAxis: {
          name: "请求数量(次)",
          type: "value",
          axisLine: {
            show: false,
          },
          splitLine: {
            show: true,
            lineStyle: {
              type: "dashed",
            },
          },
          axisTick: {
            show: true,
          },
        },
        series: [
          {
            data: [],
            name: "请求数量",
            type: "line",
            smooth: true,
            symbol: "none",
            lineStyle: {
              color: "#409eff", //改变折线颜色
            },
            emphasis: {
              focus: "series",
            },
          },
        ],
      },
      hitRateChartOptions: {
        tooltip: {
          trigger: "axis",
        },
        grid: {
          bottom: "10%",
          left: "5%",
          top: "15%",
          right: "5%",
        },
        xAxis: {
          name: "时间",
          axisLine: {
            show: true,
          },
          axisTick: {
            show: true,
          },
          splitLine: {
            show: false,
          },
          axisLabel: {
            formatter: (value) => {
              return this.parseTime(value, "{h}:{i}");
            },
          },
        },
        yAxis: {
          name: "命中率(%)",
          type: "value",
          axisLine: {
            show: false,
          },
          splitLine: {
            show: true,
            lineStyle: {
              type: "dashed",
            },
          },
          axisTick: {
            show: true,
          },
        },
        series: [
          {
            data: [],
            name: "请求命中率",
            type: "line",
            smooth: true,
            symbol: "none",
            lineStyle: {
              color: "#409eff", //改变折线颜色
            },
            emphasis: {
              focus: "series",
            },
          },
        ],
      },
    };
  },
  computed: {
    pickerOptions() {
        if(this.timeType == 1) {
            return {
                disabledDate: time => {
                    return time.getTime() > Date.now() - 8.64e7 || time.getTime() < Date.now() - 2 * 24 * 60 * 60 * 1000;
                }
            }
        } else if (this.timeType == 2) {
            return {
                disabledDate: time => {
                    return time.getTime() > Date.now() || time.getTime() < Date.now() - 7 * 24 * 60 * 60 * 1000
                }
            }
        } else if (this.timeType == 3) {
            return {
                disabledDate: time => {
                    return time.getTime() > Date.now() || time.getTime() < Date.now() - 30 * 24 * 60 * 60 * 1000
                }
            }
        } else {
            return {
                disabledDate: time => {
                    return time.getTime() < Date.now() - 8.64e7 || time.getTime() > Date.now() - 8.64e7
                }
            }
        }
    }
  },
  created() {
    this.resetQuery()
  },
  methods: {
    timePickerchange() {
        this.queryParams.startTime = this.datetime&&this.datetime.length > 0 ? this.datetime[0] : undefined
        this.queryParams.endTime = this.datetime&&this.datetime.length > 0 ? this.datetime[1] : undefined
    },
    handleTimeType(type) {
        this.timeType = type
        if(this.timeType == 1) { // 昨天
            this.queryParams.startTime = `${parseTime(this.yesterday, "{y}-{m}-{d}")} 00:00:00`
            this.queryParams.endTime = `${parseTime(this.today, "{y}-{m}-{d}")} 00:00:00`
        } else if (this.timeType == 2) { // 7天内
            this.queryParams.startTime = `${parseTime(this.weekday, "{y}-{m}-{d}")} 00:00:00`
            this.queryParams.endTime = `${parseTime(this.today, "{y}-{m}-{d} {h}:{i}:{s}")}`
        } else if (this.timeType == 3) { // 30天内
            this.queryParams.startTime = `${parseTime(this.thirtyDaysAgo, "{y}-{m}-{d}")} 00:00:00`
            this.queryParams.endTime = `${parseTime(this.today, "{y}-{m}-{d} {h}:{i}:{s}")}`
        } else { // 今天
            this.queryParams.startTime = `${parseTime(this.today, "{y}-{m}-{d}")} 00:00:00`
            this.queryParams.endTime = `${parseTime(this.today, "{y}-{m}-{d} {h}:{i}:{s}")}`
        }
        this.datetime = [this.queryParams.startTime,this.queryParams.endTime]
    },
    initChart(data) {
      const chartElement = this.$refs.trafficTrends;
      if (!this.chart) {
        this.chart = echarts.init(chartElement);
      }
      this.seChartOptions(data.flux || [])
    },
    initBwChart(data) {
      const chartElement = this.$refs.bwTrends;
      if (!this.bwChart) {
        this.bwChart = echarts.init(chartElement);
      }
      this.seBwChartOptions(data.bw||[])
    },
    initReqNumChart(data) {
      const chartElement = this.$refs.reqNumTrends;
      if (!this.reqNumChart) {
        this.reqNumChart = echarts.init(chartElement);
      }
      this.seReqNumChartOptions(data.reqNum||[])
    },
    initHitRateChart(data) {
      const chartElement = this.$refs.hitRateTrends;
      if (!this.hitRateChart) {
        this.hitRateChart = echarts.init(chartElement);
      }
      this.seHitRateChartOptions(data.hitRate||[])
    },
    seChartOptions(data) {
        const minute = this.queryParams.interval == 1 ? 60 : this.queryParams.interval == 2 ? 1440 : 5
        this.chartOptions.xAxis.data = this.resetXAxis(minute,this.queryParams.startTime,this.queryParams.endTime)
        this.chartOptions.series[0].data = data;
        this.chart.setOption(this.chartOptions);
    },
    seBwChartOptions(data) {
      const minute = this.queryParams.interval == 1 ? 60 : this.queryParams.interval == 2 ? 1440 : 5
      this.bwChartOptions.xAxis.data = this.resetXAxis(minute,this.queryParams.startTime,this.queryParams.endTime)
      this.bwChartOptions.series[0].data = data;
      this.bwChart.setOption(this.bwChartOptions);
    },
    seReqNumChartOptions(data) {
      const minute = this.queryParams.interval == 1 ? 60 : this.queryParams.interval == 2 ? 1440 : 5
      this.reqNumChartOptions.xAxis.data = this.resetXAxis(minute,this.queryParams.startTime,this.queryParams.endTime)
      this.reqNumChartOptions.series[0].data = data;
      this.reqNumChart.setOption(this.reqNumChartOptions);
    },
    seHitRateChartOptions(data) {
      const minute = this.queryParams.interval == 1 ? 60 : this.queryParams.interval == 2 ? 1440 : 5
      this.hitRateChartOptions.xAxis.data = this.resetXAxis(minute,this.queryParams.startTime,this.queryParams.endTime)
      this.hitRateChartOptions.series[0].data = data;
      this.hitRateChart.setOption(this.hitRateChartOptions);
    },
    resetXAxis(minute,start,end) {
        const startTime = new Date(start);
        const endTime = new Date(end);
        const intervals = [];
        let currentTime = startTime;
        while (currentTime <= endTime) {
            intervals.push(parseTime(currentTime, "{y}-{m}-{d} {h}:{i}:{s}"));
            currentTime = new Date(currentTime.getTime() + minute * 60 * 1000);
        }
        if (intervals[intervals.length - 1] !== parseTime(endTime, "{y}-{m}-{d} {h}:{i}:{s}")) {
            intervals.push(parseTime(endTime, "{y}-{m}-{d} {h}:{i}:{s}"));
        }
        return intervals
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.timeType = 0
      this.queryParams.interval = 0
      this.queryParams.startTime = `${parseTime(this.today, "{y}-{m}-{d}")} 00:00:00`
      this.queryParams.endTime = `${parseTime(this.today, "{y}-{m}-{d} {h}:{i}:{s}")}`
      this.datetime = [this.queryParams.startTime,this.queryParams.endTime]
      this.getChartData();
    },
    getChartData() {
        const params = {
          startTime: new Date(this.queryParams.startTime).getTime(),
          endTime: new Date(this.queryParams.endTime).getTime(),
          domainName: this.queryParams.domainName,
          statType: this.queryParams.statType,
          interval: this.queryParams.interval == 1 ? 3600 : this.queryParams.interval == 2 ? 86400 : 300,
        }
        cdnStatistics(params).then(response => {
          this.summary.flux = (response.summary.result.flux /(1024 *1024)).toFixed(2);
          this.summary.req_num = response.summary.result.req_num;
          this.summary.hit_num = response.summary.result.hit_num;
          this.summary.bw = (response.summary.result.bw /(1024 *1024)).toFixed(2);
          if (response.summary.result.req_num != null && response.summary.result.hit_num != null) {
            this.summary.hit_rate = ((response.summary.result.hit_num / response.summary.result.req_num) * 100).toFixed(2) ;
          }
          if (response.detail.result.flux!=null){
            this.flux = response.detail.result.flux.map(num => (num / (1024 * 1024)).toFixed(2));
          }
          // 处理带宽数据
          if (response.detail.result.bw != null) {
            this.bw = response.detail.result.bw.map(num => (num / (1024 * 1024)).toFixed(2));
          }
          // 处理请求数据
          if (response.detail.result.req_num != null) {
            this.reqNum = response.detail.result.req_num;
          }

          if (response.detail.result.req_num != null && response.detail.result.hit_num != null) {
            // 初始化命中率数组
            this.hitRate = response.detail.result.req_num.map((req, index) => {
              const hit = response.detail.result.hit_num[index];
              return req > 0 ? ((hit / req) * 100).toFixed(2) : 0;
            });
          }

          // 初始化两个图表
          this.$nextTick(() => {
            this.initChart({ flux: this.flux });
            this.initBwChart({ bw: this.bw });
            this.initReqNumChart({ reqNum: this.reqNum });
            this.initHitRateChart({ hitRate: this.hitRate });
          });
        });

    },
  },
};
</script>

<style lang="scss" scoped>
.app-container {
  border-radius: 8px;
  .type {
    background: #f0f2f5;
    width: 80px;
    display: inline-block;
    text-align: center;
    margin-right: 5px;
    border-radius: 5px;
    cursor: pointer;
  }
  .active {
    color: #fff;
    background: #409eff;
  }
  .chart-title {
    font-size: 18px;
    font-weight: bold;
    span {
      font-size: 14px;
      font-weight: normal;
      color: #999;
      margin-left: 20px;
    }
  }
}
</style>
