SFT/docs/superpowers/specs/2026-07-28-enterprise-open-...

162 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 企业开户申请表单改版 + 客户选择机构隔离补充 设计文档
## 背景
产品提供了"钱包管理 > 企业开户"新版原型截图,与当前 `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>