zhangwencui
22 小时以前 d5448e85d7bf092299fe3a5cc32ba3ac5125e7e1
src/views/reportAnalysis/salesStatistics/index.vue
@@ -119,16 +119,16 @@
            <div class="center-metric-unit">家</div>
          </div>
          <div class="center-metric m4">
            <div class="center-metric-label">总销售区</div>
            <div class="center-metric-value">{{ totalSalesAreaCount }}</div>
            <div class="center-metric-unit">区</div>
            <div class="center-metric-label">销售方数</div>
            <div class="center-metric-value">{{ totalSalesAreaCount.toFixed(0) }}</div>
            <div class="center-metric-unit">方</div>
          </div>
        </div>
      </div>
      <!-- 左下:产品类型销量 -->
      <div class="bi-panel bi-panel-bottom-left">
        <PanelHeader :isFullscreen="true"
                     title="销量数据-排名分析" />
                     title="销量数据统计" />
        <div class="panel-tabs">
          <span class="tab-item"
                :class="{ active: blockTimeDimension === 'year' }"
@@ -157,7 +157,7 @@
            <table class="scroll-table">
              <thead>
                <tr>
                  <th>排名</th>
                  <th>序号</th>
                  <th>产品类型</th>
                  <th>年月</th>
                  <th>销售区</th>
@@ -191,15 +191,15 @@
                     title="新增客户趋势分析" />
        <div class="panel-tabs">
          <span class="tab-item"
                :class="{ active: customerTimeDimension === 'year' }"
                @click="handleCustomerTimeDimensionChange('year')">年</span>
                :class="{ active: customerTimeDimension === '年' }"
                @click="handleCustomerTimeDimensionChange('年')">年</span>
          <span class="tab-item"
                :class="{ active: customerTimeDimension === 'month' }"
                @click="handleCustomerTimeDimensionChange('month')">月</span>
                :class="{ active: customerTimeDimension === '月' }"
                @click="handleCustomerTimeDimensionChange('月')">月</span>
        </div>
        <div class="bi-panel-body">
          <div class="chart-unit-row chart-unit-single">
            <span>单位:人</span>
            <span>单位:家</span>
          </div>
          <div ref="productTypeTrendChart"
               class="echart-fill"></div>
@@ -208,7 +208,7 @@
      <!-- 右下:销售区域销量 -->
      <div class="bi-panel bi-panel-bottom-right">
        <PanelHeader :isFullscreen="true"
                     title="销售额数据-排名分析" />
                     title="销售额数据统计" />
        <div class="panel-tabs">
          <span class="tab-item"
                :class="{ active: boardTimeDimension === 'year' }"
@@ -237,7 +237,7 @@
            <table class="scroll-table">
              <thead>
                <tr>
                  <th>排名</th>
                  <th>序号</th>
                  <th>年月</th>
                  <th>销售区</th>
                  <th>销售额(万元)</th>
@@ -280,7 +280,10 @@
  import * as echarts from "echarts";
  import dayjs from "dayjs";
  import PanelHeader from "@/views/reportAnalysis/PSIDataAnalysis/components/PanelHeader.vue";
  import { findAllQualifiedStockOutRecordTypeOptions } from "../../../api/basicData/enum";
  import {
    getDashboardStatistics,
    getCustomerTrends,
  } from "@/api/reportAnalysis/salesStatistics";
  const router = useRouter();
  const screenRoot = ref(null);
