feat(withdraw): 添加实名认证验证功能

- 在提现页面集成实名认证状态检查
- 添加 fetchVerifyStatus 函数用于获取认证状态
- 实现认证状态包括未知、已认证、未认证、审核中、已驳回
- 在提交提现前验证用户是否已完成实名认证
- 添加去认证按钮跳转到认证页面
- 优化订单详情和订单列表中的取消订单逻辑
- 修复用户认证页面的表单验证逻辑
- 添加真实姓名和身份证号输入字段到企业认证表单
This commit is contained in:
2026-02-07 15:35:23 +08:00
parent 5581493772
commit 6c83f6c082
4 changed files with 153 additions and 15 deletions

View File

@@ -16,6 +16,8 @@ import {Wallet} from '@nutui/icons-react-taro'
import {businessGradients} from '@/styles/gradients'
import Taro from '@tarojs/taro'
import {useDealerUser} from '@/hooks/useDealerUser'
import {myUserVerify} from '@/api/system/userVerify'
import {goTo} from '@/utils/navigation'
import {
pageShopDealerWithdraw,
addShopDealerWithdraw,
@@ -106,6 +108,8 @@ const DealerWithdraw: React.FC = () => {
const formRef = useRef<any>(null)
const {dealerUser} = useDealerUser()
const [verifyStatus, setVerifyStatus] = useState<'unknown' | 'verified' | 'unverified' | 'pending' | 'rejected'>('unknown')
const [verifyStatusText, setVerifyStatusText] = useState<string>('')
// Tab 切换处理函数
const handleTabChange = (value: string | number) => {
@@ -185,6 +189,57 @@ const DealerWithdraw: React.FC = () => {
}
}, [fetchBalance, fetchWithdrawRecords])
// 判断实名认证状态:提现前必须完成实名认证(已通过)
const fetchVerifyStatus = useCallback(async () => {
// Fast path: some pages store this flag after login.
if (String(Taro.getStorageSync('Certification')) === '1') {
setVerifyStatus('verified')
setVerifyStatusText('已实名认证')
return
}
try {
const r = await myUserVerify({})
if (!r) {
setVerifyStatus('unverified')
setVerifyStatusText('未实名认证')
return
}
const s = Number((r as any).status)
const st = String((r as any).statusText || '')
// Common convention in this project: 0审核中/待审核, 1已通过, 2已驳回
if (s === 1) {
setVerifyStatus('verified')
setVerifyStatusText(st || '已实名认证')
return
}
if (s === 0) {
setVerifyStatus('pending')
setVerifyStatusText(st || '审核中')
return
}
if (s === 2) {
setVerifyStatus('rejected')
setVerifyStatusText(st || '已驳回')
return
}
setVerifyStatus('unverified')
setVerifyStatusText(st || '未实名认证')
} catch (e) {
console.warn('获取实名认证状态失败,将按未认证处理:', e)
setVerifyStatus('unverified')
setVerifyStatusText('未实名认证')
}
}, [])
useEffect(() => {
if (!dealerUser?.userId) return
fetchVerifyStatus().then()
}, [dealerUser?.userId, fetchVerifyStatus])
const getStatusText = (status?: number) => {
switch (status) {
case 40:
@@ -224,6 +279,14 @@ const DealerWithdraw: React.FC = () => {
return
}
if (verifyStatus !== 'verified') {
Taro.showToast({
title: '请先完成实名认证',
icon: 'none'
})
return
}
// 验证提现金额
const amount = parseFloat(String(values.amount))
const available = parseFloat(normalizeMoneyString(availableAmount).replace(/,/g, ''))
@@ -366,8 +429,28 @@ const DealerWithdraw: React.FC = () => {
return Number.isFinite(n) ? n.toFixed(2) : '0.00'
}
const goVerify = () => {
goTo('/user/userVerify/index')
}
const renderWithdrawForm = () => (
<View>
{(verifyStatus === 'unverified' || verifyStatus === 'pending' || verifyStatus === 'rejected') && (
<View className="rounded-lg bg-white px-4 py-3 mb-4 mx-4">
<View className="flex items-center justify-between">
<View className="flex flex-col">
<Text className="text-sm text-red-500"></Text>
{verifyStatusText ? (
<Text className="text-xs text-gray-500 mt-1">{verifyStatusText}</Text>
) : null}
</View>
<Text className="text-sm text-blue-600" onClick={goVerify}>
</Text>
</View>
</View>
)}
{/* 余额卡片 */}
<View className="rounded-xl p-6 mb-6 text-white relative overflow-hidden" style={{
background: businessGradients.dealer.header
@@ -452,7 +535,7 @@ const DealerWithdraw: React.FC = () => {
type="primary"
nativeType="submit"
loading={submitting}
disabled={submitting}
disabled={submitting || verifyStatus !== 'verified'}
>
{submitting ? '提交中...' : '申请提现'}
</Button>