index.vue 5.05 KB
<script setup lang="ts">
  import { ref } from 'vue';
  import LineChart from './components/LineChart.vue';
  import PieChart from './components/PieChart.vue';
  import Table from './components/Table.vue';
  import Total from './components/Total.vue';
  import TimeLineChart from './components/TimeLineChart.vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { onMounted, reactive } from 'vue';
  import {
    getApplicationRecordClassify,
    getApplicationRecordTop,
    getCustomApplicationRecordClassify,
  } from '/@/api/application/record';
  import { ApplicationRecordTopItemType, TopItemType } from '/@/api/application/model/record';
  import { Empty } from 'ant-design-vue';
  import total1 from '/@/assets/images/total1.png';
  import total2 from '/@/assets/images/total2.png';
  import total3 from '/@/assets/images/total3.png';
  import {
    DateInterval,
    transformClassifyItem,
    transformChartsOptionsByClassifyRecord,
  } from './config';
  import { EChartsOption } from 'echarts';

  const { t } = useI18n();

  interface ChartData {
    lineChartData: Recordable[];
    pieChartData: Recordable[];
    totalData: Recordable[];
    timeLineChartOptions?: Partial<EChartsOption>;
  }

  const chartData = reactive<ChartData>({
    lineChartData: [],
    pieChartData: [],
    totalData: [],
    timeLineChartOptions: {},
  });

  // API统计
  const getTop = async () => {
    const res = (await getApplicationRecordTop()) as any as ApplicationRecordTopItemType;
    chartData.totalData = [
      {
        image: total1,
        title: t('application.record.text.totalText.t1'),
        count: res.count,
      },
      {
        image: total2,
        title: t('application.record.text.totalText.t2'),
        count: res.successCount,
      },
      {
        image: total3,
        title: t('application.record.text.totalText.t3'),
        count: res.failCount,
      },
    ];
    if (Array.isArray(res.tops) && res.tops.length !== 0) {
      chartData.lineChartData = res.tops?.slice(0, 5)?.map((topItem: TopItemType) => ({
        label: topItem.name,
        value: topItem.recordNum,
      }));
      // 取服务端前5个数据
      chartData.pieChartData = res.tops?.slice(0, 5)?.map((topItem: TopItemType) => ({
        name: topItem.name,
        value: topItem.recordProportion,
      }));
      // 其他应用等于取服务端数组长度为5后面所有数值相加
      const otherApplicationCount = res?.tops
        ?.slice(5)
        ?.map((topItem: TopItemType) => ({
          name: topItem.name,
          value: topItem.recordProportion,
        }))
        ?.map((topItem) => topItem.value)
        ?.reduce((sum, curr) => sum + curr);
      // 相加总共
      if (res.tops && res.tops.length > 5) {
        chartData.pieChartData.push({
          name: '其他应用',
          value: otherApplicationCount,
        });
      }
    }
  };

  const timeType = ref('');

  // 接口调用历史
  const getClassify = async (type: DateInterval) => {
    timeType.value = type;
    const res = await getApplicationRecordClassify(type);
    const transformData = transformClassifyItem(res, type);
    chartData.timeLineChartOptions = transformChartsOptionsByClassifyRecord(transformData, type);
  };

  // 自定义调用历史
  const getCustomClassify = async (type: DateInterval, dateValue: Recordable) => {
    const res = await getCustomApplicationRecordClassify(dateValue);
    const transformData = transformClassifyItem(res, type);
    chartData.timeLineChartOptions = transformChartsOptionsByClassifyRecord(transformData, type);
  };

  const handleReceiveTimeRange = (
    value: DateInterval,
    isCustom: boolean,
    dateValue: Recordable
  ) => {
    if (!isCustom) {
      getClassify(value);
    } else {
      getCustomClassify(value, dateValue);
    }
  };

  onMounted(() => {
    getTop();
    getClassify('week'); // 默认查询一周
  });
</script>
<template>
  <div class="flex flex-col m-4 gap-4">
    <div class="flex w-full h-full items-center justify-between gap-4">
      <Total :seriesData="chartData.totalData" />
      <a-card :title="t('application.record.text.pieTitle')" class="h-99" style="width: 40%">
        <PieChart v-if="chartData.pieChartData.length" :seriesData="chartData.pieChartData" />
        <div class="w-full h-72 flex justify-center items-center" v-else>
          <Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" />
        </div>
      </a-card>
      <a-card :title="t('application.record.text.lineTitle')" class="h-99" style="width: 45%">
        <LineChart v-if="chartData.lineChartData.length" :seriesData="chartData.lineChartData" />
        <div class="w-full h-72 flex justify-center items-center" v-else>
          <Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" />
        </div>
      </a-card>
    </div>
    <div>
      <TimeLineChart
        @emitTimeRange="handleReceiveTimeRange"
        :charts-data="(chartData.timeLineChartOptions as EChartsOption)"
        :timeType="timeType"
      />
    </div>
    <div>
      <a-card class="w-full h-140">
        <Table />
      </a-card>
    </div>
  </div>
</template>

<style scoped></style>