352 lines
11 KiB
JavaScript
Raw Normal View History

// API 管理文件
class APIManager {
constructor() {
this.supabase = null;
this.currentUser = null;
this.init();
}
// 初始化 Supabase 客户端
async init() {
try {
// 加载 Supabase 客户端
const { createClient } = supabase;
this.supabase = createClient(CONFIG.SUPABASE.URL, CONFIG.SUPABASE.ANON_KEY);
// 检查用户登录状态
await this.checkAuthStatus();
console.log('API Manager 初始化成功');
} catch (error) {
console.error('API Manager 初始化失败:', error);
}
}
// 检查认证状态
async checkAuthStatus() {
try {
const { data: { user } } = await this.supabase.auth.getUser();
this.currentUser = user;
if (user) {
console.log('用户已登录:', user.email);
this.updateUIForLoggedInUser(user);
} else {
console.log('用户未登录');
this.updateUIForLoggedOutUser();
}
} catch (error) {
console.error('检查认证状态失败:', error);
}
}
// 用户注册
async register(email, password, userData = {}) {
try {
const { data, error } = await this.supabase.auth.signUp({
email: email,
password: password,
options: {
data: {
full_name: userData.fullName || '',
phone: userData.phone || '',
...userData
}
}
});
if (error) throw error;
// 创建用户档案
if (data.user) {
await this.createUserProfile(data.user, userData);
}
return { success: true, data: data };
} catch (error) {
console.error('注册失败:', error);
return { success: false, error: error.message };
}
}
// 用户登录
async login(email, password) {
try {
const { data, error } = await this.supabase.auth.signInWithPassword({
email: email,
password: password
});
if (error) throw error;
this.currentUser = data.user;
this.updateUIForLoggedInUser(data.user);
return { success: true, data: data };
} catch (error) {
console.error('登录失败:', error);
return { success: false, error: error.message };
}
}
// 用户登出
async logout() {
try {
const { error } = await this.supabase.auth.signOut();
if (error) throw error;
this.currentUser = null;
this.updateUIForLoggedOutUser();
return { success: true };
} catch (error) {
console.error('登出失败:', error);
return { success: false, error: error.message };
}
}
// 创建用户档案
async createUserProfile(user, userData) {
try {
const { data, error } = await this.supabase
.from('user_profiles')
.insert([
{
id: user.id,
email: user.email,
full_name: userData.fullName || '',
phone: userData.phone || '',
avatar_url: userData.avatarUrl || '',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
}
]);
if (error) throw error;
return data;
} catch (error) {
console.error('创建用户档案失败:', error);
throw error;
}
}
// 获取用户档案
async getUserProfile(userId = null) {
try {
const id = userId || this.currentUser?.id;
if (!id) throw new Error('用户未登录');
const { data, error } = await this.supabase
.from('user_profiles')
.select('*')
.eq('id', id)
.single();
if (error) throw error;
return data;
} catch (error) {
console.error('获取用户档案失败:', error);
throw error;
}
}
// 更新用户档案
async updateUserProfile(updates) {
try {
if (!this.currentUser) throw new Error('用户未登录');
const { data, error } = await this.supabase
.from('user_profiles')
.update({
...updates,
updated_at: new Date().toISOString()
})
.eq('id', this.currentUser.id);
if (error) throw error;
return data;
} catch (error) {
console.error('更新用户档案失败:', error);
throw error;
}
}
// 创建通话记录
async createCallRecord(callData) {
try {
if (!this.currentUser) throw new Error('用户未登录');
const { data, error } = await this.supabase
.from('call_records')
.insert([
{
user_id: this.currentUser.id,
call_type: callData.type, // 'voice' or 'video'
duration: callData.duration, // 通话时长(秒)
has_translator: callData.hasTranslator || false,
base_rate: callData.baseRate, // 基础费率
translator_rate: callData.translatorRate || 0, // 翻译费率
total_amount: callData.totalAmount, // 总金额
status: callData.status || 'completed', // 'pending', 'completed', 'cancelled'
created_at: new Date().toISOString()
}
]);
if (error) throw error;
return data;
} catch (error) {
console.error('创建通话记录失败:', error);
throw error;
}
}
// 获取通话记录
async getCallRecords(limit = 50) {
try {
if (!this.currentUser) throw new Error('用户未登录');
const { data, error } = await this.supabase
.from('call_records')
.select('*')
.eq('user_id', this.currentUser.id)
.order('created_at', { ascending: false })
.limit(limit);
if (error) throw error;
return data;
} catch (error) {
console.error('获取通话记录失败:', error);
throw error;
}
}
// 创建预约记录
async createAppointment(appointmentData) {
try {
if (!this.currentUser) throw new Error('用户未登录');
const { data, error } = await this.supabase
.from('appointments')
.insert([
{
user_id: this.currentUser.id,
translator_id: appointmentData.translatorId,
appointment_date: appointmentData.date,
appointment_time: appointmentData.time,
service_type: appointmentData.serviceType, // 'voice', 'video', 'document'
language_pair: appointmentData.languagePair, // '中文-英文'
duration: appointmentData.duration || 60, // 预约时长(分钟)
notes: appointmentData.notes || '',
status: 'pending', // 'pending', 'confirmed', 'completed', 'cancelled'
created_at: new Date().toISOString()
}
]);
if (error) throw error;
return data;
} catch (error) {
console.error('创建预约失败:', error);
throw error;
}
}
// 获取预约记录
async getAppointments() {
try {
if (!this.currentUser) throw new Error('用户未登录');
const { data, error } = await this.supabase
.from('appointments')
.select(`
*,
translator_profiles (
full_name,
avatar_url,
languages,
rating
)
`)
.eq('user_id', this.currentUser.id)
.order('appointment_date', { ascending: true });
if (error) throw error;
return data;
} catch (error) {
console.error('获取预约记录失败:', error);
throw error;
}
}
// 获取翻译员列表
async getTranslators() {
try {
const { data, error } = await this.supabase
.from('translator_profiles')
.select('*')
.eq('is_active', true)
.order('rating', { ascending: false });
if (error) throw error;
return data;
} catch (error) {
console.error('获取翻译员列表失败:', error);
throw error;
}
}
// 更新UI - 已登录用户
updateUIForLoggedInUser(user) {
// 显示用户信息
const userNameElements = document.querySelectorAll('.user-name');
userNameElements.forEach(el => {
el.textContent = user.user_metadata?.full_name || user.email;
});
// 显示/隐藏相关元素
const loginElements = document.querySelectorAll('.login-required');
loginElements.forEach(el => el.style.display = 'none');
const userElements = document.querySelectorAll('.user-only');
userElements.forEach(el => el.style.display = 'block');
}
// 更新UI - 未登录用户
updateUIForLoggedOutUser() {
// 隐藏/显示相关元素
const loginElements = document.querySelectorAll('.login-required');
loginElements.forEach(el => el.style.display = 'block');
const userElements = document.querySelectorAll('.user-only');
userElements.forEach(el => el.style.display = 'none');
}
// Stripe 支付处理
async processPayment(amount, callRecordId) {
try {
// 这里应该调用后端API来处理Stripe支付
// 由于安全考虑Stripe的secret key不应该在前端使用
console.log('处理支付:', amount, callRecordId);
// 模拟支付成功
return { success: true, paymentId: 'pi_test_' + Date.now() };
} catch (error) {
console.error('支付处理失败:', error);
return { success: false, error: error.message };
}
}
// Twilio 视频通话初始化
async initVideoCall() {
try {
// 这里应该调用后端API获取Twilio访问令牌
console.log('初始化视频通话');
return { success: true, token: 'twilio_token_placeholder' };
} catch (error) {
console.error('视频通话初始化失败:', error);
return { success: false, error: error.message };
}
}
}
// 创建全局API管理器实例
window.apiManager = new APIManager();