From d2030f17111d13974318cd1ed1e6f28cb1ffefa5 Mon Sep 17 00:00:00 2001 From: halo Date: Fri, 7 Aug 2026 16:04:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BC=81=E4=B8=9A=E5=BC=80?= =?UTF-8?q?=E6=88=B7=E4=BF=A1=E6=81=AF=E7=A1=AE=E8=AE=A4H5=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 3 +- .env.production | 1 + .../enterprise-open/EnterpriseOpenForm.vue | 185 ++++++++++++++---- 3 files changed, 147 insertions(+), 42 deletions(-) diff --git a/.env.development b/.env.development index 80d39f0..c63e8a0 100644 --- a/.env.development +++ b/.env.development @@ -1,3 +1,4 @@ VITE_API_BASE_URL=http://localhost:8888 -npmhttp://www.baidu.com +VITE_H5_QRCODE_BASE_URL=http://www.baidu.com VITE_H5_QRCODE_PATH=/mobile/personal-open +VITE_H5_QRCODE_PATH_ENTERPRISE=/mobile/enterprise-open diff --git a/.env.production b/.env.production index d0c2f85..0839c93 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,4 @@ VITE_API_BASE_URL= VITE_H5_QRCODE_BASE_URL= VITE_H5_QRCODE_PATH=/mobile/personal-open +VITE_H5_QRCODE_PATH_ENTERPRISE=/mobile/enterprise-open diff --git a/src/views/wallet/enterprise-open/EnterpriseOpenForm.vue b/src/views/wallet/enterprise-open/EnterpriseOpenForm.vue index 8c752c3..91353b6 100644 --- a/src/views/wallet/enterprise-open/EnterpriseOpenForm.vue +++ b/src/views/wallet/enterprise-open/EnterpriseOpenForm.vue @@ -380,6 +380,34 @@ + + + + + + @@ -389,6 +417,7 @@ import { ref, reactive, computed, onMounted, onUnmounted } from 'vue' import { useRoute, useRouter } from 'vue-router' import { message, Modal } from 'ant-design-vue' import { PlusOutlined } from '@ant-design/icons-vue' +import QrcodeVue from 'qrcode.vue' import ChannelSelect from '@/components/ChannelSelect.vue' import DictSelect from '@/components/DictSelect.vue' import LicenseUpload from '@/components/LicenseUpload.vue' @@ -427,6 +456,15 @@ const channelNo = ref(undefined) const agreementChecked = ref(false) const submitting = ref(false) +// "确认"按钮触发的二次确认弹窗(仅 create 模式使用):confirm=文案+三按钮态, +// qrcode=邀请扫码办理成功后的二维码展示态,仿 PersonalOpenForm.vue +const confirmModalVisible = ref(false) +const confirmModalStep = ref('confirm') +const modalSaving = ref(false) +const modalInviting = ref(false) +const qrCodeUrl = ref('') +const qrApplicationNo = ref('') + const businessLicenseFileNo = ref('') const legalPersonIdFrontFileNo = ref('') const legalPersonIdBackFileNo = ref('') @@ -554,6 +592,8 @@ let smsTimer = null const busy = computed( () => submitting.value || + modalSaving.value || + modalInviting.value || businessLicenseUploading.value || legalPersonIdFrontUploading.value || legalPersonIdBackUploading.value || @@ -565,7 +605,7 @@ const busyTip = computed(() => { if (legalPersonIdFrontUploading.value || legalPersonIdBackUploading.value) return '身份证照片上传中,请稍候...' if (beneficiaryProofUploading.value) return '受益人材料证明上传中,请稍候...' if (smsSending.value) return '验证码发送中,请稍候...' - if (submitting.value) return '提交中,请稍候...' + if (submitting.value || modalSaving.value || modalInviting.value) return '提交中,请稍候...' return '' }) @@ -1055,50 +1095,52 @@ function buildBeneficiaryBto(bene) { return bto } +// 提交给 create/update 的公共 payload,create(直接提交/邀请扫码办理)与 update(编辑保存) +// 内容一致,仅 update 调用方需额外拼接 id 字段 +function buildSubmitPayload() { + return { + organizationId: form.organizationId, + enterpriseId: form.enterpriseId, + enterpriseName: form.enterpriseName, + businessLicense: form.businessLicense, + certificateType: 'BUSINESS_LICENSE', + certificateNumber: form.certificateNumber, + certificateEffectiveDate: form.certificateEffectiveDate, + certificateExpiryDate: form.certificateExpiryDate, + certificateAddress: form.certificateAddress, + businessScope: form.businessScope, + industry: form.industry, + mobilePhone: smsForm.mobile, + bankCardNumber: form.bankCardNumber, + bankNo: form.bankNo, + bankName: form.bankName, + ...buildLegalRepPayload(), + ...buildControllerPayload(), + ...buildLeaderPayload(), + ...buildOperatorPayload(), + channelNo: channelNo.value, + businessLicenseFileNo: businessLicenseFileNo.value, + // create/update 接口当前无 verifyCode 字段,已登记《缺失的后端接口.md》 + verifyCode: smsForm.verifyCode, + enterpriseAccountOpenApplicationFileBtoList: [ + { fileNo: businessLicenseFileNo.value, fileType: '12' }, + { fileNo: legalPersonIdFrontFileNo.value, fileType: '01' }, + { fileNo: legalPersonIdBackFileNo.value, fileType: '02' }, + { fileNo: beneficiaryProofFileNo.value, fileType: '14' } + ], + enterpriseAccountOpenApplicationBeneficiaryBtoList: beneficiaryList.value.map(buildBeneficiaryBto) + } +} + +// 编辑模式"保存"按钮:校验通过后直接调用 update 接口,不经过二次确认弹窗(与 +// PersonalOpenForm.vue 的 handleEditSubmit 行为一致) async function handleSubmit() { submitting.value = true try { - const payload = { - organizationId: form.organizationId, - enterpriseId: form.enterpriseId, - enterpriseName: form.enterpriseName, - businessLicense: form.businessLicense, - certificateType: 'BUSINESS_LICENSE', - certificateNumber: form.certificateNumber, - certificateEffectiveDate: form.certificateEffectiveDate, - certificateExpiryDate: form.certificateExpiryDate, - certificateAddress: form.certificateAddress, - businessScope: form.businessScope, - industry: form.industry, - mobilePhone: smsForm.mobile, - bankCardNumber: form.bankCardNumber, - bankNo: form.bankNo, - bankName: form.bankName, - ...buildLegalRepPayload(), - ...buildControllerPayload(), - ...buildLeaderPayload(), - ...buildOperatorPayload(), - channelNo: channelNo.value, - businessLicenseFileNo: businessLicenseFileNo.value, - // create/update 接口当前无 verifyCode 字段,已登记《缺失的后端接口.md》 - verifyCode: smsForm.verifyCode, - enterpriseAccountOpenApplicationFileBtoList: [ - { fileNo: businessLicenseFileNo.value, fileType: '12' }, - { fileNo: legalPersonIdFrontFileNo.value, fileType: '01' }, - { fileNo: legalPersonIdBackFileNo.value, fileType: '02' }, - { fileNo: beneficiaryProofFileNo.value, fileType: '14' } - ], - enterpriseAccountOpenApplicationBeneficiaryBtoList: beneficiaryList.value.map(buildBeneficiaryBto) - } - let res - if (isCreate.value) { - res = await createEnterpriseOpenApplicationApi(payload) - } else { - // 已知缺口:后端 list/detail 均不返回 id,此处仍用 applicationNo 兜底传递,以实测报错为准 - res = await updateEnterpriseOpenApplicationApi({ id: route.query.applicationNo, ...payload }) - } + // 已知缺口:后端 list/detail 均不返回 id,此处仍用 applicationNo 兜底传递,以实测报错为准 + const res = await updateEnterpriseOpenApplicationApi({ id: route.query.applicationNo, ...buildSubmitPayload() }) if (res.data.code === 200) { - message.success(isCreate.value ? '开户申请已提交' : '修改成功') + message.success('修改成功') goBack() } } finally { @@ -1106,12 +1148,62 @@ async function handleSubmit() { } } +// "确认"按钮点击:create 模式校验通过后打开二次确认弹窗(不直接提交);edit 模式沿用现状直接保存 async function handleConfirmButtonClick() { const valid = await validateBeforeSubmit() if (!valid) return + if (isCreate.value) { + confirmModalStep.value = 'confirm' + confirmModalVisible.value = true + return + } await handleSubmit() } +// 弹窗内"保存":调用 create 接口提交草稿,成功后关闭弹窗并返回列表 +async function handleModalSave() { + modalSaving.value = true + try { + const res = await createEnterpriseOpenApplicationApi(buildSubmitPayload()) + if (res.data.code === 200) { + message.success('开户申请已提交') + confirmModalVisible.value = false + goBack() + } + } finally { + modalSaving.value = false + } +} + +// 拼接扫码 H5 地址:域名/路径来自环境变量,域名未配置(生产环境尚未确定)时用占位域名兜底, +// 保证二维码始终可以生成,不阻断柜员操作;域名确定后只需修改 .env.production,无需改代码。 +// 路径专用 VITE_H5_QRCODE_PATH_ENTERPRISE(与个人开户现有的 VITE_H5_QRCODE_PATH 区分,不复用)。 +function buildQrCodeUrl(applicationNo) { + const base = import.meta.env.VITE_H5_QRCODE_BASE_URL || 'https://example.com' + const path = import.meta.env.VITE_H5_QRCODE_PATH_ENTERPRISE || '/mobile/enterprise-open' + return `${base}${path}?applicationNo=${applicationNo}` +} + +// 弹窗内"邀请扫码办理":与"保存"调用同一个提交接口,成功后不关闭弹窗,切换为二维码展示态 +async function handleModalInvite() { + modalInviting.value = true + try { + const res = await createEnterpriseOpenApplicationApi(buildSubmitPayload()) + if (res.data.code === 200) { + qrApplicationNo.value = res.data.data.applicationNo + qrCodeUrl.value = buildQrCodeUrl(res.data.data.applicationNo) + confirmModalStep.value = 'qrcode' + } + } finally { + modalInviting.value = false + } +} + +// 弹窗内"取消"/关闭图标/邀请扫码办理成功后的"关闭"按钮:统一只关闭弹窗,不发请求、不跳转 +function handleModalCancel() { + confirmModalVisible.value = false +} + function goBack() { router.push('/wallet/enterprise-open') } @@ -1163,4 +1255,15 @@ function goBack() { height: auto; max-height: none; } +.confirm-modal-actions { + margin-top: 24px; + text-align: right; +} +.qrcode-panel { + text-align: center; +} +.qrcode-application-no { + margin: 12px 0 8px; + color: #333; +}