import React, { useState, useCallback, useEffect, useRef } from 'react'; import { motion } from 'framer-motion'; import { Share2, Copy, Check, X, AlertTriangle, Building2, Eye, EyeOff, Link2, Send } from 'lucide-react'; import { useResponsive } from '../../hooks/useResponsive'; import { encryptShareParams } from '../../utils/shareCrypto'; import { http, commonApi } from '../../api'; import { useAuth } from '../../contexts/AuthContext'; interface ShareModalProps { isOpen: boolean; onClose: () => void; planId: string; factoryType: 'textile' | 'washing'; factoryId?: string; factoryName?: string; planProductName?: string; planColor?: string; planColorCode?: string; onDirectPush?: () => void; // 直接推送回调 } // 合作关系类型 interface CompanyRelationship { id: string; purchaser_company_id: string; factory_company_id: string; factory_type: 'textile' | 'washing'; status: 'active' | 'inactive'; } // 分享链接状态 interface ShareLinkStatus { id: string; short_code: string; status: 'pending' | 'clicked' | 'confirmed' | 'rejected' | 'expired' | 'cancelled'; clicked_at: string | null; responded_at: string | null; response_result: 'confirmed' | 'rejected' | null; reject_reason: string | null; expires_at: string; created_at: string; } export function ShareModal({ isOpen, onClose, planId, factoryType, factoryId, factoryName, planProductName, planColor, planColorCode, onDirectPush }: ShareModalProps) { const { isMobile } = useResponsive(); const { auth } = useAuth(); const [copied, setCopied] = useState(false); const [showConfirm, setShowConfirm] = useState(false); const [recipientCompany, setRecipientCompany] = useState(''); const [confirmFactoryName, setConfirmFactoryName] = useState(''); const [confirmCompanyName, setConfirmCompanyName] = useState(''); const [error, setError] = useState(''); const [shortCode, setShortCode] = useState(''); const [hideSensitive, setHideSensitive] = useState(false); const shortLinkGenerated = useRef(false); // 新流程状态 const [hasRelationship, setHasRelationship] = useState(null); const [isCheckingRelationship, setIsCheckingRelationship] = useState(false); const [existingLink, setExistingLink] = useState(null); const [isGeneratingLink, setIsGeneratingLink] = useState(false); const [pushSuccess, setPushSuccess] = useState(false); // 获取当前用户的公司名称和检查合作关系 useEffect(() => { const fetchData = async () => { if (!isOpen || !factoryId) return; setIsCheckingRelationship(true); if (!auth.user) { setIsCheckingRelationship(false); return; } try { if (auth.company) { setRecipientCompany(auth.company.name); const res = await http.get<{ has_relationship: boolean }>('/common/companies/check-relationship', { factory_id: factoryId, }); setHasRelationship(res.data.has_relationship); if (!res.data.has_relationship) { try { const linkRes = await http.get('/common/share-links/active', { plan_id: planId, factory_type: factoryType, }); if (linkRes.data) { const link = linkRes.data; const expiresAt = link.expires_at ? new Date(link.expires_at) : null; if (expiresAt && expiresAt > new Date()) { setExistingLink(link); setShortCode(link.short_code); } } } catch { // no existing link } } } } catch { setHasRelationship(false); } setIsCheckingRelationship(false); }; fetchData(); return () => { shortLinkGenerated.current = false; setShortCode(''); setExistingLink(null); setHasRelationship(null); setPushSuccess(false); }; }, [isOpen, planId, factoryType, factoryId]); // 生成短链(30分钟有效) const generateShortLink = useCallback(async () => { if (!factoryId) return; setIsGeneratingLink(true); try { const res = await commonApi.createShareLink({ type: factoryType, target_id: planId, }); if (res.code) { setShortCode(res.code); } else { setError('生成链接失败,请重试'); } } catch { setError('生成链接失败,请重试'); } setIsGeneratingLink(false); }, [planId, factoryType, hideSensitive, factoryId]); const handleDirectPush = async () => { if (!factoryId || !onDirectPush) return; setIsGeneratingLink(true); try { await http.post(`/purchaser/plans/${planId}/factories`, { factory_id: factoryId, factory_type: factoryType, }); setPushSuccess(true); setTimeout(() => { onDirectPush(); onClose(); }, 1500); } catch { setError('推送失败,请重试'); } setIsGeneratingLink(false); }; // 长链接 token(异步生成) const [longLinkToken, setLongLinkToken] = useState(''); useEffect(() => { if (isOpen && !hasRelationship) { encryptShareParams(planId, factoryType, hideSensitive).then(token => { setLongLinkToken(token); }); } }, [isOpen, planId, factoryType, hideSensitive, hasRelationship]); // 生成分享链接 const generateShareLink = useCallback(() => { const baseUrl = window.location.origin + window.location.pathname; if (shortCode) { return `${baseUrl}#/import?s=${shortCode}`; } if (longLinkToken) { return `${baseUrl}#/import?token=${longLinkToken}`; } return ''; }, [shortCode, longLinkToken]); const handleCopy = useCallback(async () => { const link = generateShareLink(); try { await navigator.clipboard.writeText(link); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch { const textarea = document.createElement('textarea'); textarea.value = link; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); setCopied(true); setTimeout(() => setCopied(false), 2000); } }, [generateShareLink]); // 检查链接状态 const checkLinkStatus = async () => { if (!existingLink) return; try { const data = await commonApi.getShareLink(existingLink.short_code || existingLink.id); if (data) { setExistingLink(data as ShareLinkStatus); } } catch { // ignore } }; if (!isOpen) return null; const link = generateShareLink(); const factoryLabel = factoryType === 'textile' ? '织布厂' : '水洗厂'; return (
{/* 加载中 */} {isCheckingRelationship && (

检查合作关系...

)} {/* 已有合作关系 - 直接推送 */} {!isCheckingRelationship && hasRelationship === true && ( <>

直接推送

已合作工厂,计划将直接推送

目标工厂

{factoryName || '未指定'}

✓ 已建立合作关系

{pushSuccess && (

✓ 计划推送成功!

)} {error && (

{error}

)}
)} {/* 无合作关系 - 生成分享链接 */} {!isCheckingRelationship && hasRelationship === false && ( <> {!showConfirm ? ( <>

生成分享链接

首次合作,需生成链接邀请

{/* 工厂信息 */}
目标工厂

{factoryName || '未指定'}

⚠ 未建立合作关系

{/* 已有链接状态显示 */} {existingLink && (
链接状态 {existingLink.status === 'pending' && '待点击'} {existingLink.status === 'clicked' && '已点击'} {existingLink.status === 'confirmed' && '已确认'} {existingLink.status === 'rejected' && '已拒绝'}
{existingLink.status === 'clicked' && (

工厂已查看,等待确认...

)} {existingLink.status === 'rejected' && existingLink.reject_reason && (

拒绝原因:{existingLink.reject_reason}

)}
)} {/* 隐藏敏感信息开关 */}
{hideSensitive ? : }

隐藏成品信息

成品名称、颜色、色号将不在链接中显示

{hideSensitive && (

以下信息将被隐藏:

{planProductName && 成品名称: {planProductName}} {planColor && 颜色: {planColor}} {planColorCode && 色号: {planColorCode}}
)}
{/* 链接显示 */} {shortCode && (

分享链接(30分钟内有效)

{link}

)} {error && (

{error}

)}
{shortCode ? ( ) : ( )}
) : ( <>

二次确认

请确认分享信息

目标工厂

{factoryName || '未指定'}

您的公司

{recipientCompany || '加载中...'}

setConfirmFactoryName(e.target.value)} placeholder="输入工厂名称" className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-amber-500/20 focus:border-amber-500" />
setConfirmCompanyName(e.target.value)} placeholder="输入对方公司名称" className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-amber-500/20 focus:border-amber-500" />
{error && (

{error}

)}
)} )}
); }