192 lines
4.8 KiB
TypeScript
192 lines
4.8 KiB
TypeScript
import { createClient } from '@supabase/supabase-js'
|
|
|
|
// Supabase配置 - 与客户端使用相同的数据库
|
|
const supabaseUrl = 'https://riwtulmitqioswmgwftg.supabase.co'
|
|
const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJpd3R1bG1pdHFpb3N3bWd3ZnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg1OTc1ODgsImV4cCI6MjA2NDE3MzU4OH0.fxSW_uEbpR1zwepjb83DIUIwTrmsboK2nTjPpS6XMtw'
|
|
|
|
// 创建Supabase客户端
|
|
export const supabase = createClient(supabaseUrl, supabaseKey)
|
|
|
|
// Supabase客户端的组合式函数
|
|
export const useSupabase = () => {
|
|
return {
|
|
supabase
|
|
}
|
|
}
|
|
|
|
// 数据库表接口定义
|
|
export interface Profile {
|
|
id: string
|
|
email: string
|
|
full_name: string
|
|
avatar_url?: string
|
|
role: 'customer' | 'interpreter' | 'admin'
|
|
languages?: string[]
|
|
credits: number
|
|
created_at: string
|
|
updated_at: string
|
|
phone?: string
|
|
is_enterprise: boolean
|
|
enterprise_id?: string
|
|
subscription_id?: string
|
|
contract_pricing?: any
|
|
status: 'active' | 'inactive' | 'suspended'
|
|
}
|
|
|
|
export interface Call {
|
|
id: string
|
|
room_id: string
|
|
caller_id: string
|
|
interpreter_id?: string
|
|
start_time: string
|
|
end_time?: string
|
|
duration?: number
|
|
status: 'pending' | 'active' | 'completed' | 'cancelled'
|
|
source_language: string
|
|
target_language: string
|
|
type: 'audio' | 'video' | 'text'
|
|
cost?: number
|
|
created_at: string
|
|
}
|
|
|
|
export interface Translation {
|
|
id: string
|
|
call_id: string
|
|
user_id: string
|
|
source_text: string
|
|
translated_text: string
|
|
source_language: string
|
|
target_language: string
|
|
type: 'real_time' | 'document'
|
|
timestamp: string
|
|
}
|
|
|
|
export interface Payment {
|
|
id: string
|
|
user_id: string
|
|
amount: number
|
|
currency: string
|
|
status: 'pending' | 'completed' | 'failed' | 'refunded'
|
|
stripe_payment_id?: string
|
|
created_at: string
|
|
}
|
|
|
|
export interface Interpreter {
|
|
id: string
|
|
name: string
|
|
avatar?: string
|
|
description?: string
|
|
status: 'available' | 'busy' | 'offline'
|
|
created_at: string
|
|
}
|
|
|
|
// 通用数据库操作函数
|
|
export const useSupabaseData = () => {
|
|
// 获取所有用户资料
|
|
const getProfiles = async () => {
|
|
const { data, error } = await supabase
|
|
.from('profiles')
|
|
.select('*')
|
|
.order('created_at', { ascending: false })
|
|
|
|
if (error) throw error
|
|
return data as Profile[]
|
|
}
|
|
|
|
// 获取所有通话记录
|
|
const getCalls = async () => {
|
|
const { data, error } = await supabase
|
|
.from('calls')
|
|
.select(`
|
|
*,
|
|
profiles!calls_caller_id_fkey(full_name, email),
|
|
interpreters(name)
|
|
`)
|
|
.order('created_at', { ascending: false })
|
|
|
|
if (error) throw error
|
|
return data
|
|
}
|
|
|
|
// 获取所有翻译记录
|
|
const getTranslations = async () => {
|
|
const { data, error } = await supabase
|
|
.from('translations')
|
|
.select(`
|
|
*,
|
|
calls(room_id, status),
|
|
profiles(full_name, email)
|
|
`)
|
|
.order('timestamp', { ascending: false })
|
|
|
|
if (error) throw error
|
|
return data
|
|
}
|
|
|
|
// 获取所有支付记录
|
|
const getPayments = async () => {
|
|
const { data, error } = await supabase
|
|
.from('payments')
|
|
.select(`
|
|
*,
|
|
profiles(full_name, email)
|
|
`)
|
|
.order('created_at', { ascending: false })
|
|
|
|
if (error) throw error
|
|
return data
|
|
}
|
|
|
|
// 获取所有口译员
|
|
const getInterpreters = async () => {
|
|
const { data, error } = await supabase
|
|
.from('interpreters')
|
|
.select('*')
|
|
.order('created_at', { ascending: false })
|
|
|
|
if (error) throw error
|
|
return data as Interpreter[]
|
|
}
|
|
|
|
// 获取统计数据
|
|
const getStats = async () => {
|
|
const [
|
|
{ count: totalUsers },
|
|
{ count: totalCalls },
|
|
{ count: activeInterpreters },
|
|
{ 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 }).eq('status', 'available'),
|
|
supabase.from('payments').select('amount').eq('status', 'completed').order('created_at', { ascending: false }).limit(100)
|
|
])
|
|
|
|
const totalRevenue = recentPayments?.reduce((sum, payment) => sum + payment.amount, 0) || 0
|
|
|
|
return {
|
|
totalUsers: totalUsers || 0,
|
|
totalCalls: totalCalls || 0,
|
|
activeInterpreters: activeInterpreters || 0,
|
|
totalRevenue
|
|
}
|
|
}
|
|
|
|
// 实时数据订阅
|
|
const subscribeToTable = (table: string, callback: (payload: any) => void) => {
|
|
return supabase
|
|
.channel(`public:${table}`)
|
|
.on('postgres_changes', { event: '*', schema: 'public', table }, callback)
|
|
.subscribe()
|
|
}
|
|
|
|
return {
|
|
getProfiles,
|
|
getCalls,
|
|
getTranslations,
|
|
getPayments,
|
|
getInterpreters,
|
|
getStats,
|
|
subscribeToTable
|
|
}
|
|
}
|