<!--
 * @Author: y_zp
 * @Date: 2022-08-02 14:00
 * @Desc: 
-->
<template>
  <div class="shcedulepageindex_container">
    <div class="task_container">
      <a-row :gutter="12">
        <a-col :span="8">
          <div class="task_item orange">
            <p class="title">任务总数（个）</p>
            <p class="num total">
              {{ (taskCount.taskCountAll.totalCountCron + taskCount.taskCountAll.totalCountRealtime) || 0 }}
            </p>
          </div>
        </a-col>
        <a-col :span="8">
          <div class="task_item green">
            <p class="title">实时任务（个）</p>
            <p class="num">
              {{ taskCount.taskCountAll.totalCountRealtime || 0 }}
            </p>
            <a-row class="detail">
              <a-col :span="7" align="center">成功
                <span class="num_succ">
                  {{ taskCount.taskCountOneDay.successCountRealtime || 0 }}
                </span>
              </a-col>
              <a-col :span="1" align="right"><a-divider type="vertical" /></a-col>
              <a-col :span="8" align="center">失败
                <span class="num_fail">
                  {{ taskCount.taskCountOneDay.failCountRealtime || 0 }}
                </span>
              </a-col>
              <a-col :span="1"><a-divider type="vertical" /></a-col>
              <a-col :span="7" align="center">运行中
                <span class="num_run">
                  {{ taskCount.taskCountOneDay.runningCountRealtime || 0 }}
                </span>
              </a-col>
            </a-row>
          </div>
        </a-col>
        <a-col :span="8">
          <div class="task_item blue">
            <p class="title">周期任务（个）</p>
            <p class="num">
              {{ taskCount.taskCountAll.totalCountCron || 0 }}
            </p>
            <a-row class="detail">
              <a-col :span="7" align="center">成功
                <span class="num_succ">
                  {{ taskCount.taskCountOneDay.successCountCron || 0 }}
                </span>
              </a-col>
              <a-col :span="1" align="right"><a-divider type="vertical" /></a-col>
              <a-col :span="8" align="center">失败
                <span class="num_fail">
                  {{ taskCount.taskCountOneDay.failCountCron || 0 }}
                </span>
              </a-col>
              <a-col :span="1"><a-divider type="vertical" /></a-col>
              <a-col :span="7" align="center">运行中
                <span class="num_run">
                  {{ taskCount.taskCountOneDay.runningCountCron || 0 }}
                </span>
              </a-col>
            </a-row>
          </div>
        </a-col>
      </a-row>
    </div>
    <div class="monitoring_container">
      <a-spin :spinning="ioLoading">
        <a-card size="small" title="集成实时数据" class="no_border">
          <span slot="extra">
            <a-select
              allowClear
              mode="multiple"
              :maxTagCount="1"
              :maxTagTextLength="1"
              placeholder="请选择集群"
              v-model="ioCountParams.clusterIds"
              :options="clusterList"
              @change="ioCountSearch"
            >
            </a-select>
            &nbsp;
            <a-range-picker
              style="width: 370px"
              :locale="locale"
              :allowClear="false"
              :value="timeVal"
              :ranges="rangesDate"
              :disabled-date="disabledDate"
              :placeholder="['请选择', '请选择']"
              :show-time="{ format: 'HH:mm:ss' }"
              format="YYYY-MM-DD HH:mm:ss"
              separator="至"
              @change="onIoTimeChange"
            >
              <a-icon slot="suffixIcon" type="calendar" />
            </a-range-picker>
            <span class="refresh">
              自动刷新<a-switch v-model="isRefresh" @change="onRefreshChange" />
            </span>
          </span>
          <a-row :gutter="12">
            <a-col :span="14">
              <div class="monitoring_list">
                <div id="real_time_monitoring" class="echarts"></div>
              </div>
            </a-col>
            <a-col :span="10">
              <div class="monitoring_data">
                <div style="height: calc(100% - 20px)">
                  <vxe-table
                    show-overflow
                    show-header-overflow
                    border
                    resizable
                    :row-config="{ isHover: true }"
                    :data="ioCpsLists"
                    height="auto"
                    show-footer
                    :footer-span-method="footerColspanMethod"
                    :footer-method="footerMethod"
                  >
                    <vxe-colgroup field="time" align="center" :title="`${ioCpsParams.startTime} ～ ${ioCpsParams.endTime}`">
                      <vxe-column type="seq" title="序号" width="50" align="center"></vxe-column>
                      <vxe-column field="taskName" title="任务名称"> </vxe-column>
                      <vxe-column field="ioCount" title="吞吐量（个）"></vxe-column>
                      <vxe-column field="period" title="区间时长"> </vxe-column>
                      <!-- <vxe-column field="cps" title="每秒吞吐量(个/秒)"></vxe-column> -->
                    </vxe-colgroup>
                    <template #empty>
                      <a-empty
                        :image-style="{
                          height: '80px',
                        }"
                      >
                        <span slot="description"> 暂无数据 </span>
                      </a-empty>
                    </template>
                  </vxe-table>
                </div>
              </div>
            </a-col>
          </a-row>
        </a-card>
      </a-spin>
    </div>
    <a-row style="margin-top: 12px;" :gutter="12">
      <a-col :span="14">
        <a-spin :spinning="generalLoading">
          <a-card size="small" title="近7日周期任务概览" class="no_border">
            <div class="scheduling_list">
              <div id="last_seven_days_job_scheduling" class="echarts"></div>
            </div>
          </a-card>
        </a-spin>
      </a-col>
      <a-col :span="10">
        <a-spin :spinning="elapsedLoading">
          <a-card
            size="small"
            title="近30天任务时长排行TOP10"
            class="no_border"
          >
            <span slot="extra">
              <!-- <a-select
                class="small"
                placeholder="请选择任务分类"
                v-model="elapsedListParams.runtimeMode"
                @change="elapsedSearch"
              >
                <a-select-option value="BATCH">周期任务</a-select-option>
                <a-select-option value="STREAMING">实时任务</a-select-option>
              </a-select> -->
              &nbsp;
              <a-select
                allowClear
                class="small"
                mode="multiple"
                :maxTagCount="1"
                :maxTagTextLength="1"
                placeholder="请选择集群"
                v-model="elapsedListParams.clusterIds"
                :options="clusterList"
                @change="elapsedSearch"
              >
              </a-select>
            </span>
            <div class="execution_list">
              <vxe-table
                show-overflow
                show-header-overflow
                border
                resizable
                :row-config="{ isHover: true }"
                :data="elapsedList"
                height="auto"
              >
                <vxe-column
                  type="seq"
                  title="序号"
                  width="50"
                  align="center"
                ></vxe-column>
                <vxe-column field="jobName" title="任务名称"> </vxe-column>
                <vxe-column field="startTime" title="开始时间"> </vxe-column>
                <vxe-column field="endTime" title="结束时间"> </vxe-column>
                <vxe-column field="period" title="执行时长" width="100">
                  <template #default="{ row }">
                    {{ row.period + row.timeUnit }}
                  </template>
                </vxe-column>
                <template #empty>
                  <a-empty
                    :image-style="{
                      height: '80px',
                    }"
                  >
                    <span slot="description"> 暂无数据 </span>
                  </a-empty>
                </template>
              </vxe-table>
            </div>
          </a-card>
        </a-spin>
      </a-col>
    </a-row>
  </div>
