import { useEffect, useState } from 'react';
import { AlertCircle, Check, ChevronRight, Landmark, ShieldCheck, Upload, UserCheck } from 'lucide-react';
import { Button, FileActions, Input, Select, Textarea } from '@/components/ui';
import { clientApi, type EnterpriseCertification, type FileObject, type FileRef } from '@/api/adminApi';
import { displayFileName } from '@/utils/fileName';
type AuthStep = 'overview' | 'profile' | 'method' | 'recharge' | 'face' | 'faceScan' | 'pending' | 'success' | 'failed';
type AuthMethod = 'face' | 'recharge';
type CertificationStatus = 'uncertified' | 'pending' | 'approved' | 'rejected';
const companyInfo = {
name: '上海闪联九玖信息通信技术有限公司',
code: 'XXXXXXXXXX',
legalPerson: '张三',
certifiedAt: '2022年07月09日 13:12:01',
address: '上海XXX区XX路XX号',
};
type CertificationForm = {
companyName: string;
licenseNo: string;
province: string;
city: string;
address: string;
contactName: string;
contactIdCard: string;
contactPhone: string;
contactEmail: string;
legalPerson: string;
legalPersonIdCard: string;
};
const emptyCertificationForm: CertificationForm = {
companyName: '',
licenseNo: '',
province: '',
city: '',
address: '',
contactName: '',
contactIdCard: '',
contactPhone: '',
contactEmail: '',
legalPerson: '',
legalPersonIdCard: '',
};
function UploadPanel({
file,
uploading,
onFile,
}: {
file: FileObject | null;
uploading: boolean;
onFile: (file: File | undefined) => void;
}) {
const fileRef: FileRef | null = file
? { contentType: file.contentType, fileName: file.fileName, fileObjectId: file.id }
: null;
return (
);
}
function EnterpriseStepper({ current }: { current: number }) {
const steps = ['填写资料', '选择认证方式', '校验认证信息', '认证完成'];
return (
{steps.map((label, index) => {
const step = index + 1;
const complete = step < current;
const active = step === current;
return (
{complete ? : step}
{label}
{index < steps.length - 1 ? : null}
);
})}
);
}
function AuthHeader({ status }: { status: CertificationStatus }) {
const statusText: Record = {
uncertified: '未认证',
pending: '审核中',
approved: '已通过',
rejected: '未通过',
};
return (
企业认证
{statusText[status]}
);
}
function statusFromCertification(certification: EnterpriseCertification | null): CertificationStatus {
if (!certification) {
return 'uncertified';
}
if (certification.status === 'approved') {
return 'approved';
}
if (certification.status === 'rejected') {
return 'rejected';
}
return 'pending';
}
export function ClientEnterpriseAuthPage() {
const [step, setStep] = useState('overview');
const [method, setMethod] = useState('face');
const [status, setStatus] = useState('uncertified');
const [form, setForm] = useState(emptyCertificationForm);
const [latestCertification, setLatestCertification] = useState(null);
const [licenseFile, setLicenseFile] = useState(null);
const [uploading, setUploading] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState('');
const currentStep =
step === 'profile'
? 1
: step === 'method'
? 2
: step === 'recharge' || step === 'face' || step === 'faceScan'
? 3
: step === 'pending' || step === 'success' || step === 'failed'
? 4
: 1;
const certificationMaterials = latestCertification?.materials ?? {};
const displayCompany = latestCertification?.companyName || form.companyName || companyInfo.name;
const displayLicenseNo = latestCertification?.licenseNo || form.licenseNo || companyInfo.code;
const displayAddress = String(certificationMaterials.address ?? (form.address || companyInfo.address));
const displayLegalPerson = String(
certificationMaterials.legalPerson ?? (form.legalPerson || companyInfo.legalPerson),
);
function loadCertification() {
clientApi
.listEnterpriseCertifications()
.then((items) => {
const latest = items[0] ?? null;
setLatestCertification(latest);
setStatus(statusFromCertification(latest));
if (latest) {
const materials = latest.materials ?? {};
setForm({
companyName: latest.companyName ?? '',
licenseNo: latest.licenseNo ?? '',
province: String(materials.province ?? ''),
city: String(materials.city ?? ''),
address: String(materials.address ?? ''),
contactName: latest.contactName ?? '',
contactIdCard: String(materials.contactIdCard ?? ''),
contactPhone: latest.contactPhone ?? '',
contactEmail: String(materials.contactEmail ?? ''),
legalPerson: String(materials.legalPerson ?? ''),
legalPersonIdCard: String(materials.legalPersonIdCard ?? ''),
});
}
setError('');
})
.catch((failure: Error) => setError(failure.message || '企业认证信息加载失败'));
}
useEffect(() => {
loadCertification();
}, []);
function updateForm(key: K, value: CertificationForm[K]) {
setForm((current) => ({ ...current, [key]: value }));
}
function uploadLicense(file: File | undefined) {
if (!file) return;
setUploading(true);
clientApi
.uploadFileObject(file, { purpose: 'enterprise_certification', prefix: 'enterprise-certifications/license' })
.then((fileObject) => {
setLicenseFile(fileObject);
setError('');
})
.catch((failure: Error) => setError(failure.message || '营业执照上传失败'))
.finally(() => setUploading(false));
}
function submitCertification() {
if (!form.companyName.trim() || !form.licenseNo.trim() || !form.contactName.trim() || !form.contactPhone.trim()) {
setError('请填写企业名称、统一社会信用代码、联系人姓名和联系人手机号');
setStep('profile');
return;
}
setSubmitting(true);
clientApi
.submitEnterpriseCertification({
companyName: form.companyName.trim(),
licenseNo: form.licenseNo.trim(),
contactName: form.contactName.trim(),
contactPhone: form.contactPhone.trim(),
materials: {
licenseFileObjectId: licenseFile?.id,
licenseFileName: licenseFile?.fileName,
licenseFileContentType: licenseFile?.contentType,
province: form.province,
city: form.city,
address: form.address,
contactIdCard: form.contactIdCard,
contactEmail: form.contactEmail,
legalPerson: form.legalPerson,
legalPersonIdCard: form.legalPersonIdCard,
authMethod: method,
},
})
.then((created) => {
setLatestCertification(created);
setStatus('pending');
setStep('pending');
setError('');
})
.catch((failure: Error) => setError(failure.message || '企业认证提交失败'))
.finally(() => setSubmitting(false));
}
if (step === 'overview') {
const overviewCopy =
status === 'approved'
? '企业认证已审核通过,可正常使用发送、签名报备等能力。'
: status === 'pending'
? '企业认证资料已提交,平台运营将在 1 个工作日内完成审核。'
: status === 'rejected'
? '企业认证未通过,请根据驳回原因修改资料后重新提交。'
: '您还未进行企业认证';
return (
{error ? {error}
: null}
{overviewCopy}
{status === 'pending' ? (
) : null}
- 企业名称:
- {latestCertification ? displayCompany : '待认证'}
- 认证时间:
- {latestCertification?.reviewedAt ?? latestCertification?.submittedAt ?? '待审核完成'}
- 统一社会信用代码:
- {latestCertification ? displayLicenseNo : '待认证'}
- 通讯地址:
- {latestCertification ? displayAddress : '待认证'}
- 法定代表人:
- {latestCertification ? displayLegalPerson : '待认证'}
);
}
return (
企业认证
{error ? {error}
: null}
{step === 'profile' ? (
请上传电子版营业执照,JPG或PNG格式,大小不超过5M
updateForm('companyName', event.target.value)}
placeholder="请填写企业全称"
hint="请严格按照营业执照上的企业名称进行填写"
value={form.companyName}
/>
updateForm('licenseNo', event.target.value)}
placeholder="请填写统一社会信用代码(若无请填写其他组织机构代码)"
value={form.licenseNo}
/>
* 通讯地址
) : null}
{step === 'method' ? (
) : null}
{step === 'recharge' ? (
认证方式
聆界平台充值认证
请使用 企业银行对公账户 向聆界平台账户打款 (小于1元){' '}
至迅联天下平台账户,认证成功后,验证金将自动打入企业的平台账户中。
付款方信息
付款企业
{form.companyName || '待填写企业名称'}
请使用与企业营业执照名称一致的对公账户进行转账,以便系统进行识别,若填报错误企业信息,转账将无效暨审核不通过
为避免充值失败的情况,请在点击 确认并充值{' '}
后,根据页面提示的金额进行转账,验证、充值金额有效期:安全充值有效期为7个工作日
,验证次数为2次。
) : null}
{step === 'face' ? (
) : null}
{step === 'faceScan' ? (
认证方式
企业法人人脸识别认证
企业法人基本信息
- 企业法人姓名
- {form.legalPerson || '-'}
- 企业法人身份证号
- {form.legalPersonIdCard || '-'}
扫码认证
为了验证您的身份,请使用支付宝扫码进行人脸识别,剩余有效时间:59分57秒
二维码
完成扫描操作后,资料将提交至运营端审核。
) : null}
{step === 'pending' ? (
认证资料已提交,等待运营审核
当前状态:运营端审核中。审核通过后将自动解锁短信发送、签名报备等能力;未通过时可根据驳回原因重新提交。
- 企业名称:
- {displayCompany}
- 提交时间:
- {latestCertification?.submittedAt ?? '-'}
- 审核时效:
- 1 个工作日内
- 当前节点:
- 运营端资料审核
) : null}
{step === 'success' ? (
认证审核通过
- 企业名称:
- {displayCompany}
- 统一社会信用代码:
- {displayLicenseNo}
- 法定代表人:
- {displayLegalPerson}
- 认证时间:
- {latestCertification?.reviewedAt ?? latestCertification?.submittedAt ?? '-'}
- 通讯地址:
- {displayAddress}
) : null}
{step === 'failed' ? (
!
认证审核未通过
驳回原因:{latestCertification?.rejectReason ?? '请根据运营端审核意见修改资料后重新提交。'}
) : null}
);
}