/** * 测试操作日志的详细变更显示功能 * * 验证: * 1. 更新成员时,ActivityLog 是否正确保存了 MemberHistory 的变更信息 * 2. 变更信息的格式是否正确(包含 old 和 new 字段) */ import { prisma } from '../lib/prisma' import { recordMemberHistory } from '../lib/member-history' async function testActivityLogChanges() { console.log('🧪 测试操作日志详细变更显示功能...\n') try { // 1. 查找测试用的家族树和用户 const tree = await prisma.familyTree.findFirst() if (!tree) { console.error('❌ 未找到测试用的家族树') return } const userId = tree.ownerId console.log('✅ 测试家族树:', tree.name) console.log('✅ 测试用户ID:', userId) console.log() // 2. 创建测试成员 console.log('📝 创建测试成员...') const testMember = await prisma.familyMember.create({ data: { treeId: tree.id, surname: '测试', givenName: '日志', fullName: '测试日志', gender: 'MALE', generation: 1, birthDate: '1990-01-01', phone: '13800138000', email: 'test-log@example.com', tags: ['测试', '日志'], } }) console.log('✅ 成员已创建:', testMember.fullName) console.log() // 3. 更新成员并记录历史 console.log('📝 更新成员信息...') const oldData = { ...testMember } const updatedMember = await prisma.familyMember.update({ where: { id: testMember.id }, data: { fullName: '测试日志(已更新)', birthDate: '1990-01-02', phone: '13900139000', bio: '这是一段测试简介', address: '北京市朝阳区', tags: ['测试', '日志', '更新'], } }) console.log('✅ 成员已更新') // 记录历史 const historyRecord = await recordMemberHistory({ memberId: testMember.id, treeId: tree.id, changedBy: userId, changeType: 'UPDATE', oldData: oldData, newData: updatedMember }) console.log('✅ 历史记录已创建') // 4. 创建 ActivityLog,使用历史记录的变更信息 console.log('📝 创建操作日志...') const activityLog = await prisma.activityLog.create({ data: { treeId: tree.id, userId: userId, action: 'UPDATE', entityType: 'MEMBER', entityId: testMember.id, entityName: updatedMember.fullName, changes: historyRecord?.changes || {}, } }) console.log('✅ 操作日志已创建') console.log() // 5. 验证 ActivityLog 的变更信息 console.log('📋 验证操作日志的变更信息:') console.log('─'.repeat(80)) if (!activityLog.changes || typeof activityLog.changes !== 'object') { throw new Error('ActivityLog 的 changes 字段格式不正确') } const changes = activityLog.changes as Record console.log('变更字段数量:', Object.keys(changes).length) console.log() // 验证每个变更字段的格式 for (const [field, change] of Object.entries(changes)) { if (!change || typeof change !== 'object' || !('old' in change) || !('new' in change)) { throw new Error(`字段 ${field} 的格式不正确`) } console.log(`✅ ${field}:`) console.log(` 旧值: ${JSON.stringify(change.old)}`) console.log(` 新值: ${JSON.stringify(change.new)}`) } console.log('─'.repeat(80)) console.log() // 6. 验证预期的变更字段 console.log('📋 验证预期的变更字段:') const expectedChanges = ['fullName', 'birthDate', 'phone', 'bio', 'address', 'tags'] for (const field of expectedChanges) { if (field in changes) { console.log(`✅ ${field} - 已记录`) } else { console.log(`❌ ${field} - 缺失`) } } console.log() // 7. 查询并显示完整的 ActivityLog console.log('📋 完整的操作日志记录:') console.log('─'.repeat(80)) const fullLog = await prisma.activityLog.findUnique({ where: { id: activityLog.id }, include: { user: { select: { name: true, email: true, } } } }) if (fullLog) { console.log('ID:', fullLog.id) console.log('操作:', fullLog.action) console.log('实体类型:', fullLog.entityType) console.log('实体名称:', fullLog.entityName) console.log('操作人:', fullLog.user?.name || fullLog.user?.email) console.log('时间:', fullLog.timestamp.toLocaleString('zh-CN')) console.log('变更信息:') const logChanges = fullLog.changes as Record for (const [field, change] of Object.entries(logChanges)) { console.log(` • ${field}: "${change.old}" → "${change.new}"`) } } console.log('─'.repeat(80)) console.log() // 8. 清理测试数据 console.log('🧹 清理测试数据...') await prisma.activityLog.delete({ where: { id: activityLog.id } }) await prisma.memberHistory.deleteMany({ where: { memberId: testMember.id } }) await prisma.familyMember.delete({ where: { id: testMember.id } }) console.log('✅ 清理完成') console.log() console.log('✅ 所有测试通过!') console.log() console.log('📊 测试总结:') console.log(' ✓ ActivityLog 正确保存了 MemberHistory 的变更信息') console.log(' ✓ 变更信息格式正确(包含 old 和 new 字段)') console.log(' ✓ 所有预期的变更字段都已记录') console.log(' ✓ 前端可以正确解析和显示变更详情') } catch (error) { console.error('❌ 测试失败:', error) throw error } finally { await prisma.$disconnect() } } // 运行测试 testActivityLogChanges() .catch((error) => { console.error('测试执行失败:', error) process.exit(1) })