forked from gxwebsoft/mp-10550
test(dealer/withdraw): 添加提现功能的单元测试
- 新增了多个测试用例,覆盖了提现功能的主要场景 - 添加了对最低提现金额、可用余额、支付宝信息完整性的验证 -测试了微信提现和支付宝提现的提交逻辑 - 新增了快捷金额按钮和全部金额按钮的测试 - 添加了调试组件,用于测试 Tabs 组件的点击和切换功能 - 优化了提现记录的渲染逻辑,增加了日志输出
This commit is contained in:
184
src/dealer/withdraw/__tests__/withdraw.test.tsx
Normal file
184
src/dealer/withdraw/__tests__/withdraw.test.tsx
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { render, fireEvent, waitFor } from '@testing-library/react'
|
||||||
|
import DealerWithdraw from '../index'
|
||||||
|
import { useDealerUser } from '@/hooks/useDealerUser'
|
||||||
|
import * as withdrawAPI from '@/api/shop/shopDealerWithdraw'
|
||||||
|
|
||||||
|
// Mock dependencies
|
||||||
|
jest.mock('@/hooks/useDealerUser')
|
||||||
|
jest.mock('@/api/shop/shopDealerWithdraw')
|
||||||
|
jest.mock('@tarojs/taro', () => ({
|
||||||
|
showToast: jest.fn(),
|
||||||
|
getStorageSync: jest.fn(() => 123),
|
||||||
|
}))
|
||||||
|
|
||||||
|
const mockUseDealerUser = useDealerUser as jest.MockedFunction<typeof useDealerUser>
|
||||||
|
const mockAddShopDealerWithdraw = withdrawAPI.addShopDealerWithdraw as jest.MockedFunction<typeof withdrawAPI.addShopDealerWithdraw>
|
||||||
|
const mockPageShopDealerWithdraw = withdrawAPI.pageShopDealerWithdraw as jest.MockedFunction<typeof withdrawAPI.pageShopDealerWithdraw>
|
||||||
|
|
||||||
|
describe('DealerWithdraw', () => {
|
||||||
|
const mockDealerUser = {
|
||||||
|
userId: 123,
|
||||||
|
money: '10000.00',
|
||||||
|
realName: '测试用户',
|
||||||
|
mobile: '13800138000'
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockUseDealerUser.mockReturnValue({
|
||||||
|
dealerUser: mockDealerUser,
|
||||||
|
loading: false,
|
||||||
|
error: null,
|
||||||
|
refresh: jest.fn()
|
||||||
|
})
|
||||||
|
|
||||||
|
mockPageShopDealerWithdraw.mockResolvedValue({
|
||||||
|
list: [],
|
||||||
|
count: 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('应该正确显示可提现余额', () => {
|
||||||
|
const { getByText } = render(<DealerWithdraw />)
|
||||||
|
expect(getByText('10000.00')).toBeInTheDocument()
|
||||||
|
expect(getByText('可提现余额')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('应该验证最低提现金额', async () => {
|
||||||
|
mockAddShopDealerWithdraw.mockResolvedValue('success')
|
||||||
|
|
||||||
|
const { getByPlaceholderText, getByText } = render(<DealerWithdraw />)
|
||||||
|
|
||||||
|
// 输入低于最低金额的数值
|
||||||
|
const amountInput = getByPlaceholderText('请输入提现金额')
|
||||||
|
fireEvent.change(amountInput, { target: { value: '50' } })
|
||||||
|
|
||||||
|
// 选择提现方式
|
||||||
|
const wechatRadio = getByText('微信钱包')
|
||||||
|
fireEvent.click(wechatRadio)
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitButton = getByText('申请提现')
|
||||||
|
fireEvent.click(submitButton)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(require('@tarojs/taro').showToast).toHaveBeenCalledWith({
|
||||||
|
title: '最低提现金额为100元',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('应该验证提现金额不超过可用余额', async () => {
|
||||||
|
const { getByPlaceholderText, getByText } = render(<DealerWithdraw />)
|
||||||
|
|
||||||
|
// 输入超过可用余额的金额
|
||||||
|
const amountInput = getByPlaceholderText('请输入提现金额')
|
||||||
|
fireEvent.change(amountInput, { target: { value: '20000' } })
|
||||||
|
|
||||||
|
// 选择提现方式
|
||||||
|
const wechatRadio = getByText('微信钱包')
|
||||||
|
fireEvent.click(wechatRadio)
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitButton = getByText('申请提现')
|
||||||
|
fireEvent.click(submitButton)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(require('@tarojs/taro').showToast).toHaveBeenCalledWith({
|
||||||
|
title: '提现金额超过可用余额',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('应该验证支付宝账户信息完整性', async () => {
|
||||||
|
const { getByPlaceholderText, getByText } = render(<DealerWithdraw />)
|
||||||
|
|
||||||
|
// 输入有效金额
|
||||||
|
const amountInput = getByPlaceholderText('请输入提现金额')
|
||||||
|
fireEvent.change(amountInput, { target: { value: '1000' } })
|
||||||
|
|
||||||
|
// 选择支付宝提现
|
||||||
|
const alipayRadio = getByText('支付宝')
|
||||||
|
fireEvent.click(alipayRadio)
|
||||||
|
|
||||||
|
// 只填写账号,不填写姓名
|
||||||
|
const accountInput = getByPlaceholderText('请输入支付宝账号')
|
||||||
|
fireEvent.change(accountInput, { target: { value: 'test@alipay.com' } })
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitButton = getByText('申请提现')
|
||||||
|
fireEvent.click(submitButton)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(require('@tarojs/taro').showToast).toHaveBeenCalledWith({
|
||||||
|
title: '请填写完整的支付宝信息',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('应该成功提交微信提现申请', async () => {
|
||||||
|
mockAddShopDealerWithdraw.mockResolvedValue('success')
|
||||||
|
|
||||||
|
const { getByPlaceholderText, getByText } = render(<DealerWithdraw />)
|
||||||
|
|
||||||
|
// 输入有效金额
|
||||||
|
const amountInput = getByPlaceholderText('请输入提现金额')
|
||||||
|
fireEvent.change(amountInput, { target: { value: '1000' } })
|
||||||
|
|
||||||
|
// 选择微信提现
|
||||||
|
const wechatRadio = getByText('微信钱包')
|
||||||
|
fireEvent.click(wechatRadio)
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitButton = getByText('申请提现')
|
||||||
|
fireEvent.click(submitButton)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockAddShopDealerWithdraw).toHaveBeenCalledWith({
|
||||||
|
userId: 123,
|
||||||
|
money: '1000',
|
||||||
|
payType: 10,
|
||||||
|
applyStatus: 10,
|
||||||
|
platform: 'MiniProgram'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(require('@tarojs/taro').showToast).toHaveBeenCalledWith({
|
||||||
|
title: '提现申请已提交',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('快捷金额按钮应该正常工作', () => {
|
||||||
|
const { getByText, getByPlaceholderText } = render(<DealerWithdraw />)
|
||||||
|
|
||||||
|
// 点击快捷金额按钮
|
||||||
|
const quickAmountButton = getByText('500')
|
||||||
|
fireEvent.click(quickAmountButton)
|
||||||
|
|
||||||
|
// 验证金额输入框的值
|
||||||
|
const amountInput = getByPlaceholderText('请输入提现金额') as HTMLInputElement
|
||||||
|
expect(amountInput.value).toBe('500')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('全部按钮应该设置为可用余额', () => {
|
||||||
|
const { getByText, getByPlaceholderText } = render(<DealerWithdraw />)
|
||||||
|
|
||||||
|
// 点击全部按钮
|
||||||
|
const allButton = getByText('全部')
|
||||||
|
fireEvent.click(allButton)
|
||||||
|
|
||||||
|
// 验证金额输入框的值
|
||||||
|
const amountInput = getByPlaceholderText('请输入提现金额') as HTMLInputElement
|
||||||
|
expect(amountInput.value).toBe('10000.00')
|
||||||
|
})
|
||||||
|
})
|
||||||
80
src/dealer/withdraw/debug.tsx
Normal file
80
src/dealer/withdraw/debug.tsx
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { View, Text } from '@tarojs/components'
|
||||||
|
import { Tabs, Button } from '@nutui/nutui-react-taro'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提现功能调试组件
|
||||||
|
* 用于测试 Tabs 组件的点击和切换功能
|
||||||
|
*/
|
||||||
|
const WithdrawDebug: React.FC = () => {
|
||||||
|
const [activeTab, setActiveTab] = useState<string | number>('0')
|
||||||
|
const [clickCount, setClickCount] = useState(0)
|
||||||
|
|
||||||
|
// Tab 切换处理函数
|
||||||
|
const handleTabChange = (value: string | number) => {
|
||||||
|
console.log('Tab切换:', { from: activeTab, to: value, type: typeof value })
|
||||||
|
setActiveTab(value)
|
||||||
|
setClickCount(prev => prev + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动切换测试
|
||||||
|
const manualSwitch = (tab: string | number) => {
|
||||||
|
console.log('手动切换到:', tab)
|
||||||
|
setActiveTab(tab)
|
||||||
|
setClickCount(prev => prev + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="bg-gray-50 min-h-screen p-4">
|
||||||
|
<View className="bg-white rounded-lg p-4 mb-4">
|
||||||
|
<Text className="text-lg font-bold mb-2">调试信息</Text>
|
||||||
|
<Text className="block mb-1">当前Tab: {String(activeTab)}</Text>
|
||||||
|
<Text className="block mb-1">切换次数: {clickCount}</Text>
|
||||||
|
<Text className="block mb-1">Tab类型: {typeof activeTab}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="bg-white rounded-lg p-4 mb-4">
|
||||||
|
<Text className="text-lg font-bold mb-2">手动切换测试</Text>
|
||||||
|
<View className="flex gap-2">
|
||||||
|
<Button size="small" onClick={() => manualSwitch('0')}>
|
||||||
|
切换到申请提现
|
||||||
|
</Button>
|
||||||
|
<Button size="small" onClick={() => manualSwitch('1')}>
|
||||||
|
切换到提现记录
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="bg-white rounded-lg">
|
||||||
|
<Tabs value={activeTab} onChange={handleTabChange}>
|
||||||
|
<Tabs.TabPane title="申请提现" value="0">
|
||||||
|
<View className="p-4">
|
||||||
|
<Text className="text-center text-gray-600">申请提现页面内容</Text>
|
||||||
|
<Text className="text-center text-sm text-gray-400 mt-2">
|
||||||
|
当前Tab值: {String(activeTab)}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</Tabs.TabPane>
|
||||||
|
|
||||||
|
<Tabs.TabPane title="提现记录" value="1">
|
||||||
|
<View className="p-4">
|
||||||
|
<Text className="text-center text-gray-600">提现记录页面内容</Text>
|
||||||
|
<Text className="text-center text-sm text-gray-400 mt-2">
|
||||||
|
当前Tab值: {String(activeTab)}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</Tabs.TabPane>
|
||||||
|
</Tabs>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="bg-white rounded-lg p-4 mt-4">
|
||||||
|
<Text className="text-lg font-bold mb-2">事件日志</Text>
|
||||||
|
<Text className="text-sm text-gray-500">
|
||||||
|
请查看控制台输出以获取详细的切换日志
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WithdrawDebug
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useRef, useEffect, useCallback } from 'react'
|
import React, {useState, useRef, useEffect, useCallback} from 'react'
|
||||||
import { View, Text } from '@tarojs/components'
|
import {View, Text} from '@tarojs/components'
|
||||||
import {
|
import {
|
||||||
Cell,
|
Cell,
|
||||||
Space,
|
Space,
|
||||||
@@ -14,19 +14,19 @@ import {
|
|||||||
Loading,
|
Loading,
|
||||||
PullToRefresh
|
PullToRefresh
|
||||||
} from '@nutui/nutui-react-taro'
|
} from '@nutui/nutui-react-taro'
|
||||||
import { Wallet } from '@nutui/icons-react-taro'
|
import {Wallet} from '@nutui/icons-react-taro'
|
||||||
import { businessGradients } from '@/styles/gradients'
|
import {businessGradients} from '@/styles/gradients'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import { useDealerUser } from '@/hooks/useDealerUser'
|
import {useDealerUser} from '@/hooks/useDealerUser'
|
||||||
import { pageShopDealerWithdraw, addShopDealerWithdraw } from '@/api/shop/shopDealerWithdraw'
|
import {pageShopDealerWithdraw, addShopDealerWithdraw} from '@/api/shop/shopDealerWithdraw'
|
||||||
import type { ShopDealerWithdraw } from '@/api/shop/shopDealerWithdraw/model'
|
import type {ShopDealerWithdraw} from '@/api/shop/shopDealerWithdraw/model'
|
||||||
|
|
||||||
interface WithdrawRecordWithDetails extends ShopDealerWithdraw {
|
interface WithdrawRecordWithDetails extends ShopDealerWithdraw {
|
||||||
accountDisplay?: string
|
accountDisplay?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const DealerWithdraw: React.FC = () => {
|
const DealerWithdraw: React.FC = () => {
|
||||||
const [activeTab, setActiveTab] = useState('0')
|
const [activeTab, setActiveTab] = useState<string | number>('0')
|
||||||
const [selectedAccount, setSelectedAccount] = useState('')
|
const [selectedAccount, setSelectedAccount] = useState('')
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
const [refreshing, setRefreshing] = useState<boolean>(false)
|
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||||||
@@ -35,17 +35,28 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
const [withdrawRecords, setWithdrawRecords] = useState<WithdrawRecordWithDetails[]>([])
|
const [withdrawRecords, setWithdrawRecords] = useState<WithdrawRecordWithDetails[]>([])
|
||||||
const formRef = useRef<any>(null)
|
const formRef = useRef<any>(null)
|
||||||
|
|
||||||
const { dealerUser } = useDealerUser()
|
const {dealerUser} = useDealerUser()
|
||||||
|
|
||||||
|
// Tab 切换处理函数
|
||||||
|
const handleTabChange = (value: string | number) => {
|
||||||
|
console.log('Tab切换到:', value)
|
||||||
|
setActiveTab(value)
|
||||||
|
|
||||||
|
// 如果切换到提现记录页面,刷新数据
|
||||||
|
if (String(value) === '1') {
|
||||||
|
fetchWithdrawRecords()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 获取可提现余额
|
// 获取可提现余额
|
||||||
const fetchBalance = useCallback(async () => {
|
const fetchBalance = useCallback(async () => {
|
||||||
console.log(dealerUser,'dealerUser...')
|
console.log(dealerUser, 'dealerUser...')
|
||||||
try {
|
try {
|
||||||
setAvailableAmount(dealerUser?.money || '0.00')
|
setAvailableAmount(dealerUser?.money || '0.00')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取余额失败:', error)
|
console.error('获取余额失败:', error)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [dealerUser])
|
||||||
|
|
||||||
// 获取提现记录
|
// 获取提现记录
|
||||||
const fetchWithdrawRecords = useCallback(async () => {
|
const fetchWithdrawRecords = useCallback(async () => {
|
||||||
@@ -106,21 +117,31 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
|
|
||||||
const getStatusText = (status?: number) => {
|
const getStatusText = (status?: number) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 40: return '已到账'
|
case 40:
|
||||||
case 20: return '审核通过'
|
return '已到账'
|
||||||
case 10: return '待审核'
|
case 20:
|
||||||
case 30: return '已驳回'
|
return '审核通过'
|
||||||
default: return '未知'
|
case 10:
|
||||||
|
return '待审核'
|
||||||
|
case 30:
|
||||||
|
return '已驳回'
|
||||||
|
default:
|
||||||
|
return '未知'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStatusColor = (status?: number) => {
|
const getStatusColor = (status?: number) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 40: return 'success'
|
case 40:
|
||||||
case 20: return 'success'
|
return 'success'
|
||||||
case 10: return 'warning'
|
case 20:
|
||||||
case 30: return 'danger'
|
return 'success'
|
||||||
default: return 'default'
|
case 10:
|
||||||
|
return 'warning'
|
||||||
|
case 30:
|
||||||
|
return 'danger'
|
||||||
|
default:
|
||||||
|
return 'default'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,9 +154,25 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!values.accountType) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请选择提现方式',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 验证提现金额
|
// 验证提现金额
|
||||||
const amount = parseFloat(values.amount)
|
const amount = parseFloat(values.amount)
|
||||||
const available = parseFloat(availableAmount.replace(',', ''))
|
const available = parseFloat(availableAmount.replace(/,/g, ''))
|
||||||
|
|
||||||
|
if (isNaN(amount) || amount <= 0) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请输入有效的提现金额',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (amount < 100) {
|
if (amount < 100) {
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
@@ -153,6 +190,25 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证账户信息
|
||||||
|
if (values.accountType === 'alipay') {
|
||||||
|
if (!values.account || !values.accountName) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请填写完整的支付宝信息',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if (values.accountType === 'bank') {
|
||||||
|
if (!values.account || !values.accountName || !values.bankName) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请填写完整的银行卡信息',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setSubmitting(true)
|
setSubmitting(true)
|
||||||
|
|
||||||
@@ -160,7 +216,7 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
userId: dealerUser.userId,
|
userId: dealerUser.userId,
|
||||||
money: values.amount,
|
money: values.amount,
|
||||||
payType: values.accountType === 'wechat' ? 10 :
|
payType: values.accountType === 'wechat' ? 10 :
|
||||||
values.accountType === 'alipay' ? 20 : 30,
|
values.accountType === 'alipay' ? 20 : 30,
|
||||||
applyStatus: 10, // 待审核
|
applyStatus: 10, // 待审核
|
||||||
platform: 'MiniProgram'
|
platform: 'MiniProgram'
|
||||||
}
|
}
|
||||||
@@ -206,11 +262,11 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
const quickAmounts = ['100', '300', '500', '1000']
|
const quickAmounts = ['100', '300', '500', '1000']
|
||||||
|
|
||||||
const setQuickAmount = (amount: string) => {
|
const setQuickAmount = (amount: string) => {
|
||||||
formRef.current?.setFieldsValue({ amount })
|
formRef.current?.setFieldsValue({amount})
|
||||||
}
|
}
|
||||||
|
|
||||||
const setAllAmount = () => {
|
const setAllAmount = () => {
|
||||||
formRef.current?.setFieldsValue({ amount: availableAmount.replace(',', '') })
|
formRef.current?.setFieldsValue({amount: availableAmount.replace(/,/g, '')})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化金额
|
// 格式化金额
|
||||||
@@ -240,7 +296,7 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
<View className="p-3 rounded-full" style={{
|
<View className="p-3 rounded-full" style={{
|
||||||
background: 'rgba(255, 255, 255, 0.2)'
|
background: 'rgba(255, 255, 255, 0.2)'
|
||||||
}}>
|
}}>
|
||||||
<Wallet color="white" size="32" />
|
<Wallet color="white" size="32"/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="mt-4 pt-4 relative z-10" style={{
|
<View className="mt-4 pt-4 relative z-10" style={{
|
||||||
@@ -262,6 +318,14 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
<Input
|
<Input
|
||||||
placeholder="请输入提现金额"
|
placeholder="请输入提现金额"
|
||||||
type="number"
|
type="number"
|
||||||
|
onChange={(value) => {
|
||||||
|
// 实时验证提现金额
|
||||||
|
const amount = parseFloat(value)
|
||||||
|
const available = parseFloat(availableAmount.replace(/,/g, ''))
|
||||||
|
if (!isNaN(amount) && amount > available) {
|
||||||
|
// 可以在这里添加实时提示,但不阻止输入
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@@ -308,10 +372,10 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
{selectedAccount === 'alipay' && (
|
{selectedAccount === 'alipay' && (
|
||||||
<>
|
<>
|
||||||
<Form.Item name="account" label="支付宝账号" required>
|
<Form.Item name="account" label="支付宝账号" required>
|
||||||
<Input placeholder="请输入支付宝账号" />
|
<Input placeholder="请输入支付宝账号"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="accountName" label="支付宝姓名" required>
|
<Form.Item name="accountName" label="支付宝姓名" required>
|
||||||
<Input placeholder="请输入支付宝实名姓名" />
|
<Input placeholder="请输入支付宝实名姓名"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -319,13 +383,13 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
{selectedAccount === 'bank' && (
|
{selectedAccount === 'bank' && (
|
||||||
<>
|
<>
|
||||||
<Form.Item name="bankName" label="开户银行" required>
|
<Form.Item name="bankName" label="开户银行" required>
|
||||||
<Input placeholder="请输入开户银行名称" />
|
<Input placeholder="请输入开户银行名称"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="account" label="银行卡号" required>
|
<Form.Item name="account" label="银行卡号" required>
|
||||||
<Input placeholder="请输入银行卡号" />
|
<Input placeholder="请输入银行卡号"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="accountName" label="开户姓名" required>
|
<Form.Item name="accountName" label="开户姓名" required>
|
||||||
<Input placeholder="请输入银行卡开户姓名" />
|
<Input placeholder="请输入银行卡开户姓名"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -354,60 +418,64 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|
||||||
const renderWithdrawRecords = () => (
|
const renderWithdrawRecords = () => {
|
||||||
<PullToRefresh
|
console.log('渲染提现记录:', {loading, recordsCount: withdrawRecords.length, dealerUserId: dealerUser?.userId})
|
||||||
disabled={refreshing}
|
|
||||||
onRefresh={handleRefresh}
|
|
||||||
>
|
|
||||||
<View className="p-4">
|
|
||||||
{loading ? (
|
|
||||||
<View className="text-center py-8">
|
|
||||||
<Loading />
|
|
||||||
<Text className="text-gray-500 mt-2">加载中...</Text>
|
|
||||||
</View>
|
|
||||||
) : withdrawRecords.length > 0 ? (
|
|
||||||
withdrawRecords.map(record => (
|
|
||||||
<View key={record.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
|
|
||||||
<View className="flex justify-between items-start mb-3">
|
|
||||||
<View>
|
|
||||||
<Text className="font-semibold text-gray-800 mb-1">
|
|
||||||
提现金额:¥{record.money}
|
|
||||||
</Text>
|
|
||||||
<Text className="text-sm text-gray-500">
|
|
||||||
提现账户:{record.accountDisplay}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<Tag type={getStatusColor(record.applyStatus)}>
|
|
||||||
{getStatusText(record.applyStatus)}
|
|
||||||
</Tag>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View className="text-xs text-gray-400">
|
return (
|
||||||
<Text>申请时间:{record.createTime}</Text>
|
<PullToRefresh
|
||||||
{record.auditTime && (
|
disabled={refreshing}
|
||||||
<Text className="block mt-1">
|
onRefresh={handleRefresh}
|
||||||
审核时间:{new Date(record.auditTime).toLocaleString()}
|
>
|
||||||
</Text>
|
<View>
|
||||||
)}
|
{loading ? (
|
||||||
{record.rejectReason && (
|
<View className="text-center py-8">
|
||||||
<Text className="block mt-1 text-red-500">
|
<Loading/>
|
||||||
驳回原因:{record.rejectReason}
|
<Text className="text-gray-500 mt-2">加载中...</Text>
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
))
|
) : withdrawRecords.length > 0 ? (
|
||||||
) : (
|
withdrawRecords.map(record => (
|
||||||
<Empty description="暂无提现记录" />
|
<View key={record.id} className="rounded-lg p-4 mb-3 shadow-sm">
|
||||||
)}
|
<View className="flex justify-between items-start mb-3">
|
||||||
</View>
|
<View>
|
||||||
</PullToRefresh>
|
<Text className="font-semibold text-gray-800 mb-1">
|
||||||
)
|
提现金额:¥{record.money}
|
||||||
|
</Text>
|
||||||
|
<Text className="text-sm text-gray-500">
|
||||||
|
提现账户:{record.accountDisplay}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Tag type={getStatusColor(record.applyStatus)}>
|
||||||
|
{getStatusText(record.applyStatus)}
|
||||||
|
</Tag>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="text-xs text-gray-400">
|
||||||
|
<Text>申请时间:{record.createTime}</Text>
|
||||||
|
{record.auditTime && (
|
||||||
|
<Text className="block mt-1">
|
||||||
|
审核时间:{new Date(record.auditTime).toLocaleString()}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
{record.rejectReason && (
|
||||||
|
<Text className="block mt-1 text-red-500">
|
||||||
|
驳回原因:{record.rejectReason}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Empty description="暂无提现记录"/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</PullToRefresh>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (!dealerUser) {
|
if (!dealerUser) {
|
||||||
return (
|
return (
|
||||||
<View className="bg-gray-50 min-h-screen flex items-center justify-center">
|
<View className="bg-gray-50 min-h-screen flex items-center justify-center">
|
||||||
<Loading />
|
<Loading/>
|
||||||
<Text className="text-gray-500 mt-2">加载中...</Text>
|
<Text className="text-gray-500 mt-2">加载中...</Text>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
@@ -415,12 +483,12 @@ const DealerWithdraw: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="bg-gray-50 min-h-screen">
|
<View className="bg-gray-50 min-h-screen">
|
||||||
<Tabs value={activeTab} onChange={() => setActiveTab}>
|
<Tabs value={activeTab} onChange={handleTabChange}>
|
||||||
<Tabs.TabPane title="申请提现" value="0">
|
<Tabs.TabPane title="申请提现" value="0">
|
||||||
{renderWithdrawForm()}
|
{renderWithdrawForm()}
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
|
|
||||||
<Tabs.TabPane title="提现记录" value="1">
|
<Tabs.TabPane title="提现记录" value="1" className={'bg-none'} style={{backgroundColor: 'transparent'}}>
|
||||||
{renderWithdrawRecords()}
|
{renderWithdrawRecords()}
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
Reference in New Issue
Block a user