225 lines
5.7 KiB
Markdown
225 lines
5.7 KiB
Markdown
# 百色中学统计数据状态管理修复总结
|
||
|
||
## 问题背景
|
||
|
||
在 `src/views/bszx/dashboard/index.vue` 中,`getTotalBszxPrice` 函数存在以下问题:
|
||
|
||
1. **异步函数在计算属性中使用错误**:
|
||
```typescript
|
||
const totalBszxPrice = computed(() => getTotalBszxPrice()); // ❌ 返回 Promise 而不是数值
|
||
```
|
||
|
||
2. **TypeScript 类型错误**:IDE 提示 "Object is possibly undefined"
|
||
|
||
3. **数据不统一**:`totalPriceAmount` 在多个组件中重复计算和传递
|
||
|
||
## 解决方案
|
||
|
||
### 1. 创建专门的百色中学统计数据 Store
|
||
|
||
**文件位置**:`src/store/modules/bszx-statistics.ts`
|
||
|
||
**核心功能**:
|
||
- 统一管理百色中学相关的统计数据
|
||
- 智能缓存机制(5分钟有效期)
|
||
- 自动刷新功能
|
||
- 完整的类型保护和错误处理
|
||
|
||
**主要特性**:
|
||
```typescript
|
||
export const useBszxStatisticsStore = defineStore({
|
||
id: 'bszx-statistics',
|
||
state: (): BszxStatisticsState => ({
|
||
totalPrice: 0,
|
||
loading: false,
|
||
lastUpdateTime: null,
|
||
cacheExpiry: 5 * 60 * 1000, // 5分钟缓存
|
||
refreshTimer: null
|
||
}),
|
||
|
||
getters: {
|
||
bszxTotalPrice: (state): number => safeNumber(state.totalPrice)
|
||
},
|
||
|
||
actions: {
|
||
async fetchBszxStatistics(forceRefresh = false),
|
||
startAutoRefresh(interval = 5 * 60 * 1000),
|
||
stopAutoRefresh()
|
||
}
|
||
});
|
||
```
|
||
|
||
### 2. 修复 Dashboard 页面
|
||
|
||
**修复前**:
|
||
```typescript
|
||
// ❌ 错误的实现
|
||
const totalBszxPrice = computed(() => getTotalBszxPrice());
|
||
const getTotalBszxPrice = async () => {
|
||
return await bszxOrderTotal()
|
||
}
|
||
```
|
||
|
||
**修复后**:
|
||
```typescript
|
||
// ✅ 正确的实现
|
||
const bszxStatisticsStore = useBszxStatisticsStore();
|
||
const totalBszxPrice = computed(() => bszxStatisticsStore.bszxTotalPrice);
|
||
|
||
onMounted(async () => {
|
||
await Promise.all([
|
||
siteStore.fetchSiteInfo(),
|
||
statisticsStore.fetchStatistics(),
|
||
bszxStatisticsStore.fetchBszxStatistics() // 加载百色中学统计数据
|
||
]);
|
||
|
||
statisticsStore.startAutoRefresh();
|
||
bszxStatisticsStore.startAutoRefresh(); // 开始自动刷新
|
||
});
|
||
```
|
||
|
||
### 3. 统一 totalPriceAmount 的使用
|
||
|
||
**涉及的文件**:
|
||
- `src/views/bszx/bszxPayRanking/index.vue`
|
||
- `src/views/bszx/bszxPayRanking/components/search.vue`
|
||
- `src/views/bsyx/bsyxPayRanking/index.vue`
|
||
- `src/views/bsyx/bsyxPayRanking/components/search.vue`
|
||
|
||
**修复策略**:
|
||
1. **Search 组件**:直接从 store 获取数据
|
||
```typescript
|
||
// 使用百色中学统计数据 store
|
||
const bszxStatisticsStore = useBszxStatisticsStore();
|
||
const bszxTotalPrice = computed(() => bszxStatisticsStore.bszxTotalPrice);
|
||
```
|
||
|
||
2. **主组件**:更新 store 数据而不是本地变量
|
||
```typescript
|
||
const datasource: DatasourceFunction = ({where}) => {
|
||
return ranking({...where}).then(data => {
|
||
// 计算总金额并更新到 store
|
||
let totalPrice = 0;
|
||
data.forEach((item) => {
|
||
if (item.totalPrice) {
|
||
totalPrice += item.totalPrice;
|
||
}
|
||
});
|
||
|
||
// 更新 store 中的数据
|
||
bszxStatisticsStore.updateStatistics({ totalPrice });
|
||
|
||
return data;
|
||
});
|
||
};
|
||
```
|
||
|
||
## 核心改进
|
||
|
||
### 1. 类型安全
|
||
- 使用 `safeNumber` 工具函数确保数据类型安全
|
||
- 完整的 TypeScript 类型定义
|
||
- 运行时类型检查
|
||
|
||
### 2. 数据一致性
|
||
- 统一的数据源(store)
|
||
- 避免重复计算和传递
|
||
- 自动同步更新
|
||
|
||
### 3. 性能优化
|
||
- 智能缓存机制(5分钟有效期)
|
||
- 自动刷新功能
|
||
- 避免不必要的 API 调用
|
||
|
||
### 4. 错误处理
|
||
- 完善的错误捕获和处理
|
||
- 优雅的降级策略
|
||
- 详细的错误日志
|
||
|
||
## 使用方式
|
||
|
||
### 在组件中使用
|
||
|
||
```typescript
|
||
import { useBszxStatisticsStore } from '@/store/modules/bszx-statistics';
|
||
|
||
const bszxStatisticsStore = useBszxStatisticsStore();
|
||
|
||
// 获取总金额
|
||
const totalPrice = computed(() => bszxStatisticsStore.bszxTotalPrice);
|
||
|
||
// 初始化数据
|
||
onMounted(async () => {
|
||
await bszxStatisticsStore.fetchBszxStatistics();
|
||
bszxStatisticsStore.startAutoRefresh(); // 开始自动刷新
|
||
});
|
||
|
||
// 清理资源
|
||
onUnmounted(() => {
|
||
bszxStatisticsStore.stopAutoRefresh();
|
||
});
|
||
```
|
||
|
||
### API 方法
|
||
|
||
```typescript
|
||
// 获取统计数据(带缓存)
|
||
await bszxStatisticsStore.fetchBszxStatistics();
|
||
|
||
// 强制刷新
|
||
await bszxStatisticsStore.fetchBszxStatistics(true);
|
||
|
||
// 更新数据
|
||
bszxStatisticsStore.updateStatistics({ totalPrice: 1000 });
|
||
|
||
// 开始自动刷新(默认5分钟间隔)
|
||
bszxStatisticsStore.startAutoRefresh();
|
||
|
||
// 停止自动刷新
|
||
bszxStatisticsStore.stopAutoRefresh();
|
||
|
||
// 清除缓存
|
||
bszxStatisticsStore.clearCache();
|
||
```
|
||
|
||
## 验证结果
|
||
|
||
✅ **TypeScript 编译通过** - 无类型错误
|
||
✅ **生产构建成功** - 无运行时错误
|
||
✅ **数据统一管理** - 避免重复计算
|
||
✅ **类型安全** - 完整的类型保护
|
||
✅ **性能优化** - 智能缓存和自动刷新
|
||
|
||
## 最佳实践
|
||
|
||
1. **生命周期管理**:
|
||
```typescript
|
||
onMounted(() => bszxStatisticsStore.startAutoRefresh());
|
||
onUnmounted(() => bszxStatisticsStore.stopAutoRefresh());
|
||
```
|
||
|
||
2. **错误处理**:
|
||
```typescript
|
||
try {
|
||
await bszxStatisticsStore.fetchBszxStatistics();
|
||
} catch (error) {
|
||
console.error('获取统计数据失败:', error);
|
||
}
|
||
```
|
||
|
||
3. **强制刷新**:
|
||
```typescript
|
||
const handleRefresh = () => bszxStatisticsStore.fetchBszxStatistics(true);
|
||
```
|
||
|
||
## 总结
|
||
|
||
通过创建专门的 `bszx-statistics` store,我们成功解决了:
|
||
|
||
1. **异步函数在计算属性中的错误使用**
|
||
2. **TypeScript 类型安全问题**
|
||
3. **数据重复计算和传递问题**
|
||
4. **缺乏统一的数据管理**
|
||
|
||
这个实现提供了更好的类型安全性、数据一致性和性能优化,为百色中学相关功能提供了可靠的数据支撑。
|