diff --git a/src/dealer/withdraw/__tests__/withdraw.test.tsx b/src/dealer/withdraw/__tests__/withdraw.test.tsx deleted file mode 100644 index c3aeab9..0000000 --- a/src/dealer/withdraw/__tests__/withdraw.test.tsx +++ /dev/null @@ -1,184 +0,0 @@ -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 -const mockAddShopDealerWithdraw = withdrawAPI.addShopDealerWithdraw as jest.MockedFunction -const mockPageShopDealerWithdraw = withdrawAPI.pageShopDealerWithdraw as jest.MockedFunction - -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() - expect(getByText('10000.00')).toBeInTheDocument() - expect(getByText('可提现余额')).toBeInTheDocument() - }) - - test('应该验证最低提现金额', async () => { - mockAddShopDealerWithdraw.mockResolvedValue('success') - - const { getByPlaceholderText, getByText } = render() - - // 输入低于最低金额的数值 - 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() - - // 输入超过可用余额的金额 - 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() - - // 输入有效金额 - 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() - - // 输入有效金额 - 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() - - // 点击快捷金额按钮 - const quickAmountButton = getByText('500') - fireEvent.click(quickAmountButton) - - // 验证金额输入框的值 - const amountInput = getByPlaceholderText('请输入提现金额') as HTMLInputElement - expect(amountInput.value).toBe('500') - }) - - test('全部按钮应该设置为可用余额', () => { - const { getByText, getByPlaceholderText } = render() - - // 点击全部按钮 - const allButton = getByText('全部') - fireEvent.click(allButton) - - // 验证金额输入框的值 - const amountInput = getByPlaceholderText('请输入提现金额') as HTMLInputElement - expect(amountInput.value).toBe('10000.00') - }) -}) diff --git a/src/dealer/withdraw/index.tsx b/src/dealer/withdraw/index.tsx index dcf27e8..f788d6e 100644 --- a/src/dealer/withdraw/index.tsx +++ b/src/dealer/withdraw/index.tsx @@ -1,13 +1,11 @@ import React, {useState, useRef, useEffect, useCallback} from 'react' import {View, Text} from '@tarojs/components' import { - Cell, Space, Button, Form, Input, CellGroup, - Radio, Tabs, Tag, Empty, @@ -89,7 +87,6 @@ const normalizeMoneyString = (money: unknown) => { const DealerWithdraw: React.FC = () => { const [activeTab, setActiveTab] = useState('0') - const [selectedAccount, setSelectedAccount] = useState('') const [loading, setLoading] = useState(false) const [refreshing, setRefreshing] = useState(false) const [submitting, setSubmitting] = useState(false) @@ -216,14 +213,6 @@ const DealerWithdraw: React.FC = () => { return } - if (!values.accountType) { - Taro.showToast({ - title: '请选择提现方式', - icon: 'error' - }) - return - } - // 验证提现金额 const amount = parseFloat(String(values.amount)) const available = parseFloat(normalizeMoneyString(availableAmount).replace(/,/g, '')) @@ -252,86 +241,48 @@ const DealerWithdraw: React.FC = () => { 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 { setSubmitting(true) const withdrawData: ShopDealerWithdraw = { userId: dealerUser.userId, money: values.amount, - payType: values.accountType === 'wechat' ? 10 : - values.accountType === 'alipay' ? 20 : 30, + // Only support WeChat wallet withdrawals. + payType: 10, applyStatus: 10, // 待审核 platform: 'MiniProgram' } - // 根据提现方式设置账户信息 - if (values.accountType === 'alipay') { - withdrawData.alipayAccount = values.account - withdrawData.alipayName = values.accountName - } else if (values.accountType === 'bank') { - withdrawData.bankCard = values.account - withdrawData.bankAccount = values.accountName - withdrawData.bankName = values.bankName || '银行卡' - } - // WeChat wallet: backend should return `package_info`, frontend opens the "confirm receipt" page // for user to click "确认收款". - if (values.accountType === 'wechat') { - if (!canRequestMerchantTransferConfirm()) { - throw new Error('当前环境不支持微信收款确认,请在微信小程序内操作') - } + if (!canRequestMerchantTransferConfirm()) { + throw new Error('当前环境不支持微信收款确认,请在微信小程序内操作') + } - const createResult = await addShopDealerWithdraw(withdrawData) - const packageInfo = extractPackageInfo(createResult) - if (!packageInfo) { - throw new Error('后台未返回 package_info,无法调起微信收款确认页') - } + 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 || '调起收款确认页失败,请稍后重试') - } - } - } else { - await addShopDealerWithdraw(withdrawData) + try { + await requestMerchantTransferConfirm(packageInfo) Taro.showToast({ - title: '提现申请已提交', + 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 || '调起收款确认页失败,请稍后重试') + } } // 重置表单 formRef.current?.resetFields() - setSelectedAccount('') // 刷新数据 await handleRefresh() @@ -350,7 +301,7 @@ const DealerWithdraw: React.FC = () => { } } - const quickAmounts = ['1','100', '300', '500', '1000'] + const quickAmounts = ['0.2','100', '300', '500', '1000'] const setQuickAmount = (amount: string) => { formRef.current?.setFieldsValue({amount}) @@ -409,14 +360,6 @@ const DealerWithdraw: React.FC = () => { { - // 实时验证提现金额 - const amount = parseFloat(String(value)) - const available = parseFloat(normalizeMoneyString(availableAmount).replace(/,/g, '')) - if (!isNaN(amount) && amount > available) { - // 可以在这里添加实时提示,但不阻止输入 - } - }} /> @@ -444,62 +387,11 @@ const DealerWithdraw: React.FC = () => { - - { - const next = String(value) - setSelectedAccount(next) - // Ensure Form gets the field value even when Radio.Group is controlled. - formRef.current?.setFieldsValue({accountType: next}) - }} - > - - - 微信钱包 - - - 支付宝 - - - 银行卡 - - - - - - {selectedAccount === 'alipay' && ( - <> - - - - - - - - )} - - {selectedAccount === 'bank' && ( - <> - - - - - - - - - - - )} - - {selectedAccount === 'wechat' && ( - - - 提交后将拉起微信收款确认页,需要您点击“确认收款”后才会完成转账 - - - )} + + + 提现方式:微信钱包(提交后将拉起微信收款确认页,需要您点击“确认收款”后才会完成转账) + + @@ -508,7 +400,7 @@ const DealerWithdraw: React.FC = () => { type="primary" nativeType="submit" loading={submitting} - disabled={submitting || !selectedAccount} + disabled={submitting} > {submitting ? '提交中...' : '申请提现'} @@ -532,21 +424,21 @@ const DealerWithdraw: React.FC = () => { 加载中... ) : withdrawRecords.length > 0 ? ( - withdrawRecords.map(record => ( - - - - - 提现金额:¥{record.money} - - - 提现账户:{record.accountDisplay} - - - - {getStatusText(record.applyStatus)} - - + withdrawRecords.map(record => ( + + + + + 提现金额:¥{record.money} + + + 提现账户:{record.accountDisplay} + + + + {getStatusText(record.applyStatus)} + + 申请时间:{record.createTime}