import { useState } from 'react' import { toast } from 'sonner' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { PenTool, Plus, X, RefreshCw, ExternalLink, FileText, AlertCircle } from 'lucide-react' import { esignApi, employeeApi } from '../lib/api-services' import PageGuide from '../components/ui/PageGuide' import Card from '../components/ui/Card' import Button from '../components/ui/Button' import { Input, Label } from '../components/ui/Input' import { InlineAlert } from '../components/ui/InlineAlert' import Modal from '../components/ui/Modal' const STATUS_CONFIG: Record = { PENDING: { label: '待签署', color: 'bg-yellow-50 text-yellow-700' }, SIGNING: { label: '签署中', color: 'bg-blue-50 text-blue-700' }, COMPLETED: { label: '已完成', color: 'bg-green-50 text-safe' }, REJECTED: { label: '已拒绝', color: 'bg-red-50 text-danger' }, EXPIRED: { label: '已过期', color: 'bg-gray-100 text-gray-500' }, CANCELLED: { label: '已取消', color: 'bg-gray-100 text-gray-500' }, } const SCENE_CONFIG: Record = { CONTRACT: { label: '劳动合同', color: 'bg-blue-50 text-blue-600 border border-blue-200' }, RESIGNATION: { label: '离职协议', color: 'bg-orange-50 text-orange-600 border border-orange-200' }, POLICY: { label: '规章制度', color: 'bg-amber-50 text-amber-600 border border-amber-200' }, PAYSLIP: { label: '工资条', color: 'bg-emerald-50 text-emerald-600 border border-emerald-200' }, ONBOARDING: { label: '入职文件', color: 'bg-purple-50 text-purple-600 border border-purple-200' }, } export default function ESign() { const queryClient = useQueryClient() const [filterStatus, setFilterStatus] = useState('') const [filterScene, setFilterScene] = useState('') const [showCreate, setShowCreate] = useState(false) const [formData, setFormData] = useState({ employeeId: '', documentTitle: '', remark: '', }) const { data: records = [], isLoading } = useQuery({ queryKey: ['esign-records', filterStatus, filterScene], queryFn: async () => { return await esignApi.list({ status: filterStatus || undefined, scene: filterScene || undefined }) }, }) const { data: rosterData = [] } = useQuery({ queryKey: ['employees-for-esign'], queryFn: async () => { return await employeeApi.allLite({ status: 'ACTIVE' }) }, enabled: showCreate, }) const createMutation = useMutation({ mutationFn: async (data: { employeeId: string; documentTitle: string; remark?: string }) => esignApi.create(data) as any, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['esign-records'] }) setShowCreate(false) setFormData({ employeeId: '', documentTitle: '', remark: '' }) toast.success('签署记录已创建,待对接易签宝后将自动发送签署链接') }, onError: () => toast.error('创建失败'), }) const cancelMutation = useMutation({ mutationFn: (id: string) => esignApi.cancel(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['esign-records'] }) toast.success('已取消签署') }, }) const refreshStatusMutation = useMutation({ mutationFn: (id: string) => esignApi.status(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['esign-records'] }) toast.success('状态已刷新') }, }) const handleCreate = () => { if (!formData.employeeId) { toast.error('请选择员工'); return } if (!formData.documentTitle.trim()) { toast.error('请填写文件标题'); return } createMutation.mutate(formData) } return (
通过易签宝平台发起电子合同签署,员工在线完成签署后自动回传签署状态和PDF文件。 当前为框架预留阶段,对接易签宝API后将自动启用在线签署功能。

电子签署

对接易签宝实现在线合同签署

对接状态:框架已就绪,待接入易签宝API
需要提供易签宝的 AppId、AppSecret 和 API 基础地址。对接后可实现: ① HR在系统发起签署 → ② 调用易签宝创建签署流程 → ③ 员工收到签署链接 → ④ 签署完成自动回调更新状态 → ⑤ 合同自动关联电子版PDF
{/* 签署记录列表 */} {isLoading ? (
加载中...
) : records.length === 0 ? (
暂无签署记录,点击「发起签署」创建
) : (
{records.map((r: any) => { const statusCfg = STATUS_CONFIG[r.status] || STATUS_CONFIG.PENDING return ( ) })}
文件标题 签署人 部门 状态 发起时间 完成时间 操作
{r.documentTitle} {r.scene && SCENE_CONFIG[r.scene] && ( {SCENE_CONFIG[r.scene].label} )}
{r.remark &&
{r.remark}
}
{r.employee?.name || '—'} {r.employee?.department || '—'} {statusCfg.label} {new Date(r.createdAt).toLocaleString('zh-CN')} {r.completedAt ? new Date(r.completedAt).toLocaleString('zh-CN') : '—'}
{r.status === 'COMPLETED' && r.signedPdfUrl && ( 查看PDF )} {(r.status === 'PENDING' || r.status === 'SIGNING') && ( <> )}
)}
{/* 发起签署 Modal */} {showCreate && ( setShowCreate(false)} title="发起电子签署" size="md">
选择员工并填写文件标题,系统将创建签署记录。对接易签宝后,将自动生成签署链接并发送给员工。
setFormData({ ...formData, documentTitle: e.target.value })} placeholder="如:2024年度劳动合同" />
setFormData({ ...formData, remark: e.target.value })} placeholder="可选" />
)}
) }