113 lines
5.0 KiB
TypeScript
113 lines
5.0 KiB
TypeScript
/**
|
||
* 处置:刘伟/江澄账号串档修复(事务,可回滚)
|
||
*
|
||
* 背景:花名册"刘伟(花名江澄,工号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) })
|