diff --git a/hangtag-ui/hangtag-ui-admin/src/views/Home/components/TradeTrendCard.vue b/hangtag-ui/hangtag-ui-admin/src/views/Home/components/TradeTrendCard.vue index 2b6a3a7..6c87dbe 100644 --- a/hangtag-ui/hangtag-ui-admin/src/views/Home/components/TradeTrendCard.vue +++ b/hangtag-ui/hangtag-ui-admin/src/views/Home/components/TradeTrendCard.vue @@ -40,42 +40,42 @@ const timeRange = new Map() .set(TimeRangeTypeEnum.DAY30, { name: '30天', series: [ - { name: '订单金额', type: 'bar', smooth: true, data: [] }, - { name: '订单数量', type: 'line', smooth: true, data: [] } + { name: '订单金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '订单数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 } ] }) .set(TimeRangeTypeEnum.WEEK, { name: '周', series: [ - { name: '上周金额', type: 'bar', smooth: true, data: [] }, - { name: '本周金额', type: 'bar', smooth: true, data: [] }, - { name: '上周数量', type: 'line', smooth: true, data: [] }, - { name: '本周数量', type: 'line', smooth: true, data: [] } + { name: '上周金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '本周金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '上周数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 }, + { name: '本周数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 } ] }) .set(TimeRangeTypeEnum.MONTH, { name: '月', series: [ - { name: '上月金额', type: 'bar', smooth: true, data: [] }, - { name: '本月金额', type: 'bar', smooth: true, data: [] }, - { name: '上月数量', type: 'line', smooth: true, data: [] }, - { name: '本月数量', type: 'line', smooth: true, data: [] } + { name: '上月金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '本月金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '上月数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 }, + { name: '本月数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 } ] }) .set(TimeRangeTypeEnum.YEAR, { name: '年', series: [ - { name: '去年金额', type: 'bar', smooth: true, data: [] }, - { name: '今年金额', type: 'bar', smooth: true, data: [] }, - { name: '去年数量', type: 'line', smooth: true, data: [] }, - { name: '今年数量', type: 'line', smooth: true, data: [] } + { name: '去年金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '今年金额', type: 'bar', smooth: true, data: [], yAxisIndex: 0 }, + { name: '去年数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 }, + { name: '今年数量', type: 'line', smooth: true, data: [], yAxisIndex: 1 } ] }) /** 图表配置 */ const eChartOptions = reactive({ grid: { left: 20, - right: '10%', + right: 20, bottom: 20, top: 50, containLabel: true @@ -87,67 +87,61 @@ const eChartOptions = reactive({ series: [], toolbox: { feature: { - // 数据区域缩放 - dataZoom: { - yAxisIndex: false // Y轴不缩放 - }, - brush: { - type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮 - }, - saveAsImage: { show: true, name: '订单量趋势' } // 保存为图片 + dataZoom: { yAxisIndex: false }, + brush: { type: ['lineX', 'clear'] }, + saveAsImage: { show: true, name: '订单量趋势' } } }, tooltip: { trigger: 'axis', - axisPointer: { - type: 'cross' - }, + axisPointer: { type: 'cross' }, padding: [5, 10] }, xAxis: { type: 'category', - inverse: true, - boundaryGap: false, - axisTick: { - show: false - }, + inverse: true, // 倒序展示,数据需同步倒序 + boundaryGap: true, // 修复:柱图需要开启边界间隙,避免贴边错位 + axisTick: { show: false }, data: [], axisLabel: { - formatter: (date: string) => { + formatter: (date: string | number) => { + if (!date) return '' + const dateStr = String(date) switch (timeRangeType.value) { case TimeRangeTypeEnum.DAY30: - return formatDate(date, 'MM-DD') + return formatDate(dateStr, 'MM-DD') case TimeRangeTypeEnum.WEEK: - let weekDay = formatDate(date, 'ddd') - if (weekDay == 'Sun') weekDay = '日' - if (weekDay == 'Mon') weekDay = '一' - if (weekDay == 'Tue') weekDay = '二' - if (weekDay == 'Wed') weekDay = '三' - if (weekDay == 'Thu') weekDay = '四' - if (weekDay == 'Fri') weekDay = '五' - if (weekDay == 'Sat') weekDay = '六' - //return '周' + weekDay - return formatDate(date, 'YYYYMMDD') + return formatDate(dateStr, 'YYYYMMDD') case TimeRangeTypeEnum.MONTH: - return formatDate(date, 'YYYYMM') + return formatDate(dateStr, 'YYYYMM') case TimeRangeTypeEnum.YEAR: - return formatDate(date, 'YYYY') + return formatDate(dateStr, 'YYYY') default: - return date + return dateStr } } } }, - yAxis: { - axisTick: { - show: false + yAxis: [ + { + // 左侧Y轴:金额 + axisTick: { show: false }, + type: 'value', + name: ' ' + }, + { + // 右侧Y轴:数量 + axisTick: { show: false }, + type: 'value', + name: ' ', + position: 'right', // 显示在右侧 + offset: 0 } - } + ] }) as EChartsOption /** 时间范围类型单选按钮选中 */ const handleTimeRangeTypeChange = async () => { - // 设置时间范围 let beginTime: Dayjs let endTime: Dayjs switch (timeRangeType.value) { @@ -165,11 +159,11 @@ const handleTimeRangeTypeChange = async () => { break case TimeRangeTypeEnum.DAY30: default: - beginTime = dayjs().subtract(30, 'day').startOf('d') - endTime = dayjs().endOf('d') + // 修复:startOf('d') → startOf('day'),参数错误导致时间范围计算错误 + beginTime = dayjs().subtract(30, 'day').startOf('day') + endTime = dayjs().endOf('day') break } - // 发送时间范围选中事件 await getOrderCountTrendComparison(beginTime, endTime) } @@ -179,32 +173,70 @@ const getOrderCountTrendComparison = async ( endTime: dayjs.ConfigType ) => { loading.value = true - // 查询数据 - const list = await TradeStatisticsApi.getOrderCountTrendComparison( - timeRangeType.value, - beginTime, - endTime - ) - // 处理数据 - const dates: string[] = [] - const series = [...timeRange.get(timeRangeType.value).series] - for (let item of list) { - dates.push(item.value.date) - if (series.length === 2) { - series[0].data.push(item?.value?.orderAmount || 0) // 当前金额 - series[1].data.push(item?.value?.orderCount || 0) // 当前数量 + try { + const list = await TradeStatisticsApi.getOrderCountTrendComparison( + timeRangeType.value, + beginTime, + endTime + ) + + // 修复1:初始化数据容器,清空残留 + const dates: string[] = [] + // 深拷贝series模板,避免污染原Map数据 + const seriesTemplate = timeRange.get(timeRangeType.value)?.series || [] + const series = JSON.parse(JSON.stringify(seriesTemplate)) + series.forEach(item => item.data = []) // 清空series数据 + + // 修复2:校验数据格式 + 按时间正序排序,避免乱序 + if (Array.isArray(list) && list.length) { + // 先按日期正序排序 + const sortedList = list.sort((a, b) => { + return dayjs(a.value.date).unix() - dayjs(b.value.date).unix() + }) + + // 填充数据 + sortedList.forEach(item => { + if (!item?.value?.date) return // 过滤无效数据 + dates.push(item.value.date) + if (series.length === 2) { + series[0].data.push(item.value.orderAmount || 0) + series[1].data.push(item.value.orderCount || 0) + } else if (series.length === 4) { + series[0].data.push(item.reference?.orderAmount || 0) + series[1].data.push(item.value?.orderAmount || 0) + series[2].data.push(item.reference?.orderCount || 0) + series[3].data.push(item.value?.orderCount || 0) + } + }) + + // 修复3:X轴逆序时,同步倒序数据,确保标签和数值一一对应 + if (eChartOptions.xAxis?.inverse) { + eChartOptions.xAxis.data = [...dates].reverse() + series.forEach(item => { + item.data = [...item.data].reverse() + }) + } else { + eChartOptions.xAxis.data = [...dates] + } + + // 修复4:强制更新系列和图例,确保匹配 + eChartOptions.series = [...series] + eChartOptions.legend.data = series.map(item => item.name) } else { - series[0].data.push(item?.reference?.orderAmount || 0) // 对照金额 - series[1].data.push(item?.value?.orderAmount || 0) // 当前金额 - series[2].data.push(item?.reference?.orderCount || 0) // 对照数量 - series[3].data.push(item?.value?.orderCount || 0) // 当前数量 + // 空数据时清空图表 + eChartOptions.xAxis!.data = [] + eChartOptions.series = [] + eChartOptions.legend.data = [] } + } catch (error) { + console.error('查询订单趋势数据失败:', error) + // 异常时清空数据 + eChartOptions.xAxis!.data = [] + eChartOptions.series = [] + eChartOptions.legend.data = [] + } finally { + loading.value = false } - eChartOptions.xAxis!['data'] = dates - eChartOptions.series = series - // legend在4个切换到2个的时候,还是显示成4个,需要手动配置一下 - eChartOptions.legend['data'] = series.map((item) => item.name) - loading.value = false } /** 初始化 **/