import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '../../contexts/AuthContext'; import { supabase } from '../../supabase/client'; import { motion, AnimatePresence } from 'framer-motion'; import { Factory, Droplets, FileText, ChevronRight, ArrowLeft, Plus, X, Building2, Phone, MapPin, User, Edit2 } from 'lucide-react'; import { useResponsive } from '../../hooks/useResponsive'; import type { Company } from '../../types'; export function FactoryManage() { const navigate = useNavigate(); const { auth } = useAuth(); const { isMobile } = useResponsive(); const [activeTab, setActiveTab] = useState<'textile' | 'washing'>('textile'); const [factories, setFactories] = useState([]); const [planCounts, setPlanCounts] = useState>({}); const [loading, setLoading] = useState(true); const [expandedId, setExpandedId] = useState(null); // 新建/编辑工厂弹窗状态 const [showModal, setShowModal] = useState(false); const [editingFactory, setEditingFactory] = useState(null); const [formData, setFormData] = useState({ name: '', contactPerson: '', contactPhone: '', address: '' }); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(''); useEffect(() => { if (!auth.company) return; fetchFactories(); }, [auth.company, activeTab]); const fetchFactories = async () => { setLoading(true); // 直接查询所有该类型的工厂(不再通过 plan_factories 关联) const { data: factoryData } = await supabase .from('companies') .select('*') .eq('role', activeTab) .order('created_at', { ascending: false }); setFactories(factoryData || []); // 计算每个工厂的计划数(通过 plan_factories 统计) if (factoryData && factoryData.length > 0) { const factoryIds = factoryData.map(f => f.id); const { data: planFactories } = await supabase .from('plan_factories') .select('factory_id') .in('factory_id', factoryIds) .eq('factory_type', activeTab); const counts: Record = {}; planFactories?.forEach(pf => { counts[pf.factory_id] = (counts[pf.factory_id] || 0) + 1; }); setPlanCounts(counts); } else { setPlanCounts({}); } setLoading(false); }; const handleOpenModal = () => { setEditingFactory(null); setFormData({ name: '', contactPerson: '', contactPhone: '', address: '' }); setError(''); setShowModal(true); }; const handleOpenEditModal = (factory: Company) => { setEditingFactory(factory); setFormData({ name: factory.name, contactPerson: '', contactPhone: factory.contact_phone || '', address: factory.address || '' }); setError(''); setShowModal(true); }; const handleCloseModal = () => { setShowModal(false); setEditingFactory(null); setFormData({ name: '', contactPerson: '', contactPhone: '', address: '' }); setError(''); }; const validateForm = () => { if (!formData.name.trim()) return '请输入工厂名称'; if (!formData.contactPhone.trim()) return '请输入联系电话'; return ''; }; // 检查工厂名称是否已存在(同一类型下) const checkDuplicateName = async (name: string, excludeId?: string): Promise => { const { data, error } = await supabase .from('companies') .select('id') .eq('role', activeTab) .ilike('name', name.trim()) .limit(1); if (error) { console.error('检查重名失败:', error); return false; } // 如果存在记录且不是当前编辑的工厂,则认为是重名 if (data && data.length > 0) { if (excludeId && data[0].id === excludeId) { return false; // 是自己,不算重名 } return true; } return false; }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const validationError = validateForm(); if (validationError) { setError(validationError); return; } if (!auth.company) { setError('请先登录'); return; } setSubmitting(true); setError(''); try { // 检查重名 const isDuplicate = await checkDuplicateName(formData.name, editingFactory?.id); if (isDuplicate) { setError(`该${activeTab === 'textile' ? '织布厂' : '水洗厂'}名称已存在,请使用其他名称`); setSubmitting(false); return; } if (editingFactory) { // 更新工厂信息 const { error: updateError } = await supabase .from('companies') .update({ name: formData.name, contact_phone: formData.contactPhone, address: formData.address }) .eq('id', editingFactory.id); if (updateError) { setError('更新工厂失败:' + updateError.message); setSubmitting(false); return; } } else { // 创建工厂(作为公司) const { data: newFactory, error: factoryError } = await supabase .from('companies') .insert({ name: formData.name, role: activeTab, contact_phone: formData.contactPhone, address: formData.address }) .select() .single(); if (factoryError || !newFactory) { setError('创建工厂失败:' + factoryError?.message); setSubmitting(false); return; } // 工厂创建成功,直接显示在列表中(不再需要通过 plan_factories 关联) } // 刷新工厂列表 await fetchFactories(); handleCloseModal(); } catch (err) { setError(editingFactory ? '更新工厂时发生错误' : '创建工厂时发生错误'); console.error(err); } setSubmitting(false); }; return (

工厂管理

新建工厂
{loading ? (
加载中...
) : factories.length === 0 ? (

暂无关联的{activeTab === 'textile' ? '织布厂' : '水洗厂'}

点击右上角"新建工厂"按钮添加

新建工厂
) : (
{factories.map(factory => (
setExpandedId(expandedId === factory.id ? null : factory.id)} className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50 transition-colors" >
{activeTab === 'textile' ? : }

{factory.name}

{factory.address || '-'}

{planCounts[factory.id] || 0}个计划
{expandedId === factory.id && (
联系人: -
联系电话: {factory.contact_phone || '-'}
地址: {factory.address || '-'}
handleOpenEditModal(factory)} className="flex items-center gap-1.5 px-3 py-1.5 text-sm text-blue-600 bg-blue-50 hover:bg-blue-100 rounded-lg transition-colors" > 编辑工厂
)}
))}
)}
{/* 新建工厂弹窗 */} {showModal && (

{editingFactory ? '编辑' : '新建'}{activeTab === 'textile' ? '织布厂' : '水洗厂'}

setFormData({ ...formData, name: e.target.value })} className="w-full pl-10 pr-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" placeholder={`请输入${activeTab === 'textile' ? '织布厂' : '水洗厂'}名称`} required />
setFormData({ ...formData, contactPerson: e.target.value })} className="w-full pl-10 pr-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" placeholder="请输入联系人姓名" />
setFormData({ ...formData, contactPhone: e.target.value })} className="w-full pl-10 pr-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all" placeholder="请输入联系电话" required />