feat: 待签合同支持登记线下签署日期
- 线下手签合同:展开后可点击「登记签署日期」选择日期并保存 保存后合同从待签列表移除(signDate 已填写) - 电子签合同:签署日期由电签系统自动回写,不可手动修改 - 后端新增 POST /esign/sign-date 接口 电子签合同拒绝手动修改签署日期 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -788,9 +788,30 @@ function PendingTab({ pendingList, loading, onRemind, remindLoading, remindData,
|
||||
remindData: any
|
||||
onDetail: (id: string) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
const [expandedEmp, setExpandedEmp] = useState<string | null>(null)
|
||||
const [remindEmpId, setRemindEmpId] = useState<string | null>(null)
|
||||
const [copied, setCopied] = useState(false)
|
||||
const [signDateEditing, setSignDateEditing] = useState<string | null>(null)
|
||||
const [signDateValue, setSignDateValue] = useState('')
|
||||
const [signDateSaving, setSignDateSaving] = useState(false)
|
||||
|
||||
/** 保存签署日期 */
|
||||
const handleSaveSignDate = async (contractId: string) => {
|
||||
if (!signDateValue) { toast.error('请选择签署日期'); return }
|
||||
setSignDateSaving(true)
|
||||
try {
|
||||
await esignApi.signDate(contractId, signDateValue)
|
||||
toast.success('签署日期已登记')
|
||||
setSignDateEditing(null)
|
||||
setSignDateValue('')
|
||||
queryClient.invalidateQueries({ queryKey: ['esign-pending'] })
|
||||
} catch (err: any) {
|
||||
toast.error(err?.response?.data?.error?.message || '登记失败')
|
||||
} finally {
|
||||
setSignDateSaving(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCopy = (url: string) => {
|
||||
navigator.clipboard?.writeText(url)
|
||||
@@ -908,7 +929,44 @@ function PendingTab({ pendingList, loading, onRemind, remindLoading, remindData,
|
||||
</button>
|
||||
)}
|
||||
{item.type === 'contract' && (
|
||||
<span className="text-gray-400 ml-auto">纸质合同未登记签署日期</span>
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
{signDateEditing === item.contractId ? (
|
||||
<>
|
||||
<input
|
||||
type="date"
|
||||
value={signDateValue}
|
||||
onChange={(e) => setSignDateValue(e.target.value)}
|
||||
className="h-7 px-2 text-xs border rounded"
|
||||
/>
|
||||
<button
|
||||
className="text-xs text-primary hover:underline"
|
||||
disabled={signDateSaving}
|
||||
onClick={() => handleSaveSignDate(item.contractId)}
|
||||
>
|
||||
{signDateSaving ? '保存中...' : '保存'}
|
||||
</button>
|
||||
<button
|
||||
className="text-xs text-gray-400 hover:text-gray-600"
|
||||
onClick={() => { setSignDateEditing(null); setSignDateValue('') }}
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-400">未登记签署日期</span>
|
||||
<button
|
||||
className="text-xs text-primary hover:underline"
|
||||
onClick={() => {
|
||||
setSignDateEditing(item.contractId)
|
||||
setSignDateValue(new Date().toISOString().slice(0, 10))
|
||||
}}
|
||||
>
|
||||
登记签署日期
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user