UNPKG

@fast-china/utils

Version:

Fast 工具库.

1 lines 14.8 kB
{"version":3,"file":"index.mjs","sources":["../../../../src/storage/index.ts"],"sourcesContent":["import { computed, reactive } from \"vue\";\nimport { base64Util } from \"../base64\";\nimport { consoleError } from \"../console\";\nimport { FastError } from \"../error\";\n\nconst state = reactive({\n\tprefix: \"fast__\",\n\texpireSuffix: \"__Expire\",\n\tcrypto: false,\n});\n\n/**\n * 本地缓存前缀 Key\n */\nexport const CACHE_PREFIX = computed(() => state.prefix);\n\n/**\n * 本地缓存过期值后缀 Key\n */\nexport const CACHE_EXPIRE_SUFFIX = computed(() => state.expireSuffix);\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/explicit-module-boundary-types\nexport const useStorage = () => {\n\treturn {\n\t\t/**\n\t\t * 设置缓存前缀 Key\n\t\t * @param key\n\t\t */\n\t\tsetPrefix(key: string): void {\n\t\t\tstate.prefix = key;\n\t\t},\n\t\t/**\n\t\t * 缓存过期值后缀 Key\n\t\t * @param key\n\t\t */\n\t\tsetExpireSuffix(key: string): void {\n\t\t\tstate.expireSuffix = key;\n\t\t},\n\t\t/**\n\t\t * 设置缓存是否加密\n\t\t * @description 请在初始化的时候确认,后续不可再修改,否则所有数据都将失效\n\t\t * @param crypto\n\t\t */\n\t\tsetCrypto(crypto: boolean): void {\n\t\t\tstate.crypto = crypto;\n\t\t},\n\t};\n};\n\nconst storage = {\n\tset(key: string, val: any): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tuni.setStorageSync(key, val);\n\t\t} else {\n\t\t\twindow.localStorage.setItem(key, val);\n\t\t}\n\t},\n\tget(key: string): string | any | null {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\treturn uni.getStorageSync(key);\n\t\t} else {\n\t\t\treturn window.localStorage.getItem(key);\n\t\t}\n\t},\n\tremove(key: string): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tuni.removeStorageSync(key);\n\t\t} else {\n\t\t\twindow.localStorage.removeItem(key);\n\t\t}\n\t},\n\tclear(): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tuni.clearStorageSync();\n\t\t} else {\n\t\t\twindow.localStorage.clear();\n\t\t}\n\t},\n\tkeys(): string[] | Storage {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\treturn uni.getStorageInfoSync().keys;\n\t\t} else {\n\t\t\treturn window.localStorage;\n\t\t}\n\t},\n};\n\n/**\n * window.localStorage\n * - 如果是 UniApp 环境则使用的是 uni.xxxStorage\n */\nexport const Local = {\n\t/**\n\t * 设置\n\t * @param key 缓存的Key\n\t * @param val 缓存值\n\t * @param expire 过期时间,单位分钟\n\t * @param encrypt 是否对缓存的数据加密\n\t */\n\tset(key: string, val: any, expire?: number, encrypt?: boolean): void {\n\t\ttry {\n\t\t\tencrypt ??= state.crypto;\n\t\t\t// 判断是否存在缓存过期时间\n\t\t\tif (expire) {\n\t\t\t\tif (isNaN(expire) || expire < 1) {\n\t\t\t\t\tthrow new FastError(\"有效期应为一个有效数值\");\n\t\t\t\t}\n\t\t\t\t// 设置过期时间的缓存\n\t\t\t\tconst expireData = {\n\t\t\t\t\ttime: Date.now(),\n\t\t\t\t\texpire,\n\t\t\t\t};\n\t\t\t\tconst expireJson = JSON.stringify(expireData);\n\t\t\t\tstorage.set(`${state.prefix}${key}${state.expireSuffix}`, expireJson);\n\t\t\t}\n\t\t\tlet valJson = JSON.stringify(val);\n\t\t\tif (encrypt) {\n\t\t\t\tvalJson = base64Util.toBase64(valJson);\n\t\t\t}\n\t\t\tstorage.set(`${state.prefix}${key}`, valJson);\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Local\", error);\n\t\t}\n\t},\n\t/**\n\t * 获取\n\t * @param key 缓存的Key\n\t * @param decrypt 是否对缓存的数据解密\n\t * @returns {T} 传入的对象类型,默认为 string\n\t */\n\tget<T = string>(key: string, decrypt?: boolean): T {\n\t\ttry {\n\t\t\tdecrypt ??= state.crypto;\n\t\t\t// 获取缓存 JSON 字符串\n\t\t\tlet valJson = storage.get(`${state.prefix}${key}`);\n\n\t\t\tif (valJson) {\n\t\t\t\t// 判断是否解密\n\t\t\t\tif (decrypt) {\n\t\t\t\t\tvalJson = base64Util.base64ToStr(valJson);\n\t\t\t\t}\n\t\t\t\t// 尝试获取缓存过期时间的 JSON 字符串\n\t\t\t\tconst expireJson = storage.get(`${state.prefix}${key}${state.expireSuffix}`);\n\t\t\t\t// 判断是否存在过期时间\n\t\t\t\tif (expireJson) {\n\t\t\t\t\tconst expireData = JSON.parse(expireJson);\n\t\t\t\t\tif (Date.now() > expireData.time + expireData.expire * 60 * 1000) {\n\t\t\t\t\t\t// 过期了,删除对应的缓存数据\n\t\t\t\t\t\tstorage.remove(`${state.prefix}${key}`);\n\t\t\t\t\t\tstorage.remove(`${state.prefix}${key}${state.expireSuffix}`);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.parse(valJson) as T;\n\t\t\t\t} catch {\n\t\t\t\t\treturn valJson as T;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Local\", error);\n\t\t}\n\t},\n\t/**\n\t * 移除\n\t * @param key 缓存的Key\n\t */\n\tremove(key: string): void {\n\t\ttry {\n\t\t\tstorage.remove(`${state.prefix}${key}`);\n\t\t\tstorage.remove(`${state.prefix}${key}${state.expireSuffix}`);\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Local\", error);\n\t\t}\n\t},\n\t/**\n\t * 根据前缀移除\n\t * @param key 缓存的Key\n\t */\n\tremoveByPrefix(key: string): void {\n\t\ttry {\n\t\t\tfor (const itemKey in storage.keys) {\n\t\t\t\tif (itemKey.indexOf(`${state.prefix}${key}`) !== -1) {\n\t\t\t\t\tstorage.remove(itemKey);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Local\", error);\n\t\t}\n\t},\n\t/**\n\t * 移除全部\n\t */\n\tclear(): void {\n\t\ttry {\n\t\t\tstorage.clear();\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Local\", error);\n\t\t}\n\t},\n};\n\n/**\n * window.sessionStorage\n * - UniApp 环境下不可用\n */\nexport const Session = {\n\t/**\n\t * 设置会话缓存\n\t * @param key 缓存的Key\n\t * @param val 缓存值\n\t * @param expire 过期时间,单位分钟\n\t * @param encrypt 是否对缓存的数据加密\n\t */\n\tset(key: string, val: any, expire?: number, encrypt?: boolean): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tconsoleError(\"Session\", \"UniApp 环境下 [Session] 不可用。\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tencrypt ??= state.crypto;\n\t\t\t// 判断是否存在缓存过期时间\n\t\t\tif (expire) {\n\t\t\t\tif (isNaN(expire) || expire < 1) {\n\t\t\t\t\tthrow new FastError(\"有效期应为一个有效数值\");\n\t\t\t\t}\n\t\t\t\t// 设置过期时间的缓存\n\t\t\t\tconst expireData = {\n\t\t\t\t\ttime: Date.now(),\n\t\t\t\t\texpire,\n\t\t\t\t};\n\t\t\t\tconst expireJson = JSON.stringify(expireData);\n\t\t\t\twindow.sessionStorage.setItem(`${state.prefix}${key}${state.expireSuffix}`, expireJson);\n\t\t\t}\n\t\t\tlet valJson = JSON.stringify(val);\n\t\t\tif (encrypt) {\n\t\t\t\tvalJson = base64Util.toBase64(valJson);\n\t\t\t}\n\t\t\twindow.sessionStorage.setItem(`${state.prefix}${key}`, valJson);\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Session\", error);\n\t\t}\n\t},\n\t/**\n\t * 获取会话缓存\n\t * @param key 缓存的Key\n\t * @param decrypt 是否对缓存的数据解密\n\t * @returns {T} 传入的对象类型,默认为 string\n\t */\n\tget<T = string>(key: string, decrypt?: boolean): T {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tconsoleError(\"Session\", \"UniApp 环境下 [Session] 不可用。\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tdecrypt ??= state.crypto;\n\t\t\t// 获取缓存 JSON 字符串\n\t\t\tlet valJson = window.sessionStorage.getItem(`${state.prefix}${key}`);\n\t\t\tif (valJson) {\n\t\t\t\t// 判断是否解密\n\t\t\t\tif (decrypt) {\n\t\t\t\t\tvalJson = base64Util.base64ToStr(valJson);\n\t\t\t\t}\n\t\t\t\t// 尝试获取缓存过期时间的 JSON 字符串\n\t\t\t\tconst expireJson = window.sessionStorage.getItem(`${state.prefix}${key}${state.expireSuffix}`);\n\t\t\t\t// 判断是否存在过期时间\n\t\t\t\tif (expireJson) {\n\t\t\t\t\tconst expireData = JSON.parse(expireJson);\n\t\t\t\t\tif (Date.now() > expireData.time + expireData.expire * 60 * 1000) {\n\t\t\t\t\t\t// 过期了,删除对应的缓存数据\n\t\t\t\t\t\twindow.sessionStorage.removeItem(`${state.prefix}${key}`);\n\t\t\t\t\t\twindow.sessionStorage.removeItem(`${state.prefix}${key}${state.expireSuffix}`);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.parse(valJson) as T;\n\t\t\t\t} catch {\n\t\t\t\t\treturn valJson as T;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Session\", error);\n\t\t}\n\t},\n\t/**\n\t * 移除会话缓存\n\t * @param key 缓存的Key\n\t */\n\tremove(key: string): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tconsoleError(\"Session\", \"UniApp 环境下 [Session] 不可用。\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\twindow.sessionStorage.removeItem(`${state.prefix}${key}`);\n\t\t\twindow.sessionStorage.removeItem(`${state.prefix}${key}${state.expireSuffix}`);\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Session\", error);\n\t\t}\n\t},\n\t/**\n\t * 根据前缀移除会话缓存\n\t * @param key 缓存的Key\n\t */\n\tremoveByPrefix(key: string): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tconsoleError(\"Session\", \"UniApp 环境下 [Session] 不可用。\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tfor (const itemKey in window.sessionStorage) {\n\t\t\t\tif (itemKey.indexOf(`${state.prefix}${key}`) !== -1) {\n\t\t\t\t\twindow.sessionStorage.removeItem(itemKey);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Session\", error);\n\t\t}\n\t},\n\t/**\n\t * 移除全部会话缓存\n\t */\n\tclear(): void {\n\t\tif (typeof uni !== \"undefined\") {\n\t\t\tconsoleError(\"Session\", \"UniApp 环境下 [Session] 不可用。\");\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\twindow.sessionStorage.clear();\n\t\t} catch (error) {\n\t\t\tconsoleError(\"Session\", error);\n\t\t}\n\t},\n};\n"],"names":[],"mappings":"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"}