From 3b98dfa150d3f34678dbad58971d8acc3b55bdff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sat, 31 Jan 2026 22:04:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(dealer):=20=E6=9B=B4=E6=96=B0=E6=8F=90?= =?UTF-8?q?=E7=8E=B0=E6=B5=81=E7=A8=8B=E4=B8=BA=E5=AE=A1=E6=A0=B8=E5=90=8E?= =?UTF-8?q?=E9=A2=86=E5=8F=96=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加新的API接口getShopDealerWithdraw和updateShopDealerWithdraw - 新增package_info相关字段用于微信确认收款流程 - 添加claimingId状态管理用于控制领取按钮 - 修改状态显示逻辑,将"审核通过"改为"待领取",颜色从success改为info - 移除直接调用微信收款确认的逻辑,改为先提交审核再领取 - 新增handleClaim函数处理提现领取流程 - 在提现记录中添加"立即领取"按钮,仅在待领取状态下显示 - 更新提现说明文案,明确审核后领取流程 - 调整记录列表界面布局,优化时间显示和按钮位置 --- src/dealer/withdraw/index.tsx | 166 ++++++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 47 deletions(-) diff --git a/src/dealer/withdraw/index.tsx b/src/dealer/withdraw/index.tsx index f788d6e..1a08079 100644 --- a/src/dealer/withdraw/index.tsx +++ b/src/dealer/withdraw/index.tsx @@ -16,11 +16,20 @@ import {Wallet} from '@nutui/icons-react-taro' import {businessGradients} from '@/styles/gradients' import Taro from '@tarojs/taro' import {useDealerUser} from '@/hooks/useDealerUser' -import {pageShopDealerWithdraw, addShopDealerWithdraw} from '@/api/shop/shopDealerWithdraw' +import { + pageShopDealerWithdraw, + addShopDealerWithdraw, + getShopDealerWithdraw, + updateShopDealerWithdraw +} from '@/api/shop/shopDealerWithdraw' import type {ShopDealerWithdraw} from '@/api/shop/shopDealerWithdraw/model' interface WithdrawRecordWithDetails extends ShopDealerWithdraw { accountDisplay?: string + // Backend may include these fields for WeChat "confirm receipt" flow after approval. + package_info?: string + packageInfo?: string + package?: string } const extractPackageInfo = (result: unknown): string | null => { @@ -90,6 +99,7 @@ const DealerWithdraw: React.FC = () => { const [loading, setLoading] = useState(false) const [refreshing, setRefreshing] = useState(false) const [submitting, setSubmitting] = useState(false) + const [claimingId, setClaimingId] = useState(null) const [availableAmount, setAvailableAmount] = useState('0.00') const [withdrawRecords, setWithdrawRecords] = useState([]) const formRef = useRef(null) @@ -179,7 +189,7 @@ const DealerWithdraw: React.FC = () => { case 40: return '已到账' case 20: - return '审核通过' + return '待领取' case 10: return '待审核' case 30: @@ -194,7 +204,7 @@ const DealerWithdraw: React.FC = () => { case 40: return 'success' case 20: - return 'success' + return 'info' case 10: return 'warning' case 30: @@ -253,33 +263,12 @@ const DealerWithdraw: React.FC = () => { platform: 'MiniProgram' } - // WeChat wallet: backend should return `package_info`, frontend opens the "confirm receipt" page - // for user to click "确认收款". - if (!canRequestMerchantTransferConfirm()) { - throw new Error('当前环境不支持微信收款确认,请在微信小程序内操作') - } - - const createResult = await addShopDealerWithdraw(withdrawData) - const packageInfo = extractPackageInfo(createResult) - if (!packageInfo) { - throw new Error('后台未返回 package_info,无法调起微信收款确认页') - } - - try { - await requestMerchantTransferConfirm(packageInfo) - Taro.showToast({ - title: '已调起收款确认页', - icon: 'success' - }) - } catch (e: any) { - const msg = String(e?.errMsg || e?.message || '') - if (/cancel/i.test(msg)) { - Taro.showToast({title: '已取消收款确认', icon: 'none'}) - } else { - // Keep the original WeChat error for troubleshooting (e.g. "商户号错误"). - throw new Error(msg || '调起收款确认页失败,请稍后重试') - } - } + // Security flow: + // 1) user submits => applyStatus=10 (待审核) + // 2) backend审核通过 => applyStatus=20 (待领取) + // 3) user goes to records to "领取" => applyStatus=40 (已到账) + await addShopDealerWithdraw(withdrawData) + Taro.showToast({title: '提现申请已提交,等待审核', icon: 'success'}) // 重置表单 formRef.current?.resetFields() @@ -301,6 +290,71 @@ const DealerWithdraw: React.FC = () => { } } + const handleClaim = async (record: WithdrawRecordWithDetails) => { + if (!record?.id) { + Taro.showToast({title: '记录不存在', icon: 'error'}) + return + } + + if (record.applyStatus !== 20) { + Taro.showToast({title: '当前状态不可领取', icon: 'none'}) + return + } + + if (record.payType !== 10) { + Taro.showToast({title: '仅支持微信提现领取', icon: 'none'}) + return + } + + if (claimingId !== null) return + + try { + setClaimingId(record.id) + + if (!canRequestMerchantTransferConfirm()) { + throw new Error('当前环境不支持微信收款确认,请在微信小程序内操作') + } + + // Prefer getting package from the list record; if missing, query detail. + let packageInfo = extractPackageInfo(record as any) + if (!packageInfo) { + const detail = await getShopDealerWithdraw(record.id) + packageInfo = extractPackageInfo(detail as any) + } + + if (!packageInfo) { + throw new Error('后台未返回 package_info,无法领取,请联系管理员') + } + + try { + await requestMerchantTransferConfirm(packageInfo) + } catch (e: any) { + const msg = String(e?.errMsg || e?.message || '') + if (/cancel/i.test(msg)) { + Taro.showToast({title: '已取消领取', icon: 'none'}) + return + } + throw new Error(msg || '领取失败,请稍后重试') + } + + // Best-effort: ask backend to mark as "已到账". + try { + await updateShopDealerWithdraw({id: record.id, applyStatus: 40} as any) + } catch (e) { + // Backend may enforce state transitions; still refresh to reflect backend truth. + console.warn('更新提现状态失败:', e) + } + + Taro.showToast({title: '领取成功', icon: 'success'}) + await handleRefresh() + } catch (e: any) { + console.error('领取失败:', e) + Taro.showToast({title: e?.message || '领取失败', icon: 'error'}) + } finally { + setClaimingId(null) + } + } + const quickAmounts = ['0.2','100', '300', '500', '1000'] const setQuickAmount = (amount: string) => { @@ -389,7 +443,7 @@ const DealerWithdraw: React.FC = () => { - 提现方式:微信钱包(提交后将拉起微信收款确认页,需要您点击“确认收款”后才会完成转账) + 提现方式:微信钱包(提交后进入“待审核”,审核通过后请到“提现记录”点击“领取到微信零钱”完成收款确认) @@ -431,28 +485,46 @@ const DealerWithdraw: React.FC = () => { 提现金额:¥{record.money} - - 提现账户:{record.accountDisplay} - + {/**/} + {/* 提现账户:{record.accountDisplay}*/} + {/**/} - + {getStatusText(record.applyStatus)} - - 申请时间:{record.createTime} - {record.auditTime && ( - - 审核时间:{new Date(record.auditTime).toLocaleString()} - + + {record.applyStatus === 20 && record.payType === 10 && ( + + + )} - {record.rejectReason && ( - - 驳回原因:{record.rejectReason} - - )} - + + + + 创建时间:{record.createTime} + {record.auditTime && ( + + 审核时间:{record.auditTime} + + )} + {record.rejectReason && ( + + 驳回原因:{record.rejectReason} + + )} + + + )) ) : (