Require dual signatures for aftersales confirmation
This commit is contained in:
+121
-45
@@ -29,8 +29,11 @@ function AftersalesConfirmPage() {
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [rejectReason, setRejectReason] = useState('');
|
||||
const [showRejectDialog, setShowRejectDialog] = useState(false);
|
||||
const [signatureData, setSignatureData] = useState('');
|
||||
const [showSignatureOverlay, setShowSignatureOverlay] = useState(false);
|
||||
const [customerSignatureData, setCustomerSignatureData] = useState('');
|
||||
const [responsibleSignatureData, setResponsibleSignatureData] = useState('');
|
||||
const [activeSignatureRole, setActiveSignatureRole] = useState<'customer' | 'responsible' | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
const loadOrder = async () => {
|
||||
setLoading(true);
|
||||
@@ -53,15 +56,20 @@ function AftersalesConfirmPage() {
|
||||
}, [serialNumber]);
|
||||
|
||||
const handleAuthorize = async () => {
|
||||
if (!signatureData) {
|
||||
message.error('请先签名');
|
||||
if (!customerSignatureData) {
|
||||
message.error('请先完成客户签名');
|
||||
return;
|
||||
}
|
||||
if (!responsibleSignatureData) {
|
||||
message.error('请先完成负责人签名');
|
||||
return;
|
||||
}
|
||||
setSubmitting(true);
|
||||
try {
|
||||
const updated = await aftersalesApi.customerConfirm(serialNumber, {
|
||||
action: 'authorize',
|
||||
signature: signatureData,
|
||||
signature: customerSignatureData,
|
||||
responsibleSignature: responsibleSignatureData,
|
||||
});
|
||||
setOrder(updated);
|
||||
message.success('感谢您的确认,工单已完成');
|
||||
@@ -99,8 +107,16 @@ function AftersalesConfirmPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleClearSignature = () => {
|
||||
setSignatureData('');
|
||||
const handleClearSignature = (role: 'customer' | 'responsible') => {
|
||||
if (role === 'customer') {
|
||||
setCustomerSignatureData('');
|
||||
return;
|
||||
}
|
||||
setResponsibleSignatureData('');
|
||||
};
|
||||
|
||||
const openSignatureOverlay = (role: 'customer' | 'responsible') => {
|
||||
setActiveSignatureRole(role);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
@@ -220,48 +236,103 @@ function AftersalesConfirmPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isClosed && order.signature && (
|
||||
{isClosed && (order.signature || order.responsibleSignature) && (
|
||||
<div className="aftersales-signature-archived">
|
||||
<p className="aftersales-signature-tip">客户确认签名</p>
|
||||
<img
|
||||
src={order.signature}
|
||||
alt="客户确认签名"
|
||||
className="aftersales-signature-archived-img"
|
||||
/>
|
||||
<div className="aftersales-signature-grid">
|
||||
{order.signature && (
|
||||
<div className="aftersales-signature-archived-item">
|
||||
<p className="aftersales-signature-tip">客户签名</p>
|
||||
<img
|
||||
src={order.signature}
|
||||
alt="客户签名"
|
||||
className="aftersales-signature-archived-img"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{order.responsibleSignature && (
|
||||
<div className="aftersales-signature-archived-item">
|
||||
<p className="aftersales-signature-tip">负责人签名</p>
|
||||
<img
|
||||
src={order.responsibleSignature}
|
||||
alt="负责人签名"
|
||||
className="aftersales-signature-archived-img"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isPending && (
|
||||
<>
|
||||
<div className="aftersales-signature-section">
|
||||
<div className="aftersales-signature-header">
|
||||
<p className="aftersales-signature-tip">请签名确认维修结果</p>
|
||||
{signatureData && (
|
||||
<Button size="small" type="link" onClick={handleClearSignature}>
|
||||
清除签名
|
||||
</Button>
|
||||
)}
|
||||
<p className="aftersales-signature-section-title">请签名确认维修结果</p>
|
||||
<div className="aftersales-signature-grid">
|
||||
<div className="aftersales-signature-item">
|
||||
<div className="aftersales-signature-header">
|
||||
<p className="aftersales-signature-tip">客户签名</p>
|
||||
{customerSignatureData && (
|
||||
<Button size="small" type="link" onClick={() => handleClearSignature('customer')}>
|
||||
清除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{customerSignatureData ? (
|
||||
<button
|
||||
type="button"
|
||||
className="aftersales-signature-preview"
|
||||
onClick={() => openSignatureOverlay('customer')}
|
||||
>
|
||||
<img src={customerSignatureData} alt="客户签名" />
|
||||
<span className="aftersales-signature-preview-hint">点击可重新签名</span>
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="aftersales-signature-trigger"
|
||||
onClick={() => openSignatureOverlay('customer')}
|
||||
>
|
||||
<EditOutlined />
|
||||
<span>客户签名</span>
|
||||
<small>将进入签名页</small>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="aftersales-signature-item">
|
||||
<div className="aftersales-signature-header">
|
||||
<p className="aftersales-signature-tip">负责人签名</p>
|
||||
{responsibleSignatureData && (
|
||||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
onClick={() => handleClearSignature('responsible')}
|
||||
>
|
||||
清除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{responsibleSignatureData ? (
|
||||
<button
|
||||
type="button"
|
||||
className="aftersales-signature-preview"
|
||||
onClick={() => openSignatureOverlay('responsible')}
|
||||
>
|
||||
<img src={responsibleSignatureData} alt="负责人签名" />
|
||||
<span className="aftersales-signature-preview-hint">点击可重新签名</span>
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="aftersales-signature-trigger"
|
||||
onClick={() => openSignatureOverlay('responsible')}
|
||||
>
|
||||
<EditOutlined />
|
||||
<span>负责人签名</span>
|
||||
<small>将进入签名页</small>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{signatureData ? (
|
||||
<button
|
||||
type="button"
|
||||
className="aftersales-signature-preview"
|
||||
onClick={() => setShowSignatureOverlay(true)}
|
||||
>
|
||||
<img src={signatureData} alt="客户确认签名" />
|
||||
<span className="aftersales-signature-preview-hint">点击可重新签名</span>
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="aftersales-signature-trigger"
|
||||
onClick={() => setShowSignatureOverlay(true)}
|
||||
>
|
||||
<EditOutlined />
|
||||
<span>点击此处签名</span>
|
||||
<small>将进入签名页</small>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="aftersales-actions">
|
||||
<Button
|
||||
@@ -288,11 +359,16 @@ function AftersalesConfirmPage() {
|
||||
</Card>
|
||||
|
||||
<SignatureOverlay
|
||||
open={showSignatureOverlay}
|
||||
onCancel={() => setShowSignatureOverlay(false)}
|
||||
open={activeSignatureRole !== null}
|
||||
title={activeSignatureRole === 'responsible' ? '负责人签名' : '客户签名'}
|
||||
onCancel={() => setActiveSignatureRole(null)}
|
||||
onConfirm={(url) => {
|
||||
setSignatureData(url);
|
||||
setShowSignatureOverlay(false);
|
||||
if (activeSignatureRole === 'responsible') {
|
||||
setResponsibleSignatureData(url);
|
||||
} else {
|
||||
setCustomerSignatureData(url);
|
||||
}
|
||||
setActiveSignatureRole(null);
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user