zhangwencui
昨天 6c0dcb777cb0afaa23c49985018afb85353aeb00
销售统计看板接口对接
已添加1个文件
已修改1个文件
151 ■■■■ 文件已修改
src/api/reportAnalysis/salesStatistics.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/salesStatistics/index.vue 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/reportAnalysis/salesStatistics.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
import request from '@/utils/request'
// æ–°å¢žå®¢æˆ·è¶‹åŠ¿åˆ†æž
export function getCustomerTrends(params) {
  return request({
    url: '/home/customerTrends?days=' + params.days,
    method: 'get',
  })
}
// ä¸­å¿ƒçœ‹æ¿
export function getDashboardStatistics() {
  return request({
    url: '/home/total',
    method: 'get'
  })
}
src/views/reportAnalysis/salesStatistics/index.vue
@@ -191,11 +191,11 @@
                     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">
@@ -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.totalSalesAreaCount || 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,12 +1137,56 @@
      "#8A6BFF",
      "#C8C447",
      "#FF6B6B",
      "#FF8B6B",
      "#FFCB6B",
      "#8BC34A",
      "#4CAF50",
    ];
    const year = 2024;
    const periodType = customerTimeDimension.value;
    // ç”Ÿæˆæ—¶é—´æ®µ
    let periods = [];
    let salesAreas = [];
    let series = [];
    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);
      // ä¸ºæ¯ä¸ªé”€å”®åŒºåŸŸç”Ÿæˆæ•°æ®
      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++) {
@@ -1131,8 +1204,8 @@
      }
    }
    // ä¸ºæ¯ä¸ªé”€å”®åŒºç”Ÿæˆæ•°æ®
    const series = salesAreas.map((area, index) => {
      salesAreas = [];
      series = salesAreas.map((area, index) => {
      const data = periods.map(() => {
        return periodType === "year"
          ? Math.floor(Math.random() * 10) + 2
@@ -1148,6 +1221,7 @@
        itemStyle: { color: colors[index] },
      };
    });
    }
    return {
      backgroundColor: "transparent",
@@ -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(() => {
@@ -1545,6 +1619,10 @@
    generateBlockSalesData();
    generateBoardSalesData();
    // èŽ·å–æ•°æ®
    await fetchDashboardData();
    await fetchCustomerTrendsData();
    // ç­‰å¾…DOM更新后初始化图表
    nextTick(() => {
      initCharts();