From 7b6fac7c418ba01881aae0bd3d42e4f799c6bbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sun, 7 Sep 2025 13:18:09 +0800 Subject: [PATCH] =?UTF-8?q?refactor(statistics):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E6=95=B0=E6=8D=AE=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用 Promise.allSettled 替代 Promise.all,提高容错性 - 添加详细的错误处理和日志记录,便于调试 - 优化用户、订单和销售额的计算逻辑,提高数据准确性 - 移除无效的 API 调用和冗余代码,简化代码结构 - 在 dashboard 页面添加刷新统计按钮,实现统计数据的强制刷新功能 --- src/api/shop/shopOrder/index.ts | 5 +- src/store/modules/statistics.ts | 136 +++++++++++++++++++++++++---- src/views/cms/cmsWebsite/index.vue | 57 +----------- src/views/shop/dashboard/index.vue | 22 ++++- 4 files changed, 142 insertions(+), 78 deletions(-) diff --git a/src/api/shop/shopOrder/index.ts b/src/api/shop/shopOrder/index.ts index e05f8cd..d0107ac 100644 --- a/src/api/shop/shopOrder/index.ts +++ b/src/api/shop/shopOrder/index.ts @@ -129,8 +129,9 @@ export async function shopOrderTotal(params?: ShopOrderParam) { params } ); - if (res.data.code === 0 && res.data.data) { - return res.data.data; + if (res.data.code === 0) { + // 即使没有数据也返回空数组,而不是抛出错误 + return res.data.data || []; } return Promise.reject(new Error(res.data.message)); } diff --git a/src/store/modules/statistics.ts b/src/store/modules/statistics.ts index 4ba3856..c0aff55 100644 --- a/src/store/modules/statistics.ts +++ b/src/store/modules/statistics.ts @@ -4,9 +4,13 @@ import { defineStore } from 'pinia'; import { pageUsers } from '@/api/system/user'; import { pageShopOrder, shopOrderTotal } from '@/api/shop/shopOrder'; -import { addCmsStatistics, listCmsStatistics, updateCmsStatistics } from '@/api/cms/cmsStatistics'; +import { + addCmsStatistics, + listCmsStatistics, + updateCmsStatistics +} from '@/api/cms/cmsStatistics'; import { CmsStatistics } from '@/api/cms/cmsStatistics/model'; -import { safeNumber, hasValidId, isValidApiResponse } from '@/utils/type-guards'; +import { safeNumber, hasValidId } from '@/utils/type-guards'; export interface StatisticsState { // 统计数据 @@ -88,7 +92,7 @@ export const useStatisticsStore = defineStore({ isCacheValid: (state): boolean => { if (!state.lastUpdateTime) return false; const now = Date.now(); - return (now - state.lastUpdateTime) < state.cacheExpiry; + return now - state.lastUpdateTime < state.cacheExpiry; } }, @@ -105,16 +109,101 @@ export const useStatisticsStore = defineStore({ this.loading = true; try { - // 并行获取各种统计数据 - const [users, orders, total, statisticsData] = await Promise.all([ - pageUsers({}), - pageShopOrder({}), - shopOrderTotal(), - listCmsStatistics({}) - ]); + // 并行获取各种统计数据,使用Promise.allSettled确保部分失败不影响整体 + const [usersResult, ordersResult, totalResult, statisticsResult] = + await Promise.allSettled([ + pageUsers({}), + pageShopOrder({}), + shopOrderTotal(), + listCmsStatistics({}) + ]); + + // 安全提取结果 + const users = + usersResult.status === 'fulfilled' ? usersResult.value : null; + const orders = + ordersResult.status === 'fulfilled' ? ordersResult.value : null; + const total = + totalResult.status === 'fulfilled' ? totalResult.value : null; + const statisticsData = + statisticsResult.status === 'fulfilled' + ? statisticsResult.value + : null; + + // 记录失败的API调用 + if (usersResult.status === 'rejected') { + console.error('❌ 用户API调用失败:', usersResult.reason); + } + if (ordersResult.status === 'rejected') { + console.error('❌ 订单API调用失败:', ordersResult.reason); + } + if (totalResult.status === 'rejected') { + console.error('❌ 订单总额API调用失败:', totalResult.reason); + } + if (statisticsResult.status === 'rejected') { + console.error('❌ 统计数据API调用失败:', statisticsResult.reason); + } + + // 添加调试日志 + console.log('🔍 统计数据获取结果:', { + users: users, + orders: orders, + total: total, + statisticsData: statisticsData + }); let statistics: CmsStatistics; + // 安全获取用户数量,添加更详细的验证 + const userCount = (() => { + if (!users) { + console.warn('⚠️ 用户API返回空数据'); + return 0; + } + if (typeof users === 'object' && 'count' in users) { + const count = users.count; + console.log('✅ 用户数量:', count); + return safeNumber(count); + } + console.warn('⚠️ 用户API返回数据格式不正确:', users); + return 0; + })(); + + // 安全获取订单数量 + const orderCount = (() => { + if (!orders) { + console.warn('⚠️ 订单API返回空数据'); + return 0; + } + if (typeof orders === 'object' && 'count' in orders) { + const count = orders.count; + console.log('✅ 订单数量:', count); + return safeNumber(count); + } + console.warn('⚠️ 订单API返回数据格式不正确:', orders); + return 0; + })(); + + // 安全获取总销售额,处理数组情况 + const totalSales = (() => { + if (!total) { + console.warn('⚠️ 订单总额API返回空数据'); + return 0; + } + if (Array.isArray(total)) { + // 如果是数组,计算总金额 + const sum = total.reduce((acc, order) => { + const amount = order.payPrice || order.totalPrice || 0; + return acc + safeNumber(amount); + }, 0); + console.log('✅ 总销售额(数组计算):', sum); + return sum; + } + const amount = safeNumber(total); + console.log('✅ 总销售额(直接值):', amount); + return amount; + })(); + if (statisticsData && statisticsData.length > 0) { // 更新现有统计数据 const existingStatistics = statisticsData[0]; @@ -123,9 +212,9 @@ export const useStatisticsStore = defineStore({ if (hasValidId(existingStatistics)) { const updateData: Partial = { id: existingStatistics.id, - userCount: safeNumber(isValidApiResponse(users) ? users.count : 0), - orderCount: safeNumber(isValidApiResponse(orders) ? orders.count : 0), - totalSales: safeNumber(total), + userCount: userCount, + orderCount: orderCount, + totalSales: totalSales }; // 异步更新数据库 @@ -140,17 +229,17 @@ export const useStatisticsStore = defineStore({ } else { // 如果现有数据无效,使用基础数据 statistics = { - userCount: safeNumber(isValidApiResponse(users) ? users.count : 0), - orderCount: safeNumber(isValidApiResponse(orders) ? orders.count : 0), - totalSales: safeNumber(total), + userCount: userCount, + orderCount: orderCount, + totalSales: totalSales }; } } else { // 创建新的统计数据 statistics = { - userCount: safeNumber(isValidApiResponse(users) ? users.count : 0), - orderCount: safeNumber(isValidApiResponse(orders) ? orders.count : 0), - totalSales: safeNumber(total), + userCount: userCount, + orderCount: orderCount, + totalSales: totalSales }; // 异步保存到数据库 @@ -191,6 +280,15 @@ export const useStatisticsStore = defineStore({ this.lastUpdateTime = null; }, + /** + * 强制刷新统计数据 + */ + async forceRefresh() { + console.log('🔄 强制刷新统计数据...'); + this.clearCache(); + return await this.fetchStatistics(true); + }, + /** * 设置缓存有效期 */ diff --git a/src/views/cms/cmsWebsite/index.vue b/src/views/cms/cmsWebsite/index.vue index 2ce2e06..addd52a 100644 --- a/src/views/cms/cmsWebsite/index.vue +++ b/src/views/cms/cmsWebsite/index.vue @@ -114,9 +114,9 @@