master #1

Open
gxwebsoft wants to merge 108 commits from developer/template-10584:master into master
Showing only changes of commit 3b98dfa150 - Show all commits

View File

@@ -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<boolean>(false)
const [refreshing, setRefreshing] = useState<boolean>(false)
const [submitting, setSubmitting] = useState<boolean>(false)
const [claimingId, setClaimingId] = useState<number | null>(null)
const [availableAmount, setAvailableAmount] = useState<string>('0.00')
const [withdrawRecords, setWithdrawRecords] = useState<WithdrawRecordWithDetails[]>([])
const formRef = useRef<any>(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 = () => {
<View className="px-4 py-2">
<Text className="text-sm text-gray-500">
</Text>
</View>
</CellGroup>
@@ -431,20 +485,36 @@ const DealerWithdraw: React.FC = () => {
<Text className="font-semibold text-gray-800 mb-1">
¥{record.money}
</Text>
<Text className="text-sm text-gray-500">
{record.accountDisplay}
</Text>
{/*<Text className="text-sm text-gray-500">*/}
{/* 提现账户:{record.accountDisplay}*/}
{/*</Text>*/}
</Space>
<Tag type={getStatusColor(record.applyStatus)}>
<Tag background="#999999" type={getStatusColor(record.applyStatus)} plain>
{getStatusText(record.applyStatus)}
</Tag>
</View>
{record.applyStatus === 20 && record.payType === 10 && (
<View className="flex justify-center">
<Button
size="small"
type="primary"
loading={claimingId === record.id}
disabled={claimingId !== null}
onClick={() => handleClaim(record)}
>
</Button>
</View>
)}
<View className="flex justify-between items-center">
<View className="text-xs text-gray-400">
<Text>{record.createTime}</Text>
<Text>{record.createTime}</Text>
{record.auditTime && (
<Text className="block mt-1">
{new Date(record.auditTime).toLocaleString()}
{record.auditTime}
</Text>
)}
{record.rejectReason && (
@@ -454,6 +524,8 @@ const DealerWithdraw: React.FC = () => {
)}
</View>
</View>
</View>
))
) : (
<Empty description="暂无提现记录"/>