128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
// frontend/utils/draftStorage.js
|
||
// 草稿 storage 双读单写封装
|
||
// 目的:账号隔离 + 迁移兼容(老无 uid 后缀 key 过渡到 *_${uid} 形式)
|
||
|
||
// 注意:BASE_KEYS 是**实际存储 key 值**(不是 JS 变量名)
|
||
// 'CASTLOVE_FORM_KEY' 是 export const 名,其值是 'castlove_form_data',因此不要写 'CASTLOVE_FORM_KEY'
|
||
const BASE_KEYS = [
|
||
'castlove_form_data',
|
||
'temp_nft_data',
|
||
'generated_images',
|
||
'generation_result_meta',
|
||
'lenticular_studio_payload',
|
||
'craft_selected_image',
|
||
]
|
||
|
||
/**
|
||
* 取当前用户 uid(用于拼 key 后缀)
|
||
* @returns {string|null}
|
||
*/
|
||
export function getCurrentUid() {
|
||
try {
|
||
const userStr = uni.getStorageSync('user')
|
||
if (!userStr) return null
|
||
const user = typeof userStr === 'string' ? JSON.parse(userStr) : userStr
|
||
return user?.uid ? String(user.uid) : null
|
||
} catch (e) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 构造带 uid 后缀的 key(无 uid 时 fallback 到原 key,用于未登录态的兼容性读)
|
||
*/
|
||
function buildKey(baseKey, uid) {
|
||
return uid ? `${baseKey}_${uid}` : baseKey
|
||
}
|
||
|
||
/**
|
||
* 读取草稿(双读:先新后旧,命中后迁移)
|
||
* **返回原始 storage 值**(字符串或对象,取决于写入方式),由调用方决定是否 JSON.parse。
|
||
* 这样保持与原 `uni.getStorageSync(...)` 后接 `JSON.parse(...)` 的调用模式完全兼容。
|
||
* @param {string} baseKey
|
||
* @returns {any|null} 原始值(可能是 JSON 字符串或已 stringify 的对象);null = 未命中
|
||
*/
|
||
export function readDraft(baseKey) {
|
||
const uid = getCurrentUid()
|
||
// 1. 优先读新 key
|
||
const newKey = buildKey(baseKey, uid)
|
||
try {
|
||
const val = uni.getStorageSync(newKey)
|
||
if (val !== '' && val !== null && val !== undefined) return val
|
||
} catch (e) { /* 继续 fallback */ }
|
||
|
||
// 2. fallback 读老 key(仅登录态有意义)
|
||
if (uid) {
|
||
try {
|
||
const oldVal = uni.getStorageSync(baseKey)
|
||
if (oldVal !== '' && oldVal !== null && oldVal !== undefined) {
|
||
// 3. 迁移:写到新 key,删老 key
|
||
try {
|
||
uni.setStorageSync(newKey, oldVal)
|
||
uni.removeStorageSync(baseKey)
|
||
} catch (e) { /* 迁移失败也返回数据 */ }
|
||
return oldVal
|
||
}
|
||
} catch (e) { /* ignore */ }
|
||
}
|
||
return null
|
||
}
|
||
|
||
/**
|
||
* 写入草稿(仅写新 key;未登录态拒绝写)
|
||
* @param {string} baseKey
|
||
* @param {string|object} value 通常是 JSON.stringify 后的字符串
|
||
* @returns {boolean} 是否写入成功
|
||
*/
|
||
export function writeDraft(baseKey, value) {
|
||
const uid = getCurrentUid()
|
||
if (!uid) return false
|
||
const newKey = buildKey(baseKey, uid)
|
||
try {
|
||
uni.setStorageSync(newKey, typeof value === 'string' ? value : JSON.stringify(value))
|
||
return true
|
||
} catch (e) {
|
||
console.warn('[draftStorage] writeDraft failed:', baseKey, e.message)
|
||
return false
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除草稿(仅删当前 uid 的新 key + 老 key)
|
||
*/
|
||
export function removeDraft(baseKey) {
|
||
const uid = getCurrentUid()
|
||
const newKey = buildKey(baseKey, uid)
|
||
try { uni.removeStorageSync(newKey) } catch (e) { /* skip */ }
|
||
try { uni.removeStorageSync(baseKey) } catch (e) { /* skip */ }
|
||
}
|
||
|
||
/**
|
||
* 获取所有 base key(用于 handler 遍历)
|
||
*/
|
||
export function getAllBaseKeys() {
|
||
return BASE_KEYS.slice()
|
||
}
|
||
|
||
/**
|
||
* 列出当前 uid 的所有草稿 key(含老 key 兜底)
|
||
*/
|
||
export function listCurrentDraftKeys() {
|
||
const uid = getCurrentUid()
|
||
try {
|
||
const info = uni.getStorageInfoSync()
|
||
const allKeys = info.keys || []
|
||
if (uid) {
|
||
return allKeys.filter((k) => {
|
||
return BASE_KEYS.some((base) => k === `${base}_${uid}` || k === base)
|
||
})
|
||
} else {
|
||
return allKeys.filter((k) => BASE_KEYS.includes(k))
|
||
}
|
||
} catch (e) {
|
||
return []
|
||
}
|
||
}
|
||
|
||
// safeParse 移除(readDraft 现在返回原值,调用方自行 JSON.parse)
|