feat: 侧边栏记录
parent
b6e5c59a9c
commit
b03f804e35
@ -0,0 +1,18 @@
|
||||
import { ls } from '@/utils/storage'
|
||||
|
||||
export interface AppState {
|
||||
siderCollapsed: boolean
|
||||
}
|
||||
|
||||
export function defaultSetting() {
|
||||
return { siderCollapsed: false }
|
||||
}
|
||||
|
||||
export function getAppSetting() {
|
||||
const localSetting: AppState = ls.get('appSetting')
|
||||
return localSetting ?? defaultSetting()
|
||||
}
|
||||
|
||||
export function setAppSetting(setting: AppState) {
|
||||
ls.set('appSetting', setting)
|
||||
}
|
@ -1,19 +1,16 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
interface AppState {
|
||||
siderCollapsed: boolean
|
||||
}
|
||||
import type { AppState } from './helper'
|
||||
import { getAppSetting, setAppSetting } from './helper'
|
||||
|
||||
export const useAppStore = defineStore('app-store', {
|
||||
state: (): AppState => ({
|
||||
siderCollapsed: false,
|
||||
}),
|
||||
state: (): AppState => getAppSetting(),
|
||||
actions: {
|
||||
setSiderCollapsed(collapsed: boolean) {
|
||||
this.siderCollapsed = collapsed
|
||||
setAppSetting(this.$state)
|
||||
},
|
||||
toggleSiderCollapse() {
|
||||
this.siderCollapsed = !this.siderCollapsed
|
||||
this.setSiderCollapsed(!this.siderCollapsed)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -0,0 +1,18 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
const CryptoSecret = '__CRYPTO_SECRET__'
|
||||
|
||||
export function enCrypto(data: any) {
|
||||
const str = JSON.stringify(data)
|
||||
return CryptoJS.AES.encrypt(str, CryptoSecret).toString()
|
||||
}
|
||||
|
||||
export function deCrypto(data: string) {
|
||||
const bytes = CryptoJS.AES.decrypt(data, CryptoSecret)
|
||||
const str = bytes.toString(CryptoJS.enc.Utf8)
|
||||
|
||||
if (str)
|
||||
return JSON.parse(str)
|
||||
|
||||
return null
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
export function isNumber<T extends number>(value: T | unknown): value is number {
|
||||
return Object.prototype.toString.call(value) === '[object Number]'
|
||||
}
|
||||
|
||||
export function isString<T extends string>(value: T | unknown): value is string {
|
||||
return Object.prototype.toString.call(value) === '[object String]'
|
||||
}
|
||||
|
||||
export function isBoolean<T extends boolean>(value: T | unknown): value is boolean {
|
||||
return Object.prototype.toString.call(value) === '[object Boolean]'
|
||||
}
|
||||
|
||||
export function isNull<T extends null>(value: T | unknown): value is null {
|
||||
return Object.prototype.toString.call(value) === '[object Null]'
|
||||
}
|
||||
|
||||
export function isUndefine<T extends undefined>(value: T | unknown): value is undefined {
|
||||
return Object.prototype.toString.call(value) === '[object Undefined]'
|
||||
}
|
||||
|
||||
export function isObject<T extends object>(value: T | unknown): value is object {
|
||||
return Object.prototype.toString.call(value) === '[object Object]'
|
||||
}
|
||||
|
||||
export function isArray<T extends any[]>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object Array]'
|
||||
}
|
||||
|
||||
export function isFunction<T extends (...args: any[]) => any | void | never>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object Function]'
|
||||
}
|
||||
|
||||
export function isDate<T extends Date>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object Date]'
|
||||
}
|
||||
|
||||
export function isRegExp<T extends RegExp>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object RegExp]'
|
||||
}
|
||||
|
||||
export function isPromise<T extends Promise<any>>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object Promise]'
|
||||
}
|
||||
|
||||
export function isSet<T extends Set<any>>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object Set]'
|
||||
}
|
||||
|
||||
export function isMap<T extends Map<any, any>>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object Map]'
|
||||
}
|
||||
|
||||
export function isFile<T extends File>(value: T | unknown): value is T {
|
||||
return Object.prototype.toString.call(value) === '[object File]'
|
||||
}
|
@ -0,0 +1 @@
|
||||
export * from './local'
|
@ -0,0 +1,59 @@
|
||||
import { deCrypto, enCrypto } from '../crypto'
|
||||
|
||||
interface StorageData<T = any> {
|
||||
value: T
|
||||
expire: number | null
|
||||
}
|
||||
|
||||
function createLocalStorage() {
|
||||
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7 // 7 days
|
||||
|
||||
function set<T = any>(key: string, value: T, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
const storageData: StorageData<T> = {
|
||||
value,
|
||||
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
||||
}
|
||||
const json = enCrypto(storageData)
|
||||
window.localStorage.setItem(key, json)
|
||||
}
|
||||
|
||||
function get(key: string) {
|
||||
const json = window.localStorage.getItem(key)
|
||||
if (json) {
|
||||
let storageData: StorageData | null = null
|
||||
|
||||
try {
|
||||
storageData = deCrypto(json)
|
||||
}
|
||||
catch {
|
||||
// Prevent failure
|
||||
}
|
||||
|
||||
if (storageData) {
|
||||
const { value, expire } = storageData
|
||||
if (expire === null || expire >= Date.now())
|
||||
return value
|
||||
}
|
||||
|
||||
remove(key)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function remove(key: string) {
|
||||
window.localStorage.removeItem(key)
|
||||
}
|
||||
|
||||
function clear() {
|
||||
window.localStorage.clear()
|
||||
}
|
||||
|
||||
return {
|
||||
set,
|
||||
get,
|
||||
remove,
|
||||
clear,
|
||||
}
|
||||
}
|
||||
|
||||
export const ls = createLocalStorage()
|
Loading…
Reference in New Issue