refactor(statistics): 重构统计数据获取逻辑

- 使用 Promise.allSettled 替代 Promise.all,提高容错性
- 添加详细的错误处理和日志记录,便于调试
- 优化用户、订单和销售额的计算逻辑,提高数据准确性
- 移除无效的 API 调用和冗余代码,简化代码结构
- 在 dashboard 页面添加刷新统计按钮,实现统计数据的强制刷新功能
This commit is contained in:
2025-09-07 13:18:09 +08:00
parent a0375d8a97
commit 7b6fac7c41
4 changed files with 142 additions and 78 deletions

View File

@@ -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<CmsStatistics> = {
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);
},
/**
* 设置缓存有效期
*/