import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Head from 'next/head'; import { toast } from 'react-hot-toast'; import { MagnifyingGlassIcon, BuildingOfficeIcon, UsersIcon, DocumentTextIcon, CurrencyDollarIcon, PlusIcon, PencilIcon, TrashIcon, EyeIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline'; import { supabase, TABLES } from '@/lib/supabase'; import { getDemoData } from '@/lib/demo-data'; import { formatTime } from '@/utils'; import Layout from '@/components/Layout'; interface EnterpriseContract { id: string; enterprise_id: string; enterprise_name: string; contract_number: string; contract_type: 'annual' | 'monthly' | 'project'; start_date: string; end_date: string; total_amount: number; currency: string; status: 'active' | 'expired' | 'terminated'; service_rates: { ai_voice: number; // AI语音翻译费率(元/分钟) ai_video: number; // AI视频翻译费率(元/分钟) sign_language: number; // 手语翻译费率(元/分钟) human_interpreter: number; // 真人翻译费率(元/分钟) document_translation: number; // 文档翻译费率(元/字) }; created_at: string; updated_at: string; } interface EnterpriseEmployee { id: string; enterprise_id: string; enterprise_name: string; name: string; email: string; department: string; position: string; status: 'active' | 'inactive'; total_calls: number; total_cost: number; created_at: string; } interface EnterpriseBilling { id: string; enterprise_id: string; enterprise_name: string; period: string; total_calls: number; total_duration: number; total_amount: number; currency: string; status: 'pending' | 'paid' | 'overdue'; due_date: string; paid_date?: string; created_at: string; } interface EnterpriseFilters { search: string; tab: 'contracts' | 'employees' | 'billing'; status: 'all' | 'active' | 'inactive' | 'expired' | 'pending' | 'paid' | 'overdue'; enterprise: 'all' | string; sortBy: 'created_at' | 'name' | 'amount' | 'total_calls'; sortOrder: 'asc' | 'desc'; } export default function EnterprisePage() { const [contracts, setContracts] = useState([]); const [employees, setEmployees] = useState([]); const [billing, setBilling] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [totalCount, setTotalCount] = useState(0); const [isDemoMode, setIsDemoMode] = useState(false); const [filters, setFilters] = useState({ search: '', tab: 'contracts', status: 'all', enterprise: 'all', sortBy: 'created_at', sortOrder: 'desc' }); const router = useRouter(); const pageSize = 20; // 获取企业数据 const fetchEnterpriseData = async (page = 1) => { try { setLoading(true); // 检查是否为演示模式 const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const isDemo = !supabaseUrl || supabaseUrl === 'https://demo.supabase.co' || supabaseUrl === ''; setIsDemoMode(isDemo); if (isDemo) { // 使用演示数据 const result = await getDemoData.enterprise(); switch (filters.tab) { case 'contracts': setContracts(result.contracts); setTotalCount(result.contracts.length); break; case 'employees': setEmployees(result.employees); setTotalCount(result.employees.length); break; case 'billing': setBilling(result.billing); setTotalCount(result.billing.length); break; } setTotalPages(Math.ceil(totalCount / pageSize)); setCurrentPage(page); } else { // 使用真实数据 - 这里需要根据实际数据库结构调整 // 暂时使用演示数据 const result = await getDemoData.enterprise(); switch (filters.tab) { case 'contracts': setContracts(result.contracts); setTotalCount(result.contracts.length); break; case 'employees': setEmployees(result.employees); setTotalCount(result.employees.length); break; case 'billing': setBilling(result.billing); setTotalCount(result.billing.length); break; } setTotalPages(Math.ceil(totalCount / pageSize)); setCurrentPage(page); } } catch (error) { console.error('Error fetching enterprise data:', error); toast.error('获取企业数据失败'); } finally { setLoading(false); } }; // 处理筛选变更 const handleFilterChange = (key: keyof EnterpriseFilters, value: any) => { setFilters(prev => ({ ...prev, [key]: value })); }; // 应用筛选 const applyFilters = () => { setCurrentPage(1); fetchEnterpriseData(1); }; // 重置筛选 const resetFilters = () => { setFilters({ search: '', tab: filters.tab, status: 'all', enterprise: 'all', sortBy: 'created_at', sortOrder: 'desc' }); setCurrentPage(1); fetchEnterpriseData(1); }; // 获取状态颜色 const getStatusColor = (status: string) => { switch (status) { case 'active': return 'bg-green-100 text-green-800'; case 'inactive': case 'expired': return 'bg-red-100 text-red-800'; case 'terminated': return 'bg-gray-100 text-gray-800'; case 'pending': return 'bg-yellow-100 text-yellow-800'; case 'paid': return 'bg-green-100 text-green-800'; case 'overdue': return 'bg-red-100 text-red-800'; default: return 'bg-gray-100 text-gray-800'; } }; // 获取状态文本 const getStatusText = (status: string) => { switch (status) { case 'active': return '活跃'; case 'inactive': return '非活跃'; case 'expired': return '已过期'; case 'terminated': return '已终止'; case 'pending': return '待付款'; case 'paid': return '已付款'; case 'overdue': return '逾期'; default: return '未知'; } }; // 删除员工 const handleDeleteEmployee = async (employeeId: string) => { if (confirm('确定要删除此员工吗?')) { try { // 这里应该调用删除API toast.success('员工删除成功'); fetchEnterpriseData(); } catch (error) { toast.error('删除员工失败'); } } }; // 员工结算 const handleEmployeeSettlement = async (employeeId: string) => { try { // 这里应该调用结算API toast.success('员工结算完成'); fetchEnterpriseData(); } catch (error) { toast.error('员工结算失败'); } }; // 获取唯一的企业列表(用于筛选下拉框) const getUniqueEnterprises = () => { const enterprises = new Set(); employees.forEach(emp => enterprises.add(emp.enterprise_name)); contracts.forEach(contract => enterprises.add(contract.enterprise_name)); return Array.from(enterprises) as string[]; }; useEffect(() => { fetchEnterpriseData(); }, [filters.tab]); const renderContracts = () => (

企业合同管理

管理企业合同信息和服务费率配置

{/* 搜索和筛选 */}
handleFilterChange('search', e.target.value)} />
{/* 合同列表 */}
{contracts.map((contract) => (

{contract.enterprise_name}

合同号: {contract.contract_number}

{getStatusText(contract.status)}
合同类型
{contract.contract_type === 'annual' ? '年度合同' : contract.contract_type === 'monthly' ? '月度合同' : '项目合同'}
合同期限
{formatTime(contract.start_date)} - {formatTime(contract.end_date)}
合同金额
¥{contract.total_amount.toLocaleString()}
{/* 服务费率配置 */}
服务费率配置
AI语音翻译
¥{contract.service_rates.ai_voice}/分钟
AI视频翻译
¥{contract.service_rates.ai_video}/分钟
手语翻译
¥{contract.service_rates.sign_language}/分钟
真人翻译
¥{contract.service_rates.human_interpreter}/分钟
文档翻译
¥{contract.service_rates.document_translation}/字
))}
{/* 分页 */} {totalPages > 1 && (
显示第 {(currentPage - 1) * pageSize + 1} - {Math.min(currentPage * pageSize, totalCount)} 条,共 {totalCount} 条
{currentPage} / {totalPages}
)}
); const renderEmployees = () => (

企业员工管理

管理企业员工信息和通话记录

{/* 搜索和筛选 */}
handleFilterChange('search', e.target.value)} />
{/* 员工列表 */}
{employees.map((employee) => ( ))}
员工信息 所属企业 部门/职位 通话统计 状态 操作
{employee.name.charAt(0)}
{employee.name}
{employee.email}
{employee.enterprise_name}
{employee.department}
{employee.position}
{employee.total_calls} 次通话
¥{employee.total_cost.toFixed(2)}
{getStatusText(employee.status)}
); const renderBilling = () => (
{billing.map((bill) => (

{bill.enterprise_name}

账单期间: {bill.period}

通话次数: {bill.total_calls} | 总时长: {Math.floor(bill.total_duration / 60)}分钟

金额: ¥{bill.total_amount.toFixed(2)}

到期日期: {formatTime(bill.due_date)} {bill.paid_date && ` | 付款日期: ${formatTime(bill.paid_date)}`}

{getStatusText(bill.status)}
))}
); return ( 企业服务 - 口译服务管理后台
{/* 页面标题 */}

企业服务管理

{/* 标签页 */}
{/* 搜索和筛选 */}
{/* 搜索框 */}
handleFilterChange('search', e.target.value)} className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-blue-500 focus:border-blue-500" />
{/* 状态筛选 */}
{/* 排序 */}
{/* 内容区域 */} {loading ? (
) : (

{filters.tab === 'contracts' ? '企业合同' : filters.tab === 'employees' ? '企业员工' : '结算记录'} ({totalCount} 条记录)

{filters.tab === 'contracts' && renderContracts()} {filters.tab === 'employees' && renderEmployees()} {filters.tab === 'billing' && renderBilling()} {/* 分页 */} {totalPages > 1 && (

显示第 {(currentPage - 1) * pageSize + 1} 到{' '} {Math.min(currentPage * pageSize, totalCount)} {' '} 条,共 {totalCount} 条记录

)}
)}
); }