107 lines
2.8 KiB
TypeScript
107 lines
2.8 KiB
TypeScript
import { prisma } from './prisma'
|
|
import { Action } from '@prisma/client'
|
|
|
|
/**
|
|
* 记录成员历史版本
|
|
*/
|
|
export async function recordMemberHistory(params: {
|
|
memberId: string
|
|
treeId: string
|
|
changedBy: string
|
|
changeType: Action
|
|
oldData?: any
|
|
newData: any
|
|
}) {
|
|
const { memberId, treeId, changedBy, changeType, oldData, newData } = params
|
|
|
|
// 获取当前最大版本号
|
|
const lastHistory = await prisma.memberHistory.findFirst({
|
|
where: { memberId },
|
|
orderBy: { version: 'desc' },
|
|
select: { version: true }
|
|
})
|
|
|
|
const nextVersion = (lastHistory?.version || 0) + 1
|
|
|
|
// 计算变更的字段
|
|
let changes: Record<string, { old: any, new: any }> | undefined = undefined
|
|
|
|
if (changeType === 'UPDATE' && oldData) {
|
|
const tempChanges: Record<string, { old: any, new: any }> = {}
|
|
const fieldsToTrack = [
|
|
'fullName', 'surname', 'givenName', 'gender', 'birthDate', 'deathDate',
|
|
'birthPlace', 'ancestralHome', 'generation', 'bio', 'phone', 'email',
|
|
'address', 'photoIds', 'spouseIds', 'childrenIds', 'motherId', 'fatherId',
|
|
'generationName', 'courtesyName', 'artName', 'posthumousName', 'rank',
|
|
'isFounder', 'isLunarDate', 'burialPlace', 'telephone', 'tags',
|
|
'avatarUrl', 'stories'
|
|
]
|
|
|
|
for (const field of fieldsToTrack) {
|
|
const oldValue = oldData[field]
|
|
const newValue = newData[field]
|
|
|
|
// 比较值是否真的变化了
|
|
const isChanged = JSON.stringify(oldValue) !== JSON.stringify(newValue)
|
|
if (isChanged) {
|
|
tempChanges[field] = { old: oldValue, new: newValue }
|
|
}
|
|
}
|
|
|
|
// 如果没有实际变更,不记录
|
|
if (Object.keys(tempChanges).length === 0) {
|
|
return null
|
|
}
|
|
|
|
changes = tempChanges
|
|
}
|
|
|
|
// 创建历史记录
|
|
const history = await prisma.memberHistory.create({
|
|
data: {
|
|
memberId,
|
|
treeId,
|
|
version: nextVersion,
|
|
snapshot: newData,
|
|
changedBy,
|
|
changeType,
|
|
changes: changes || undefined,
|
|
}
|
|
})
|
|
|
|
return history
|
|
}
|
|
|
|
/**
|
|
* 获取成员的历史版本列表
|
|
*/
|
|
export async function getMemberHistory(memberId: string) {
|
|
return await prisma.memberHistory.findMany({
|
|
where: { memberId },
|
|
orderBy: { version: 'desc' }
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 获取两个版本之间的差异
|
|
*/
|
|
export function compareVersions(oldVersion: any, newVersion: any) {
|
|
const changes: Record<string, { old: any, new: any }> = {}
|
|
|
|
const allFields = new Set([
|
|
...Object.keys(oldVersion.snapshot),
|
|
...Object.keys(newVersion.snapshot)
|
|
])
|
|
|
|
for (const field of allFields) {
|
|
const oldValue = oldVersion.snapshot[field]
|
|
const newValue = newVersion.snapshot[field]
|
|
|
|
if (JSON.stringify(oldValue) !== JSON.stringify(newValue)) {
|
|
changes[field] = { old: oldValue, new: newValue }
|
|
}
|
|
}
|
|
|
|
return changes
|
|
}
|