- ASP.NET Core 9 Web API backend with JWT auth, EF Core MySQL - Vue 3 + Vite + Pinia + Ant Design Vue frontend - Multi-platform connection management (UOOC & Zhihuishu) - Video brushing with AES-CBC encryption for Zhihuishu - Multi-task queue with cross-platform parallel execution - Task persistence via MySQL database - Progress tracking with inline catalog enrichment - Mobile-responsive UI Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61 lines
1.3 KiB
TypeScript
61 lines
1.3 KiB
TypeScript
const isBrowser = typeof window !== 'undefined';
|
|
|
|
const rootKey = 'uooc-progress';
|
|
|
|
export const storageKeys = {
|
|
accessToken: `${rootKey}:access-token`,
|
|
selectedPlatformId: (userId: number) => `${rootKey}:user:${userId}:selected-platform-id`,
|
|
selectedCourseIds: (userId: number) => `${rootKey}:user:${userId}:selected-course-map`,
|
|
courseOptions: (userId: number) => `${rootKey}:user:${userId}:course-options`,
|
|
progressSnapshots: (userId: number) => `${rootKey}:user:${userId}:progress-snapshots`,
|
|
};
|
|
|
|
export function readText(key: string, fallback = ''): string {
|
|
if (!isBrowser) {
|
|
return fallback;
|
|
}
|
|
|
|
return window.localStorage.getItem(key) ?? fallback;
|
|
}
|
|
|
|
export function writeText(key: string, value: string): void {
|
|
if (!isBrowser) {
|
|
return;
|
|
}
|
|
|
|
window.localStorage.setItem(key, value);
|
|
}
|
|
|
|
export function removeKey(key: string): void {
|
|
if (!isBrowser) {
|
|
return;
|
|
}
|
|
|
|
window.localStorage.removeItem(key);
|
|
}
|
|
|
|
export function readJson<T>(key: string, fallback: T): T {
|
|
if (!isBrowser) {
|
|
return fallback;
|
|
}
|
|
|
|
const raw = window.localStorage.getItem(key);
|
|
if (!raw) {
|
|
return fallback;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(raw) as T;
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
export function writeJson<T>(key: string, value: T): void {
|
|
if (!isBrowser) {
|
|
return;
|
|
}
|
|
|
|
window.localStorage.setItem(key, JSON.stringify(value));
|
|
}
|