返回 AiToEarn
publishDetailCache.ts
根目录 / project / aitoearn-web / src / store / publishDetailCache.ts
1 /**
2 * publishDetailCache - 发布详情缓存 Store
3 * 使用 IndexedDB 持久化存储发布记录详情,避免重复 API 调用
4 */
5
6 import type { PublishRecordItem } from '@/api/platforms/publish.types'
7 import { getPublishRecordDetail } from '@/api/platforms/publish.api'
8 import { createPersistStore } from '@/utils/storage/createPersistStore'
9
10 // 缓存过期时间:5 分钟
11 const CACHE_EXPIRY_MS = 5 * 60 * 1000
12
13 export interface IPublishDetailCacheState {
14 // flowId -> PublishRecordItem 的映射
15 cache: Record<string, PublishRecordItem>
16 // flowId -> 最后更新时间戳
17 timestamps: Record<string, number>
18 }
19
20 const initialState: IPublishDetailCacheState = {
21 cache: {},
22 timestamps: {},
23 }
24
25 export const usePublishDetailCache = createPersistStore(
26 { ...initialState },
27 (set, get) => {
28 const methods = {
29 /**
30 * 获取缓存的详情
31 */
32 getDetail(flowId: string): PublishRecordItem | null {
33 const { cache } = get()
34 return cache[flowId] || null
35 },
36
37 /**
38 * 设置缓存
39 */
40 setDetail(flowId: string, data: PublishRecordItem): void {
41 set(state => ({
42 cache: { ...state.cache, [flowId]: data },
43 timestamps: { ...state.timestamps, [flowId]: Date.now() },
44 }))
45 },
46
47 /**
48 * 检查缓存是否过期
49 */
50 isExpired(flowId: string): boolean {
51 const { timestamps } = get()
52 const lastUpdate = timestamps[flowId]
53 if (!lastUpdate)
54 return true
55 return Date.now() - lastUpdate > CACHE_EXPIRY_MS
56 },
57
58 /**
59 * 获取并缓存详情
60 * 如果缓存有效则返回缓存,否则调用 API 获取
61 * @param forceRefresh 是否强制刷新(跳过缓存)
62 */
63 async fetchAndCache(flowId: string, forceRefresh = false): Promise<PublishRecordItem | null> {
64 const { cache, timestamps } = get()
65
66 // 检查缓存是否有效
67 if (!forceRefresh && cache[flowId]) {
68 const lastUpdate = timestamps[flowId]
69 if (lastUpdate && Date.now() - lastUpdate < CACHE_EXPIRY_MS) {
70 return cache[flowId]
71 }
72 }
73
74 // 调用 API 获取
75 try {
76 const response = await getPublishRecordDetail(flowId)
77 if (response && response.data) {
78 methods.setDetail(flowId, response.data)
79 return response.data
80 }
81 return null
82 }
83 catch (error) {
84 console.error('Failed to fetch publish detail:', error)
85 return null
86 }
87 },
88
89 /**
90 * 清除指定 flowId 的缓存
91 */
92 clearCache(flowId: string): void {
93 set((state) => {
94 const newCache = { ...state.cache }
95 const newTimestamps = { ...state.timestamps }
96 delete newCache[flowId]
97 delete newTimestamps[flowId]
98 return { cache: newCache, timestamps: newTimestamps }
99 })
100 },
101
102 /**
103 * 清除所有缓存
104 */
105 clearAllCache(): void {
106 set({ cache: {}, timestamps: {} })
107 },
108 }
109
110 return methods
111 },
112 {
113 name: 'publish-detail-cache',
114 },
115 'indexedDB',
116 )
117
117 lines TYPESCRIPT