88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
"use client";
|
||
|
||
/**
|
||
* UserStorage 完整实现(基于 unstorage 抽象)
|
||
*
|
||
* 对齐 Dart 端 `UserStorage`(lib/data/services/storage/user_storage.dart):
|
||
* - 三个独立字段:User 对象 / userId / avatarUrl
|
||
* - `clearUserData()` 批量清空
|
||
*
|
||
* 设计:内部使用 SpAsyncUtil 静态类 + Zod 校验;保持对外 API 完全兼容。
|
||
*
|
||
* 边界:
|
||
* - `getUser` 走 `UserSchema` 解析:缺字段时 Zod `.default()` 自动兜底
|
||
* - `setUser` 走 `UserSchema` 校验写入:保证存储的总是完整 UserData
|
||
* - 单例挂在 class 静态字段,HMR 复用安全
|
||
*/
|
||
|
||
import { UserSchema, type UserData } from "@/data/schemas/user/user";
|
||
import { type Result as ResultT, SpAsyncUtil } from "@/utils";
|
||
import { StorageKeys } from "../storage_keys";
|
||
import type { IUserStorage } from "./iuser_storage";
|
||
|
||
export class UserStorage implements IUserStorage {
|
||
private static _instance: UserStorage | null = null;
|
||
|
||
static getInstance(): UserStorage {
|
||
if (!UserStorage._instance) UserStorage._instance = new UserStorage();
|
||
return UserStorage._instance;
|
||
}
|
||
|
||
/** @internal */
|
||
static _resetForTests(): void {
|
||
UserStorage._instance = null;
|
||
}
|
||
|
||
// ---- user object ----
|
||
|
||
getUser(): Promise<ResultT<UserData | null>> {
|
||
return SpAsyncUtil.getJson(StorageKeys.user, UserSchema);
|
||
}
|
||
|
||
setUser(user: UserData): Promise<ResultT<void>> {
|
||
return SpAsyncUtil.setJson(StorageKeys.user, user, UserSchema);
|
||
}
|
||
|
||
clearUser(): Promise<ResultT<void>> {
|
||
return SpAsyncUtil.remove(StorageKeys.user);
|
||
}
|
||
|
||
// ---- userId ----
|
||
|
||
getUserId(): Promise<ResultT<string | null>> {
|
||
return SpAsyncUtil.getString(StorageKeys.userId);
|
||
}
|
||
|
||
setUserId(id: string): Promise<ResultT<void>> {
|
||
return SpAsyncUtil.setString(StorageKeys.userId, id);
|
||
}
|
||
|
||
clearUserId(): Promise<ResultT<void>> {
|
||
return SpAsyncUtil.remove(StorageKeys.userId);
|
||
}
|
||
|
||
// ---- avatarUrl ----
|
||
|
||
getAvatarUrl(): Promise<ResultT<string | null>> {
|
||
return SpAsyncUtil.getString(StorageKeys.userAvatar);
|
||
}
|
||
|
||
setAvatarUrl(url: string): Promise<ResultT<void>> {
|
||
return SpAsyncUtil.setString(StorageKeys.userAvatar, url);
|
||
}
|
||
|
||
clearAvatarUrl(): Promise<ResultT<void>> {
|
||
return SpAsyncUtil.remove(StorageKeys.userAvatar);
|
||
}
|
||
|
||
// ---- bulk clear ----
|
||
|
||
async clearUserData(): Promise<ResultT<void>> {
|
||
const r1 = await this.clearUser();
|
||
if (!r1.success) return r1;
|
||
const r2 = await this.clearUserId();
|
||
if (!r2.success) return r2;
|
||
return this.clearAvatarUrl();
|
||
}
|
||
}
|