- 创建统一的下载错误处理模块 (lib/download-errors.ts) - 实现13种错误类型分类和中文错误消息 - 后端统一使用 createDownloadError 创建标准化错误响应 - 前端统一使用 parseDownloadError 解析错误并显示 - 修复正式系统数据库Schema,添加产品全案相关字段和表 - 执行数据库迁移:添加 task_no, task_status, task_fetched_at 字段 - 创建 material_assets, api_keys, api_call_logs 表
269 lines
8.0 KiB
TypeScript
269 lines
8.0 KiB
TypeScript
/**
|
||
* 查找用户账户的调试脚本
|
||
* 用于查找"玄女"账户,即使后台搜索不到
|
||
*/
|
||
|
||
import { PrismaClient } from '@prisma/client';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
async function findUser(searchTerm: string) {
|
||
console.log(`\n=== 查找用户 "${searchTerm}" ===\n`);
|
||
|
||
try {
|
||
// 1. 精确匹配用户名
|
||
console.log('1. 精确匹配用户名:');
|
||
const exactMatch = await prisma.user.findUnique({
|
||
where: { username: searchTerm },
|
||
});
|
||
if (exactMatch) {
|
||
console.log(' ✅ 找到精确匹配:', {
|
||
id: exactMatch.id,
|
||
username: exactMatch.username,
|
||
email: exactMatch.email,
|
||
isActive: exactMatch.isActive,
|
||
role: exactMatch.role,
|
||
department: exactMatch.department,
|
||
dingtalkUserId: (exactMatch as any).dingtalkUserId || '(未设置)',
|
||
loginType: (exactMatch as any).loginType || 'normal',
|
||
});
|
||
} else {
|
||
console.log(' ❌ 未找到精确匹配');
|
||
}
|
||
|
||
// 2. 模糊匹配用户名(包含搜索词)
|
||
console.log(`\n2. 模糊匹配用户名(包含 "${searchTerm}"):`);
|
||
const usernameMatches = await prisma.user.findMany({
|
||
where: {
|
||
username: {
|
||
contains: searchTerm,
|
||
mode: 'insensitive',
|
||
},
|
||
},
|
||
select: {
|
||
id: true,
|
||
username: true,
|
||
email: true,
|
||
isActive: true,
|
||
role: true,
|
||
department: true,
|
||
dingtalkUserId: true,
|
||
loginType: true,
|
||
realName: true,
|
||
},
|
||
});
|
||
|
||
if (usernameMatches.length > 0) {
|
||
console.log(` ✅ 找到 ${usernameMatches.length} 个匹配结果:`);
|
||
usernameMatches.forEach((user: any) => {
|
||
console.log(' ', {
|
||
id: user.id,
|
||
username: user.username,
|
||
email: user.email,
|
||
realName: user.realName || '(未设置)',
|
||
isActive: user.isActive ? '✅ 已激活' : '❌ 未激活',
|
||
role: user.role,
|
||
department: user.department || '(未设置)',
|
||
dingtalkUserId: user.dingtalkUserId || '(未设置)',
|
||
loginType: user.loginType || 'normal',
|
||
});
|
||
});
|
||
} else {
|
||
console.log(' ❌ 未找到模糊匹配');
|
||
}
|
||
|
||
// 3. 搜索邮箱(包含搜索词)
|
||
console.log(`\n3. 搜索邮箱(包含 "${searchTerm}"):`);
|
||
const emailMatches = await prisma.user.findMany({
|
||
where: {
|
||
email: {
|
||
contains: searchTerm,
|
||
mode: 'insensitive',
|
||
},
|
||
},
|
||
select: {
|
||
id: true,
|
||
username: true,
|
||
email: true,
|
||
isActive: true,
|
||
role: true,
|
||
department: true,
|
||
dingtalkUserId: true,
|
||
loginType: true,
|
||
realName: true,
|
||
},
|
||
});
|
||
|
||
if (emailMatches.length > 0) {
|
||
console.log(` ✅ 找到 ${emailMatches.length} 个匹配结果:`);
|
||
emailMatches.forEach((user: any) => {
|
||
console.log(' ', {
|
||
id: user.id,
|
||
username: user.username,
|
||
email: user.email,
|
||
realName: user.realName || '(未设置)',
|
||
isActive: user.isActive ? '✅ 已激活' : '❌ 未激活',
|
||
role: user.role,
|
||
department: user.department || '(未设置)',
|
||
dingtalkUserId: user.dingtalkUserId || '(未设置)',
|
||
loginType: user.loginType || 'normal',
|
||
});
|
||
});
|
||
} else {
|
||
console.log(' ❌ 未找到邮箱匹配');
|
||
}
|
||
|
||
// 4. 搜索真实姓名(包含搜索词)
|
||
console.log(`\n4. 搜索真实姓名(包含 "${searchTerm}"):`);
|
||
const realNameMatches = await prisma.user.findMany({
|
||
where: {
|
||
realName: {
|
||
contains: searchTerm,
|
||
mode: 'insensitive',
|
||
},
|
||
},
|
||
select: {
|
||
id: true,
|
||
username: true,
|
||
email: true,
|
||
isActive: true,
|
||
role: true,
|
||
department: true,
|
||
dingtalkUserId: true,
|
||
loginType: true,
|
||
realName: true,
|
||
},
|
||
});
|
||
|
||
if (realNameMatches.length > 0) {
|
||
console.log(` ✅ 找到 ${realNameMatches.length} 个匹配结果:`);
|
||
realNameMatches.forEach((user: any) => {
|
||
console.log(' ', {
|
||
id: user.id,
|
||
username: user.username,
|
||
email: user.email,
|
||
realName: user.realName || '(未设置)',
|
||
isActive: user.isActive ? '✅ 已激活' : '❌ 未激活',
|
||
role: user.role,
|
||
department: user.department || '(未设置)',
|
||
dingtalkUserId: user.dingtalkUserId || '(未设置)',
|
||
loginType: user.loginType || 'normal',
|
||
});
|
||
});
|
||
} else {
|
||
console.log(' ❌ 未找到真实姓名匹配');
|
||
}
|
||
|
||
// 5. 查找所有未激活的钉钉账户
|
||
console.log(`\n5. 所有未激活的钉钉账户:`);
|
||
const inactiveDingtalkUsers = await prisma.user.findMany({
|
||
where: {
|
||
isActive: false,
|
||
loginType: 'dingtalk',
|
||
},
|
||
select: {
|
||
id: true,
|
||
username: true,
|
||
email: true,
|
||
isActive: true,
|
||
role: true,
|
||
department: true,
|
||
dingtalkUserId: true,
|
||
loginType: true,
|
||
realName: true,
|
||
createdAt: true,
|
||
},
|
||
orderBy: {
|
||
createdAt: 'desc',
|
||
},
|
||
});
|
||
|
||
if (inactiveDingtalkUsers.length > 0) {
|
||
console.log(` ✅ 找到 ${inactiveDingtalkUsers.length} 个未激活的钉钉账户:`);
|
||
inactiveDingtalkUsers.forEach((user: any) => {
|
||
const containsSearchTerm =
|
||
(user.username && user.username.includes(searchTerm)) ||
|
||
(user.realName && user.realName.includes(searchTerm)) ||
|
||
(user.email && user.email.includes(searchTerm));
|
||
|
||
const mark = containsSearchTerm ? '⭐' : ' ';
|
||
console.log(`${mark}`, {
|
||
id: user.id,
|
||
username: user.username,
|
||
email: user.email,
|
||
realName: user.realName || '(未设置)',
|
||
isActive: '❌ 未激活',
|
||
role: user.role,
|
||
department: user.department || '(未设置)',
|
||
dingtalkUserId: user.dingtalkUserId || '(未设置)',
|
||
createdAt: user.createdAt,
|
||
});
|
||
});
|
||
} else {
|
||
console.log(' ❌ 未找到未激活的钉钉账户');
|
||
}
|
||
|
||
// 6. 查找所有钉钉账户(不管激活状态)
|
||
console.log(`\n6. 所有钉钉账户(检查是否有用户名相似的情况):`);
|
||
const allDingtalkUsers = await prisma.user.findMany({
|
||
where: {
|
||
loginType: 'dingtalk',
|
||
},
|
||
select: {
|
||
id: true,
|
||
username: true,
|
||
email: true,
|
||
isActive: true,
|
||
role: true,
|
||
department: true,
|
||
dingtalkUserId: true,
|
||
loginType: true,
|
||
realName: true,
|
||
},
|
||
orderBy: {
|
||
username: 'asc',
|
||
},
|
||
});
|
||
|
||
if (allDingtalkUsers.length > 0) {
|
||
console.log(` 共 ${allDingtalkUsers.length} 个钉钉账户`);
|
||
// 只显示可能相关的(包含搜索词或相似字符)
|
||
const relevantUsers = allDingtalkUsers.filter((user: any) => {
|
||
const username = (user.username || '').toLowerCase();
|
||
const realName = (user.realName || '').toLowerCase();
|
||
const searchLower = searchTerm.toLowerCase();
|
||
return username.includes(searchLower) || realName.includes(searchLower);
|
||
});
|
||
|
||
if (relevantUsers.length > 0) {
|
||
console.log(` 其中可能相关的账户:`);
|
||
relevantUsers.forEach((user: any) => {
|
||
console.log(' ', {
|
||
id: user.id,
|
||
username: user.username,
|
||
email: user.email,
|
||
realName: user.realName || '(未设置)',
|
||
isActive: user.isActive ? '✅ 已激活' : '❌ 未激活',
|
||
role: user.role,
|
||
department: user.department || '(未设置)',
|
||
dingtalkUserId: user.dingtalkUserId || '(未设置)',
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ 查询时出错:', error);
|
||
if (error instanceof Error) {
|
||
console.error('错误信息:', error.message);
|
||
}
|
||
} finally {
|
||
await prisma.$disconnect();
|
||
}
|
||
}
|
||
|
||
// 执行查找
|
||
const searchTerm = process.argv[2] || '玄女';
|
||
findUser(searchTerm);
|
||
|