feat: 更改加载时间

This commit is contained in:
王天骄
2026-06-15 17:55:07 +08:00
parent 9b95789595
commit 4c130cee9d
3 changed files with 148 additions and 16 deletions
+62
View File
@@ -48,6 +48,13 @@ export type CaseListPage = {
results: ClinicalCase[]
}
export type CaseListPrefetch = {
source: CaseListSource
query: CaseListQuery
page: CaseListPage
cachedAt: number
}
type QueryValue = string | number | boolean | null | undefined
type ServerCaseListPage = {
@@ -88,6 +95,8 @@ const CASE_LIST_PATHS: Record<CaseListSource, string> = {
}
const TONES: CaseTone[] = ['blue', 'teal', 'pink', 'orange', 'purple', 'green']
const CASE_LIST_PREFETCH_STORAGE_KEY = 'clinical-thinking-prefetched-case-list'
const CASE_LIST_PREFETCH_MAX_AGE_MS = 60 * 1000
export async function fetchCaseList(source: CaseListSource = 'recommended', query: CaseListQuery = {}): Promise<ClinicalCase[]> {
const page = await fetchCaseListPage(source, query)
@@ -102,6 +111,30 @@ export async function fetchCaseListPage(source: CaseListSource = 'recommended',
return page
}
export function savePrefetchedCaseList(payload: CaseListPrefetch) {
uni.setStorageSync(CASE_LIST_PREFETCH_STORAGE_KEY, payload)
}
export function clearPrefetchedCaseList() {
uni.removeStorageSync(CASE_LIST_PREFETCH_STORAGE_KEY)
}
export function takePrefetchedCaseList(source: CaseListSource, query: CaseListQuery): CaseListPage | null {
const value = uni.getStorageSync(CASE_LIST_PREFETCH_STORAGE_KEY)
if (!isCaseListPrefetch(value)) return null
const isFresh = Date.now() - value.cachedAt <= CASE_LIST_PREFETCH_MAX_AGE_MS
if (!isFresh) {
clearPrefetchedCaseList()
return null
}
if (value.source !== source || !isSameCaseListQuery(value.query, query)) return null
clearPrefetchedCaseList()
return value.page
}
export function readStoredClinicalCase() {
const value = uni.getStorageSync('clinical-thinking-selected-case')
if (value && typeof value === 'object') return value as ClinicalCase
@@ -224,6 +257,35 @@ function withQuery(path: string, query: Record<string, QueryValue>) {
return params ? `${path}?${params}` : path
}
function isCaseListPrefetch(value: unknown): value is CaseListPrefetch {
if (!value || typeof value !== 'object') return false
const payload = value as Partial<CaseListPrefetch>
return isCaseListSource(payload.source) &&
typeof payload.query === 'object' &&
payload.query !== null &&
!!payload.page &&
typeof payload.page === 'object' &&
Array.isArray(payload.page.results) &&
typeof payload.cachedAt === 'number'
}
function isCaseListSource(value: unknown): value is CaseListSource {
return value === 'recommended' ||
value === 'specialty' ||
value === 'weak' ||
value === 'teaching' ||
value === 'teacher-task'
}
function isSameCaseListQuery(left: CaseListQuery, right: CaseListQuery) {
const keys: Array<keyof CaseListQuery> = ['search', 'case_type', 'difficulty', 'department', 'page', 'page_size']
return keys.every(key => normalizeQueryValue(left[key]) === normalizeQueryValue(right[key]))
}
function normalizeQueryValue(value: unknown) {
return value === undefined || value === null || value === '' ? '' : String(value)
}
function readErrorMessage(data: unknown, fallback: string) {
if (data && typeof data === 'object') {
const payload = data as Record<string, unknown>