import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { Card, Button, Spin, Result, message, Modal, Input } from 'antd'; import { CheckCircleOutlined, CloseCircleOutlined, ClockCircleOutlined, ExclamationCircleOutlined, EditOutlined, } from '@ant-design/icons'; import { aftersalesApi } from '@/services/api'; import type { AftersalesPublicView, AftersalesServiceType } from '@/types'; import PublicLayout, { PublicLogo } from '@/components/PublicLayout'; import SignatureOverlay from '@/components/SignatureOverlay'; import './styles/PublicQuery.css'; import './styles/AftersalesConfirm.css'; const SERVICE_TYPE_LABEL: Record = { software: '软件故障', hardware: '硬件故障', maintenance: '售后维保', }; function AftersalesConfirmPage() { const { serialNumber = '' } = useParams<{ serialNumber: string }>(); const [order, setOrder] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [submitting, setSubmitting] = useState(false); const [rejectReason, setRejectReason] = useState(''); const [showRejectDialog, setShowRejectDialog] = useState(false); const [signatureData, setSignatureData] = useState(''); const [showSignatureOverlay, setShowSignatureOverlay] = useState(false); const loadOrder = async () => { setLoading(true); setError(null); try { const data = await aftersalesApi.publicQuery(serialNumber); setOrder(data); } catch (err: any) { setError(err?.response?.data?.message || err.message || '查询失败'); } finally { setLoading(false); } }; useEffect(() => { if (serialNumber) { loadOrder(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [serialNumber]); const handleAuthorize = async () => { if (!signatureData) { message.error('请先签名'); return; } setSubmitting(true); try { const updated = await aftersalesApi.customerConfirm(serialNumber, { action: 'authorize', signature: signatureData, }); setOrder(updated); message.success('感谢您的确认,工单已完成'); } catch (err: any) { message.error(err?.response?.data?.message || err.message || '提交失败'); } finally { setSubmitting(false); } }; const openRejectDialog = () => { setRejectReason(''); setShowRejectDialog(true); }; const confirmReject = async () => { const reason = rejectReason.trim(); if (!reason) { message.error('请填写退回原因'); return; } setSubmitting(true); try { const updated = await aftersalesApi.customerConfirm(serialNumber, { action: 'reject', rejectReason: reason, }); setOrder(updated); setShowRejectDialog(false); message.success('已通知技术员重新处理'); } catch (err: any) { message.error(err?.response?.data?.message || err.message || '提交失败'); } finally { setSubmitting(false); } }; const handleClearSignature = () => { setSignatureData(''); }; if (loading) { return (

正在加载工单...

); } if (error || !order) { return ( } title="工单不存在" subTitle={error || '请检查您扫描的二维码是否正确'} /> ); } const isPending = order.workOrderStatus === 'pending_confirmation'; const isClosed = order.workOrderStatus === 'closed'; const isRejected = order.workOrderStatus === 'rejected'; const isCreated = order.workOrderStatus === 'created'; const renderStatusBanner = () => { if (isClosed) { return ( } title="工单已完成" subTitle={ order.confirmedAt ? `确认时间:${new Date(order.confirmedAt).toLocaleString('zh-CN')}` : undefined } /> ); } if (isRejected) { return ( } title="工单已退回" subTitle="技术员将重新处理,请耐心等待" /> ); } if (isCreated) { return ( } title="工单处理中" subTitle="技术员尚未提交客户确认,请稍后再来查看" /> ); } return null; }; return (

售后服务确认

{order.serialNumber}

{renderStatusBanner()}
公司名称 {order.companyName}
公司位置 {order.companyAddress}
联系人 {order.contactName}
服务类型 {SERVICE_TYPE_LABEL[order.serviceType] || order.serviceType}
问题描述反馈 {order.issueDescription}
{order.resolutionNote && (
处理结果 {order.resolutionNote}
)} {order.technicianName && (
处理人 {order.technicianName}
)}
创建日期 {new Date(order.createdAt).toLocaleString('zh-CN')}
{isClosed && order.signature && (

客户确认签名

客户确认签名
)} {isPending && ( <>

请签名确认维修结果

{signatureData && ( )}
{signatureData ? ( ) : ( )}
)}
setShowSignatureOverlay(false)} onConfirm={(url) => { setSignatureData(url); setShowSignatureOverlay(false); }} /> setShowRejectDialog(false)} onOk={confirmReject} okText="确认退回" cancelText="取消" confirmLoading={submitting} > setRejectReason(e.target.value)} maxLength={200} />
); } export default AftersalesConfirmPage;