import { invoke } from '../../bridge' const STORAGE_DATA_TYPE = '__TYPE' const STORAGE_KEYS = 'uni-storage-keys' function parseValue (value) { const types = ['object', 'string', 'number', 'boolean', 'undefined'] try { const object = typeof value === 'string' ? JSON.parse(value) : value const type = object.type if (types.indexOf(type) >= 0) { const keys = Object.keys(object) if (keys.length === 2 && 'data' in object) { // eslint-disable-next-line valid-typeof if (typeof object.data === type) { return object.data } // eslint-disable-next-line no-useless-escape if (type === 'object' && /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data)) { // ISO 8601 格式返回 Date return new Date(object.data) } } else if (keys.length === 1) { return '' } } } catch (error) {} } export function setStorage ({ key, data, isSync } = {}, callbackId) { const type = typeof data const value = type === 'string' ? data : JSON.stringify({ type, data: data }) try { if (type === 'string' && parseValue(value) !== undefined) { plus.storage.setItemAsync(key + STORAGE_DATA_TYPE, type, () => {}) } else { plus.storage.removeItemAsync(key + STORAGE_DATA_TYPE, () => {}) } plus.storage.setItemAsync(key, value, function () { invoke(callbackId, { errMsg: 'setStorage:ok' }) }, function (err) { invoke(callbackId, { errMsg: `setStorage:fail ${err.message}` }) }) } catch (error) { invoke(callbackId, { errMsg: `setStorage:fail ${error}` }) } } export function setStorageSync (key, data) { const type = typeof data const value = type === 'string' ? data : JSON.stringify({ type, data: data }) try { if (type === 'string' && parseValue(value) !== undefined) { plus.storage.setItem(key + STORAGE_DATA_TYPE, type) } else { plus.storage.removeItem(key + STORAGE_DATA_TYPE) } plus.storage.setItem(key, value) } catch (error) { } } function parseGetStorage (type, value) { let data = value if (type !== 'string' || (type === 'string' && value === '{"type":"undefined"}')) { try { // 兼容H5和V3初期历史格式 let object = JSON.parse(value) const result = parseValue(object) if (result !== undefined) { data = result } else if (type) { // 兼容App端历史格式 data = object if (typeof object === 'string') { object = JSON.parse(object) const objectType = typeof object if (objectType === 'number' && type === 'date') { data = new Date(object) } else if (objectType === (['null', 'array'].indexOf(type) < 0 ? type : 'object')) { data = object } } } } catch (error) {} } return data } export function getStorage ({ key } = {}, callbackId) { plus.storage.getItemAsync(key, function (res) { plus.storage.getItemAsync(key + STORAGE_DATA_TYPE, function (typeRes) { const typeOrigin = typeRes.data || '' const type = typeOrigin.toLowerCase() invoke(callbackId, { data: parseGetStorage(type, res.data), errMsg: 'getStorage:ok' }) }, function () { const type = '' invoke(callbackId, { data: parseGetStorage(type, res.data), errMsg: 'getStorage:ok' }) }) }, function (err) { invoke(callbackId, { data: '', errMsg: `getStorage:fail ${err.message}` }) }) } export function getStorageSync (key) { const value = plus.storage.getItem(key) const typeOrigin = plus.storage.getItem(key + STORAGE_DATA_TYPE) || '' const type = typeOrigin.toLowerCase() if (typeof value !== 'string') { return '' } return parseGetStorage(type, value) } export function removeStorage ({ key } = {}, callbackId) { // 兼容App端历史格式 plus.storage.removeItemAsync(key + STORAGE_DATA_TYPE, () => {}) plus.storage.removeItemAsync(key, function (res) { invoke(callbackId, { errMsg: 'removeStorage:ok' }) }, function (err) { invoke(callbackId, { errMsg: `removeStorage:fail ${err.message}` }) }) } export function removeStorageSync (key) { plus.storage.removeItem(key + STORAGE_DATA_TYPE) plus.storage.removeItem(key) } export function clearStorage (args, callbackId) { plus.storage.clearAsync(function (res) { invoke(callbackId, { errMsg: 'clearStorage:ok' }) }, function (err) { invoke(callbackId, { errMsg: `clearStorage:fail ${err.message}` }) }) } export function clearStorageSync () { plus.storage.clear() } export function getStorageInfo () { const length = (plus.storage.length || plus.storage.getLength()) || 0 const keys = [] let currentSize = 0 for (let index = 0; index < length; index++) { const key = plus.storage.key(index) if (key !== STORAGE_KEYS && (key.indexOf(STORAGE_DATA_TYPE) < 0 || key.indexOf(STORAGE_DATA_TYPE) + STORAGE_DATA_TYPE.length !== key.length)) { const value = plus.storage.getItem(key) currentSize += key.length + value.length keys.push(key) } } return { keys, currentSize: Math.ceil(currentSize * 2 / 1024), limitSize: Number.MAX_VALUE, errMsg: 'getStorageInfo:ok' } } export function getStorageInfoSync () { const res = getStorageInfo() delete res.errMsg return res }