5.9 KiB
5.9 KiB
个人开户"确认"二次确认弹窗 + 邀请扫码办理 设计文档
背景
src/views/wallet/personal-open/PersonalOpenForm.vue(新增个人开户申请页)当前点击顶部"确认"按钮后,直接执行前置校验并调用 create-draft 接口提交,没有任何二次确认环节。产品要求新增二次确认弹窗,并在弹窗中提供"邀请扫码办理"选项,允许柜员生成二维码交由客户扫码办理(扫码后走向的移动端 H5 页面本身不在本项目前端实现范围内,仅需生成二维码内容并展示)。
本次改动只影响 PersonalOpenForm.vue 的新增(create)模式"确认"按钮流程;编辑(edit)模式的"保存"按钮不受影响。
交互流程
- 用户在新增个人开户表单页填写完信息,点击顶部"确认"按钮。
- 前端执行现有的全部前置校验(原
handleSubmit中 441-470 行逻辑):- 是否已勾选协议
- 是否已选择渠道归属
- 是否已选择客户
- 证件照片是否仍在上传中
- 创建模式下是否已上传身份证正反面 + 正面免冠照
- 身份证 OCR 信息是否与所选客户一致
- 表单
formRef.value.validate()是否通过 - 任意一项不通过:按现有方式提示错误(
showErrorModal),不弹出二次确认弹窗。
- 全部通过后,弹出"提示"二次确认弹窗(对应产品提供的截图),弹窗内容:"是否确认开户?",三个按钮:
保存(主按钮)/取消/邀请扫码办理。 - 弹窗内点击保存:
- 调用
create-draft接口(逻辑与现有提交一致:构造payload+fileList)。 - 成功(
code === 200):记录submittedApplicationNo,message.success('申请已提交'),关闭弹窗。表单页因submittedApplicationNo有值而自动切换到现有的"开户申请已提交"结果面板(既有 template 条件不变)。 - 失败:由全局响应拦截器统一弹出错误提示(
showErrorModal,见src/api/request.js响应拦截器),弹窗保持打开,允许用户重试或取消。
- 调用
- 弹窗内点击取消:仅关闭弹窗,不发任何请求,不做页面跳转,表单数据保留,用户可以继续修改后重新点击"确认"。
- 弹窗内点击邀请扫码办理:
- 调用与"保存"完全相同的提交逻辑(同一个
create-draft接口),拿到applicationNo并同样记录到submittedApplicationNo(因此背后的表单页状态与点"保存"效果一致,会进入"已提交"结果面板)。 - 成功后不关闭弹窗,而是把弹窗内容切换为"二维码展示"态:显示二维码图片 + "申请编号:{applicationNo}" 文字 + "关闭"按钮;不额外弹出"申请已提交"的 message 提示(避免和二维码展示态叠加打扰)。
- 二维码内容为一个完整 URL:
${VITE_H5_QRCODE_BASE_URL}${VITE_H5_QRCODE_PATH}?applicationNo=${applicationNo}。域名/路径通过环境变量配置(见下),当前域名尚未确定,未配置时使用占位域名照常生成二维码(不阻断流程)。 - 用户点击"关闭"或弹窗右上角 X:仅关闭弹窗,此时表单页已处于"已提交"结果面板状态(与点保存效果一致)。
- 失败:同上由全局拦截器提示,弹窗保持在"确认"态,允许重试。
- 调用与"保存"完全相同的提交逻辑(同一个
UI 结构
复用 ant-design-vue 的 a-modal:
title="提示":footer="null"(按钮放在正文里自定义,与截图一致):mask-closable="false"(避免误触遮罩关闭)- 内部用一个
confirmModalStepref('confirm' | 'qrcode')控制展示"确认文案+三按钮"还是"二维码+关闭按钮"两种视图。
二维码组件使用新增依赖 qrcode.vue(Vue3 兼容,peerDependencies: vue ^3.0.0),以 <qrcode-vue :value="qrCodeUrl" :size="200" /> 方式渲染。
代码结构调整(PersonalOpenForm.vue)
将原 handleSubmit 拆分为职责更清晰的几个函数,避免重复代码:
validateBeforeSubmit():抽取原 441-470 行的全部前置校验(含formRef.value.validate()),返回boolean(或 reject)。供"确认"按钮预检和isEdit保存流程共用。buildSubmitPayload():抽取原 473-495 行fileList/payload构造逻辑,供 create 提交与 edit 保存共用。submitCreateDraft():仅负责调用createPersonalOpenDraftApi,成功后设置submittedApplicationNo并返回applicationNo;失败返回null(错误提示交给全局拦截器)。供弹窗内"保存"与"邀请扫码办理"共用,各自维护自己的 loading ref(modalSaving/modalInviting),防止重复点击。handleConfirmButtonClick():新增个人开户"确认"按钮的点击处理——调用validateBeforeSubmit(),通过后打开确认弹窗(confirmModalVisible = true,confirmModalStep = 'confirm')。handleEditSubmit():原handleSubmit中isEdit分支逻辑原样保留(校验 + 调用updatePersonalOpenApplicationApi),仅改名,行为不变,绑定到编辑模式"保存"按钮。
环境变量
新增于 .env.development 与 .env.production:
VITE_H5_QRCODE_BASE_URL=
VITE_H5_QRCODE_PATH=/mobile/personal-open
VITE_H5_QRCODE_BASE_URL 留空时使用代码内占位域名(如 https://example.com)兜底拼接,保证二维码始终可以生成;域名确定后运维/开发只需在 .env.production 中填入真实域名即可,无需改代码。
依赖变更
新增 qrcode.vue(dependencies)。
范围边界
- 不实现移动端 H5 扫码后的确认页面(
personal-opening/mobile/*),本次改动只负责柜员端生成二维码内容并展示。 - 不改动
isEdit(编辑)模式的提交流程与按钮。 - 不改动
isDetail(查看)模式。 - 不引入全局的
busy/a-spin统一遮罩规范补齐(该页面现状缺口不在本次需求范围内,维持现状,仅用按钮级 loading 防重复点击)。