docs: 个人开户确认二次确认弹窗+邀请扫码办理设计文档

main
halo 2026-07-23 16:56:58 +08:00
parent 92c5f272b4
commit dfbf16e81c
1 changed files with 74 additions and 0 deletions

View File

@ -0,0 +1,74 @@
# 个人开户"确认"二次确认弹窗 + 邀请扫码办理 设计文档
## 背景
`src/views/wallet/personal-open/PersonalOpenForm.vue`(新增个人开户申请页)当前点击顶部"确认"按钮后,直接执行前置校验并调用 `create-draft` 接口提交,没有任何二次确认环节。产品要求新增二次确认弹窗,并在弹窗中提供"邀请扫码办理"选项,允许柜员生成二维码交由客户扫码办理(扫码后走向的移动端 H5 页面本身不在本项目前端实现范围内,仅需生成二维码内容并展示)。
本次改动只影响 `PersonalOpenForm.vue` 的**新增create模式**"确认"按钮流程编辑edit模式的"保存"按钮不受影响。
## 交互流程
1. 用户在新增个人开户表单页填写完信息,点击顶部"确认"按钮。
2. 前端执行现有的全部前置校验(原 `handleSubmit` 中 441-470 行逻辑):
- 是否已勾选协议
- 是否已选择渠道归属
- 是否已选择客户
- 证件照片是否仍在上传中
- 创建模式下是否已上传身份证正反面 + 正面免冠照
- 身份证 OCR 信息是否与所选客户一致
- 表单 `formRef.value.validate()` 是否通过
- 任意一项不通过:按现有方式提示错误(`showErrorModal`**不弹出二次确认弹窗**。
3. 全部通过后,弹出"提示"二次确认弹窗(对应产品提供的截图),弹窗内容:"是否确认开户?",三个按钮:`保存`(主按钮)/ `取消` / `邀请扫码办理`
4. 弹窗内点击**保存**
- 调用 `create-draft` 接口(逻辑与现有提交一致:构造 `payload` + `fileList`)。
- 成功(`code === 200`):记录 `submittedApplicationNo``message.success('申请已提交')`,关闭弹窗。表单页因 `submittedApplicationNo` 有值而自动切换到现有的"开户申请已提交"结果面板(既有 template 条件不变)。
- 失败:由全局响应拦截器统一弹出错误提示(`showErrorModal`,见 `src/api/request.js` 响应拦截器),弹窗保持打开,允许用户重试或取消。
5. 弹窗内点击**取消**:仅关闭弹窗,不发任何请求,不做页面跳转,表单数据保留,用户可以继续修改后重新点击"确认"。
6. 弹窗内点击**邀请扫码办理**
- 调用与"保存"完全相同的提交逻辑(同一个 `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"`(避免误触遮罩关闭)
- 内部用一个 `confirmModalStep` ref`'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 防重复点击)。