This commit is contained in:
2026-04-22 18:54:52 +08:00
commit bc8986e3b2
49 changed files with 20987 additions and 0 deletions

5
stores/index.js Normal file
View File

@@ -0,0 +1,5 @@
const { sessionStore } = require('./modules/session')
module.exports = {
sessionStore
}

128
stores/modules/session.js Normal file
View File

@@ -0,0 +1,128 @@
const { STORAGE_KEYS } = require('../../config/constants')
const EMPTY_STATE = Object.freeze({
isLoggedIn: false,
token: '',
userInfo: null,
permissions: []
})
function cloneSessionState(state) {
return {
isLoggedIn: Boolean(state.token),
token: state.token || '',
userInfo: state.userInfo ? { ...state.userInfo } : null,
permissions: Array.isArray(state.permissions) ? [...state.permissions] : []
}
}
function normalizeSession(payload = {}) {
return cloneSessionState({
...EMPTY_STATE,
...payload
})
}
function createStorageAdapter() {
return {
get(key) {
if (typeof wx === 'undefined' || typeof wx.getStorageSync !== 'function') {
return undefined
}
try {
return wx.getStorageSync(key)
} catch (error) {
return undefined
}
},
set(key, value) {
if (typeof wx === 'undefined' || typeof wx.setStorageSync !== 'function') {
return
}
wx.setStorageSync(key, value)
},
remove(key) {
if (typeof wx === 'undefined' || typeof wx.removeStorageSync !== 'function') {
return
}
wx.removeStorageSync(key)
}
}
}
/**
* @typedef {Object} SessionPayload
* @property {string} token
* @property {Record<string, any>|null} userInfo
* @property {string[]} permissions
*/
/**
* @param {{
* storage?: {get(key: string): any, set(key: string, value: any): void, remove(key: string): void},
* storageKey?: string
* }} [options]
*/
function createSessionStore(options = {}) {
const storage = options.storage || createStorageAdapter()
const storageKey = options.storageKey || STORAGE_KEYS.session
const listeners = new Set()
let state = normalizeSession()
function emitChange() {
const snapshot = cloneSessionState(state)
listeners.forEach(listener => listener(snapshot))
}
return {
getState() {
return cloneSessionState(state)
},
hydrate() {
const cachedSession = storage.get(storageKey)
if (cachedSession) {
state = normalizeSession(cachedSession)
emitChange()
}
return this.getState()
},
/**
* @param {SessionPayload} payload
*/
setSession(payload) {
state = normalizeSession(payload)
storage.set(storageKey, {
token: state.token,
userInfo: state.userInfo,
permissions: state.permissions
})
emitChange()
return this.getState()
},
clearSession() {
state = normalizeSession()
storage.remove(storageKey)
emitChange()
return this.getState()
},
subscribe(listener) {
listeners.add(listener)
return () => {
listeners.delete(listener)
}
}
}
}
const sessionStore = createSessionStore()
module.exports = {
createSessionStore,
sessionStore
}