export interface Cache { /** * @update 获取缓存 */ get(key: string): Promise; /** * @update 设置缓存 */ set(key: string, value: any): Promise; /** * @update 删除缓存 */ del(): Promise; /** * 初始化 */ init?: () => Promise; } type User = { avatar?: string; description?: string; id?: string; needChangePassword?: boolean; orgs?: string[]; type?: string; username?: string; }; export type CacheLoginUser = { user?: User; id?: string; accessToken?: string; refreshToken?: string; accessTokenExpiresIn?: number; createdAt?: number; }; type CacheLogin = { loginUsers: CacheLoginUser[]; } & CacheLoginUser; export type CacheStore = { name: string; /** * 缓存数据 * @important 需要先调用init */ cacheData: CacheLogin; /** * 实际操作的cache, 需要先调用init */ cache: T; /** * 设置当前用户 */ setLoginUser(user: CacheLoginUser): Promise; /** * 获取当前用户 */ getCurrentUser(): Promise; /** * 获取当前用户列表 */ getCurrentUserList(): Promise; /** * 获取缓存的refreshToken */ getRefreshToken(): Promise; /** * 获取缓存的accessToken */ getAccessToken(): Promise; /** * 清除当前用户 */ clearCurrentUser(): Promise; /** * 清除所有用户 */ clearAll(): Promise; getValue(): Promise; setValue(value: CacheLogin): Promise; delValue(): Promise; init(): Promise; getIsExpired(): Promise; }; export type LoginCacheStoreOpts = { name: string; cache: T; }; export class LoginCacheStore implements CacheStore { cache: T; name: string; cacheData: CacheLogin; constructor(opts: LoginCacheStoreOpts) { if (!opts.cache) { throw new Error('cache is required'); } // @ts-ignore this.cache = opts.cache; this.cacheData = { loginUsers: [], user: undefined, id: undefined, accessToken: undefined, refreshToken: undefined, }; this.name = opts.name; } /** * 设置缓存 * @param key * @param value * @returns */ async setValue(value: CacheLogin) { await this.cache.set(this.name, value); this.cacheData = value; return value; } /** * 删除缓存 */ async delValue() { await this.cache.del(); this.cacheData = { loginUsers: [], user: undefined, id: undefined, accessToken: undefined, refreshToken: undefined, }; } getValue(): Promise { return this.cache.get(this.name); } /** * 初始化,设置默认值 */ async init() { const defaultData: CacheLogin = { loginUsers: [], user: undefined, id: undefined, accessToken: undefined, refreshToken: undefined, accessTokenExpiresIn: undefined, createdAt: undefined, }; if (this.cache.init) { try { const cacheData = await this.cache.init(); this.cacheData = cacheData || defaultData; } catch (error) { console.log('cacheInit error', error); } } else { this.cacheData = (await this.getValue()) || defaultData; } return this.cacheData; } /** * 设置当前用户 * @param user */ async setLoginUser(user: CacheLoginUser) { const has = this.cacheData.loginUsers.find((u) => u.id === user.id); if (has) { this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id); } this.cacheData.loginUsers.push(user); this.cacheData.user = user.user; this.cacheData.id = user.id; this.cacheData.accessToken = user.accessToken; this.cacheData.refreshToken = user.refreshToken; this.cacheData.accessTokenExpiresIn = user.accessTokenExpiresIn; this.cacheData.createdAt = user.createdAt; await this.setValue(this.cacheData); } getCurrentUser(): Promise { const cacheData = this.cacheData; return Promise.resolve(cacheData.user!); } getCurrentUserList(): Promise { return Promise.resolve(this.cacheData.loginUsers.filter((u) => u?.id)); } getRefreshToken(): Promise { const cacheData = this.cacheData; return Promise.resolve(cacheData.refreshToken || ''); } getAccessToken(): Promise { const cacheData = this.cacheData; return Promise.resolve(cacheData.accessToken || ''); } getIsExpired(): Promise { const cacheData = this.cacheData; if (!cacheData.accessToken) { return Promise.resolve(true); } if (!cacheData.createdAt || !cacheData.accessTokenExpiresIn) { return Promise.resolve(false); } const now = Date.now(); const expiresIn = cacheData.createdAt + cacheData.accessTokenExpiresIn * 1000; return Promise.resolve(now >= expiresIn); } async clearCurrentUser() { const user = await this.getCurrentUser(); const has = this.cacheData.loginUsers.find((u) => u.id === user.id); if (has) { this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id); } this.cacheData.user = undefined; this.cacheData.id = undefined; this.cacheData.accessToken = undefined; this.cacheData.refreshToken = undefined; this.cacheData.accessTokenExpiresIn = undefined; this.cacheData.createdAt = undefined; await this.setValue(this.cacheData); } async clearAll() { this.cacheData.loginUsers = []; this.cacheData.user = undefined; this.cacheData.id = undefined; this.cacheData.accessToken = undefined; this.cacheData.refreshToken = undefined; this.cacheData.accessTokenExpiresIn = undefined; this.cacheData.createdAt = undefined; await this.setValue(this.cacheData); } }