zxl
2025-10-23 495c4a855accf138066df32773dedac144bfd656
商户端统计
2个文件已修改
1个文件已添加
337 ■■■■■ 已修改文件
seller/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/src/api/orderStatistics.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/src/views/statistics/traffic.vue 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/package.json
@@ -15,6 +15,7 @@
    "axios": "^0.21.1",
    "cos-js-sdk-v5": "^1.10.1",
    "dplayer": "^1.27.1",
    "echarts": "^6.0.0",
    "js-cookie": "^2.2.1",
    "node-sass": "^4.14.1",
    "price-color": "^1.0.2",
seller/src/api/orderStatistics.jsx
New file
@@ -0,0 +1,39 @@
import service from "../libs/axios";
export const pvUvData = (param) =>{
  return service({
    url:"/lmk/statistics/pvUv",
    method: "GET",
    params: param
  })
}
export const getOrderCount = (param) =>{
  return service({
    url:"/lmk/statistics/orderCount",
    method: "GET",
    params: param
  })
}
export const getViewAndCompletionRateCount = (param) =>{
  return service({
    url:"/lmk/statistics/viewAndCompletionRateCount",
    method: "GET",
    params: param
  })
}
export const getOrderTimePeriod = (param) =>{
  return service({
    url:"/lmk/statistics/orderTimePeriod",
    method: "GET",
    params: param
  })
}
export const gerProductRepurchase = (param) =>{
  return service({
    url:"/lmk/statistics/productRepurchase",
    method:"GET",
    params:param
  })
}
seller/src/views/statistics/traffic.vue
@@ -31,10 +31,18 @@
    </Card>
    <!--    <Card class="card">-->
    <!--      <div>-->
    <!--        <h4>流量趋势</h4>-->
    <!--        <div id="orderChart"></div>-->
    <!--      </div>-->
    <!--    </Card>-->
    <Card class="card">
      <div>
        <h4>流量趋势</h4>
        <div id="orderChart"></div>
      <div class="chart-wrapper">
        <div class="chart-header">
          <h2>PV/UV 趋势图</h2>
        </div>
        <div ref="chartDom" class="chart-container"></div>
      </div>
    </Card>
