完善支付宝提现收款码
This commit is contained in:
@@ -235,9 +235,7 @@ export default function FinancePanel() {
|
||||
minWidth: 140,
|
||||
render: (_, row) => (
|
||||
<ImagePreviewList
|
||||
files={
|
||||
row.requestType === 'recharge' ? getRechargeProofs(row) : getWechatWithdrawQrCode(row)
|
||||
}
|
||||
files={row.requestType === 'recharge' ? getRechargeProofs(row) : getWithdrawQrCode(row)}
|
||||
size={48}
|
||||
/>
|
||||
),
|
||||
@@ -516,13 +514,21 @@ export default function FinancePanel() {
|
||||
</Descriptions.Item>
|
||||
{reviewState.request.requestType === 'withdraw' &&
|
||||
reviewState.request.accountChannel === 'alipay' ? (
|
||||
<Descriptions.Item label="支付宝账号">
|
||||
{reviewState.request.accountNo ? (
|
||||
<Typography.Text copyable>{reviewState.request.accountNo}</Typography.Text>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Descriptions.Item>
|
||||
<>
|
||||
<Descriptions.Item label="支付宝账号">
|
||||
{reviewState.request.accountNo ? (
|
||||
<Typography.Text copyable>{reviewState.request.accountNo}</Typography.Text>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="支付宝收款二维码">
|
||||
<ImagePreviewList
|
||||
files={getAlipayWithdrawQrCode(reviewState.request)}
|
||||
size={88}
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
</>
|
||||
) : null}
|
||||
{reviewState.request.requestType === 'recharge' ? (
|
||||
<>
|
||||
@@ -697,6 +703,30 @@ function getWechatWithdrawQrCode(request: WorkerFinanceRequest): UploadedFile[]
|
||||
]
|
||||
}
|
||||
|
||||
function getWithdrawQrCode(request: WorkerFinanceRequest): UploadedFile[] {
|
||||
if (request.accountChannel === 'alipay') return getAlipayWithdrawQrCode(request)
|
||||
return getWechatWithdrawQrCode(request)
|
||||
}
|
||||
|
||||
function getAlipayWithdrawQrCode(request: WorkerFinanceRequest): UploadedFile[] {
|
||||
if (request.requestType !== 'withdraw' || request.accountChannel !== 'alipay') return []
|
||||
const payload = asRecord(request.payload)
|
||||
const file = asRecord(payload.alipayQrCodeImage)
|
||||
const url = String(file.url || '').trim()
|
||||
if (!url) return []
|
||||
return [
|
||||
{
|
||||
url,
|
||||
mediumUrl: String(file.mediumUrl || '').trim(),
|
||||
thumbnailUrl: String(file.thumbnailUrl || '').trim(),
|
||||
objectKey: String(file.objectKey || '').trim(),
|
||||
filename: String(file.filename || '').trim(),
|
||||
contentType: String(file.contentType || '').trim(),
|
||||
size: Number(file.size || 0),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
function getRechargePaidAt(request: WorkerFinanceRequest): string {
|
||||
const payload = asRecord(request.payload)
|
||||
return String(payload.paidAt || '').trim()
|
||||
|
||||
@@ -39,6 +39,7 @@ type WithdrawalAccountFormValues = {
|
||||
accountChannel?: string
|
||||
accountName?: string
|
||||
accountNo?: string
|
||||
alipayQrCodeImages?: UploadedFile[]
|
||||
wechatQrCodeImages?: UploadedFile[]
|
||||
}
|
||||
|
||||
@@ -69,6 +70,9 @@ export default function WorkersPanel() {
|
||||
const [resetPasswordForm] = Form.useForm<{ password: string }>()
|
||||
const [freezeForm] = Form.useForm<FreezeWorkerFormValues>()
|
||||
const withdrawalAccountChannel = Form.useWatch('accountChannel', withdrawalAccountForm)
|
||||
const editingAlipayAccount = withdrawalAccounts.find(
|
||||
(account) => account.accountChannel === 'alipay',
|
||||
)
|
||||
|
||||
const workersQuery = useQuery({
|
||||
queryKey: ['admin-worker-platform-workers', status, keyword, workerType, page, pageSize],
|
||||
@@ -225,6 +229,7 @@ export default function WorkersPanel() {
|
||||
accountChannel,
|
||||
accountName: account?.accountName || '',
|
||||
accountNo: account?.accountNo || '',
|
||||
alipayQrCodeImages: account?.alipayQrCodeImage ? [account.alipayQrCodeImage] : [],
|
||||
wechatQrCodeImages: account?.wechatQrCodeImage ? [account.wechatQrCodeImage] : [],
|
||||
})
|
||||
}
|
||||
@@ -240,6 +245,7 @@ export default function WorkersPanel() {
|
||||
{
|
||||
accountName: String(values.accountName || '').trim(),
|
||||
accountNo: String(values.accountNo || '').trim(),
|
||||
alipayQrCodeImages: values.alipayQrCodeImages || [],
|
||||
wechatQrCodeImages: values.wechatQrCodeImages || [],
|
||||
},
|
||||
)
|
||||
@@ -559,13 +565,28 @@ export default function WorkersPanel() {
|
||||
<ImageUpload scene="admin-worker-withdrawal-wechat-qr" scope="admin" maxCount={1} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<Form.Item
|
||||
label="支付宝账号"
|
||||
name="accountNo"
|
||||
rules={[{ required: true, message: '请输入支付宝账号' }]}
|
||||
>
|
||||
<Input placeholder="请输入支付宝账号" />
|
||||
</Form.Item>
|
||||
<>
|
||||
<Form.Item
|
||||
label="支付宝账号"
|
||||
name="accountNo"
|
||||
rules={
|
||||
editingAlipayAccount ? [] : [{ required: true, message: '请输入支付宝账号' }]
|
||||
}
|
||||
>
|
||||
<Input
|
||||
placeholder={
|
||||
editingAlipayAccount ? '历史账户未登记账号,可仅补充二维码' : '请输入支付宝账号'
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="支付宝收款二维码"
|
||||
name="alipayQrCodeImages"
|
||||
rules={[{ required: true, message: '请上传支付宝收款二维码' }]}
|
||||
>
|
||||
<ImageUpload scene="admin-worker-withdrawal-alipay-qr" scope="admin" maxCount={1} />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
deleteWorkerSession,
|
||||
fetchWorkerWalletLedgers,
|
||||
logoutWorker,
|
||||
saveWorkerAlipayWithdrawalQrCode,
|
||||
} from '@/services/worker'
|
||||
import type {
|
||||
UploadedFile,
|
||||
@@ -80,9 +81,14 @@ type WithdrawalAccountFormValues = {
|
||||
accountChannel?: string
|
||||
accountName?: string
|
||||
accountNo?: string
|
||||
alipayQrCodeImages?: UploadedFile[]
|
||||
wechatQrCodeImages?: UploadedFile[]
|
||||
}
|
||||
|
||||
type AlipayQrCodeFormValues = {
|
||||
alipayQrCodeImages?: UploadedFile[]
|
||||
}
|
||||
|
||||
type PasswordFormValues = {
|
||||
currentPassword?: string
|
||||
newPassword?: string
|
||||
@@ -106,6 +112,7 @@ export default function WorkerProfilePage() {
|
||||
const [rechargeOpen, setRechargeOpen] = useState(false)
|
||||
const [withdrawOpen, setWithdrawOpen] = useState(false)
|
||||
const [withdrawalAccountOpen, setWithdrawalAccountOpen] = useState(false)
|
||||
const [alipayQrCodeOpen, setAlipayQrCodeOpen] = useState(false)
|
||||
const [passwordOpen, setPasswordOpen] = useState(false)
|
||||
const [contactOpen, setContactOpen] = useState(false)
|
||||
const [devicesOpen, setDevicesOpen] = useState(false)
|
||||
@@ -116,6 +123,7 @@ export default function WorkerProfilePage() {
|
||||
const [rechargeForm] = Form.useForm<RechargeFormValues>()
|
||||
const [withdrawForm] = Form.useForm<WithdrawFormValues>()
|
||||
const [withdrawalAccountForm] = Form.useForm<WithdrawalAccountFormValues>()
|
||||
const [alipayQrCodeForm] = Form.useForm<AlipayQrCodeFormValues>()
|
||||
const [passwordForm] = Form.useForm<PasswordFormValues>()
|
||||
const selectedWithdrawChannel = Form.useWatch('accountChannel', withdrawForm)
|
||||
const selectedWithdrawalAccountChannel = Form.useWatch('accountChannel', withdrawalAccountForm)
|
||||
@@ -141,6 +149,9 @@ export default function WorkerProfilePage() {
|
||||
const selectedWithdrawalAccount = withdrawalAccounts.find(
|
||||
(account) => account.accountChannel === selectedWithdrawChannel,
|
||||
)
|
||||
const alipayWithdrawalAccount = withdrawalAccounts.find(
|
||||
(account) => account.accountChannel === 'alipay',
|
||||
)
|
||||
const canUseFinanceActions = worker?.status === 'active'
|
||||
|
||||
async function copyInviteCode() {
|
||||
@@ -233,6 +244,11 @@ export default function WorkerProfilePage() {
|
||||
openWithdrawalAccountModal()
|
||||
return
|
||||
}
|
||||
if (alipayWithdrawalAccount && !alipayWithdrawalAccount.alipayQrCodeImage) {
|
||||
message.warning('请先补充支付宝收款二维码')
|
||||
openAlipayQrCodeModal()
|
||||
return
|
||||
}
|
||||
withdrawForm.setFieldValue('accountChannel', withdrawalAccounts[0].accountChannel)
|
||||
setWithdrawOpen(true)
|
||||
}
|
||||
@@ -249,6 +265,19 @@ export default function WorkerProfilePage() {
|
||||
setWithdrawalAccountOpen(true)
|
||||
}
|
||||
|
||||
function openAlipayQrCodeModal() {
|
||||
if (!alipayWithdrawalAccount) {
|
||||
openWithdrawalAccountModal()
|
||||
return
|
||||
}
|
||||
alipayQrCodeForm.setFieldsValue({
|
||||
alipayQrCodeImages: alipayWithdrawalAccount.alipayQrCodeImage
|
||||
? [alipayWithdrawalAccount.alipayQrCodeImage]
|
||||
: [],
|
||||
})
|
||||
setAlipayQrCodeOpen(true)
|
||||
}
|
||||
|
||||
async function submitRecharge(values: RechargeFormValues) {
|
||||
setSubmittingRecharge(true)
|
||||
try {
|
||||
@@ -301,6 +330,7 @@ export default function WorkerProfilePage() {
|
||||
accountChannel: String(values.accountChannel || ''),
|
||||
accountName: String(values.accountName || '').trim(),
|
||||
accountNo: String(values.accountNo || '').trim(),
|
||||
alipayQrCodeImages: values.alipayQrCodeImages || [],
|
||||
wechatQrCodeImages: values.wechatQrCodeImages || [],
|
||||
})
|
||||
message.success('提现信息已添加,该方式后续修改请联系客服处理')
|
||||
@@ -316,6 +346,20 @@ export default function WorkerProfilePage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function submitAlipayQrCode(values: AlipayQrCodeFormValues) {
|
||||
try {
|
||||
await saveWorkerAlipayWithdrawalQrCode({
|
||||
alipayQrCodeImages: values.alipayQrCodeImages || [],
|
||||
})
|
||||
message.success('支付宝收款二维码已保存')
|
||||
setAlipayQrCodeOpen(false)
|
||||
alipayQrCodeForm.resetFields()
|
||||
await refreshAll()
|
||||
} catch (error) {
|
||||
message.error(error instanceof Error ? error.message : '保存支付宝收款二维码失败')
|
||||
}
|
||||
}
|
||||
|
||||
async function submitPasswordChange(values: PasswordFormValues) {
|
||||
setSubmittingPassword(true)
|
||||
try {
|
||||
@@ -673,6 +717,22 @@ export default function WorkerProfilePage() {
|
||||
</div>
|
||||
<span>邀请好友</span>
|
||||
</button>
|
||||
{alipayWithdrawalAccount && !alipayWithdrawalAccount.alipayQrCodeImage ? (
|
||||
<button
|
||||
type="button"
|
||||
className="worker-profile-mobile-tool-item"
|
||||
disabled={!canUseFinanceActions}
|
||||
onClick={openAlipayQrCodeModal}
|
||||
>
|
||||
<div
|
||||
className="worker-profile-mobile-tool-icon"
|
||||
style={{ background: '#f5f3ff', color: '#7c3aed' }}
|
||||
>
|
||||
<BankOutlined />
|
||||
</div>
|
||||
<span>补充支付宝收款码</span>
|
||||
</button>
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
className="worker-profile-mobile-tool-item"
|
||||
@@ -1152,6 +1212,15 @@ export default function WorkerProfilePage() {
|
||||
添加提现信息
|
||||
</Button>
|
||||
) : null}
|
||||
{alipayWithdrawalAccount && !alipayWithdrawalAccount.alipayQrCodeImage ? (
|
||||
<Button
|
||||
icon={<BankOutlined />}
|
||||
disabled={!canUseFinanceActions}
|
||||
onClick={openAlipayQrCodeModal}
|
||||
>
|
||||
补充支付宝收款码
|
||||
</Button>
|
||||
) : null}
|
||||
<Button icon={<LockOutlined />} onClick={() => setPasswordOpen(true)}>
|
||||
修改密码
|
||||
</Button>
|
||||
@@ -1234,10 +1303,14 @@ export default function WorkerProfilePage() {
|
||||
<Typography.Text type="secondary">
|
||||
{account.accountChannel === 'wechat'
|
||||
? '已上传收款二维码'
|
||||
: account.accountNoMasked}
|
||||
: `${account.accountNoMasked} / ${
|
||||
account.alipayQrCodeImage
|
||||
? '已上传收款二维码'
|
||||
: '未上传收款二维码'
|
||||
}`}
|
||||
</Typography.Text>
|
||||
<Typography.Text type="secondary">
|
||||
已锁定,修改请联系客服
|
||||
收款人姓名和账号已锁定
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
))}
|
||||
@@ -1533,7 +1606,7 @@ export default function WorkerProfilePage() {
|
||||
<Alert
|
||||
showIcon
|
||||
type="warning"
|
||||
message="支付宝和微信可分别添加一次;每种方式添加后均无法自行修改,如需修改请联系客服。"
|
||||
message="支付宝和微信可分别添加一次;收款人姓名和账号添加后不可自行修改。历史支付宝账户缺少二维码时,仅可补充一次。"
|
||||
style={{ marginBottom: 16 }}
|
||||
/>
|
||||
<Form form={withdrawalAccountForm} layout="vertical" onFinish={submitWithdrawalAccount}>
|
||||
@@ -1570,17 +1643,54 @@ export default function WorkerProfilePage() {
|
||||
<ImageUpload scene="worker-withdrawal-wechat-qr" scope="worker" maxCount={1} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<Form.Item
|
||||
label="支付宝账号"
|
||||
name="accountNo"
|
||||
rules={[{ required: true, message: '请输入支付宝账号' }]}
|
||||
>
|
||||
<Input placeholder="请输入支付宝账号" />
|
||||
</Form.Item>
|
||||
<>
|
||||
<Form.Item
|
||||
label="支付宝账号"
|
||||
name="accountNo"
|
||||
rules={[{ required: true, message: '请输入支付宝账号' }]}
|
||||
>
|
||||
<Input placeholder="请输入支付宝账号" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="支付宝收款二维码"
|
||||
name="alipayQrCodeImages"
|
||||
rules={[{ required: true, message: '请上传支付宝收款二维码' }]}
|
||||
>
|
||||
<ImageUpload scene="worker-withdrawal-alipay-qr" scope="worker" maxCount={1} />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="补充支付宝收款二维码"
|
||||
open={alipayQrCodeOpen}
|
||||
width={isMobile ? '92%' : 500}
|
||||
destroyOnHidden
|
||||
onCancel={() => {
|
||||
setAlipayQrCodeOpen(false)
|
||||
alipayQrCodeForm.resetFields()
|
||||
}}
|
||||
onOk={() => alipayQrCodeForm.submit()}
|
||||
>
|
||||
<Alert
|
||||
showIcon
|
||||
type="info"
|
||||
message="历史账户仅可补充一次支付宝收款二维码,保存后不可自行修改;已登记的收款人姓名和账号保持锁定。"
|
||||
style={{ marginBottom: 16 }}
|
||||
/>
|
||||
<Form form={alipayQrCodeForm} layout="vertical" onFinish={submitAlipayQrCode}>
|
||||
<Form.Item
|
||||
label="支付宝收款二维码"
|
||||
name="alipayQrCodeImages"
|
||||
rules={[{ required: true, message: '请上传支付宝收款二维码' }]}
|
||||
>
|
||||
<ImageUpload scene="worker-withdrawal-alipay-qr" scope="worker" maxCount={1} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="提现申请"
|
||||
open={withdrawOpen}
|
||||
|
||||
@@ -310,6 +310,7 @@ export function saveAdminWorkerWithdrawalAccount(
|
||||
payload: {
|
||||
accountName: string
|
||||
accountNo?: string
|
||||
alipayQrCodeImages?: UploadedFile[]
|
||||
wechatQrCodeImages?: UploadedFile[]
|
||||
},
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { apiDelete, apiGet, apiPost } from '@/lib/http'
|
||||
import { apiDelete, apiGet, apiPost, apiPut } from '@/lib/http'
|
||||
import type {
|
||||
CollectLookupResponse,
|
||||
UploadedFile,
|
||||
@@ -176,11 +176,16 @@ export function createWorkerWithdrawalAccount(payload: {
|
||||
accountChannel: string
|
||||
accountName: string
|
||||
accountNo?: string
|
||||
alipayQrCodeImages?: UploadedFile[]
|
||||
wechatQrCodeImages?: UploadedFile[]
|
||||
}) {
|
||||
return apiPost('/api/v1/worker/profile/withdrawal-account', payload)
|
||||
}
|
||||
|
||||
export function saveWorkerAlipayWithdrawalQrCode(payload: { alipayQrCodeImages: UploadedFile[] }) {
|
||||
return apiPut('/api/v1/worker/profile/withdrawal-account/alipay-qr-code', payload)
|
||||
}
|
||||
|
||||
export function changeWorkerPassword(payload: { currentPassword: string; newPassword: string }) {
|
||||
return apiPost<{ worker: WorkerUser; reloginRequired: boolean }>(
|
||||
'/api/v1/worker/profile/change-password',
|
||||
|
||||
@@ -197,6 +197,7 @@ export type WorkerWithdrawalAccount = {
|
||||
accountChannel: string
|
||||
accountName: string
|
||||
accountNoMasked: string
|
||||
alipayQrCodeImage: UploadedFile | null
|
||||
wechatQrCodeImage: UploadedFile | null
|
||||
createdAt: string | null
|
||||
}
|
||||
@@ -205,6 +206,7 @@ export type AdminWorkerWithdrawalAccount = {
|
||||
accountChannel: string
|
||||
accountName: string
|
||||
accountNo: string
|
||||
alipayQrCodeImage: UploadedFile | null
|
||||
wechatQrCodeImage: UploadedFile | null
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user