</template>
<script>
import moment from 'moment';
/**
 * @Author: y_zp
 * @description: 调度概览
 */
const $dataIntegration = require("@/api/dataIntegration");
const $dispatchcenter = require("@/api/dispatchcenter");

let rangesDate = {
  近1小时: [moment().subtract(1, "hours"), moment()],
  近3小时: [moment().subtract(3, "hours"), moment()],
  近12小时: [moment().subtract(12, "hours"), moment()],
  近24小时: [moment().subtract(1, "days"), moment()],
  近7天: [moment().subtract(7, "days"), moment()],
  近1个月: [moment().subtract(1, "months"), moment()],
};
let colorList = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc', '#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83']
export default {
  data() {
    return {
      timeVal: [moment().subtract(1, 'days'), moment()],
      taskCount: {
        taskCountAll: {},
        taskCountOneDay: {}
      },
      generalLoading: false,
      elapsedLoading: false,
      ioLoading: false,
      rangesDate: rangesDate,
      clusterList: [],
      ioCountParams: {
        clusterIds: [],
        startTime: moment().subtract(1, "days").format("YYYY-MM-DD HH:mm:ss"),
        endTime: moment().format("YYYY-MM-DD HH:mm:ss"),
      },
      ioCpsParams: {
        startTime: "",
        endTime: "",
      },
      ioDates: [],
      jobDates: [],
      elapsedListParams: {
        clusterIds: [],
        // runtimeMode: "BATCH",
        startTime: moment().subtract(30, "days").format("YYYY-MM-DD HH:mm:ss"),
        endTime: moment().format("YYYY-MM-DD HH:mm:ss"),
      },
      elapsedList: [],
      ioCpsLists: [],
      refreshTimer: null,
      isRefresh: true,
    };
  },
  created() {
    this.getClusterList();
    this.getTaskCount();
    this.getElapsedList();
    setTimeout(() => {
      this.$nextTick(() => {
        this.initIoCount();
        this.initjobGeneral();
      });
    }, 10);
    // 自动刷新
    this.refreshFun()
  },
  methods: {
    /**
     * @Author: y_zp
     * @description: 设置不可选日期
     */
    disabledDate(cur) {
      return cur && cur > moment().endOf("day");
    },

    /**
     * @Author: y_zp
     * @description: 获取集群列表
     */
    getClusterList() {
      $dataIntegration
        .getClusterManager({
          pageNum: 1,
          pageSize: 10000,
          queryParams: {
            F_isDel_eq: 0,
          },
        })
        .then((req) => {
          this.clusterList = req.data.map((item) => {
            return {
              value: item.clusterId,
              label: item.name,
            };
          });
        })
        .finally(() => {});
    },

    /**
     * @Author: y_zp
     * @description: 任务运行情况
     */
    getTaskCount() {
      $dispatchcenter
        .getTaskCountOverview()
        .then((req) => {
          let info = req.data;
          this.taskCount = info;
        })
    },

    /**
     * @Author: y_zp
     * @description: 调度情况概览-chart
     */
    initjobGeneral() {
      let myChart = this.$echarts.init(
        document.getElementById("last_seven_days_job_scheduling")
      );
      let option = {
        tooltip: {
          trigger: "axis",
        },
        legend: {
          orient: "horizontal",
          right: "10",
          top: "0",
          itemGap: 20,
          data: ["运行成功", "运行失败", "运行中"],
        },
        grid: {
          top: "12%",
          left: "2%",
          bottom: "7%",
          containLabel: true,
        },
        color: ["#29DF7E", "#EA4B4B", "#F3CF25"],
        xAxis: {
          name: "单位：日",
          type: "category",
          data: [],
        },
        yAxis: {
          name: "单位：个",
          type: "value",
          minInterval: 1,
          splitLine: {
            lineStyle: {
              type: "dashed",
            },
          },
        },
        graphic: [],
        series: [
          {
            name: "运行成功",
            type: "bar",
            stack: "Ad",
            barWidth: "20%",
            label: {
              show: true,
              formatter: function (val) {
                if (val.value == 0) {
                  return "";
                }
              },
            },
            data: [],
          },
          {
            name: "运行失败",
            type: "bar",
            stack: "Ad",
            barWidth: "20%",
            label: {
              show: true,
              formatter: function (val) {
                if (val.value == 0) {
                  return "";
                }
              },
            },
            data: [],
          },
          {
            name: "运行中",
            type: "bar",
            stack: "Ad",
            barWidth: "20%",
            label: {
              show: true,
              formatter: function (val) {
                if (val.value == 0) {
                  return "";
                }
              },
            },
            data: [],
          },
        ],
      };
      $dispatchcenter
        .chartInfo()
        .then((req) => {
          let info = req.data;
          option.xAxis.data = info.triggerDayList;
          option.series[0].data = info.triggerDayCountSucList;
          option.series[1].data = info.triggerDayCountFailList;
          option.series[2].data = info.triggerDayCountRunningList;
        })
        .finally(() => {
          myChart.setOption(option);
          this.generalLoading = false;
        });
    },

    /**
     * @Author: y_zp
     * @description: 执行时长TOP10
     */
    getElapsedList() {
      this.elapsedLoading = true;
      $dispatchcenter
        .getElapsedList(this.elapsedListParams)
        .then((req) => {
          this.elapsedList = req.data;
        })
        .finally(() => {
          this.elapsedLoading = false;
        });
    },

    /**
     * @Author: y_zp
     * @description: 执行时长TOP10查询
     */
    elapsedSearch() {
      this.getElapsedList();
    },

    /**
     * @Author: y_zp
     * @description: 获取实时任务监控-chart
     */
    initIoCount() {
      var _this = this;
      this.ioLoading = true;
      let myChart = this.$echarts.init(
        document.getElementById("real_time_monitoring")
      );
      let option = {
        tooltip: {
          trigger: "axis",
        },
        legend: {
          orient: "horizontal",
          left: "10",
          top: "0",
          itemGap: 10,
          data: [],
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "7%",
          containLabel: true,
        },
        color: [],
        xAxis: {
          type: "category",
          data: [],
        },
        yAxis: {
          name: "单位：个",
          type: "value",
          minInterval: 1,
          splitLine: {
            lineStyle: {
              type: "dashed",
            },
          },
        },
        series: [],
      };
      if (this.isRefresh) {
        let curTime = moment();
        let diff = curTime.diff(this.ioCountParams.endTime);
        // console.log(diff);
        this.ioCountParams.startTime = moment(this.ioCountParams.startTime).add(diff, "milliseconds").format("YYYY-MM-DD HH:mm:ss");
        this.ioCountParams.endTime = moment().format("YYYY-MM-DD HH:mm:ss");
        this.timeVal = [moment(this.ioCountParams.startTime), moment(this.ioCountParams.endTime)];
      }
      $dataIntegration
        .getRuntimeTotal(this.ioCountParams)
        .then((req) => {
          let info = req.data;
          if (info.length > 0) {
            this.ioDates = info[0].dates;
            option.xAxis.data = info[0].xs;
            info.forEach((item, index) => {
              colorList[index] = colorList[index] || `#${Math.random().toString(16).substr(2,6)}`;
              option.color[index] = colorList[index];
              option.series.push({
                name: item.lineName,
                type: "line",
                lineStyle: {
                  width: 2,
                },
                data: item.values,
                smooth: true
              });
            });
          }
          // 获取实时监控数据
          this.ioCpsParams.startTime = info.length > 0 ? this.ioDates[this.ioDates.length -2] : this.ioCountParams.startTime;
          this.ioCpsParams.endTime = info.length > 0 ? this.ioDates[this.ioDates.length -1] : this.ioCountParams.endTime;
          this.getIoCpsLists();
        })
        .finally(() => {
          myChart.setOption(option);
          _this.ioLoading = false;
          myChart.on("click", function (param) {
            _this.ioCpsParams.startTime = param.dataIndex == 0 ? _this.ioDates[param.dataIndex] : _this.ioDates[param.dataIndex-1];
            _this.ioCpsParams.endTime = (param.dataIndex == _this.ioDates.length -1) ? _this.ioDates[param.dataIndex] : _this.ioDates[param.dataIndex + 1];
            _this.getIoCpsLists();
          });
        });
    },

    /**
     * @Author: y_zp
     * @description: 获取实时监控-list
     */
    getIoCpsLists() {
      this.ioLoading = true;
      $dataIntegration
        .getRuntimeIoCountTotal({ ...this.ioCountParams, ...this.ioCpsParams })
        .then((req) => {
          this.ioCpsLists = req.data;
        })
        .finally(() => {
          this.ioLoading = false;
        });
    },

    /**
     * @Author: y_zp
     * @description: 获取实时监控-list 求和
     */
    sumNum(list, field) {
      let count = 0;
      list.forEach((item) => {
        count += Number(item[field]);
      });
      return count;
    },
    footerMethod({ columns, data }) {
      const footerData = [
        columns.map((column, _columnIndex) => {
          if (_columnIndex === 0) {
            return "合计";
          }
          if (["jobId"].includes(column.property)) {
            return "合计";
          }
          if (["ioCount", "period", "cps", "delay"].includes(column.property)) {
            return column.property == "period" ? "--" : this.sumNum(data, column.property);
          }
          return null;
        }),
      ];
      return footerData;
    },

    /**
     * @Author: y_zp
     * @description: 获取实时监控-list 合并
     */
    footerColspanMethod({ _columnIndex }) {
      if (_columnIndex === 0) {
        return {
          rowspan: 1,
          colspan: 2,
        };
      } else if (_columnIndex === 1) {
        return {
          rowspan: 0,
          colspan: 0,
        };
      }
    },

    /**
     * @Author: y_zp
     * @description: 实时监控查询时间选择
     */
    onIoTimeChange(date, dateString) {
      this.ioCountParams.startTime = dateString[0];
      this.ioCountParams.endTime = dateString[1];
      let curTime = moment();
      let diff = curTime.diff(this.ioCountParams.endTime);
      // 超过一分钟，关掉定时刷新
      if (Number(diff) > 1000*60) {
        this.isRefresh = false;
        clearInterval(this.timer);
      } else {
        this.isRefresh = true;
      }
      this.timeVal = [moment(dateString[0]), moment(dateString[1])];
      this.ioCountSearch();
    },

    /**
     * @Author: y_zp
     * @description: 实时监控查询
     */
    ioCountSearch() {
      console.log(this.ioCountParams.clusterIds)
      this.initIoCount();
      if (this.isRefresh) {
        clearInterval(this.refreshTimer);
        this.refreshFun();
      }
    },

    /**
     * @Author: y_zp
     * @description: 自动刷新
     */
    onRefreshChange(val) {
      this.isRefresh = val;
      this.initIoCount();
      if (val) {
        this.refreshFun();
      } else {
        clearInterval(this.refreshTimer);
      }
    },

    /**
     * @Author: y_zp
     * @description: 定时刷新数据
     */
    refreshFun() {
      this.refreshTimer = setInterval(() => {
        this.initIoCount();
      }, 1000 * 15);
    },
  },
  deactivated() {
    clearInterval(this.refreshTimer);
  },
  beforeDestroy() {
    clearInterval(this.refreshTimer);
  },
};
</script>
<style lang="less">
.shcedulepageindex_container {
  .task_container {
    .radio_item {
      display: inline-block;
      margin-right: 12px;
      margin-bottom: 12px;
      padding: 3px 20px;
      cursor: pointer;
      &.cur {
        color: #fff;
        background: #4071FF;
        border-radius: 3px;
      }
    }
    .task_item {
      height: 120px;
      background: #fff;
      padding: 12px;
      font-size: 14px;
      font-weight: 600;
      color: #000000;
    }
    .orange {
      border-top: 2px solid #F3AF24;
    }
    .green {
      border-top: 2px solid #00AB45;
    }
    .blue {
      border-top: 2px solid #2D5BFA;
    }
    .purple {
      border-top: 2px solid #B37FEB;
    }
    .num {
      margin-top: 5px;
      text-align: center;
      font-size: 24px;
      &.total {
        margin-top: 15px;
      }
    }
    .detail {
      font-weight: normal;
      margin-top: 12px;
      span {
        margin-left: 5px;
      }
      .num_succ {
        color: #29DF7E;
      }
      .num_fail {
        color: #EA4B4B;
      }
      .num_run {
        color: #2d5afa;
      }
    }
  }
  .search_label {
    font-weight: 400;
    color: #000;
    margin-right: 6px;
    margin-left: 12px;
  }
  .ant-select {
    width: 160px;
  }
  .search-icon {
    cursor: pointer;
    margin-left: 6px;
    color: #999;
    vertical-align: middle;
    font-size: 20px;
  }
  .scheduling_list,
  .execution_list,
  .monitoring_list,
  .monitoring_data {
    margin-top: 12px;
    height: 310px;
  }
  .execution_list {
    height: 298px;
    padding-bottom: 12px;
  }
  .echarts {
    width: 100%;
    height: 100%;
  }
  .ant-time-picker {
    width: 140px;
  }
  .time {
    margin-bottom: 12px;
  }
  .refresh {
    margin-left: 20px;
  }
  .monitoring_container {
    margin-top: 12px;
    .ant-switch {
      margin-left: 12px;
      vertical-align: middle;
      margin-top: -3px;
    }
    .ant-switch-inner {
      color: #333;
    }
  }
}
</style>