@@ -50,6 +58,8 @@
import affixTime from "@/views/lili-components/affix-time";
import * as API_Member from "@/api/member";
import { Chart } from "@antv/g2";
import * as echarts from 'echarts';
import {pvUvData} from "../../api/orderStatistics";
import Cookies from "js-cookie";
export default {
  components: { affixTime },
@@ -108,6 +118,8 @@
      ],
      data: [], // 客户增长报表数据
      chart:null //新pvuv
    };
  },
  watch: {
@@ -115,19 +127,56 @@
      handler(val) {
        this.uvs = 0;
        this.pvs = 0;
        this.init();
        // this.init();
      },
      deep: true,
    },
  },
  methods: {
    // 订单图
    initChart() {
      // 默认已经加载 legend-filter 交互
      /**
       * 将数据分成三组来进行展示
       */
    getDates(param){
      const dates = [];
      const today = new Date();
      let days = 1;
      if(param.year !== null && param.year !== undefined && param.month !== null && param.month !== undefined && param.month !=='' ){
        // 当传入年份和月份时,生成该月份的所有日期
        const year = parseInt(param.year);
        const month = parseInt(param.month);
        // 获取该月的天数
        const daysInMonth = new Date(year, month, 0).getDate();
        // 生成该月所有日期
        for (let day = 1; day <= daysInMonth; day++) {
          const date = new Date(year, month - 1, day); // 月份从0开始,所以要减1
          dates.push(this.formatDate(date, 'MM-dd'));
        }
      }else{
        // 确定天数逻辑不变
        if (param.searchType === "TODAY") {
          days = 1;
        } else if (param.searchType === "YESTERDAY") {
          days = 1;
        } else if (param.searchType === "LAST_SEVEN") {
          days = 7;
        } else if (param.searchType === "LAST_THIRTY") {
          days = 30;
        }
        for (let i = days - 1; i >= 0; i--) {
          const date = new Date(today);
          date.setDate(today.getDate() - i);
          dates.push(this.formatDate(date, 'MM-dd'));
        }
      }
      // 生成日期数组逻辑不变
      return dates;
    },
    // 订单图
    initChart2(){
      this.chart = echarts.init(this.$refs.chartDom)
      this.updateChartData(this.params)//更新 pvuv
    },
    initChart() {
      let uv = [];
      let pv = [];
@@ -177,14 +226,211 @@
          stroke: "#fff",
          lineWidth: 1,
        });
      this.orderChart.area().position("date*pv").color("title").shape("smooth");
      this.orderChart.render();
    },
    //------------更新图表数据pvuv start
    async updateChartData(param) {
      // 生成日期和PV数据
      const { pvData ,uvData} = await this.generateChartData(param)
      // 设置图表配置
      this.chart.setOption(this.getChartOption(this.getDates(param), pvData, uvData))
    },
    // 获取图表配置项
    // 图表配置项(恢复原始颜色)
    getChartOption(dates, pvData, uvData) {
      return {
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(255, 255, 255, 0.9)',
          borderColor: '#eee',
          borderWidth: 1,
          textStyle: { color: '#333' },
          formatter: (params) => {
            const date = params[0].name;
            const pv = params.find(item => item.seriesName === '浏览量(PV)')?.value || 0;
            const uv = params.find(item => item.seriesName === '独立访客(UV)')?.value || 0;
            // 优化:添加换行符转义,避免潜在格式问题(可选,不影响功能)
            return `<div class="font-medium">${date}</div>
                <div>浏览量(PV): <span style="color: #165DFF; font-weight: bold">${pv.toLocaleString()}</span></div>
                <div>独立访客(UV): <span style="color: #00b42a; font-weight: bold">${uv.toLocaleString()}</span></div>`;
          },
        },
        legend: {
          data: ['浏览量(PV)', '独立访客(UV)'],
          top: 0,
          textStyle: { color: '#666' }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
          top: '15%'
        },
        xAxis: {
          type: 'category',
          data: dates,
          axisLine: { lineStyle: { color: '#eee' } },
          axisTick: { show: false },
          axisLabel: { interval: 'auto', rotate: 0, color: '#86909C' },
          splitLine: { show: false }
        },
        yAxis: {
          type: 'value',
          axisLine: { show: false },
          axisTick: { show: false },
          axisLabel: { color: '#86909C', formatter: '{value}' },
          splitLine: { lineStyle: { color: '#f2f3f5' } },
          min: 0
        },
        series: [
          // PV折线(保留原始蓝色系,优化点线衔接)
          {
            name: '浏览量(PV)',
            type: 'line',
            data: pvData,
            symbol: 'circle',
            symbolSize: 6, // 保留原有点大小
            emphasis: {
              symbolSize: 8,
              showSymbol: true
            },
            lineStyle: {
              width: 3, // 保留原有线宽
              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                { offset: 0, color: '#165DFF' }, // 原始PV主色
                { offset: 1, color: '#36CFC9' }  // 原始渐变辅助色
              ]),
              // 关键优化1:线条端点设为圆角,避免“切口”空白
              cap: 'round',
              // 关键优化2:线条拐角设为圆角,避免衔接间隙
              join: 'round',
              // 辅助:控制拐角圆角大小(与线宽匹配,避免溢出)
              miterLimit: 3
            },
            itemStyle: {
              color: '#165DFF', // 原始点颜色
              borderColor: '#fff', // 保留白色边框(增强层次感)
              // 关键优化3:减小边框宽度,避免遮挡线条导致断层
              borderWidth: 0 // 从2调整为1.5
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(22, 93, 255, 0.2)' }, // 原始填充色
                { offset: 1, color: 'rgba(22, 93, 255, 0)' }
              ])
            },
            smooth: true,
            showSymbol: true, // 保留你设置的“默认显示所有点”
          },
          // UV折线(保留原始绿色系,同PV优化逻辑)
          {
            name: '独立访客(UV)',
            type: 'line',
            data: uvData,
            symbol: 'circle',
            symbolSize: 6, // 保留原有点大小
            emphasis: {
              symbolSize: 8,
              showSymbol: true
            },
            lineStyle: {
              width: 3, // 保留原有线宽
              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                { offset: 0, color: '#00b42a' }, // 原始UV主色
                { offset: 1, color: '#72c140' }  // 原始渐变辅助色
              ]),
              // 同PV优化:端点圆角+拐角圆角
              cap: 'round',
              join: 'round',
              miterLimit: 3
            },
            itemStyle: {
              color: '#00b42a', // 原始点颜色
              borderColor: '#fff', // 保留白色边框
              // 同PV优化:减小边框宽度
              borderWidth: 0 // 从2调整为1.5
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: 'rgba(0, 180, 42, 0.2)' }, // 原始填充色
                { offset: 1, color: 'rgba(0, 180, 42, 0)' }
              ])
            },
            smooth: true,
            showSymbol: true, // 保留“默认显示所有点”
          }
        ],
        animation: true,
        animationDuration: 1500,
        animationEasing: 'cubicOut'
      };
    },
    // 生成pv/uv图表数据
    async generateChartData(param) {
      // 1. 声明为async函数
      // 2. 使用await等待接口返回,确保数据获取后再继续
      let pvData = [];
      let uvData = [];
      try {
        const res = await pvUvData(param); // 等待接口响应
        if (res.code === 200) {
          pvData = res.data.pvData;
          uvData = res.data.uvData;
          // 计算pv总和(pvs)
          this.pvs = pvData.reduce((total, current) => {
            // 确保current是数字(避免接口返回非数字格式)
            return total + (Number(current) || 0);
          }, 0);
          // 计算uv总和(uvs)
          this.uvs = uvData.reduce((total, current) => {
            return total + (Number(current) || 0);
          }, 0);
          const dates = this.getDates(param); // 获取当前筛选条件的日期数组
          this.data = dates.map((date, index) => {
            return {
              date: date, // 日期
              pvNum: Number(pvData[index]) || 0, // 对应索引的浏览量(容错为0)
              uvNum: Number(uvData[index]) || 0  // 对应索引的访客数(容错为0)
            };
          });
        }
      } catch (error) {
        console.error("接口调用失败", error);
        // 可根据需求添加错误处理(如默认数据)
        this.pvs = 0;
        this.uvs = 0;
      }
      // 3. 此时pvData和uvData已被接口数据填充,再返回
      return { pvData, uvData };
    },
    formatDate(date) {
      const month = date.getMonth() + 1; // 月份从0开始,需+1
      const day = date.getDate();
      // 补零:如果是个位数,前面加0
      const formattedMonth = month < 10 ? `0${month}` : month;
      const formattedDay = day < 10 ? `0${day}` : day;
      return `${formattedMonth}-${formattedDay}`;
    },
    handleResize() {
      if (this.chart) {
        this.chart.resize()
      }
    },
    //-------------end
    // 订单图
    // 时间筛选
    clickBreadcrumb(item, index) {
      let callback = JSON.parse(JSON.stringify(item));
      this.params = callback;
      console.log(this.params)
      this.updateChartData(this.params)
    },
    // 初始化
    init() {
@@ -211,7 +457,11 @@
    },
  },
  mounted() {
    this.init();
    // this.init();
    this.$nextTick(() => {
      this.initChart2();
    });
    window.addEventListener('resize', this.handleResize)
  },
};
</script>
@@ -248,4 +498,29 @@
.card {
  margin-bottom: 10px;
}
.chart-wrapper {
  width: 100%;
  height: 500px;
  background-color: #fff;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  margin-bottom: 15px;
}
.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}
.chart-header h2 {
  font-size: 18px;
  font-weight: 600;
  color: #1d2129;
}
.chart-container {
  width: 100%;
  height: 400px;
}
</style>