399 lines
15 KiB
JavaScript
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 };
|