299 lines
7.2 KiB
Markdown
299 lines
7.2 KiB
Markdown
# examCache 缓存系统使用指南
|
||
|
||
## 概述
|
||
|
||
`examCache` 是一个基于 Pinia 的缓存系统,用于在页面间存储和获取 `examId`、`orgId` 等检查相关信息。该系统支持自动持久化到 localStorage,并具有缓存有效期管理功能。
|
||
|
||
## 特性
|
||
|
||
- ✅ 基于 Pinia 状态管理
|
||
- ✅ 自动持久化到 localStorage
|
||
- ✅ 缓存有效期管理(24小时)
|
||
- ✅ 支持从 URL 参数自动更新缓存
|
||
- ✅ TypeScript 类型支持
|
||
- ✅ 优雅的降级处理
|
||
|
||
## 安装和配置
|
||
|
||
### 1. 确保已安装依赖
|
||
|
||
项目已经安装了必要的依赖:
|
||
- `pinia`
|
||
- `pinia-plugin-persistedstate`
|
||
|
||
### 2. 缓存 Store 已配置
|
||
|
||
缓存 Store 位于 `src/store/modules/examCache.ts`,已在主 Store 中注册。
|
||
|
||
## 基本使用
|
||
|
||
### 1. 设置缓存
|
||
|
||
在页面跳转前设置缓存:
|
||
|
||
```typescript
|
||
import { useExamCacheStore } from '@/store/modules/examCache'
|
||
|
||
const examCacheStore = useExamCacheStore()
|
||
|
||
// 设置缓存
|
||
examCacheStore.setCache('EXAM001', 'ORG001', 'http://example.com/image.jpg')
|
||
```
|
||
|
||
### 2. 获取缓存
|
||
|
||
在目标页面获取缓存:
|
||
|
||
```typescript
|
||
import { useExamCacheStore } from '@/store/modules/examCache'
|
||
|
||
const examCacheStore = useExamCacheStore()
|
||
|
||
// 获取有效的 examId 和 orgId
|
||
const examId = examCacheStore.getValidExamId
|
||
const orgId = examCacheStore.getValidOrgId
|
||
const imgUrl = examCacheStore.imgUrl
|
||
|
||
// 检查缓存是否有效
|
||
if (examCacheStore.isCacheValid) {
|
||
console.log('缓存有效,可以使用')
|
||
} else {
|
||
console.log('缓存已过期或不存在')
|
||
}
|
||
```
|
||
|
||
### 3. 从 URL 参数更新缓存
|
||
|
||
当页面通过 URL 参数传递数据时,可以自动更新缓存:
|
||
|
||
```typescript
|
||
import { useExamCacheStore } from '@/store/modules/examCache'
|
||
import { useRoute } from 'vue-router'
|
||
|
||
const route = useRoute()
|
||
const examCacheStore = useExamCacheStore()
|
||
|
||
// 从路由参数更新缓存
|
||
examCacheStore.updateFromRoute(route.query)
|
||
```
|
||
|
||
### 4. 清除缓存
|
||
|
||
```typescript
|
||
import { useExamCacheStore } from '@/store/modules/examCache'
|
||
|
||
const examCacheStore = useExamCacheStore()
|
||
|
||
// 清除缓存
|
||
examCacheStore.clearCache()
|
||
```
|
||
|
||
## 实际应用场景
|
||
|
||
### 场景1: ECGForm 页面跳转到 translate 页面
|
||
|
||
**在 ECGForm.vue 中:**
|
||
|
||
```typescript
|
||
// 在跳转前设置缓存
|
||
const examCacheStore = useExamCacheStore()
|
||
examCacheStore.setCache(rowinfo.value.examId, rowinfo.value.orgId, imageUrl)
|
||
|
||
// 跳转到 translate 页面
|
||
router.push({
|
||
path: '/translate',
|
||
query: {
|
||
img: imageUrl,
|
||
examId: rowinfo.value.examId,
|
||
orgId: rowinfo.value.orgId
|
||
}
|
||
})
|
||
```
|
||
|
||
**在 translate/index.vue 中:**
|
||
|
||
```typescript
|
||
import { onMounted } from 'vue'
|
||
import { useRoute } from 'vue-router'
|
||
import { useExamCacheStore } from '@/store/modules/examCache'
|
||
|
||
const route = useRoute()
|
||
const examCacheStore = useExamCacheStore()
|
||
|
||
onMounted(() => {
|
||
// 优先从 URL 参数获取,如果没有则从缓存获取
|
||
const examId = (route.query.examId as string) || examCacheStore.getValidExamId
|
||
const orgId = (route.query.orgId as string) || examCacheStore.getValidOrgId
|
||
const imgUrl = (route.query.img as string) || examCacheStore.imgUrl
|
||
|
||
// 如果从 URL 参数获取到数据,更新缓存
|
||
if (route.query.examId || route.query.orgId || route.query.img) {
|
||
examCacheStore.updateFromRoute(route.query)
|
||
}
|
||
})
|
||
```
|
||
|
||
### 场景2: ukey.ts 中使用缓存
|
||
|
||
**修改 ukey.ts 中的 uploadPdf 函数:**
|
||
|
||
```typescript
|
||
import { useExamCacheStore } from '@/store/modules/examCache'
|
||
|
||
const uploadPdf = async (byteArray: number[], filename: string = 'signed.pdf') => {
|
||
try {
|
||
const fileStream = byteArray.join(',')
|
||
|
||
// 获取缓存 store
|
||
const examCacheStore = useExamCacheStore()
|
||
|
||
// 优先从缓存获取 examId 和 orgId,如果没有则从 route.query 获取
|
||
const examId = examCacheStore.getValidExamId || (route.query.examId as string) || ''
|
||
const orgId = examCacheStore.getValidOrgId || (route.query.orgId as string) || ''
|
||
|
||
const formData = new FormData()
|
||
formData.append('examId', examId)
|
||
formData.append('orgId', orgId)
|
||
// ... 其他代码
|
||
} catch (error) {
|
||
console.error('文件上传失败:', error)
|
||
throw error
|
||
}
|
||
}
|
||
```
|
||
|
||
## API 参考
|
||
|
||
### Store 状态
|
||
|
||
```typescript
|
||
interface ExamCacheState {
|
||
examId: string // 检查编号
|
||
orgId: string // 机构编号
|
||
imgUrl: string // 图片地址
|
||
timestamp: number // 缓存时间戳
|
||
}
|
||
```
|
||
|
||
### Getters
|
||
|
||
- `isCacheValid`: 检查缓存是否有效(24小时内)
|
||
- `getValidExamId`: 获取有效的 examId
|
||
- `getValidOrgId`: 获取有效的 orgId
|
||
|
||
### Actions
|
||
|
||
- `setCache(examId: string, orgId: string, imgUrl?: string)`: 设置缓存
|
||
- `clearCache()`: 清除缓存
|
||
- `updateFromRoute(query: any)`: 从路由参数更新缓存
|
||
|
||
## 缓存策略
|
||
|
||
### 优先级顺序
|
||
|
||
1. **URL 参数** - 最高优先级
|
||
2. **缓存数据** - 次优先级
|
||
3. **空值** - 最低优先级
|
||
|
||
### 有效期管理
|
||
|
||
- 缓存有效期为 **24 小时**
|
||
- 过期后需要重新设置
|
||
- 时间戳不持久化,每次页面刷新后重新计算
|
||
|
||
### 持久化配置
|
||
|
||
```typescript
|
||
persist: {
|
||
key: 'exam-cache',
|
||
storage: localStorage,
|
||
paths: ['examId', 'orgId', 'imgUrl'] // 只持久化这些字段
|
||
}
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 在页面跳转前设置缓存
|
||
|
||
```typescript
|
||
// 推荐:在跳转前设置缓存
|
||
const examCacheStore = useExamCacheStore()
|
||
examCacheStore.setCache(examId, orgId, imgUrl)
|
||
router.push({ path: '/target', query: { examId, orgId, img: imgUrl } })
|
||
```
|
||
|
||
### 2. 在目标页面优先使用 URL 参数
|
||
|
||
```typescript
|
||
// 推荐:优先使用 URL 参数,然后回退到缓存
|
||
const examId = (route.query.examId as string) || examCacheStore.getValidExamId
|
||
const orgId = (route.query.orgId as string) || examCacheStore.getValidOrgId
|
||
```
|
||
|
||
### 3. 定期清理过期缓存
|
||
|
||
```typescript
|
||
// 在应用启动时检查缓存有效性
|
||
const examCacheStore = useExamCacheStore()
|
||
if (!examCacheStore.isCacheValid) {
|
||
examCacheStore.clearCache()
|
||
}
|
||
```
|
||
|
||
### 4. 错误处理
|
||
|
||
```typescript
|
||
// 添加错误处理
|
||
try {
|
||
const examId = examCacheStore.getValidExamId
|
||
if (!examId) {
|
||
throw new Error('未找到有效的检查编号')
|
||
}
|
||
// 使用 examId
|
||
} catch (error) {
|
||
console.error('获取缓存失败:', error)
|
||
// 处理错误
|
||
}
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
1. **缓存有效期**: 缓存有效期为 24 小时,过期后需要重新设置
|
||
2. **类型安全**: 使用 TypeScript 确保类型安全
|
||
3. **降级处理**: 始终提供降级方案,避免因缓存问题导致功能不可用
|
||
4. **调试**: 使用浏览器开发者工具查看 localStorage 中的缓存数据
|
||
5. **清理**: 在适当的时候清理过期缓存
|
||
|
||
## 故障排除
|
||
|
||
### 常见问题
|
||
|
||
1. **缓存不生效**
|
||
- 检查 Pinia 是否正确配置
|
||
- 检查 localStorage 是否可用
|
||
- 检查缓存是否已过期
|
||
|
||
2. **类型错误**
|
||
- 确保正确导入类型
|
||
- 检查 TypeScript 配置
|
||
|
||
3. **缓存数据丢失**
|
||
- 检查 localStorage 存储限制
|
||
- 检查浏览器隐私设置
|
||
|
||
### 调试方法
|
||
|
||
```typescript
|
||
// 在浏览器控制台中调试
|
||
const examCacheStore = useExamCacheStore()
|
||
console.log('缓存状态:', {
|
||
examId: examCacheStore.examId,
|
||
orgId: examCacheStore.orgId,
|
||
imgUrl: examCacheStore.imgUrl,
|
||
timestamp: examCacheStore.timestamp,
|
||
isValid: examCacheStore.isCacheValid
|
||
})
|
||
|
||
// 查看 localStorage
|
||
console.log('localStorage:', localStorage.getItem('exam-cache'))
|
||
``` |