Files
2026-09-09 14:47:29 +08:00

87 lines
2.4 KiB
JavaScript

const SNAPSHOT_FIELDS = [
'cardId',
'chapterId',
'chapterNumber',
'chapterTitle',
'characterName',
'eraLine',
'tableEcho',
'lifeAction',
'familyLine',
'eraObject',
]
function cleanSnapshot(source = {}) {
return SNAPSHOT_FIELDS.reduce((snapshot, field) => {
const value = source[field]
if (field === 'chapterNumber') {
const number = Number(value)
if (number > 0) snapshot[field] = number
} else if (typeof value === 'string' && value.trim()) {
snapshot[field] = value.trim()
}
return snapshot
}, {})
}
function normalizeProgress(progress) {
const next = progress && typeof progress === 'object'
? { ...progress }
: {}
next.collectedMemoryCards = Array.isArray(next.collectedMemoryCards)
? [...new Set(next.collectedMemoryCards.filter((id) => typeof id === 'string' && id))]
: []
next.memoryCardSnapshots = next.memoryCardSnapshots
&& typeof next.memoryCardSnapshots === 'object'
&& !Array.isArray(next.memoryCardSnapshots)
? { ...next.memoryCardSnapshots }
: {}
return next
}
function addMemoryCard(progress, card, chapter = {}) {
const next = normalizeProgress(progress)
if (!card || !card.cardId) return next
const snapshot = cleanSnapshot({
...chapter,
...card,
chapterId: chapter.chapterId || card.chapterId,
chapterNumber: chapter.chapterNumber || card.chapterNumber,
chapterTitle: chapter.chapterTitle || chapter.title || card.chapterTitle,
})
if (!snapshot.cardId) return next
if (!next.collectedMemoryCards.includes(snapshot.cardId)) {
next.collectedMemoryCards.push(snapshot.cardId)
}
next.memoryCardSnapshots[snapshot.cardId] = snapshot
return next
}
function getCollectedMemories(progress, catalog = []) {
const normalized = normalizeProgress(progress)
const catalogById = (Array.isArray(catalog) ? catalog : []).reduce(
(map, card) => {
if (card && card.cardId) map[card.cardId] = cleanSnapshot(card)
return map
},
{},
)
return normalized.collectedMemoryCards
.map((cardId) => {
const fallback = catalogById[cardId] || {}
const saved = cleanSnapshot(normalized.memoryCardSnapshots[cardId] || {})
const card = cleanSnapshot({ ...fallback, ...saved, cardId })
return card.chapterNumber ? card : null
})
.filter(Boolean)
.sort((a, b) => a.chapterNumber - b.chapterNumber)
}
module.exports = {
addMemoryCard,
cleanSnapshot,
getCollectedMemories,
normalizeProgress,
}