interpreter-admin/scripts/test-admin-connection.js
Mars Developer 51f8d95bf9 first commit
2025-06-26 11:24:11 +08:00

399 lines
15 KiB
JavaScript

const { createClient } = require('@supabase/supabase-js');
// 颜色输出函数
const colors = {
red: (text) => `\x1b[31m${text}\x1b[0m`,
green: (text) => `\x1b[32m${text}\x1b[0m`,
yellow: (text) => `\x1b[33m${text}\x1b[0m`,
blue: (text) => `\x1b[34m${text}\x1b[0m`,
cyan: (text) => `\x1b[36m${text}\x1b[0m`,
bold: (text) => `\x1b[1m${text}\x1b[0m`
};
async function testAdminConnection() {
console.log(colors.bold('\n🔍 测试后台管理端 Supabase 连接...\n'));
// Supabase配置 - 与客户端使用相同的配置
const supabaseUrl = 'https://riwtulmitqioswmgwftg.supabase.co';
const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJpd3R1bG1pdHFpb3N3bWd3ZnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg1OTc1ODgsImV4cCI6MjA2NDE3MzU4OH0.fxSW_uEbpR1zwepjb83DIUIwTrmsboK2nTjPpS6XMtw';
console.log(colors.cyan('📡 Supabase URL:'), supabaseUrl);
console.log(colors.cyan('🔑 API Key:'), supabaseKey.substring(0, 20) + '...');
// 创建客户端
const supabase = createClient(supabaseUrl, supabaseKey);
try {
// 1. 测试基本连接
console.log(colors.blue('\n🔄 测试基本数据库连接...'));
const { data: rates, error: ratesError } = await supabase
.from('rates')
.select('service_type, price_per_minute, currency')
.limit(5);
if (ratesError) {
console.log(colors.red('❌ 数据库连接失败:'), ratesError.message);
throw ratesError;
}
console.log(colors.green('✅ 基本连接成功,费率数据:'));
rates.forEach(rate => {
console.log(colors.cyan(` - ${rate.service_type}: $${rate.price_per_minute}/${rate.currency}`));
});
// 2. 测试管理端需要的数据表
console.log(colors.blue('\n🔄 测试管理端数据表访问...'));
const tables = [
{ name: 'profiles', description: '用户资料' },
{ name: 'calls', description: '通话记录' },
{ name: 'translations', description: '翻译记录' },
{ name: 'payments', description: '支付记录' },
{ name: 'interpreters', description: '口译员信息' }
];
for (const table of tables) {
try {
const { count, error } = await supabase
.from(table.name)
.select('*', { count: 'exact', head: true });
if (error) throw error;
console.log(colors.green(`${table.description} (${table.name}): ${count || 0} 条记录`));
} catch (error) {
console.log(colors.red(`${table.description} (${table.name}): ${error.message}`));
}
}
// 3. 测试统计数据查询
console.log(colors.blue('\n🔄 测试统计数据查询...'));
const [
{ count: totalUsers },
{ count: totalCalls },
{ count: totalInterpreters },
{ data: recentPayments }
] = await Promise.all([
supabase.from('profiles').select('*', { count: 'exact', head: true }),
supabase.from('calls').select('*', { count: 'exact', head: true }),
supabase.from('interpreters').select('*', { count: 'exact', head: true }),
supabase.from('payments').select('amount').eq('status', 'completed').limit(10)
]);
const totalRevenue = recentPayments?.reduce((sum, payment) => sum + payment.amount, 0) || 0;
console.log(colors.green('📊 系统统计数据:'));
console.log(colors.cyan(` - 总用户数: ${totalUsers || 0}`));
console.log(colors.cyan(` - 总通话数: ${totalCalls || 0}`));
console.log(colors.cyan(` - 口译员数: ${totalInterpreters || 0}`));
console.log(colors.cyan(` - 总收入: $${totalRevenue.toFixed(2)}`));
// 4. 测试实时订阅功能
console.log(colors.blue('\n🔄 测试实时数据订阅...'));
const channel = supabase
.channel('admin-test')
.on('postgres_changes', { event: '*', schema: 'public', table: 'calls' }, (payload) => {
console.log(colors.yellow('📢 实时数据更新:'), payload);
})
.subscribe();
// 等待订阅建立
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(colors.green('✅ 实时订阅功能正常'));
// 清理订阅
supabase.removeChannel(channel);
// 总结
console.log(colors.bold(colors.green('\n🎉 后台管理端连接测试通过!')));
console.log(colors.green('✅ 数据库连接正常'));
console.log(colors.green('✅ 所有管理端表都可访问'));
console.log(colors.green('✅ 统计查询功能正常'));
console.log(colors.green('✅ 实时数据订阅正常'));
console.log(colors.bold('\n💡 后台管理端已准备就绪,可以查看和管理客户端数据!'));
} catch (error) {
console.log(colors.bold(colors.red('\n❌ 连接测试失败!')));
console.log(colors.red('错误信息:'), error.message);
console.log(colors.yellow('\n🔧 故障排除建议:'));
console.log(colors.cyan('1. 检查网络连接'));
console.log(colors.cyan('2. 验证 Supabase URL 和 API 密钥'));
console.log(colors.cyan('3. 确认 Supabase 项目状态'));
console.log(colors.cyan('4. 检查数据库表是否存在'));
process.exit(1);
}
}
// 数据同步测试函数
async function testDataSync() {
console.log(colors.bold('\n🔄 测试客户端-管理端数据同步...\n'));
const supabase = createClient(
'https://riwtulmitqioswmgwftg.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJpd3R1bG1pdHFpb3N3bWd3ZnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg1OTc1ODgsImV4cCI6MjA2NDE3MzU4OH0.fxSW_uEbpR1zwepjb83DIUIwTrmsboK2nTjPpS6XMtw'
);
try {
// 模拟客户端创建一条测试数据
const testData = {
id: `test-${Date.now()}`,
name: '测试口译员',
avatar: null,
description: '这是管理端连接测试创建的数据',
status: 'available',
created_at: new Date().toISOString()
};
console.log(colors.blue('📝 创建测试数据...'));
const { data: createdData, error: createError } = await supabase
.from('interpreters')
.insert(testData)
.select()
.single();
if (createError) throw createError;
console.log(colors.green('✅ 测试数据创建成功:'), createdData.name);
// 等待数据同步
await new Promise(resolve => setTimeout(resolve, 1000));
// 从管理端查询数据
console.log(colors.blue('🔍 从管理端查询数据...'));
const { data: queriedData, error: queryError } = await supabase
.from('interpreters')
.select('*')
.eq('id', testData.id)
.single();
if (queryError) throw queryError;
console.log(colors.green('✅ 管理端成功读取数据:'), queriedData.name);
// 清理测试数据
console.log(colors.blue('🧹 清理测试数据...'));
const { error: deleteError } = await supabase
.from('interpreters')
.delete()
.eq('id', testData.id);
if (deleteError) throw deleteError;
console.log(colors.green('✅ 测试数据清理完成'));
console.log(colors.bold(colors.green('\n🎉 数据同步测试通过!')));
console.log(colors.green('✅ 客户端写入的数据可以在管理端实时查看'));
console.log(colors.green('✅ 管理端可以对客户端数据进行完整的CRUD操作'));
} catch (error) {
console.log(colors.bold(colors.red('\n❌ 数据同步测试失败!')));
console.log(colors.red('错误信息:'), error.message);
}
}
// 运行测试
if (require.main === module) {
testAdminConnection()
.then(() => testDataSync())
.catch(console.error);
}
module.exports = { testAdminConnection, testDataSync };
// 颜色输出函数
const colors = {
red: (text) => `\x1b[31m${text}\x1b[0m`,
green: (text) => `\x1b[32m${text}\x1b[0m`,
yellow: (text) => `\x1b[33m${text}\x1b[0m`,
blue: (text) => `\x1b[34m${text}\x1b[0m`,
cyan: (text) => `\x1b[36m${text}\x1b[0m`,
bold: (text) => `\x1b[1m${text}\x1b[0m`
};
async function testAdminConnection() {
console.log(colors.bold('\n🔍 测试后台管理端 Supabase 连接...\n'));
// Supabase配置 - 与客户端使用相同的配置
const supabaseUrl = 'https://riwtulmitqioswmgwftg.supabase.co';
const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJpd3R1bG1pdHFpb3N3bWd3ZnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg1OTc1ODgsImV4cCI6MjA2NDE3MzU4OH0.fxSW_uEbpR1zwepjb83DIUIwTrmsboK2nTjPpS6XMtw';
console.log(colors.cyan('📡 Supabase URL:'), supabaseUrl);
console.log(colors.cyan('🔑 API Key:'), supabaseKey.substring(0, 20) + '...');
// 创建客户端
const supabase = createClient(supabaseUrl, supabaseKey);
try {
// 1. 测试基本连接
console.log(colors.blue('\n🔄 测试基本数据库连接...'));
const { data: rates, error: ratesError } = await supabase
.from('rates')
.select('service_type, price_per_minute, currency')
.limit(5);
if (ratesError) {
console.log(colors.red('❌ 数据库连接失败:'), ratesError.message);
throw ratesError;
}
console.log(colors.green('✅ 基本连接成功,费率数据:'));
rates.forEach(rate => {
console.log(colors.cyan(` - ${rate.service_type}: $${rate.price_per_minute}/${rate.currency}`));
});
// 2. 测试管理端需要的数据表
console.log(colors.blue('\n🔄 测试管理端数据表访问...'));
const tables = [
{ name: 'profiles', description: '用户资料' },
{ name: 'calls', description: '通话记录' },
{ name: 'translations', description: '翻译记录' },
{ name: 'payments', description: '支付记录' },
{ name: 'interpreters', description: '口译员信息' }
];
for (const table of tables) {
try {
const { count, error } = await supabase
.from(table.name)
.select('*', { count: 'exact', head: true });
if (error) throw error;
console.log(colors.green(`${table.description} (${table.name}): ${count || 0} 条记录`));
} catch (error) {
console.log(colors.red(`${table.description} (${table.name}): ${error.message}`));
}
}
// 3. 测试统计数据查询
console.log(colors.blue('\n🔄 测试统计数据查询...'));
const [
{ count: totalUsers },
{ count: totalCalls },
{ count: totalInterpreters },
{ data: recentPayments }
] = await Promise.all([
supabase.from('profiles').select('*', { count: 'exact', head: true }),
supabase.from('calls').select('*', { count: 'exact', head: true }),
supabase.from('interpreters').select('*', { count: 'exact', head: true }),
supabase.from('payments').select('amount').eq('status', 'completed').limit(10)
]);
const totalRevenue = recentPayments?.reduce((sum, payment) => sum + payment.amount, 0) || 0;
console.log(colors.green('📊 系统统计数据:'));
console.log(colors.cyan(` - 总用户数: ${totalUsers || 0}`));
console.log(colors.cyan(` - 总通话数: ${totalCalls || 0}`));
console.log(colors.cyan(` - 口译员数: ${totalInterpreters || 0}`));
console.log(colors.cyan(` - 总收入: $${totalRevenue.toFixed(2)}`));
// 4. 测试实时订阅功能
console.log(colors.blue('\n🔄 测试实时数据订阅...'));
const channel = supabase
.channel('admin-test')
.on('postgres_changes', { event: '*', schema: 'public', table: 'calls' }, (payload) => {
console.log(colors.yellow('📢 实时数据更新:'), payload);
})
.subscribe();
// 等待订阅建立
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(colors.green('✅ 实时订阅功能正常'));
// 清理订阅
supabase.removeChannel(channel);
// 总结
console.log(colors.bold(colors.green('\n🎉 后台管理端连接测试通过!')));
console.log(colors.green('✅ 数据库连接正常'));
console.log(colors.green('✅ 所有管理端表都可访问'));
console.log(colors.green('✅ 统计查询功能正常'));
console.log(colors.green('✅ 实时数据订阅正常'));
console.log(colors.bold('\n💡 后台管理端已准备就绪,可以查看和管理客户端数据!'));
} catch (error) {
console.log(colors.bold(colors.red('\n❌ 连接测试失败!')));
console.log(colors.red('错误信息:'), error.message);
console.log(colors.yellow('\n🔧 故障排除建议:'));
console.log(colors.cyan('1. 检查网络连接'));
console.log(colors.cyan('2. 验证 Supabase URL 和 API 密钥'));
console.log(colors.cyan('3. 确认 Supabase 项目状态'));
console.log(colors.cyan('4. 检查数据库表是否存在'));
process.exit(1);
}
}
// 数据同步测试函数
async function testDataSync() {
console.log(colors.bold('\n🔄 测试客户端-管理端数据同步...\n'));
const supabase = createClient(
'https://riwtulmitqioswmgwftg.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJpd3R1bG1pdHFpb3N3bWd3ZnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg1OTc1ODgsImV4cCI6MjA2NDE3MzU4OH0.fxSW_uEbpR1zwepjb83DIUIwTrmsboK2nTjPpS6XMtw'
);
try {
// 模拟客户端创建一条测试数据
const testData = {
id: `test-${Date.now()}`,
name: '测试口译员',
avatar: null,
description: '这是管理端连接测试创建的数据',
status: 'available',
created_at: new Date().toISOString()
};
console.log(colors.blue('📝 创建测试数据...'));
const { data: createdData, error: createError } = await supabase
.from('interpreters')
.insert(testData)
.select()
.single();
if (createError) throw createError;
console.log(colors.green('✅ 测试数据创建成功:'), createdData.name);
// 等待数据同步
await new Promise(resolve => setTimeout(resolve, 1000));
// 从管理端查询数据
console.log(colors.blue('🔍 从管理端查询数据...'));
const { data: queriedData, error: queryError } = await supabase
.from('interpreters')
.select('*')
.eq('id', testData.id)
.single();
if (queryError) throw queryError;
console.log(colors.green('✅ 管理端成功读取数据:'), queriedData.name);
// 清理测试数据
console.log(colors.blue('🧹 清理测试数据...'));
const { error: deleteError } = await supabase
.from('interpreters')
.delete()
.eq('id', testData.id);
if (deleteError) throw deleteError;
console.log(colors.green('✅ 测试数据清理完成'));
console.log(colors.bold(colors.green('\n🎉 数据同步测试通过!')));
console.log(colors.green('✅ 客户端写入的数据可以在管理端实时查看'));
console.log(colors.green('✅ 管理端可以对客户端数据进行完整的CRUD操作'));
} catch (error) {
console.log(colors.bold(colors.red('\n❌ 数据同步测试失败!')));
console.log(colors.red('错误信息:'), error.message);
}
}
// 运行测试
if (require.main === module) {
testAdminConnection()
.then(() => testDataSync())
.catch(console.error);
}
module.exports = { testAdminConnection, testDataSync };