@@ -346,7 +349,7 @@
  const boardTimeDimension = ref("year");
  const boardSelectedArea = ref("全部");
  const boardProductType = ref("板材");
  const customerTimeDimension = ref("year");
  const customerTimeDimension = ref("年");
  const salesAreas = [
    "全部",
@@ -650,6 +653,9 @@
  });
  const totalSalesAmount = ref(1299);
  const centerNewCustomerCount = ref(112);
  const completedOrders = ref(1829);
  const totalSalesAreaCount = ref(12);
  const newCustomerCount = computed(() => {
    return filteredData.value.reduce((sum, item) => sum + item.newCustomers, 0);
@@ -667,17 +673,49 @@
    return Object.values(customerMap).reduce((sum, count) => sum + count, 0);
  });
  // 中间中心环指标(用于大屏展示,使用现有统计数据做映射)
  const centerNewCustomerCount = computed(() => 112);
  const completedOrders = computed(() => 1829);
  const salesOrderCount = computed(() => 34);
  const totalSalesAreaCount = computed(() => 12);
  // 客户趋势数据
  const customerTrendsData = ref([]);
  // 变化率计算(模拟)
  const salesVolumeChange = ref("+5.2");
  const salesAmountChange = ref("+7.8");
  const customerCountChange = ref("+3.5");
  const totalCustomerChange = ref("+2.1");
  // 获取中心看板数据
  const fetchDashboardData = async () => {
    try {
      const response = await getDashboardStatistics();
      if (response && response.data) {
        totalSalesAmount.value = response.data.price || 0;
        completedOrders.value = response.data.delivery || 0;
        centerNewCustomerCount.value = response.data.customer || 0;
        totalSalesAreaCount.value = response.data.volume || 0;
      }
    } catch (error) {
      console.error("获取中心看板数据失败:", error);
    }
  };
  // 获取客户趋势数据
  const fetchCustomerTrendsData = async () => {
    try {
      const response = await getCustomerTrends({
        days: customerTimeDimension.value,
      });
      if (response && response.data) {
        // API返回的数据结构如下:
        // {
        //   "dates": ["2026-01-01", "2025-01-01", ...],
        //   "customerTrends": [{"ALLIN": 4, "银川": 3, ...}, ...]
        // }
        customerTrendsData.value = response.data;
        updateCharts();
      }
    } catch (error) {
      console.error("获取客户趋势数据失败:", error);
    }
  };
  // 表格数据
  const tableData = computed(() => {
@@ -785,7 +823,7 @@
        right: "1%",
        textStyle: {
          color: "#B8C8E0",
          fontSize: getResponsiveValue(9),
          fontSize: getResponsiveValue(10),
        },
        itemWidth: getResponsiveValue(10),
        itemHeight: getResponsiveValue(10),
@@ -912,7 +950,7 @@
        right: "1%",
        textStyle: {
          color: "#B8C8E0",
          fontSize: getResponsiveValue(9),
          fontSize: getResponsiveValue(10),
        },
        itemWidth: getResponsiveValue(10),
        itemHeight: getResponsiveValue(10),
@@ -1092,15 +1130,6 @@
  // 新增客户趋势图表配置(按销售区和年月维度)
  const productTypeTrendChartOption = computed(() => {
    // 为每个销售区生成数据
    const salesAreas = [
      "全部",
      "A销售区",
      "B销售区",
      "C销售区",
      "D销售区",
      "E销售区",
    ];
    const colors = [
      "#00A4ED",
      "#34D8F7",
@@ -1108,46 +1137,91 @@
      "#8A6BFF",
      "#C8C447",
      "#FF6B6B",
      "#FF8B6B",
      "#FFCB6B",
      "#8BC34A",
      "#4CAF50",
    ];
    const year = 2024;
    const periodType = customerTimeDimension.value;
    // 生成时间段
    let periods = [];
    if (periodType === "year") {
      // 年度数据:12个月
      for (let month = 1; month <= 12; month++) {
        periods.push(`${year}-${month.toString().padStart(2, "0")}`);
      }
    } else {
      // 月度数据:30天
      const month = 1;
      for (let day = 1; day <= 30; day++) {
        periods.push(
          `${year}-${month.toString().padStart(2, "0")}-${day
            .toString()
            .padStart(2, "0")}`
        );
      }
    }
    let salesAreas = [];
    let series = [];
    // 为每个销售区生成数据
    const series = salesAreas.map((area, index) => {
      const data = periods.map(() => {
        return periodType === "year"
          ? Math.floor(Math.random() * 10) + 2
          : Math.floor(Math.random() * 3) + 1;
    if (
      customerTrendsData.value &&
      customerTrendsData.value.dates &&
      customerTrendsData.value.customerTrends
    ) {
      // 使用API返回的数据
      periods = customerTrendsData.value.dates;
      // 提取所有销售区域
      const areaSet = new Set();
      customerTrendsData.value.customerTrends.forEach(item => {
        Object.keys(item).forEach(key => {
          areaSet.add(key);
        });
      });
      salesAreas = Array.from(areaSet);
      return {
        name: area,
        data: data,
        type: "line",
        smooth: false,
        lineStyle: { width: getResponsiveValue(1), color: colors[index] },
        itemStyle: { color: colors[index] },
      };
    });
      // 为每个销售区域生成数据
      series = salesAreas.map((area, index) => {
        const data = customerTrendsData.value.customerTrends.map((item, i) => {
          return item[area] || 0;
        });
        return {
          name: area,
          data: data,
          type: "line",
          smooth: false,
          lineStyle: {
            width: getResponsiveValue(1),
            color: colors[index % colors.length],
          },
          itemStyle: { color: colors[index % colors.length] },
        };
      });
    } else {
      // 模拟数据
      const year = 2024;
      if (periodType === "year") {
        // 年度数据:12个月
        for (let month = 1; month <= 12; month++) {
          periods.push(`${year}-${month.toString().padStart(2, "0")}`);
        }
      } else {
        // 月度数据:30天
        const month = 1;
        for (let day = 1; day <= 30; day++) {
          periods.push(
            `${year}-${month.toString().padStart(2, "0")}-${day
              .toString()
              .padStart(2, "0")}`
          );
        }
      }
      salesAreas = [];
      series = salesAreas.map((area, index) => {
        const data = periods.map(() => {
          return periodType === "year"
            ? Math.floor(Math.random() * 10) + 2
            : Math.floor(Math.random() * 3) + 1;
        });
        return {
          name: area,
          data: data,
          type: "line",
          smooth: false,
          lineStyle: { width: getResponsiveValue(1), color: colors[index] },
          itemStyle: { color: colors[index] },
        };
      });
    }
    return {
      backgroundColor: "transparent",
@@ -1160,7 +1234,7 @@
        formatter: function (params) {
          let result = params[0].name + "<br/>";
          params.forEach(param => {
            result += `${param.marker}${param.seriesName}: ${param.value} 人<br/>`;
            result += `${param.marker}${param.seriesName}: ${param.value} 家<br/>`;
          });
          return result;
        },
@@ -1171,7 +1245,7 @@
        right: "1%",
        textStyle: {
          color: "#B8C8E0",
          fontSize: getResponsiveValue(9),
          fontSize: getResponsiveValue(10),
        },
        itemWidth: getResponsiveValue(10),
        itemHeight: getResponsiveValue(10),
@@ -1414,7 +1488,7 @@
  // 处理新增客户趋势时间维度切换
  const handleCustomerTimeDimensionChange = dimension => {
    customerTimeDimension.value = dimension;
    updateCharts();
    fetchCustomerTrendsData();
  };
  // 生成砌块销售数据
@@ -1525,7 +1599,7 @@
  };
  // 生命周期
  onMounted(() => {
  onMounted(async () => {
    // 启动顶部栏时间刷新
    if (!timeTicker) {
      timeTicker = setInterval(() => {
@@ -1544,6 +1618,10 @@
    // 生成初始数据
    generateBlockSalesData();
    generateBoardSalesData();
    // 获取数据
    await fetchDashboardData();
    await fetchCustomerTrendsData();
    // 等待DOM更新后初始化图表
    nextTick(() => {
@@ -1880,12 +1958,12 @@
  }
  /* .scroll-table tbody tr:nth-child(odd) {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  background-color: rgba(64, 158, 255, 0.05);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                background-color: rgba(64, 158, 255, 0.05);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                .scroll-table tbody tr:nth-child(even) {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    background-color: rgba(64, 158, 255, 0.1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      } */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              .scroll-table tbody tr:nth-child(even) {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  background-color: rgba(64, 158, 255, 0.1);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    } */
  .oddTableTr {
    background-color: rgba(64, 158, 255, 0.05);
  }