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