SaleTabCard.vue 6.4 KB
<template>
  <a-card :loading="loading" :bordered="false" :body-style="{ padding: '0' }">
    <div class="salesCard">
      <a-tabs default-active-key="1" size="large" :tab-bar-style="{ marginBottom: '24px', paddingLeft: '16px' }">
        <template #rightExtra>
          <div class="extra-wrapper">
            <div class="extra-item">
              <a :class="{ active: activeRange === 'all' }" @click="changeRange('all')">全部</a>
              <a :class="{ active: activeRange === 'today' }" @click="changeRange('today')">今日</a>
              <a :class="{ active: activeRange === 'week' }" @click="changeRange('week')">本周</a>
              <a :class="{ active: activeRange === 'month' }" @click="changeRange('month')">本月</a>
              <a :class="{ active: activeRange === 'year' }" @click="changeRange('year')">本年</a>
            </div>
            <a-range-picker :style="{ width: '256px' }" @change="handleDateChange" :value="dateRange" />
          </div>
        </template>
        <a-tab-pane loading="true" tab="按钮统计数据" key="1">
          <a-row>
            <a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
              <Bar :chartData="barChartData" :option="barOption" height="40vh" :seriesColor="seriesColor" />
            </a-col>
            <a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
              <RankList title="按钮统计榜" :list="buttonStatsData" />
            </a-col>
          </a-row>
        </a-tab-pane>
        <!--        <a-tab-pane tab="销售趋势" key="2">-->
        <!--          <a-row>-->
        <!--            <a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">-->
        <!--              <Bar-->
        <!--                :chartData="barData.reverse()"-->
        <!--                :option="{ title: { text: '', textStyle: { fontWeight: 'lighter' } } }"-->
        <!--                height="40vh"-->
        <!--                :seriesColor="seriesColor"-->
        <!--              />-->
        <!--            </a-col>-->
        <!--            <a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">-->
        <!--              <RankList title="门店销售排行榜" :list="rankList" />-->
        <!--            </a-col>-->
        <!--          </a-row>-->
        <!--        </a-tab-pane>-->
      </a-tabs>
    </div>
  </a-card>
</template>
<script lang="ts" setup>
  import { computed, onMounted, ref } from 'vue';
  import Bar from '/@/components/chart/Bar.vue';
  import RankList from '/@/components/chart/RankList.vue';
  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
  import { getButtonStats } from '@/views/dashboard/Analysis/api';

  // 删除props中的barData和buttonStats
  defineProps({
    loading: {
      type: Boolean,
    },
  });

  const activeRange = ref('all');
  const dateRange = ref<any>(null);
  const buttonStatsData = ref<Array<{ name: string; total: number }>>([]); // 存储按钮统计数据
  const loadingStats = ref(false); // 按钮数据加载状态

  const emit = defineEmits(['range-change']);

  // 获取按钮统计数据
  const fetchButtonStats = async (params?: { rangeType?: string | null; startTime?: string; endTime?: string }) => {
    try {
      loadingStats.value = true;
      const res = await getButtonStats(params);
      buttonStatsData.value = res || [];
    } catch (error) {
      console.error('获取按钮统计数据失败', error);
      buttonStatsData.value = [];
    } finally {
      loadingStats.value = false;
    }
  };

  // 将按钮统计数据转换为柱状图格式
  const barChartData = computed(() => {
    return buttonStatsData.value.map((item) => ({
      name: item.name,
      value: item.total,
    }));
  });

  const barOption = ref({
    tooltip: {
      trigger: 'axis', // 使用 'axis' 而不是 'item'
      formatter: (params: any) => {
        // 检查参数有效性
        if (!params || !params.length) return '';

        const param = params[0];
        // 确保我们访问的是正确的数据结构
        if (param && param.data && param.data.name && param.data.value) {
          return `${param.data.name}<br/>问答次数: ${param.data.value}`;
        }

        // 备选访问方式
        if (param && param.name && param.value) {
          return `${param.name}<br/>问答次数: ${param.value}`;
        }

        return '数据加载中...';
      },
    },
    grid: {
      top: 30,
      bottom: 60, // 增加底部空间以容纳旋转的标签
      left: 30,
      right: 30,
    },
    xAxis: {
      type: 'category',
      axisLabel: {
        interval: 0, // 强制显示所有标签
        formatter: (value: string) => {
          // 截断过长的标签
          return value.length > 6 ? value.substring(0, 6) + '...' : value;
        },
      },
    },
    yAxis: {
      type: 'value',
    },
    series: [
      {
        type: 'bar',
        barWidth: '60%',
      },
    ],
  });

  // 初始化加载数据
  onMounted(() => {
    fetchButtonStats();
  });

  const changeRange = (rangeType: string) => {
    activeRange.value = rangeType;
    dateRange.value = null; // 清除日期选择

    // 根据范围类型构建参数
    const params = rangeType === 'all' ? null : { rangeType };
    fetchButtonStats(params); // 获取对应范围的按钮数据

    if (rangeType === 'all') {
      emit('range-change', { rangeType: null });
    } else {
      emit('range-change', { rangeType });
    }
  };

  const handleDateChange = (dates: any, dateStrings: [string, string]) => {
    if (dateStrings[0] && dateStrings[1]) {
      activeRange.value = 'custom';
      dateRange.value = dates;

      // 构建自定义范围参数
      const params = {
        rangeType: 'custom',
        startTime: dateStrings[0] + ' 00:00:00',
        endTime: dateStrings[1] + ' 23:59:59',
      };

      fetchButtonStats(params); // 获取自定义范围的按钮数据
      emit('range-change', params);
    } else {
      activeRange.value = 'all';
      fetchButtonStats(); // 重置为全部数据
      emit('range-change', { rangeType: null });
    }
  };

  const { getThemeColor } = useRootSetting();
  const seriesColor = computed(() => {
    return getThemeColor.value;
  });
</script>

<style lang="less" scoped>
  .extra-wrapper {
    line-height: 55px;
    padding-right: 24px;

    .extra-item {
      display: inline-block;
      margin-right: 24px;

      a {
        margin-left: 24px;
      }
    }
  }
</style>