Files
mp-vue/src/store/modules/statistics.ts

223 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 统计数据 store
*/
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 { CmsStatistics } from '@/api/cms/cmsStatistics/model';
import { safeNumber, hasValidId, isValidApiResponse } from '@/utils/type-guards';
export interface StatisticsState {
// 统计数据
statistics: CmsStatistics | null;
// 加载状态
loading: boolean;
// 最后更新时间
lastUpdateTime: number | null;
// 缓存有效期(毫秒)- 统计数据缓存时间较短
cacheExpiry: number;
// 自动刷新定时器
refreshTimer: number | null;
}
export const useStatisticsStore = defineStore({
id: 'statistics',
state: (): StatisticsState => ({
statistics: null,
loading: false,
lastUpdateTime: null,
// 默认缓存5分钟
cacheExpiry: 5 * 60 * 1000,
refreshTimer: null
}),
getters: {
/**
* 获取用户总数
*/
userCount: (state): number => {
return safeNumber(state.statistics?.userCount);
},
/**
* 获取订单总数
*/
orderCount: (state): number => {
return safeNumber(state.statistics?.orderCount);
},
/**
* 获取总销售额
*/
totalSales: (state): number => {
return safeNumber(state.statistics?.totalSales);
},
/**
* 获取今日销售额
*/
todaySales: (state): number => {
return safeNumber(state.statistics?.todaySales);
},
/**
* 获取本月销售额
*/
monthSales: (state): number => {
return safeNumber(state.statistics?.monthSales);
},
/**
* 获取今日订单数
*/
todayOrders: (state): number => {
return safeNumber(state.statistics?.todayOrders);
},
/**
* 获取今日新增用户
*/
todayUsers: (state): number => {
return safeNumber(state.statistics?.todayUsers);
},
/**
* 检查缓存是否有效
*/
isCacheValid: (state): boolean => {
if (!state.lastUpdateTime) return false;
const now = Date.now();
return (now - state.lastUpdateTime) < state.cacheExpiry;
}
},
actions: {
/**
* 获取统计数据
* @param forceRefresh 是否强制刷新
*/
async fetchStatistics(forceRefresh = false) {
// 如果缓存有效且不强制刷新,直接返回缓存数据
if (!forceRefresh && this.isCacheValid && this.statistics) {
return this.statistics;
}
this.loading = true;
try {
// 并行获取各种统计数据
const [users, orders, total, statisticsData] = await Promise.all([
pageUsers({}),
pageShopOrder({}),
shopOrderTotal(),
listCmsStatistics({})
]);
let statistics: CmsStatistics;
if (statisticsData && statisticsData.length > 0) {
// 更新现有统计数据
const existingStatistics = statisticsData[0];
// 确保数据存在且有有效的 ID
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),
};
// 异步更新数据库
setTimeout(() => {
updateCmsStatistics(updateData).catch((error) => {
console.error('更新统计数据失败:', error);
});
}, 1000);
// 更新本地数据
statistics = { ...existingStatistics, ...updateData };
} else {
// 如果现有数据无效,使用基础数据
statistics = {
userCount: safeNumber(isValidApiResponse(users) ? users.count : 0),
orderCount: safeNumber(isValidApiResponse(orders) ? orders.count : 0),
totalSales: safeNumber(total),
};
}
} else {
// 创建新的统计数据
statistics = {
userCount: safeNumber(isValidApiResponse(users) ? users.count : 0),
orderCount: safeNumber(isValidApiResponse(orders) ? orders.count : 0),
totalSales: safeNumber(total),
};
// 异步保存到数据库
setTimeout(() => {
addCmsStatistics(statistics).catch((error) => {
console.error('保存统计数据失败:', error);
});
}, 1000);
}
this.statistics = statistics;
this.lastUpdateTime = Date.now();
return statistics;
} catch (error) {
console.error('获取统计数据失败:', error);
throw error;
} finally {
this.loading = false;
}
},
/**
* 更新统计数据
*/
updateStatistics(statistics: Partial<CmsStatistics>) {
if (this.statistics) {
this.statistics = { ...this.statistics, ...statistics };
this.lastUpdateTime = Date.now();
}
},
/**
* 清除缓存
*/
clearCache() {
this.statistics = null;
this.lastUpdateTime = null;
},
/**
* 设置缓存有效期
*/
setCacheExpiry(expiry: number) {
this.cacheExpiry = expiry;
},
/**
* 开始自动刷新
* @param interval 刷新间隔毫秒默认5分钟
*/
startAutoRefresh(interval = 5 * 60 * 1000) {
this.stopAutoRefresh();
this.refreshTimer = window.setInterval(() => {
this.fetchStatistics(true).catch(console.error);
}, interval);
},
/**
* 停止自动刷新
*/
stopAutoRefresh() {
if (this.refreshTimer) {
clearInterval(this.refreshTimer);
this.refreshTimer = null;
}
}
}
});