import { createClient } from '@supabase/supabase-js'; import { Database } from '../types/database'; // 环境变量检查和默认值 const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || 'https://demo.supabase.co'; const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || 'demo-key'; const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY || 'demo-service-key'; // 检查是否在开发环境中使用默认配置 const isDemoMode = supabaseUrl === 'https://demo.supabase.co'; // 单一的 Supabase 客户端实例 export const supabase = isDemoMode ? createClient(supabaseUrl, supabaseAnonKey, { realtime: { params: { eventsPerSecond: 0, }, }, auth: { persistSession: false, autoRefreshToken: false, }, }) : createClient(supabaseUrl, supabaseAnonKey, { auth: { autoRefreshToken: true, persistSession: true, detectSessionInUrl: true } }); // 服务端使用的 Supabase 客户端(具有管理员权限) export const supabaseAdmin = isDemoMode ? createClient(supabaseUrl, supabaseServiceKey, { auth: { autoRefreshToken: false, persistSession: false, }, realtime: { params: { eventsPerSecond: 0, }, }, }) : createClient(supabaseUrl, supabaseServiceKey, { auth: { autoRefreshToken: false, persistSession: false, }, }); // 数据库表名常量 export const TABLES = { USERS: 'users', CALLS: 'calls', APPOINTMENTS: 'appointments', INTERPRETERS: 'interpreters', DOCUMENTS: 'document_translations', ORDERS: 'orders', INVOICES: 'invoices', ENTERPRISE_EMPLOYEES: 'enterprise_employees', PRICING_RULES: 'pricing_rules', NOTIFICATIONS: 'notifications', SYSTEM_SETTINGS: 'system_settings', ACCOUNT_BALANCES: 'account_balances', } as const; // 实时订阅配置 export const REALTIME_CHANNELS = { CALLS: 'calls:*', NOTIFICATIONS: 'notifications:*', APPOINTMENTS: 'appointments:*', } as const; // 用户认证相关函数 export const auth = { // 获取当前用户 getCurrentUser: async () => { const { data: { user }, error } = await supabase.auth.getUser(); if (error) throw error; return user; }, // 登录 signIn: async (email: string, password: string) => { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) throw error; return data; }, // 注册 signUp: async (email: string, password: string, userData?: any) => { const { data, error } = await supabase.auth.signUp({ email, password, options: { data: userData, }, }); if (error) throw error; return data; }, // 登出 signOut: async () => { const { error } = await supabase.auth.signOut(); if (error) throw error; }, // 重置密码 resetPassword: async (email: string) => { const { data, error } = await supabase.auth.resetPasswordForEmail(email, { redirectTo: `${window.location.origin}/auth/reset-password`, }); if (error) throw error; return data; }, // 更新密码 updatePassword: async (password: string) => { const { data, error } = await supabase.auth.updateUser({ password, }); if (error) throw error; return data; }, // 获取当前会话 getSession: async () => { const { data: { session }, error } = await supabase.auth.getSession(); if (error) throw error; return session; }, // 更新用户信息 updateUser: async (updates: any) => { const { data, error } = await supabase.auth.updateUser(updates); if (error) throw error; return data; }, }; // 数据库操作辅助函数 export const db = { // 通用查询函数 select: async (table: string, query?: any) => { let queryBuilder = supabase.from(table).select(query || '*'); const { data, error } = await queryBuilder; if (error) throw error; return data as T[]; }, // 通用插入函数 insert: async (table: string, data: any) => { const { data: result, error } = await supabase .from(table) .insert(data) .select() .single(); if (error) throw error; return result as T; }, // 通用更新函数 update: async (table: string, id: string, data: any) => { const { data: result, error } = await supabase .from(table) .update(data) .eq('id', id) .select() .single(); if (error) throw error; return result as T; }, // 通用删除函数 delete: async (table: string, id: string) => { const { error } = await supabase .from(table) .delete() .eq('id', id); if (error) throw error; }, // 根据条件查询单条记录 findOne: async (table: string, conditions: Record, select?: string) => { let query = supabase.from(table).select(select || '*'); Object.entries(conditions).forEach(([key, value]) => { query = query.eq(key, value); }); const { data, error } = await query.single(); if (error) throw error; return data as T; }, // 根据条件查询多条记录 findMany: async (table: string, conditions?: Record, select?: string) => { let query = supabase.from(table).select(select || '*'); if (conditions) { Object.entries(conditions).forEach(([key, value]) => { query = query.eq(key, value); }); } const { data, error } = await query; if (error) throw error; return data as T[]; }, // 计数查询 count: async (table: string, conditions?: Record) => { let query = supabase.from(table).select('*', { count: 'exact', head: true }); if (conditions) { Object.entries(conditions).forEach(([key, value]) => { query = query.eq(key, value); }); } const { count, error } = await query; if (error) throw error; return count || 0; }, }; // 实时订阅管理 export const realtime = { subscribe: (table: string, callback: (payload: any) => void) => { const channel = supabase .channel(`${table}_changes`) .on('postgres_changes', { event: '*', schema: 'public', table: table }, callback ) .subscribe(); return channel; }, unsubscribe: (channel: any) => { if (channel) { supabase.removeChannel(channel); } }, }; // 文件上传相关函数 export const storage = { // 上传文件 upload: async (bucket: string, path: string, file: File) => { const { data, error } = await supabase.storage .from(bucket) .upload(path, file); if (error) throw error; return data; }, // 下载文件 download: async (bucket: string, path: string) => { const { data, error } = await supabase.storage .from(bucket) .download(path); if (error) throw error; return data; }, // 获取公共URL getPublicUrl: (bucket: string, path: string) => { const { data } = supabase.storage .from(bucket) .getPublicUrl(path); return data.publicUrl; }, // 删除文件 remove: async (bucket: string, paths: string[]) => { const { data, error } = await supabase.storage .from(bucket) .remove(paths); if (error) throw error; return data; }, }; // 用户类型定义 export type UserRole = 'admin' | 'interpreter' | 'client' | 'enterprise'; // 用户权限检查 export const permissions = { // 检查用户是否有特定权限 hasPermission: (userRole: UserRole, requiredRole: UserRole) => { const roleHierarchy: Record = { 'client': 1, 'interpreter': 2, 'enterprise': 3, 'admin': 4, }; return roleHierarchy[userRole] >= roleHierarchy[requiredRole]; }, // 检查用户是否为管理员 isAdmin: (userRole: UserRole) => userRole === 'admin', // 检查用户是否为翻译员 isInterpreter: (userRole: UserRole) => userRole === 'interpreter', // 检查用户是否为企业用户 isEnterprise: (userRole: UserRole) => userRole === 'enterprise', }; // 错误处理 export const handleSupabaseError = (error: any) => { console.error('Supabase Error:', error); // 根据错误类型返回用户友好的消息 if (error.code === 'PGRST116') { return '未找到记录'; } else if (error.code === '23505') { return '数据已存在'; } else if (error.code === '23503') { return '数据关联错误'; } else if (error.message?.includes('JWT')) { return '登录已过期,请重新登录'; } else if (error.message?.includes('permission')) { return '权限不足'; } else { return error.message || '操作失败,请稍后重试'; } }; // 检查 Supabase 是否正确配置 export const isSupabaseConfigured = () => { return !isDemoMode && supabaseUrl !== 'https://demo.supabase.co' && supabaseAnonKey !== 'demo-key'; }; // 获取配置状态 export const getConfigStatus = () => { return { isDemoMode, isConfigured: isSupabaseConfigured(), url: supabaseUrl, hasAnonKey: supabaseAnonKey !== 'demo-key', hasServiceKey: supabaseServiceKey !== 'demo-service-key', }; }; // 默认导出 export default supabase;