ecg-form/docs/examCache-usage.md

299 lines
7.2 KiB
Markdown
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.

# 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'))
```