- 创建统一的下载错误处理模块 (lib/download-errors.ts) - 实现13种错误类型分类和中文错误消息 - 后端统一使用 createDownloadError 创建标准化错误响应 - 前端统一使用 parseDownloadError 解析错误并显示 - 修复正式系统数据库Schema,添加产品全案相关字段和表 - 执行数据库迁移:添加 task_no, task_status, task_fetched_at 字段 - 创建 material_assets, api_keys, api_call_logs 表
111 lines
3.1 KiB
TypeScript
111 lines
3.1 KiB
TypeScript
/**
|
||
* 数据迁移脚本:将 isActive 迁移到 status 字段
|
||
*
|
||
* 阶段一:用户状态管理优化
|
||
*
|
||
* 迁移规则:
|
||
* - isActive = true -> status = 'active'
|
||
* - isActive = false -> status = 'pending'
|
||
*
|
||
* 注意:此脚本假设 status 字段已经通过 Prisma migrate 添加到数据库
|
||
*
|
||
* 使用方法:
|
||
* npx tsx scripts/migrate-user-status.ts
|
||
*/
|
||
|
||
import { PrismaClient } from '@prisma/client';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
async function main() {
|
||
console.log('开始迁移用户状态字段...\n');
|
||
|
||
try {
|
||
// 1. 检查是否已经迁移过(如果所有用户都有status值且不是默认值,说明可能已经迁移)
|
||
const totalUsers = await prisma.user.count();
|
||
const usersWithStatus = await prisma.user.count({
|
||
where: {
|
||
status: {
|
||
not: 'pending', // 不是默认值
|
||
},
|
||
},
|
||
});
|
||
|
||
console.log(`总用户数:${totalUsers}`);
|
||
console.log(`已设置status的用户数:${usersWithStatus}`);
|
||
|
||
// 2. 迁移 isActive = true -> status = 'active'
|
||
const activeUsers = await prisma.user.updateMany({
|
||
where: {
|
||
isActive: true,
|
||
status: 'pending', // 只迁移还没有设置status的
|
||
},
|
||
data: {
|
||
status: 'active',
|
||
},
|
||
});
|
||
|
||
console.log(`\n✅ 已激活用户迁移:${activeUsers.count} 个用户设置为 active`);
|
||
|
||
// 3. isActive = false 的用户已经是 pending(默认值),无需更新
|
||
// 但我们可以统计一下
|
||
const pendingUsers = await prisma.user.count({
|
||
where: {
|
||
isActive: false,
|
||
status: 'pending',
|
||
},
|
||
});
|
||
|
||
console.log(`📋 待激活用户:${pendingUsers} 个(保持 pending 状态)`);
|
||
|
||
// 4. 统计最终状态分布
|
||
console.log('\n=== 迁移后状态分布 ===');
|
||
const statusCounts = await prisma.user.groupBy({
|
||
by: ['status'],
|
||
_count: {
|
||
id: true,
|
||
},
|
||
});
|
||
|
||
statusCounts.forEach((item) => {
|
||
console.log(` ${item.status}: ${item._count.id} 个用户`);
|
||
});
|
||
|
||
// 5. 验证迁移完整性
|
||
// 注意:status 字段有默认值 'pending',所以不会有 null 值
|
||
const usersWithoutStatus = await prisma.user.count({
|
||
where: {
|
||
status: '',
|
||
},
|
||
});
|
||
|
||
if (usersWithoutStatus > 0) {
|
||
console.warn(`\n⚠️ 警告:仍有 ${usersWithoutStatus} 个用户的status为空`);
|
||
} else {
|
||
console.log('\n✅ 迁移完成,所有用户都已设置status字段');
|
||
}
|
||
|
||
} catch (error: any) {
|
||
// 如果status字段不存在,提示先运行Prisma migrate
|
||
if (error.message?.includes('Unknown column') || error.message?.includes('status')) {
|
||
console.error('\n❌ 错误:status 字段不存在!');
|
||
console.error('请先运行 Prisma 迁移:');
|
||
console.error(' npx prisma migrate dev --name add_user_status_fields');
|
||
console.error('或者:');
|
||
console.error(' npx prisma db push');
|
||
process.exit(1);
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
main()
|
||
.catch((error) => {
|
||
console.error('\n❌ 迁移失败:', error);
|
||
process.exit(1);
|
||
})
|
||
.finally(async () => {
|
||
await prisma.$disconnect();
|
||
});
|
||
|