fix: 修复刘伟/江澄同名串档——删除外部交流刘伟账号,江澄账号绑定品类六部M1档案并升DEPT_ADMIN

This commit is contained in:
chenpei 2026-08-14 18:48:15 +08:00
parent b2784ac279
commit 9d23656669

View File

@ -0,0 +1,112 @@
/**
* 处置:刘伟/江澄账号串档修复(事务,可回滚)
*
* 背景:花名册"刘伟(花名江澄,工号JS19071901,M1,品类六部运营主管)"的档案
* 被素材库"刘伟"账号(外部交流,钉钉ID 36135934671751)错误绑定;
* 素材库"江澄"账号(品类六部正主,钉钉ID 1617610635671751)反而无绑定。
*
* 处置(用户确认):
* 1. 硬删除素材库"刘伟"账号(无素材/无日志,影响已评估为零)
* 2. 档案 6eb6fd4e(M1/JS19071901)部门修正为品类六部
* 3. 建立"江澄"账号 ↔ 该档案的活跃绑定(MANUAL_VERIFIED)
* 4. "江澄"账号角色升为 DEPT_ADMIN(M1 负责人)
*
* 用法:npx tsx --env-file=.env scripts/fix-liuwei-jiangcheng.ts --apply
* 不加 --apply 为预演
*/
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const APPLY = process.argv.includes('--apply')
const LIUWEI_USER_ID = 'f8fe5ab5-29ab-44c9-833d-7a7247f39d7d'
const JIANGCHENG_USER_ID = 'da2f7fc3-8453-4ae4-a61c-7fc060ed7a49'
const PROFILE_ID = '6eb6fd4e-6cdd-43ca-8697-7f48a116171a'
const CATEGORY6_DEPT_PATH = '江苏简尚品牌管理有限公司/运营中心A/事业三部/品类六部'
;(async () => {
console.log(APPLY ? '=== 实际执行模式 ===' : '=== 预演模式(不写入)===')
// 预检:确认关键对象存在
const liuwei = await prisma.user.findUnique({ where: { id: LIUWEI_USER_ID } })
const jiangcheng = await prisma.user.findUnique({ where: { id: JIANGCHENG_USER_ID } })
const profile = await prisma.performanceSurveyEmployeeProfile.findUnique({ where: { id: PROFILE_ID } })
if (!liuwei) throw new Error('刘伟账号不存在')
if (!jiangcheng) throw new Error('江澄账号不存在')
if (!profile) throw new Error('品类六部档案不存在')
console.log(`刘伟账号: ${liuwei.username} (${liuwei.dingtalkUserId})`)
console.log(`江澄账号: ${jiangcheng.username} (${jiangcheng.dingtalkUserId})`)
console.log(`档案: ${profile.displayName} | 当前部门: ${profile.departmentPath} | 等级: ${profile.positionLevel}(${profile.levelType})`)
console.log('')
// 预检:刘伟账号必须无素材/无日志
const mats = await prisma.material.count({ where: { userId: LIUWEI_USER_ID } })
const logs = await prisma.materialDownloadLog.count({ where: { userId: LIUWEI_USER_ID } }).catch(() => 0)
if (mats > 0 || logs > 0) {
throw new Error(`刘伟账号还有数据(素材${mats}/日志${logs}),拒绝删除,请人工检查`)
}
console.log(`安全预检通过:刘伟账号素材=${mats} 日志=${logs}`)
if (!APPLY) {
console.log('\n[预演] 将执行:')
console.log(' 1. 删除刘伟账号(含其绑定)')
console.log(` 2. 档案 ${PROFILE_ID} 部门 → ${CATEGORY6_DEPT_PATH}`)
console.log(' 3. 江澄账号 ↔ 档案 建立 ACTIVE 绑定(MANUAL_VERIFIED)')
console.log(' 4. 江澄账号角色 → DEPT_ADMIN')
console.log('\n(未写入任何数据,加 --apply 执行)')
await prisma.$disconnect()
return
}
await prisma.$transaction(async (tx) => {
// 1. 删除刘伟账号(级联删绑定;素材/日志已确认为 0)
await tx.userEmployeeBinding.deleteMany({ where: { userId: LIUWEI_USER_ID } })
await tx.user.delete({ where: { id: LIUWEI_USER_ID } })
console.log('✓ 已删除刘伟账号及其绑定')
// 2. 档案部门修正为品类六部
await tx.performanceSurveyEmployeeProfile.update({
where: { id: PROFILE_ID },
data: {
departmentPath: CATEGORY6_DEPT_PATH,
departmentName: '品类六部',
},
})
console.log(`✓ 档案部门已修正: ${CATEGORY6_DEPT_PATH}`)
// 3. 江澄账号 ↔ 档案 绑定
await tx.userEmployeeBinding.create({
data: {
userId: JIANGCHENG_USER_ID,
employeeProfileId: PROFILE_ID,
bindingSource: 'MANUAL_VERIFIED',
status: 'ACTIVE',
verifiedAt: new Date(),
note: '人工处置:刘伟/江澄同名串档修复(2026-08-14)',
},
})
console.log('✓ 江澄账号已建立绑定')
// 4. 江澄角色升 DEPT_ADMIN
await tx.user.update({
where: { id: JIANGCHENG_USER_ID },
data: { role: 'DEPT_ADMIN' },
})
console.log('✓ 江澄账号角色 → DEPT_ADMIN')
})
// 验证
const verify = await prisma.user.findUnique({
where: { id: JIANGCHENG_USER_ID },
select: {
username: true, role: true,
employeeBindings: { where: { status: 'ACTIVE' }, select: { employeeProfile: { select: { displayName: true, departmentPath: true, positionLevel: true, levelType: true } } } },
},
})
console.log('\n=== 验证 ===')
console.log(JSON.stringify(verify, null, 2))
const liuweiAfter = await prisma.user.findUnique({ where: { id: LIUWEI_USER_ID } }).catch(() => null)
console.log(`刘伟账号删除后存在: ${Boolean(liuweiAfter)}`)
await prisma.$disconnect()
})().catch((e) => { console.error(e); process.exit(1) })