import { useState } from 'react'; import { Image, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'; import { colors, spacing } from '../../../src/theme'; import { useEnterpriseCertification, useIdentitySwitch, useImagePick, useOnboarding, useRegisterFinish, } from '../../../src/hooks'; import { ScreenShell } from '../ui/ScreenShell'; import { Illustration } from '../ui/Illustration'; import { PrimaryButton } from '../ui/PrimaryButton'; export function B3Recruiter() { const { data, setData, back } = useOnboarding(); const finish = useRegisterFinish(); const { pick, picking, error: pickError } = useImagePick(); const { submit, submitting } = useEnterpriseCertification(); const { switchTo, switching } = useIdentitySwitch(); const [submitFailed, setSubmitFailed] = useState(false); /** 服务端返回的失败原因(身份选择或认证提交),比「提交失败」四个字有用 */ const [failReason, setFailReason] = useState(null); // 三项都是认证必需,缺一项不放行:没有营业执照的「企业认证」提交不出有意义的结果 const canSubmit = data.recruiterCompany.trim().length > 0 && data.recruiterContact.trim().length > 0 && data.recruiterLicenseUri !== null; const pickLicense = async () => { // 营业执照是文档,方形裁剪会把内容切掉,用 4:3 const result = await pick('library', { aspect: [4, 3] }); if (result.status === 'picked') setData({ recruiterLicenseUri: result.uri }); }; const handleSubmit = async () => { if (!canSubmit || submitting || switching) return; setSubmitFailed(false); setFailReason(null); try { /* * 第一步:先让服务端确认这个账号是企业身份。 * 契约 POST /auth/identity/select 要求选 COMPANY 时必须带 company 资料; * 这一步成功后才拿得到企业角色,后面的认证提交才有意义 —— 顺序不能反。 * 「提交认证」也**不等于**「认证通过」:认证结果由审核决定,本地不做任何置位。 */ const identityOutcome = await switchTo('COMPANY', { name: data.recruiterCompany.trim(), industry: '', description: '', website: '', address: '', }); if (!identityOutcome.ok) { setSubmitFailed(true); setFailReason(identityOutcome.message ?? '企业身份创建失败,请稍后重试'); return; } // 第二步:提交企业认证资料,审核状态由接口返回驱动 const res = await submit({ companyName: data.recruiterCompany.trim(), // B3 不采集统一社会信用代码,由企业端「企业认证」页补全(该页已存在且有入口) creditCode: '', licenseUrl: data.recruiterLicenseUri ?? undefined, contactName: data.recruiterContact.trim(), // 联系人手机号用注册时登录的手机号,避免再问一次 contactPhone: data.phone, }); if (!res.success) { setSubmitFailed(true); setFailReason('认证提交未通过,请核对资料后重试'); return; } // 落地前 useRegisterFinish 会 flushSave,把认证资料一起落库 await finish('enterprise'); } catch (e) { setSubmitFailed(true); setFailReason((e as Error).message || '网络异常,请稍后重试'); } }; return ( 请完成企业认证,开启招聘之旅 公司名称 setData({ recruiterCompany: t })} placeholder="请输入公司全称" placeholderTextColor={colors.textHint} /> 营业执照 void pickLicense()} > {data.recruiterLicenseUri ? ( ) : ( )} {data.recruiterLicenseUri ? '已选择,点击可重新选择' : '点击上传营业执照'} {pickError ? {pickError} : null} 联系人 setData({ recruiterContact: t })} placeholder="请输入联系人姓名" placeholderTextColor={colors.textHint} /> {submitFailed ? ( {failReason ?? '认证提交失败,请稍后重试'} ) : null} void handleSubmit()} /> ); } const styles = StyleSheet.create({ tip: { fontSize: 13, color: colors.textHint, marginBottom: spacing.block }, label: { fontSize: 14, fontWeight: '700', color: colors.textPrimary, marginTop: 16, marginBottom: 8 }, input: { height: 50, borderRadius: 12, borderWidth: 1, borderColor: colors.border, backgroundColor: colors.white, paddingHorizontal: 14, fontSize: 15, color: colors.textPrimary, }, upload: { alignItems: 'center', justifyContent: 'center', gap: 8, paddingVertical: spacing.block, borderRadius: 12, borderWidth: 1, borderStyle: 'dashed', borderColor: colors.borderStrong, backgroundColor: colors.white, }, dim: { opacity: 0.5 }, licensePreview: { width: 160, height: 120, borderRadius: 12 }, uploadText: { fontSize: 13, color: colors.textHint }, error: { fontSize: 12, color: colors.dangerText, marginTop: spacing.sm }, footer: { marginTop: 28 }, });