topfans/frontend/utils/handlers/draftHandler.js
2026-07-29 16:03:33 +08:00

163 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// frontend/utils/handlers/draftHandler.js
// 创作草稿 handler分组型按 uid 分组;草稿 key 已通过 M0 改造为 *_${uid} 形式)
import { getCurrentUid, getAllBaseKeys } from '@/utils/draftStorage'
function bytesOf(keys) {
let total = 0
for (const k of keys) {
try { const v = uni.getStorageSync(k); if (v != null) total += JSON.stringify(v).length } catch (e) {}
}
return total
}
function listAllDraftLikeKeys() {
try {
const info = uni.getStorageInfoSync()
const all = info.keys || []
const baseKeys = getAllBaseKeys()
return all.filter((k) => baseKeys.some((base) => k === base || k.startsWith(`${base}_`)))
} catch (e) { return [] }
}
function extractUidFromDraftKey(key, baseKey) {
const prefix = `${baseKey}_`
if (!key.startsWith(prefix)) return null
return key.slice(prefix.length)
}
/**
* Remove the listed storage keys, counting only successful removals.
* Reads each value first to capture accurate freedBytes before deletion.
* @param {string[]} targets
* @returns {{freedBytes: number, keyCount: number}}
*/
function removeAndCount(targets) {
let freed = 0
let count = 0
for (const k of targets) {
try {
let bytes = 0
try { const v = uni.getStorageSync(k); if (v != null) bytes = JSON.stringify(v).length } catch (e) {}
uni.removeStorageSync(k)
freed += bytes
count++
} catch (e) {
console.warn('[draftHandler] remove failed:', k, e.message)
}
}
return { freedBytes: freed, keyCount: count }
}
export default {
id: 'draft',
label: '创作中的草稿',
description: '未提交的创作表单/生成结果',
warning: true,
warningText: '将清空你未提交的创作草稿,是否继续?',
strongWarningText: '将清空该账号的草稿,对方下次登录不会看到。是否继续?',
async computeSize() {
const keys = listAllDraftLikeKeys()
return { sizeBytes: bytesOf(keys), keyCount: keys.length }
},
async computeBreakdown() {
const currentUid = getCurrentUid()
const allKeys = listAllDraftLikeKeys()
const groups = []
const baseKeys = getAllBaseKeys()
const isLoggedIn = !!currentUid
// 按 uid 聚合
const byUid = new Map()
for (const k of allKeys) {
const matchedBase = baseKeys.find((b) => k === b || k.startsWith(`${b}_`))
if (!matchedBase) continue
const uid = extractUidFromDraftKey(k, matchedBase)
const groupUid = uid || '__legacy__'
if (!byUid.has(groupUid)) byUid.set(groupUid, [])
byUid.get(groupUid).push(k)
}
for (const [uid, keys] of byUid) {
const isCurrent = uid === currentUid
const isLegacy = uid === '__legacy__'
let canClean, disabledReason
if (!isLoggedIn) {
canClean = false
disabledReason = 'logged-out'
} else if (isLegacy) {
// 老无 uid 后缀 key 单独分组(不与他人草稿混合)
canClean = keys.length > 0
disabledReason = keys.length === 0 ? 'empty' : null
} else {
canClean = keys.length > 0
disabledReason = keys.length === 0 ? 'empty' : null
}
groups.push({
uid,
displayUid: isLegacy ? '老版本数据' : (isCurrent ? `我的 (${uid})` : `其他用户 (${uid})`),
isCurrent,
sizeBytes: bytesOf(keys),
keyCount: keys.length,
canClean,
disabledReason,
})
}
return groups.sort((a, b) => b.sizeBytes - a.sizeBytes)
},
async cleanGroup({ uid }) {
const currentUid = getCurrentUid()
const allKeys = listAllDraftLikeKeys()
const baseKeys = getAllBaseKeys()
const reserved = new Set()
if (currentUid) {
// 保留当前 uid 的 keys
for (const k of allKeys) {
const base = baseKeys.find((b) => k === b || k.startsWith(`${b}_`))
if (!base) continue
if (extractUidFromDraftKey(k, base) === currentUid) reserved.add(k)
}
}
if (uid === 'self') {
const targets = allKeys.filter((k) => {
const base = baseKeys.find((b) => k === b || k.startsWith(`${b}_`))
if (!base) return false
return extractUidFromDraftKey(k, base) === currentUid
})
return removeAndCount(targets)
} else if (uid === '__legacy__') {
// 单独清老无 uid 后缀 key不删其他用户的
const targets = allKeys.filter((k) => {
const base = baseKeys.find((b) => k === b || k.startsWith(`${b}_`))
if (!base) return false
return k === base
})
return removeAndCount(targets)
} else if (uid === 'others') {
// 其他用户聚合(不含 legacy
const targets = allKeys.filter((k) => {
const base = baseKeys.find((b) => k === b || k.startsWith(`${b}_`))
if (!base) return false
const u = extractUidFromDraftKey(k, base)
return u && u !== currentUid
})
return removeAndCount(targets)
} else {
// 具体其他 uid
const targets = allKeys.filter((k) => {
const base = baseKeys.find((b) => k === b || k.startsWith(`${b}_`))
if (!base) return false
if (reserved.has(k)) return false // defensive
return extractUidFromDraftKey(k, base) === uid
})
return removeAndCount(targets)
}
},
}