<template>
  <BasicLayout>
    <template #wrapper>
      <div style="padding-top:20px">
        <div class="ob-info-box">
          <div class="interface-service-header">
            <span style="font-size:18px;">{{ name }}</span>
            <span style="float:right;font-size:18px;">类型：API</span>
          </div>
          <div class="service-header">
            <div class="service-header-left" @click="goDrawer">
              <span class="fontSize18">基本信息:</span>
              <div style="width:100%"><p class="service-header-p"><span class="service-span-right">所属应用： </span><el-tooltip class="item" effect="dark" :content=" appItem.alias ? baseInfoObj.app_name + '(' + appItem.alias + ')' : '--'" placement="top"><span class="service-span-left">{{ baseInfoObj.app_name }} {{ appItem.alias ? '(' + appItem.alias+ ')' : '--' }}</span></el-tooltip></p></div>
              <div style="width:100%"><p class="service-header-p"><span class="service-span-right">所属服务：</span><el-tooltip class="item" effect="dark" :content="getServiceName" placement="top"><span class="service-span-left" style="color: #165DFF;"> {{ getServiceName }} </span></el-tooltip></p></div>
            </div>
            <div class="service-header-right">
              <div class="service-header-rightcol">
                <el-tooltip placement="bottom" effect="dark" :visible-arrow="false">
                  <div slot="content">
                    <i class="dot" />
                    <span>{{ total !=undefined? total:0 }}</span>
                  </div>
                  <div>
                    <div>
                      <div class="service-right-tit">请求总数</div>
                      <div class="service-right-con">{{ digitsObj.total !=undefined? digitsObj.total:0 }}</div>
                    </div>
                  </div>
                </el-tooltip>
              </div>
              <div class="service-header-rightcol">
                <el-tooltip placement="bottom" effect="dark" :visible-arrow="false">
                  <div slot="content">
                    <i class="dot" />
                    <span>{{ (digitsObj.error_num) || 0 }}</span>
                  </div>
                  <div>
                    <div>
                      <div class="service-right-tit">错误数</div>
                      <div class="service-right-con">{{ digitsObj.error_num|| 0 }}</div>
                    </div>
                  </div>
                </el-tooltip>
              </div>
              <div class="service-header-rightcol">
                <el-tooltip placement="bottom" effect="dark" :visible-arrow="false">
                  <div slot="content">
                    <i class="dot" />
                    <span>{{ (digitsObj.error_rate *100).toFixed(2) + '%' || '0%' }}</span>
                  </div>
                  <div>
                    <div>
                      <div class="service-right-tit">错误率</div>
                      <div class="service-right-con">{{ (digitsObj.error_rate *100).toFixed(2) + '%'|| '0%' }}</div>
                    </div>
                  </div>
                </el-tooltip>
              </div>
              <div class="service-header-rightcol">
                <el-tooltip placement="bottom" effect="dark" :visible-arrow="false">
                  <div slot="content">
                    <i class="dot" />
                    <span>{{ digitsObj.qpm!=undefined?digitsObj.qpm:0 }}</span>
                  </div>
                  <div class="border-bottom">
                    <div>
                      <div class="service-right-tit">请求频率/min</div>
                      <div class="service-right-con">{{ digitsObj.qpm!=undefined?Number(digitsObj.qpm).toFixed(2):0 }}</div>
                    </div>
                  </div>
                </el-tooltip>
              </div>
              <div class="service-header-rightcol" style="padding-top: 16px;">
                <el-tooltip placement="bottom" effect="dark" :visible-arrow="false">
                  <div slot="content">
                    <i class="dot" />
                    <span>{{ digitsObj.median_duration != undefined?digitsObj.median_duration:0 }}</span>
                  </div>
                  <div class="border-bottom">
                    <div>
                      <div class="service-right-tit">中位时延 (ms)</div>
                      <div class="service-right-con" style="color:#F53F3F">{{ digitsObj.median_duration != undefined?Number(digitsObj.median_duration).toFixed(2):0 }}</div>
                    </div>
                    <div class="service-right-btn" @click="handelClickDrawer">查看全部请求</div>
                  </div>
                </el-tooltip>
              </div>
            </div>
          </div>
        </div>
        <div class="ob-interface-box"><LineCharts class="line-div" @chartClick="chartClick" /></div>
        <div class="ob-interface-box">
          <!-- 异常事件统计图 -->
          <div v-if="isChartLoading" v-loading="isChartLoading" />
          <AbnormalChart v-else :chart-data="chartData" :title="'当前接口错误分布情况'" :bis-type="'interface'" :trace-kind="traceKind" :current-alias="currentAlias" :chart-dom-id="'interfaceChartDom'" :service_name="service_name" :route="name" />
        </div>
      </div>
      <ServiceDrawer v-if="isOpendrawer" :is-opendrawer="isOpendrawer" @handleClose="handleClose" />
      <!-- 链路详情抽屉 -->
      <LinkDetailsDrawer v-if="isShowLinkDrawer" :is-opendrawer="isShowLinkDrawer" :tract-i-d="tractID" :span-i-d="spanID" @handleClose="closeLinkDrawer" />
      <el-drawer
        title="最新请求"
        :visible.sync="lastReqDrawer"
        :direction="'rtl'"
        append-to-body
        :before-close="handleCloseDrawer"
        size="70%"
        custom-class="service-drawer"
      >
        <!-- <div class="ob-interface-title">最新请求</div> -->
        <div style="text-align: right; padding-right:10px;margin-bottom:10px">
          <el-checkbox v-model="onlyException" @change="handelChange()">仅异常</el-checkbox>
          <el-checkbox v-model="onlyDuration" @change="handelCheckChange()">
            延迟 >
            <el-select v-model="durationOption" placeholder="请选择" size="mini" style="margin-left:5px;" @change="handelSelectChange">
              <el-option
                v-for="item in options"
                :key="item.key"
                :label="item.value"
                :value="item.key"
              />
            </el-select>
          </el-checkbox>
        </div>
        <el-table
          v-loading="tableLoading"
          :data="rowData"
          @row-click="handleClickTable"
          @sort-change="sortChangeTable"
        >
          <!-- <el-table-column header-align="center" label="TraceID" prop="trace_id" align="center" width="240">
              <template slot-scope="scope">
                <span >{{ scope.row.trace_id }}</span>
              </template>
            </el-table-column> -->
          <!-- <el-table-column header-align="center" label="ServiceName" prop="service_name" align="center" :show-overflow-tooltip="true" /> -->
          <el-table-column header-align="center" label="Url" prop="target" align="center" :show-overflow-tooltip="true" />
          <!-- <el-table-column header-align="center" label="Method" prop="method" align="center">
              <template slot-scope="scope">
                <el-tag type="info">{{ scope.row.method }}</el-tag>
              </template>
            </el-table-column> -->
          <el-table-column header-align="center" label="状态码" prop="status_code" align="center">
            <template slot-scope="scope">
              <span>
                <el-tag v-if="scope.row.status_code<400" class="colorwhite" type="success" effect="dark">{{ scope.row.status_code }}</el-tag>
                <el-tag v-else color="#F53F3F" style="color:white" type="danger">{{ scope.row.status_code }}</el-tag>
              </span>
            </template>
          </el-table-column>
          <el-table-column header-align="center" sortable="custom" label="请求时长(ms)" prop="duration" align="center">
            <template slot-scope="scope">
              <el-tag v-if="scope.row.duration>=2000" type="danger">{{ scope.row.duration }}</el-tag>
              <el-tag v-if="scope.row.duration<2000" type="info">{{ scope.row.duration }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column header-align="center" sortable="custom" label="日期" prop="datetime" align="center" />
        </el-table>
        <pagination
          v-show="total>0"
          :total="total"
          :page.sync="childQueryParams.pageIndex"
          :limit.sync="childQueryParams.pageSize"
          :page-sizes="[5, 10, 20, 30, 50]"
          @pagination="getTableListFn"
        />
      </el-drawer>
    </template>
  </BasicLayout>
</template>
<script>
import { getUrlMappingRange, urlMappingSubdigits, getBasicInfo, getAbnormalStatistics } from '@/api/mapping'
import storage from '@/utils/storage'
import LineCharts from './components/LineCharts.vue'
import ServiceDrawer from './components/ServiceDrawer.vue'
import LinkDetailsDrawer from './components/LinkDetailsDrawer.vue'
import AbnormalChart from '../../business-analysis/system-space/components/AbnormalChart.vue'
import moment from 'moment'
export default {
  components: {
    LineCharts,
    ServiceDrawer,
    LinkDetailsDrawer,
    AbnormalChart
  },
  data() {
    return {
      rowData: [],
      tableLoading: false,
      total: 0,
      childQueryParams: {
        start_time: 0,
        end_time: 0,
        id: 0,
        app_id: 0,
        kind: '',
        only_error: 0,
        pageIndex: 1,
        pageSize: 5,
        name: '', // 临时写的，主要用于业务解析节点跳转过来接受参数
        method: '',
        service_name: '',
        sort_field: 'Timestamp', // 目前就一个Timestamp排序先写死
        sort_type: 'DESC',
        min_duration: 0
      },
      serviceMapTimer: null,
      appItem: {},
      row: {}, // 从列表中保存的每行数据
      name: '',
      service_name: '',
      myChartScale: null,
      backFlag: true,
      digitsObj: {
        error_rate: 0,
        qpm: 0,
        median_duration: 0
      },
      isOpendrawer: false,
      durationOption: 2500,
      onlyException: false,
      onlyDuration: false,
      options: [{ value: '0ms', key: 0 }, { value: '2500ms', key: 2500 }, { value: '5000ms', key: 5000 }, {
        value: '10000ms',
        key: 10000
      }],
      subdigitsQuery: {
        start_time: 0,
        end_time: 0,
        id: undefined
      },
      baseInfoObj: {},
      isShowLinkDrawer: false,
      tractID: '',
      spanID: '',
      chartData: [],
      traceKind: 'interface',
      currentAlias: '',
      lastReqDrawer: false,
      isChartLoading: false
    }
  },
  computed: {
    getServiceName() {
      if (this.baseInfoObj.service_name_cn === this.baseInfoObj.service_name) {
        return this.baseInfoObj.service_name
      } else {
        return this.baseInfoObj.service_name_cn ? (this.baseInfoObj.service_name_cn + '(' + this.baseInfoObj.service_name + ')') : this.baseInfoObj.service_name
      }
    }
  },
  watch: {
    '$store.state.time.globalTimes': {
      handler(newValue, oldValue) {
        if (newValue) {
          this.subdigitsQuery.start_time = newValue.startTime
          this.subdigitsQuery.end_time = newValue.endTime
          this.childQueryParams.start_time = newValue.startTime
          this.childQueryParams.end_time = newValue.endTime
          this.childQueryParams.pageIndex = 1
          this.getBasicInfoFn()
          this.getTableListFn()
          // this.getAbnormalChartData(2) // 异常信息柱状图
          if (newValue.timeOut) {
            if (newValue.timeOut === 1) {
              clearInterval(this.serviceMapTimer)
            } else {
              clearInterval(this.serviceMapTimer)
              this.Refresh(newValue.timeOut)
            }
          }
        }
      },
      // immediate: true,
      deep: true
    },
    '$store.state.alias.currentAlias': { // 当前应用切换
      handler(newValue, oldValue) {
        this.appItem = storage.get('appsItem')
        this.currentAlias = newValue
        this.getBasicInfoFn()
        this.getTableListFn()
        // this.getAbnormalChartData(2) // 异常信息柱状图
      },
      deep: true
    }
  },
  created() {
    if (window.history.length <= 1) {
      this.backFlag = false
    } else {
      this.backFlag = true
    }
    // 说明
    // appItem中的id和app_id是一样的
    this.appItem = storage.get('appsItem')
    this.currentAlias = this.appItem.alias
    const start_time = this.$store.state.time.globalTimes.startTime
    const end_time = this.$store.state.time.globalTimes.endTime
    this.subdigitsQuery.start_time = start_time
    this.subdigitsQuery.end_time = end_time
    if (JSON.stringify(this.appItem) !== '{}') {
      this.childQueryParams.start_time = start_time
      this.childQueryParams.end_time = end_time
      this.childQueryParams.app_id = this.appItem.id
    }
    if (this.$route.query.kind !== undefined) {
      this.name = this.$route.query.kind
      this.childQueryParams.kind = this.$route.query.kind
    }
    if (this.$route.query.id !== undefined) {
      this.childQueryParams.id = this.$route.query.id
    }
    if (this.$route.query.service_name !== undefined) {
      this.service_name = this.$route.query.service_name
      this.childQueryParams.service_name = this.$route.query.service_name
    }
    if (this.$route.query.method !== undefined) {
      this.childQueryParams.method = this.$route.query.method
    }
    if (this.$route.query.route !== undefined) {
      this.childQueryParams.route = this.$route.query.route
    }
    if (this.$route.query.name !== undefined) {
      this.childQueryParams.name = this.$route.query.name// 用于业务解析节点接口名跳转过来
    }
    this.row = storage.get('row')
    this.getBasicInfoFn()
    // this.getAbnormalChartData(2) // 异常信息柱状图
  },
  beforeDestroy() {
    clearInterval(this.serviceMapTimer)
  },
  methods: {
    handelClickDrawer() {
      this.lastReqDrawer = true
      this.getTableListFn()
    },
    handleCloseDrawer() {
      this.lastReqDrawer = false
    },
    async getAbnormalChartData(type) { // 获取异常统计数据
      this.isChartLoading = true
      let end_time = null
      let start_time = null
      if (type === 1) { // 默认24小时
        end_time = Math.floor(moment().valueOf() / 1000)
        start_time = Math.floor(moment().subtract(12, 'hours').valueOf() / 1000)
      } else { // type 2 全局时间控件时间
        end_time = this.subdigitsQuery.end_time
        start_time = this.subdigitsQuery.start_time
      }
      const params = {
        kind: 'interface',
        subcondition_value: this.subdigitsQuery.id,
        start_time: start_time,
        end_time: end_time,
        app_alias: this.appItem.alias
      }
      const res = await getAbnormalStatistics(params)
      if (res && res.code === 200) {
        this.chartData = res.data
      } else {
        this.chartData = []
      }
      this.isChartLoading = false
    },
    Refresh(timeOut) {
      this.serviceMapTimer = setInterval(() => {
        this.getBasicInfoFn()
        this.getTableListFn()
      }, timeOut)
    },
    // 获取查看全部请求table 数据
    getTableListFn() {
      this.tableLoading = true
      getUrlMappingRange(this.childQueryParams).then(res => {
        if (res.code === 200) {
          this.tableLoading = false
          this.rowData = res.data.list
          this.total = res.data.count
        }
      })
    },
    back() {
      this.$router.go(-1)
    },
    chartClick(timestamp) {
      // this.childQueryParams.start_time = timestamp
      // this.childQueryParams.end_time = timestamp
      // this.getTableListFn()
    },
    sortChangeTable(val) {
      const prop = val.prop
      this.childQueryParams.sort_field = prop === 'duration' ? 'Duration' : 'Timestamp'
      // desc（倒序）和asc（正序
      if (val.order === 'descending') {
        this.childQueryParams.sort_type = 'DESC'
      } else if (val.order === 'ascending') {
        this.childQueryParams.sort_type = 'ASC'
      }

      this.getTableListFn()
    },
    getUrlMappingSubdigits() {
      urlMappingSubdigits(this.subdigitsQuery).then(res => {
        if (res && res.code === 200) {
          this.digitsObj = res.data || {}
        } else {
          this.digitsObj = {}
        }
      })
    },
    goDrawer() {
      this.isOpendrawer = true
    },
    handleClose() {
      this.isOpendrawer = false
    },
    // Duration > 2500ms checkbox 勾选时
    handelCheckChange() {
      // 勾选延时时默认值2500,反之不显示
      // this.durationOption = this.onlyDuration ? 2500 : ''
      this.childQueryParams.min_duration = this.onlyDuration ? this.durationOption : 0
      this.getTableListFn()
    },
    // 仅异常 勾选时
    handelChange() {
      this.childQueryParams.only_exception = this.onlyException ? 1 : 0
      this.getTableListFn()
    },
    // Duration 下拉框change
    handelSelectChange() {
      if (this.onlyDuration) {
        this.childQueryParams.min_duration = this.onlyDuration ? this.durationOption : 0
        this.getTableListFn()
      }
    },
    async getBasicInfoFn() {
      const obj = {
        url: this.name,
        method: this.childQueryParams.method,
        app_alias: this.appItem.alias,
        service_name: this.service_name
      }
      const res = await getBasicInfo(obj)
      if (res && res.code === 200) {
        this.baseInfoObj = res.data
        this.subdigitsQuery.id = res.data.id
        this.getAbnormalChartData(2) // 异常信息柱状图
        this.getUrlMappingSubdigits()
      } else {
        this.baseInfoObj = {}
      }
    },
    handleClickTable(row) {
      this.isShowLinkDrawer = true
      this.tractID = row.trace_id
      this.spanID = row.span_id
    },
    closeLinkDrawer() {
      this.isShowLinkDrawer = false
    }
  }
}
</script>
<style lang="scss" scoped>
  .green_small{
    display: inline-block;
    width:8px;
    height: 8px;
    border-radius: 50%;
    background:#67C23A;
    margin-right:8px;
  }
  .red_small{
    width:8px;
    height: 8px;
    display: inline-block;
    border-radius: 50%;
    background:#F56C6C;
    margin-right:8px;
  }
  .line-div{
    width:100%;
    height:100%;
  }
  .service-header{
    display: flex;
  }
  .service-header-left{
    width: 4.5rem;
    // height: 120px;
    border-radius: 8px;
    cursor: pointer;
    color: #4E5969;
    padding: 20px;
    margin-right: 20px;
    box-sizing: border-box;
    background: url('../../../assets/pic-bg.png');
    background-position: right;
    background-size: cover;
    background-repeat: no-repeat;
  }
  .service-header-right{
    // width: calc(100% - 6rem);
    flex: 1;
    display: flex;
  }
  .service-header-rightcol{
    width: 20%;
    // height: 120px;
    background: linear-gradient( 155deg, #FFFFFF 0%, #FFFFFF 50%, #EFF4FF 100%);
    border: 1px solid rgba(96,97,112,0.07);
    margin-right:20px;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 20px;
    border-radius: 8px;
    box-sizing: border-box;
  }
  .service-header-rightcol:last-child{
    margin-right: 0;
  }
  .service-right-tit{
    font-weight: bold;
    font-size: 0.2rem;
    color: #4E5969;
    text-align: center;
  }
  .service-right-con{
    font-weight: bold;
    font-size: 0.38rem;
    color: #1A2233;
    margin-top:10px;
    text-align: center;
  }
  .service-right-btn{
    color: #165DFF;
    cursor: pointer;
    font-size: 12px;
    cursor: pointer;
    text-align: right;
    // margin-top: 5px;
    margin-right: -15px;
  }
  .fontSize18{
    font-size: 18px;
    font-weight: bold;
  }
  .service-header-p{
    font-weight: bold;
    font-size:0.2rem;;
    margin-bottom: 0;
    margin-top:10px;
    display: flex;
    align-items: center;
    span{
      display: inline-block;
    }
    .service-span-right{
      text-align: right;
      width:30%;
    }
    .service-span-left{
      text-align: left;
      width:70%;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
.interface-service-header{
  height: 40px;
  background: #E8F3FF;
  border-radius: 4px;
  font-weight: bold;
  font-size: 14px;
  margin-bottom: 20px;
  color: #165DFF;
  line-height:40px;
  padding:0 20px;
}
 ::v-deep .colorwhite .el-tag{
  color:white;
}
.colorwhite ::v-deep .el-tag.el-tag--danger{
  color:white;
}
.ob-info-box{
  padding: 20px;
  background: #FFFFFF;
  border-radius: 12px;
  margin-bottom: 20px;
}
.ob-interface-box{
  padding: 20px;
  background: #FFFFFF;
  border-radius: 12px;
  margin-bottom: 20px;
  height: 350px;
}
.ob-interface-title{
  font-weight: bold;
  font-size: 18px;
  color: #333333;
}
::v-deep .el-pagination__jump{
  margin-left:10px;
}
::v-deep .service-drawer .el-drawer__header{
  text-align: center !important;
  color:white !important;
  font-size: 24px !important;
  font-weight: bold;
  height: 60px !important;
  background: #4E5969 !important;
  padding:20px;
  margin-bottom: 0;
}
::v-deep .el-pagination .el-select .el-input{
  width: 80px;
}
</style>
