|
|
@@ -171,16 +171,26 @@ onMounted(() => {
|
|
|
})
|
|
|
|
|
|
const isFormValid = computed(() => {
|
|
|
- // Check if ID card images are available (either uploaded or existing)
|
|
|
+ // Only validate fields that will be submitted.
|
|
|
+ // Rule:
|
|
|
+ // - If any part is not applied (state=0), submit both.
|
|
|
+ // - Otherwise submit only the rejected part(s) (state=3).
|
|
|
+ const shouldSubmitBoth = idCardState.value === 0 || bankCardState.value === 0
|
|
|
+ || (idCardState.value === 3 && bankCardState.value === 3)
|
|
|
+ const shouldSubmitIdCard = shouldSubmitBoth || idCardState.value === 3
|
|
|
+ const shouldSubmitBankCard = shouldSubmitBoth || bankCardState.value === 3
|
|
|
+
|
|
|
+ if (!shouldSubmitIdCard && !shouldSubmitBankCard) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
const hasIdCardImages = (frontIdFile.value || frontIdImageUrl.value)
|
|
|
&& (backIdFile.value || backIdImageUrl.value)
|
|
|
|
|
|
return (
|
|
|
realName.value.trim()
|
|
|
- && idNo.value.trim()
|
|
|
- && hasIdCardImages
|
|
|
- && bankNo.value.trim()
|
|
|
- && bankName.value.trim()
|
|
|
+ && (!shouldSubmitIdCard || (idNo.value.trim() && hasIdCardImages))
|
|
|
+ && (!shouldSubmitBankCard || (bankNo.value.trim() && bankName.value.trim()))
|
|
|
&& !submitting.value
|
|
|
&& !uploadingFront.value
|
|
|
&& !uploadingBack.value
|
|
|
@@ -188,78 +198,106 @@ const isFormValid = computed(() => {
|
|
|
})
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
|
- // Validate all fields
|
|
|
- if (!realName.value.trim()) {
|
|
|
- showToast(t('wallet.withdraw.auth.validation.realNameRequired'))
|
|
|
+ // Decide which parts to submit.
|
|
|
+ // - If any part is not applied (state=0), submit both.
|
|
|
+ // - Otherwise submit only the rejected part(s) (state=3).
|
|
|
+ const shouldSubmitBoth = idCardState.value === 0 || bankCardState.value === 0
|
|
|
+ || (idCardState.value === 3 && bankCardState.value === 3)
|
|
|
+ const shouldSubmitIdCard = shouldSubmitBoth || idCardState.value === 3
|
|
|
+ const shouldSubmitBankCard = shouldSubmitBoth || bankCardState.value === 3
|
|
|
+
|
|
|
+ if (!shouldSubmitIdCard && !shouldSubmitBankCard) {
|
|
|
+ showToast(t('wallet.withdraw.auth.failed'))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- if (!idNo.value.trim()) {
|
|
|
- showToast(t('wallet.withdraw.auth.validation.idNoRequired'))
|
|
|
+ // Validate common field
|
|
|
+ if (!realName.value.trim()) {
|
|
|
+ showToast(t('wallet.withdraw.auth.validation.realNameRequired'))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // Check if ID card images are available (either new files or existing URLs)
|
|
|
- if (!frontIdFile.value && !frontIdImageUrl.value) {
|
|
|
- showToast(t('wallet.withdraw.auth.validation.frontImageRequired'))
|
|
|
- return
|
|
|
- }
|
|
|
+ // Validate only the parts being submitted
|
|
|
+ if (shouldSubmitIdCard) {
|
|
|
+ if (!idNo.value.trim()) {
|
|
|
+ showToast(t('wallet.withdraw.auth.validation.idNoRequired'))
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- if (!backIdFile.value && !backIdImageUrl.value) {
|
|
|
- showToast(t('wallet.withdraw.auth.validation.backImageRequired'))
|
|
|
- return
|
|
|
- }
|
|
|
+ // Check if ID card images are available (either new files or existing URLs)
|
|
|
+ if (!frontIdFile.value && !frontIdImageUrl.value) {
|
|
|
+ showToast(t('wallet.withdraw.auth.validation.frontImageRequired'))
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- if (!bankNo.value.trim()) {
|
|
|
- showToast(t('wallet.withdraw.auth.validation.bankNoRequired'))
|
|
|
- return
|
|
|
+ if (!backIdFile.value && !backIdImageUrl.value) {
|
|
|
+ showToast(t('wallet.withdraw.auth.validation.backImageRequired'))
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (!bankName.value.trim()) {
|
|
|
- showToast(t('wallet.withdraw.auth.validation.bankNameRequired'))
|
|
|
- return
|
|
|
+ if (shouldSubmitBankCard) {
|
|
|
+ if (!bankNo.value.trim()) {
|
|
|
+ showToast(t('wallet.withdraw.auth.validation.bankNoRequired'))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!bankName.value.trim()) {
|
|
|
+ showToast(t('wallet.withdraw.auth.validation.bankNameRequired'))
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
submitting.value = true
|
|
|
|
|
|
- // Upload front ID card image (only if new file selected)
|
|
|
+ // Upload ID card images only when needed.
|
|
|
let frontImageUrl = frontIdImageUrl.value
|
|
|
- if (frontIdFile.value) {
|
|
|
- const uploadedUrl = await uploadFrontFile(frontIdFile.value)
|
|
|
- if (!uploadedUrl) {
|
|
|
- return
|
|
|
+ let backImageUrl = backIdImageUrl.value
|
|
|
+ if (shouldSubmitIdCard) {
|
|
|
+ // Upload front ID card image (only if new file selected)
|
|
|
+ if (frontIdFile.value) {
|
|
|
+ const uploadedUrl = await uploadFrontFile(frontIdFile.value)
|
|
|
+ if (!uploadedUrl) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ frontImageUrl = uploadedUrl
|
|
|
}
|
|
|
- frontImageUrl = uploadedUrl
|
|
|
- }
|
|
|
|
|
|
- // Upload back ID card image (only if new file selected)
|
|
|
- let backImageUrl = backIdImageUrl.value
|
|
|
- if (backIdFile.value) {
|
|
|
- const uploadedUrl = await uploadBackFile(backIdFile.value)
|
|
|
- if (!uploadedUrl) {
|
|
|
- return
|
|
|
+ // Upload back ID card image (only if new file selected)
|
|
|
+ if (backIdFile.value) {
|
|
|
+ const uploadedUrl = await uploadBackFile(backIdFile.value)
|
|
|
+ if (!uploadedUrl) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ backImageUrl = uploadedUrl
|
|
|
}
|
|
|
- backImageUrl = uploadedUrl
|
|
|
}
|
|
|
|
|
|
- // Submit to backend (use same realName for both idCard and bankCard)
|
|
|
- const result = await walletApi.submitWithdrawRealNameAuth({
|
|
|
- idCard: {
|
|
|
+ // Build payload: submit only rejected part(s), unless any part is not applied.
|
|
|
+ const payload: Parameters<typeof walletApi.submitWithdrawRealNameAuth>[0] = {}
|
|
|
+ if (shouldSubmitIdCard) {
|
|
|
+ payload.idCard = {
|
|
|
idNo: idNo.value.trim(),
|
|
|
realName: realName.value.trim(),
|
|
|
idCardFrontImage: frontImageUrl,
|
|
|
idCardBackImage: backImageUrl,
|
|
|
- },
|
|
|
- bankCard: {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (shouldSubmitBankCard) {
|
|
|
+ payload.bankCard = {
|
|
|
bankNo: bankNo.value.trim(),
|
|
|
realName: realName.value.trim(),
|
|
|
bankName: bankName.value.trim(),
|
|
|
- },
|
|
|
- })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await walletApi.submitWithdrawRealNameAuth(payload)
|
|
|
|
|
|
// Check result
|
|
|
- if (result?.idCardApply && result?.idBankCardApply) {
|
|
|
+ const idOk = !payload.idCard || !!result?.idCardApply
|
|
|
+ const bankOk = !payload.bankCard || !!result?.idBankCardApply
|
|
|
+ if (idOk && bankOk) {
|
|
|
showToast(t('wallet.withdraw.auth.success'))
|
|
|
// Reload status to show updated state
|
|
|
await loadAuthStatus()
|
|
|
@@ -518,7 +556,7 @@ const onBack = () => {
|
|
|
<!-- Tip -->
|
|
|
<div class="withdraw-auth-card__section withdraw-auth-card__section--tip">
|
|
|
<div class="withdraw-auth-tip">
|
|
|
- <TipIcon />
|
|
|
+ <TipIcon class="withdraw-auth-tip__icon" />
|
|
|
<p class="withdraw-auth-tip__text">
|
|
|
{{ t('wallet.withdraw.auth.tip') }}
|
|
|
</p>
|
|
|
@@ -663,8 +701,7 @@ const onBack = () => {
|
|
|
.withdraw-auth-upload {
|
|
|
margin-top: 10px;
|
|
|
display: flex;
|
|
|
- gap: 8px;
|
|
|
- justify-content: center;
|
|
|
+ justify-content: space-between;
|
|
|
}
|
|
|
|
|
|
.withdraw-auth-upload-item {
|
|
|
@@ -812,8 +849,12 @@ const onBack = () => {
|
|
|
|
|
|
.withdraw-auth-tip {
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
+ align-items: flex-start;
|
|
|
gap: 3px;
|
|
|
+
|
|
|
+ &__icon {
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.withdraw-auth-tip__text {
|