162 lines
19 KiB
Markdown
162 lines
19 KiB
Markdown
# 企业开户申请表单改版 + 客户选择机构隔离补充 设计文档
|
||
|
||
## 背景
|
||
|
||
产品提供了"钱包管理 > 企业开户"新版原型截图,与当前 `src/views/wallet/enterprise-open/EnterpriseOpenForm.vue` 的既有实现(阶段4设计,`2026-07-09-phase4-wallet-management-design.md`)相比,新增/调整了大量字段与交互:证件类型单选、查询受益人、营业执照发放/到期日展示、居住地省市、经营地址、开户银行三种录入方式、行业类别下拉、法定代表人/负责人/经办人同一人开关、受益人信息改为多受益人 + 认定类型多选、受益人材料证明影像、短信认证区块、顶部协议勾选门禁提交按钮。
|
||
|
||
同时补充一项需求:新增个人开户申请、新增企业开户申请时选择客户,必须按机构(`organizationId`)隔离,柜员只能选到自己权限范围内的客户。
|
||
|
||
本次改动范围:
|
||
1. 重写 `EnterpriseOpenForm.vue`(新增/编辑/查看三态同步采用新结构),不改 `EnterpriseOpenList.vue`、路由、菜单层级。
|
||
2. 新建 3 个组件:`BankSelector.vue`、`BeneficiaryProofUpload.vue`、`EnterpriseBeneficiaryCard.vue`。
|
||
3. 修改 `WalletCustomerPicker.vue`,enterprise 模式补充机构筛选。
|
||
4. 更新《缺失的后端接口.md》,登记本次产生的新缺口。
|
||
|
||
`PersonalOpenForm.vue`(个人开户申请)的客户选择本身已复用带机构筛选的 `PersonalCustomerPicker.vue`,符合机构隔离要求,本次**不改动**。
|
||
|
||
## 一、基础信息区
|
||
|
||
| 截图字段 | 后端字段(`CreateEnterpriseAccountOpenBto`) | 数据来源 / 锁定规则 |
|
||
|---|---|---|
|
||
| 渠道归属 | `channelNo` | 复用 `ChannelSelect.vue`;label 由"所属渠道"改为"渠道归属",placeholder 改为"请选择核心企业" |
|
||
| 客户 | `enterpriseId`/`enterpriseName` | `WalletCustomerPicker`(enterprise模式) 选择 → `fetchEnterpriseCustomerDetailApi` 详情回填 → **锁定**(按钮+文本展示) |
|
||
| 证件类型(营业执照 / 个体工商户) | 提交固定传 `certificateType: 'BUSINESS_LICENSE'` | 企业详情接口无来源字段,**不锁定**,柜员手动单选,默认"营业执照";选择"个体工商户"不改变其余字段展示/校验规则(枚举无对应值,登记缺口) |
|
||
| 营业执照/统一社会信用代码 | `businessLicense` / `certificateNumber` | 选客户后回填,**锁定** |
|
||
| 查询受益人(按钮) | 无对应接口 | 保留按钮,点击调用占位函数,`message.info('该功能待后端接口就绪后开放')`,不发起真实请求,登记缺口 |
|
||
| 营业执照发放日 | `certificateEffectiveDate` | 选客户后回填,**锁定**(现状已存值未展示,本次补UI) |
|
||
| 营业执照到期日 + 长期 | `certificateExpiryDate` | 选客户后回填,**锁定**;若值等于长期哨兵 `CERTIFICATE_LONG_TERM_DATE`(`9999-12-31 00:00:00`)则"长期"勾选态展示(禁用态,非用户可切换) |
|
||
| 居住地省市 | 无对应字段,不提交 | 企业详情无结构化省市编码,**不锁定**,柜员手动选择(`RegionCascader`),登记缺口"暂无法自动回填" |
|
||
| 经营地址 | `certificateAddress` | 选客户后回填,**锁定** |
|
||
| 企业银行账号 | `bankCardNumber` | 本次开户新填,**不锁定**,人工输入 |
|
||
| 开户银行/网点 | `bankNo` / `bankName` | 新建 `BankSelector.vue`(快速/详细/手动三模式,均产出这两个字段),**不锁定**;联行号字典缺失,登记缺口 |
|
||
| 经营范围 | `businessScope` | 选客户后回填,**锁定**(现状可编辑,本次改为锁定,对齐"回填不可修改"要求) |
|
||
| 行业类别 | `industry` | 企业详情无该字段(已登记缺口);UI 改为可搜索组合框(`a-select` 允许自由输入、无预置选项),**不锁定** |
|
||
|
||
删除现状"手机号码"字段(新截图基础信息区不再展示;企业客户联系手机号改为在"短信认证"区默认预填,见第六节)。
|
||
|
||
### `BankSelector.vue`(新建)
|
||
|
||
- Props:`bankNo`(v-model)、`bankName`(v-model)。
|
||
- 内部三个 `a-tabs`/`a-radio-group` 切换的 Tab("快速"/"详细"/"手动"),均只产出 `bankNo`/`bankName` 两个字段,不新增后端字段:
|
||
- **快速**:前端硬编码常见银行名称下拉(如工商银行/农业银行/中国银行/建设银行/交通银行/招商银行/浙商银行/浙江稠州商业银行等),选中后写入 `bankName`,`bankNo` 留空。
|
||
- **详细**:`RegionCascader`(省市)+ 支行名称文本输入,拼接写入 `bankName`(如"浙江省/杭州市 + 用户输入的支行名称"),`bankNo` 留空。无联行号字典接口,登记缺口。
|
||
- **手动**:`bankNo` + `bankName` 两个文本框直接输入(现状写法)。
|
||
- 三个 Tab 切换不清空已填值,只是录入方式不同,最终提交的仍是同一份 `bankNo`/`bankName`。
|
||
|
||
## 二、法定代表人信息
|
||
|
||
- "姓名" → `PersonalCustomerPicker` 选择个人客户 → `fetchPersonalCustomerDetailApi` 详情回填 → **锁定**。
|
||
- "身份证号"(`legalPersonIdNo`)、"身份证到期日 + 长期"(`legalPersonOpto`,长期哨兵值规则同上)均回填后**锁定**。
|
||
- 姓名字段下方常驻红字提示"*请先在个人客户管理中维护"(静态文案,不随选中状态隐藏)。
|
||
|
||
## 三、影像信息
|
||
|
||
新增第 4 张"受益人材料证明"上传(`BeneficiaryProofUpload.vue`,新建,克隆 `LicenseUpload.vue` 结构:`props: channelNo/readonly`,`emit: update:fileNo/update:uploading`,上传逻辑同 `uploadCustomerFileApi`,`fileType` 编码待后端确认,先用占位值 `'14'` 并登记缺口)。四张图统一映射进 `enterpriseAccountOpenApplicationFileBtoList`(`fileType`:12营业执照/01法人身份证正面/02法人身份证反面/14受益人材料证明-占位)。
|
||
|
||
## 四、法定代表人 / 负责人 / 经办人 同一人开关
|
||
|
||
- 开关默认**开启**(对齐截图展示态),仅显示"法定代表人"一个卡片。提交时 `controllerName/controllerIdType/controllerIdNo/controllerOpto`、`leaderName/leaderIdType/leaderIdNo/leaderMobile/leaderOpto`、`operatorName/operatorIdType/operatorIdNo/operatorMobile/operatorOpto` 均取法定代表人对应值(沿用现状"控制人默认同法人代表"逻辑,扩展到负责人/经办人;`leaderMobile`/`operatorMobile` 开启态取空,见下方补充说明)。
|
||
- 关闭后,额外展示"实际控制人信息"、"负责人信息"、"经办人信息" 3 个卡片,均复用"选择个人客户 → 详情回填 → 锁定"模式(与法定代表人一致的 UI),各自独立 `PersonalCustomerPicker` 实例。
|
||
- `leaderXxx`/`operatorXxx` 字段为本次新增采集,`CreateEnterpriseAccountOpenBto` 已具备对应字段(非后端缺口)。
|
||
|
||
**补充记录(2026-07-28 第二轮,按用户提供的"关闭同一人开关"截图修正)**:关闭态三张卡片布局改为:卡片头部左侧角色名称(蓝色加粗)+ 右侧按钮"点击选择法定代表人信息"(复用 `PersonalCustomerPicker`,按钮文案严格按截图,不再是"选择/重新选择");卡片内字段顺序改为"证件类型(纯文本展示)→ 证件号码(锁定)→ 姓名(锁定)→ [手机号] → 证件失效日期+长期”。"负责人"/"经办人"两张卡片新增"手机号"输入框(截图明确新增,`leaderMobile`/`operatorMobile` 有了真实 UI 来源,柜员手工输入,不随选择客户回填锁定,不属于锁定字段范围);"实际控制人"卡片没有手机号字段。
|
||
|
||
## 五、受益人信息(重点改造)
|
||
|
||
- 由单条 `beneficiary` 对象改为 `beneficiaryList` 数组,支持"添加受益人"。
|
||
- **受益人1(法定代表人,自动填充,不可删除)**:选中法定代表人后自动生成,姓名/性别/国籍/证件类型/证件号码/证件有效期/地址/联系电话/出生日期全部**锁定**(与法定代表人强制一致),仅"受益人认定类型"5 个 checkbox 可勾选。
|
||
- **受益人2/3...(新增)**:点击"添加受益人" → `PersonalCustomerPicker` 选择个人客户 → 详情回填 → 同样锁定基础字段,仅认定类型可勾选。
|
||
- 字段映射:
|
||
- 姓名 → `beneName`,性别 → `beneSex`(`'0'`男/`'1'`女,来自 `GenderEnum` 映射),国籍 → `beneNationality`(固定"中国"),证件类型 → `beneIdType`(隐式取选中客户 `certificateType`,不独立展示),证件号码 → `beneIdNo`,证件有效期 → `beneOpto`,地址 → `beneAddress`,联系电话 → `beneMobile`(**新增采集**,取个人客户详情 `mobilePhone`),出生日期 → `beneBirthday`(**新增采集**,取个人客户详情 `birthDate`)。
|
||
- 认定类型 5 个 checkbox → 股权/合伙权益≥25% → `actCtrl`;收益权/表决权≥25% → `priBenfit`;实际控制 → 勾选后展开二级面板,`actCtrlCpny` 取二级面板"控制类型"选择的真实值(不再是占位值,见下方补充说明);日常经营管理高管 → `seniorMgr`;在华最高层级高管 → `seniorMgrCn`。
|
||
- ~~删除现状"是否股东(是/否单选)"+"持股比例"两个输入~~:**补充记录(2026-07-28 第二轮)已修正**——"持股比例"未被删除,而是移入"股权/合伙权益≥25%"勾选后展开的"股权信息"二级面板内(见下)。
|
||
- 说明框(6 条互斥规则)用 `<a-alert type="warning" show-icon>` 展示原型原文:
|
||
1. 5 种类型至少选 1 种。
|
||
2. 选"股权/合伙权益≥25%"则禁用其余 4 种(单选式互斥)。
|
||
3. 选"日常经营管理高管"则禁用其余 4 种。
|
||
4. 选"在华最高层级高管"则禁用其余 4 种。
|
||
5. **补充记录(2026-07-28 第二轮)已修正**:原文档误判第5条"不实现",实际按截图2-6已完整实现——选"收益权/表决权≥25%"时展开二级面板,"收益权比例"与"表决权比例"两个数值输入本身选填,但各自对应的开始/结束日期均必填。
|
||
6. "收益权/表决权≥25%"和"实际控制"两者之间不互斥,可同时勾选也可只勾选一个,但两者都与2/3/4类互斥。
|
||
- 提交时整体覆盖 `enterpriseAccountOpenApplicationBeneficiaryBtoList`(沿用现状"全量替换"策略,`update` 语义未定的缺口已登记,不重复登记)。
|
||
|
||
### 五-1、受益人认定类型二级信息面板(2026-07-28 第二轮补充,取代原"仅5个checkbox不展开"决策)
|
||
|
||
产品补充提供了截图2-6,要求每个认定类型勾选后展开对应的二级信息面板(`EnterpriseBeneficiaryCard.vue` 内实现),字段与后端 `EnterpriseAccountOpenApplicationBeneficiaryBto` 映射如下:
|
||
|
||
| 认定类型 | 面板标题 | 字段(*必填) | 映射后端字段 |
|
||
|---|---|---|---|
|
||
| 股权/合伙权益≥25% | 股权信息 | *持股比例(%)、*形成日期、*终止日期 | `actHdRat`/`shareRatioStartDate`/`shareRatioEndDate` |
|
||
| 收益权/表决权≥25% | 收益权/表决权信息 | 收益权比例(%)(选填)、*收益权开始日期、*收益权结束日期、表决权比例(%)(选填)、*表决权开始日期、*表决权结束日期 | `actOwnerProfitRatio`/`profitRatioStartDate`/`profitRatioEndDate`/`actOwnerProfitRatioVote`/`profitRatioVoteStartDate`/`profitRatioVoteEndDate` |
|
||
| 实际控制 | 实际控制信息 | *控制类型(select)、*控制开始日期、*控制结束日期、*控制内容(自由输入组合框)、其他形式内容(选填)、上层实体是否存在(switch)、[上层实体是否存在=开启时]*上层实体名称、*统一社会信用代码 | `actCtrlCpny`/`obtainActDate`/`terminationActDate`/`actCtrlType`/`actOtherForms`/`actConUpperMarket`/`actConUpperEntName`/`actConUniScid` |
|
||
| 日常经营管理高管 | 日常经营管理高管信息 | *职位(select:法定代表人/董事长/经理/董事/执行合伙事务的自然人/其他人员,截图直接给出,非编造)、其他职位(选填) | `seniorMgrPos`/`actDailyMgmtPostOther` |
|
||
| 在华最高层级高管 | 在华最高层级高管信息 | *在华职位(select:分支机构负责人/其他高级管理人员,截图直接给出)、其他职位(选填)、*开始日期、*结束日期 | `seniorMgrPosCn`/`ownerRightMgmtPostOther`/`benStartDate`/`benEndDate` |
|
||
|
||
已知缺口(登记入《缺失的后端接口.md》第103-105条):
|
||
1. "控制类型"截图默认选中值显示为数字"1",与 swagger `actCtrlCpny` 字段说明"2协议约定 3其他形式"不一致,前端以 swagger 为准提供 2/3 两个选项,未采用截图的"1"。
|
||
2. "控制内容"(`actCtrlType`)后端未提供任何枚举,改用 `a-auto-complete` 自由输入组合框(无预置选项),不编造枚举。
|
||
3. "在华最高层级高管信息"的"开始日期/结束日期"字段,swagger 未见专属字段命名,暂映射到通用的 `benStartDate`/`benEndDate`(受益所有权形成/终止日期-通用),需后端确认是否有专属字段。
|
||
|
||
## 六、短信认证
|
||
|
||
- 手机号:若已选中法定代表人或受益人1有 `mobilePhone`,默认预填(可编辑,不属于"基础信息/法定代表人信息回填锁定"范围);否则为空,人工输入。
|
||
- 验证码 + 发送按钮:复用绑卡/提现弹窗的"倒计时按钮"交互模式(非 `SmsCodeInput.vue`,该组件项目内实际未被任何页面使用,改用与 `BindCardModal.vue`/`WithdrawModal.vue` 一致的现役模式),`businessType` 约定传 `'WALLET_ENTERPRISE_OPEN'`。
|
||
- `verifyCode` 一并放入提交 payload;`create`/`update` 接口当前无该字段,登记缺口。
|
||
|
||
## 七、页面顶部布局
|
||
|
||
- 参照 `PersonalOpenForm.vue` 的 `<a-page-header>` `#extra` slot 写法:协议勾选("本人已阅读并同意" + 两个协议链接)+ "确认"(`:disabled="!agreementChecked"`)+ "取消" 同行展示,替换现状"提交/取消"按钮置底布局。仅新增(create)态展示协议勾选;编辑(edit)态展示"保存/取消"(无需协议勾选,比照 `PersonalOpenForm.vue` 编辑态);查看(detail)态不展示操作按钮。
|
||
- 协议弹窗复用 `PersonalOpenForm.vue` 的 `Modal.info` 占位文案模式(同一套"浙江稠州商业银行用户支付服务协议/隐私政策"占位内容)。
|
||
- `pageTitle` 文案:`{ create: '新增企业开户', edit: '编辑企业开户', detail: '查看企业开户' }`(去掉"申请"二字,对齐截图"企业开户"措辞)。
|
||
|
||
## 八、编辑 / 查看模式
|
||
|
||
- 三态共用本次新结构;`isDetail` 时全部输入态字段整体禁用;受益人卡片查看态隐藏"添加/删除"操作;同一人开关查看态禁用切换(保留当前值展示)。
|
||
- 沿用现状 `applicationNo` 兜底传 `id` 的已知缺口处理方式,不在本次修复范围内。
|
||
|
||
## 九、客户选择机构隔离补充
|
||
|
||
- **个人开户申请**(`PersonalOpenForm.vue`):客户选择已复用 `PersonalCustomerPicker.vue`(自带 `organizationIdEq` 默认值 = `getCurrentOrganizationId()` + `OrgTreeSelect` 可选切换),符合要求,**不改动**。
|
||
- **企业开户申请**:
|
||
- "法定代表人/实际控制人/负责人/经办人/受益人"选择均用 `PersonalCustomerPicker.vue`,已符合要求,不改动。
|
||
- "客户"(企业客户)选择用 `WalletCustomerPicker.vue` 的 `enterprise` 模式 → `fetchEnterpriseCustomerPageApi`,当前查询表单**没有**机构筛选。本次修改 `WalletCustomerPicker.vue`:
|
||
- enterprise 模式 `initial-search` 增加 `organizationId: getCurrentOrganizationId()`。
|
||
- enterprise 模式 `#search` slot 增加 `<a-form-item label="所属机构"><OrgTreeSelect v-model="form.organizationId" style="width: 180px" /></a-form-item>`。
|
||
- 清理死代码字段 `mobilePhone: ''`(enterprise 模式 `initial-search` 中未使用的遗留字段)。
|
||
- **已知限制**(沿用《缺失的后端接口.md》已登记条目,不新增重复条目):`POST /api/enterprise-customer/page` 后端当前不支持 `organizationId` 请求参数(第58条),UI 补齐后实际过滤效果依赖该条后端改造;机构下拉框本身目前仍是全量机构树(第52/53条未完成),不是严格意义上"选不出权限外机构",属于项目级已知限制。
|
||
|
||
## 十、新增/需要更新的《缺失的后端接口.md》条目
|
||
|
||
1. 证件类型枚举(`CertificateTypeEnum`)缺少"个体工商户"对应值,企业开户申请证件类型单选"个体工商户"时暂沿用 `BUSINESS_LICENSE` 提交。
|
||
2. `EnterpriseCustomerDetailVo` 无结构化省市字段,企业开户申请"居住地省市"无法自动回填,改为人工填写。
|
||
3. 企业开户申请"查询受益人"按钮无对应后端接口,当前为 UI 占位。
|
||
4. 无联行号字典查询接口,"开户银行/网点"三种录入方式(快速/详细/手动)均为简化实现,均不产出真实联行号。
|
||
5. 受益人认定类型"实际控制"勾选与 `actCtrlCpny` 枚举字段(协议约定/其他形式)的映射方式待后端确认,当前勾选时固定回填占位值 `'3'`。
|
||
6. "受益人材料证明"影像资料的 `fileType` 编码待后端确认,当前使用占位值 `'14'`。
|
||
7. `enterprise-open-application/create`、`update` 的请求体(`CreateEnterpriseAccountOpenBto`/`UpdateEnterpriseAccountOpenApplicationBto`)无 `verifyCode` 字段,企业开户申请短信认证环节验证码当前仅前端展示效果,实际不会被后端校验。
|
||
8. 受益人 `beneMobile`(联系电话)、`beneBirthday`(出生日期)本次改版新增采集并提交,此前裁剪清单(阶段4设计文档"仅采集8字段")需更新为 10 字段。
|
||
9. 受益人持股比例 `actHdRat` 本次改版起不再采集(原"是否股东/持股比例"UI 已被"受益人认定类型" 5 项 checkbox 取代)。
|
||
|
||
第23/24(已被第2条延续说明)/25 条既有缺口继续保留,不重复登记。
|
||
|
||
## 十一、组件变更清单
|
||
|
||
| 文件 | 变更类型 |
|
||
|---|---|
|
||
| `src/views/wallet/enterprise-open/EnterpriseOpenForm.vue` | 重写 |
|
||
| `src/components/BankSelector.vue` | 新建 |
|
||
| `src/components/BeneficiaryProofUpload.vue` | 新建 |
|
||
| `src/components/EnterpriseBeneficiaryCard.vue` | 新建 |
|
||
| `src/components/WalletCustomerPicker.vue` | 修改(enterprise 模式补机构筛选) |
|
||
| `缺失的后端接口.md` | 修改(新增本节第十条列出的条目) |
|
||
|
||
复用不改动:`ChannelSelect.vue`、`PersonalCustomerPicker.vue`、`RegionCascader.vue`、`IdCardUpload.vue`、`LicenseUpload.vue`、`SmsCodeInput.vue`、`OrgTreeSelect.vue`、`src/utils/orgScope.js`。
|
||
|
||
## 范围边界
|
||
|
||
- 不改动 `EnterpriseOpenList.vue`、路由映射、菜单层级(现状"钱包管理→企业开户申请"两级菜单维持不变)。
|
||
- 不修复 `enterprise-open-application` 的 `id` 缺失已知缺口(第23条),沿用现状 `applicationNo` 兜底方案。
|
||
- 不实现"查询受益人"真实查询逻辑、不实现联行号字典查询,均为 UI 占位 + 缺口登记。
|
||
- 不改动 `PersonalOpenForm.vue`、`PersonalCustomerPicker.vue`(已符合机构隔离要求)。
|
||
- 不推进机构树/机构列表接口按登录用户身份裁剪(第52/53条),维持全量机构树现状。
|
||
</content>
|