feat: 更改加载时间
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user