diff --git a/docs/superpowers/specs/2026-07-20-personal-customer-idcard-ocr-loading-design.md b/docs/superpowers/specs/2026-07-20-personal-customer-idcard-ocr-loading-design.md
index eb3b27b..b3f66c4 100644
--- a/docs/superpowers/specs/2026-07-20-personal-customer-idcard-ocr-loading-design.md
+++ b/docs/superpowers/specs/2026-07-20-personal-customer-idcard-ocr-loading-design.md
@@ -38,3 +38,28 @@
- 不新建可复用的全局 loading 组件(超出本次需求范围,且项目暂无其他场景需要)。
- 不改动企业客户表单等其他复用同一上传组件的页面。
- 不改变现有 OCR/上传接口调用方式(仍是 base64 并发调用 `ocrIdCardApi` + `uploadCustomerFileApi`)。
+
+## 追加需求:身份证缩略图 hover 操作按钮
+
+### 背景
+
+身份证图片上传成功后,缩略图目前只是一张静态 `
`,没有任何交互提示。需要参照截图样式,鼠标 hover 缩略图时叠加半透明遮罩,展示"预览(眼睛)/ 重新上传(铅笔)/ 删除(垃圾桩)"三个操作图标。
+
+### 范围确认(与用户确认过的细节)
+
+- 查看详情模式(`isDetail`)下缩略图只保留"预览"图标,隐藏"重新上传"/"删除"。新增、编辑模式三个图标都显示。
+- 点击删除图标直接清空图片和 `fileNo`,不弹二次确认;只影响当前这一侧(正面或反面),已回填的 OCR 表单字段不受影响。
+- 点击预览图标弹出一个简单 Modal 展示原图(不使用 antd Image 的缩放/旋转工具条)。
+- 点击重新上传(铅笔)图标直接复用现有上传入口重新选图并重新识别,覆盖旧缩略图和旧 `fileNo`,不做二次确认提示。
+
+### 方案
+
+- `IdCardUpload.vue`:
+ - 新增 `readonly` prop,由父组件传入 `isDetail` 控制。
+ - 有预览图时,`
` 外包一层 `.thumb-wrapper`,内部叠加 `.hover-mask`(默认 `opacity:0`,`:hover` 时 `opacity:1`),放置 `EyeOutlined`/`EditOutlined`/`DeleteOutlined` 三个图标(`readonly` 时只渲染 `EyeOutlined`)。
+ - 预览:点击眼睛图标(`@click.stop` 阻止冒泡触发文件选择)打开 `` 展示 `previewUrl` 原图。
+ - 删除:点击垃圾桩图标(`@click.stop`)清空 `previewUrl` 并 `emit('update:fileNo', '')`,不改动表单其他字段。
+ - 重新上传:铅笔图标不调用 `stopPropagation`,复用 `a-upload` 自身"点击区域内任意位置即打开文件选择"的默认行为,点击后走既有的 `handleBeforeUpload` 全流程(OCR + 上传并发调用),自然覆盖旧数据。
+- `PersonalForm.vue`:两个 `IdCardUpload` 实例都新增 `:readonly="isDetail"`。
+
+
diff --git a/缺失的后端接口.md b/缺失的后端接口.md
index 19bc706..18aeff5 100644
--- a/缺失的后端接口.md
+++ b/缺失的后端接口.md
@@ -56,7 +56,7 @@
| `POST /api/role/update` | `{id, roleName, organizationId}` | 不含权限 |
| `POST /api/role/delete` | `{roleId}` | 单条 |
| `GET /api/auth/role-permission/list-by-role?roleId=` | — | 响应 `RolePermissionVo[]` |
-| `POST /api/auth/role-permission/bind` / `unbind` | `{roleId, permissionIdList}` | 前端采用"查旧集合→diff→分别 bind/unbind"策略 |
+| `POST /api/auth/role-permission/bind` | `{roleId, permissionIdList}` | 后端未提供 `unbind` 接口;前端不计算 diff,直接把页面上勾选的**全量**权限id列表一次性提交给 `bind`,由后端做全量覆盖 |
角色模型**不含**数据权限范围(dataScope)字段。
@@ -84,7 +84,7 @@
同时存在于同一条机构记录上。`/api/organization/tree`(POST,无筛选参数的全量树)与 `query-tree` 功能重叠,
前端统一只使用 `query-tree`。
-### 1.6 基础配置 —— 核心企业 / 客户经理
+### 1.6 基础配置 —— 核心企业(渠道) / 客户经理
| 接口 | Body | 说明 |
| --- | --- | --- |
@@ -96,16 +96,30 @@
核心企业、客户经理模型均**不含** `organizationName`,前端本地通过 `organization/list-all` 建 id→name 映射
展示所属机构列。
+> **重要说明(2026-07-17 补充)**:全局多处组件(`ChannelSelect.vue` 及其 8 个调用点:发票登记/匹配/
+> 作废、绑卡、提现、身份证与营业执照上传、企业/个人开户等)的"所属渠道"下拉,复用的正是本接口
+> `enterpriseName`/`enterpriseCode` 字段作为"渠道名称/渠道编号"。即产品侧"核心企业管理"页面本质上
+> 就是全系统"渠道"的维护入口,`enterpriseName = 渠道名称`、`enterpriseCode = 渠道编号`,并非另一套
+> 独立概念,原型图的字段命名(渠道/渠道编号)与现有接口字段语义完全一致,**无需**新增或改名这两个
+> 字段。本次前端改造仅为"核心企业管理"页面新增/移除以下字段展示,详见 Part 2 第 67 条。
+>
+> **⚠️ 更正(2026-07-20)**:上述"复用 enterpriseName/enterpriseCode,无需改名"的结论已过期!
+> 后端同事提供了最新 `CreateCoreEnterpriseBto` 源码截图,真实字段为 `channelName`(渠道名称)/
+> `channelNo`(渠道编号,全局唯一)/`appNo`/`bankName`/`bankNo`/`organizationId`/`enterpriseName`
+> (企业名称,与渠道名称是两个独立字段),`enterpriseCode` 字段已不存在。本次依据的 07-09 版 swagger
+> 快照已明显滞后于后端真实实现。详见 Part 6 补充说明。
+
### 1.7 客户管理 —— 个人客户
| 接口 | 说明 |
| --- | --- |
-| `POST /api/customer-info/personal/list` | `{organizationIdEq,customerCodeEq,customerNameLike,certificateNumberEq,page,pageSize}`,响应 `records: IndividualCustomerListVo[]`(仅 `id,organizationId,customerName,certificateType,certificateNumber,mobilePhone,ocrStatus,customerCode`,不含性别/创建人/创建时间) |
+| `POST /api/customer-info/personal/list` | `{organizationIdEq,customerCodeEq,customerNameLike,certificateNumberEq,page,pageSize}`,响应 `records: IndividualCustomerListVo[]`(仅 `id,organizationId,customerName,certificateType,certificateNumber,mobilePhone,ocrStatus,customerCode`,不含性别/创建人/创建时间;列表页最新处理方式见 Part 8 第77/78条) |
| `POST /api/customer-info/personal/detail` | `{id}` 或 `{customerCode}`,响应 `IndividualCustomerDetailVo` |
| `POST /api/customer-info/personal/create` | `CreateIndividualCustomerBto`,响应 `data`=新建id |
| `POST /api/customer-info/personal/update` | `UpdateIndividualCustomerBto` |
| `POST /api/customer-info/personal/ocr-idcard` | `{fileBase64,channelNo,fileType('01'\|'02')}`,响应 `OcrIdCardResultVo` |
| `POST /api/customer-info/personal/upload-file` | `{fileBase64,channelNo}`,响应 `{fileNo}`,个人身份证与企业营业执照图片均调用此通用接口 |
+| `POST /api/customer-info/personal/face-recognize` | `{fileData(人脸照片base64),idNo,name,channelNo}`,响应含 `fileNo`+`recode`/`recodeInfo`(识别结果码/说明,枚举未文档化,详见 Part 10 第87条),个人开户"正面免冠照"专用,识别通过即完成文件存档,无需再调用 `upload-file` |
### 1.8 客户管理 —— 企业客户
@@ -137,9 +151,18 @@
| 接口 | 说明 |
| --- | --- |
-| `POST .../query-customer` | 个人开户专属客户查询,响应字段同 `IndividualCustomerDetailVo` |
+| `POST .../query-customer` | 个人开户专属客户查询,响应字段同 `IndividualCustomerDetailVo`(2026-07-22 起"个人开户"页面改用 `/api/customer-info/personal/list`+`/detail` 组合,不再调用本接口;但 `WalletCustomerPicker.vue` 在个人贷款申请等场景仍在使用,详见 Part 10) |
| `POST .../create-draft` | 提交开户草稿,响应 `{applicationNo}` |
| `POST .../query-progress` | `{applicationNo}`,响应 `ApplicationProgressVo` |
+| `POST .../list`(**后端未提供,前端假设契约**) | 2026-07-23 新增"个人开户申请"列表页,参照
+ `enterprise-open-application/list` 结构假设请求体含 `applicationNo`/`customerNameLike`/
+ `certificateNumber`/`applicationStatus`/`startDate`/`endDate`/`page`/`pageSize`,响应
+ `{total,page,pageSize,records}`,详见 Part 11 第91条 |
+| `POST .../detail`(**后端未提供,前端假设契约**) | 请求 `{applicationNo}`,响应字段假设与
+ `create-draft` 请求体对齐(含 `applicationStatus`/`failReason`/`mainAccountNo`/`customerNo`
+ 等开户结果字段),详见 Part 11 第91条 |
+| `POST .../update`(**后端未提供,前端假设契约**) | 用 `applicationNo` 定位记录(而非数字 id),
+ 仅允许 `DRAFT` 状态记录编辑,详见 Part 11 第91条 |
### 1.11 钱包管理 —— 企业开户申请与企业绑卡(`/api/wallet-management/enterprise-open-application/*`、`enterprise-bank-card/*`)
@@ -223,9 +246,8 @@
置灰禁用,提示改用"密码重置"。
5. **`user/create`、`user/reset-password` 是否已实际发送短信通知用户,新密码规则(固定值/随机)未文档化**:
前端仅按约定展示"已通过短信通知用户"提示文案,不做实际校验。
-6. **`role-permission/bind`/`unbind` 的语义(全量替换 vs 增量追加)未在 swagger 说明**:前端已按"先查旧
- 集合、计算 diff、分别调用 bind(新增项)/unbind(移除项)"的保守策略实现,不受该语义影响,但建议
- 后端在文档中明确。
+6. **`role-permission/unbind` 接口后端未提供**:前端已改为不计算 diff,直接把页面上勾选的全量权限id
+ 列表一次性调用 `bind` 提交给后端,由后端按全量覆盖处理,不再调用 `unbind`。
7. **角色列表(`role/page`)不支持按所属机构过滤;核心企业、客户经理列表只支持单一名称模糊搜索**:
相比原前端自行设计的契约,过滤能力收窄,搜索表单已同步精简,若后续产品侧需要更多筛选维度,需后端
评估补充查询参数。
@@ -371,3 +393,547 @@
接口能力下无法实现,前端在汇总订单详情弹窗中用 `a-alert` 明确提示该缺口,未展示虚假数据,建议
后端为 `original-order/page` 补充 `summaryOrderId` 过滤参数,或在 `summary-order/detail` 响应中
直接内嵌关联的原始订单列表。
+52. **`GET /api/organization/query-tree` 需按登录用户机构自动限定返回范围(机构数据隔离需求)**:
+ 当前该接口返回全量机构树,不区分调用者身份。需要后端基于请求头 `Authorization` 中的 JWT 识别
+ 当前登录用户,若该用户所属机构不是顶级机构,则只返回"该机构 + 其下属机构"组成的子树(顶级机构
+ 用户仍返回全树);不新增请求参数,现有 `organizationName`/`organizationId` 筛选参数含义不变,
+ 在裁剪后的范围内叠加过滤。前端 `OrgTreeSelect.vue` 组件已按"完全信任接口返回数据,不做二次裁剪"
+ 的方式实现,后端完成本条改造后前端机构下拉框会自动生效为"仅本机构及下属机构可选",无需前端
+ 再次改动。
+53. **`GET /api/organization/list-all` 需要同样按登录用户机构自动限定返回范围**:规则同第 52 条,
+ 返回"当前用户机构 + 下属机构"组成的扁平列表(顶级机构用户返回全部)。
+54. **`POST /api/role/page` 需新增 `organizationId`(数字,机构主键)请求参数**:传入时按"该机构及
+ 其下属机构"过滤角色列表结果(呼应本文档 Part 2 第 7 条已登记的缺口,现补充明确参数名与语义)。
+ 前端 `RoleList.vue` 已新增"所属机构"筛选字段并会传该参数,后端未支持前该筛选暂不会真正生效。
+55. **机构数据隔离的安全边界说明**:第 52/53/54 条只解决 UI 展示层"默认值 + 可选范围"的问题;真正
+ 的数据安全隔离必须由后端在各业务查询接口(用户、角色、客户、商户等分页接口)内部,基于当前
+ 登录用户可见的机构范围校验/过滤查询条件与结果,不能仅信任前端传入的 `organizationId` 参数,
+ 否则用户可直接调用接口绕过前端限制越权查看其他机构数据。建议后端在通用鉴权层增加"按机构数据
+ 权限"的统一拦截能力。
+
+## Part 3:机构数据隔离改造 —— 各业务列表查询接口补充 `organizationId` 过滤参数
+
+> 以下接口对应的数据实体(Vo)**已经含有** `organizationId` 字段,仅列表查询接口的请求参数缺少
+> 对应的过滤入参。前端已在对应列表页新增"所属机构"筛选项并默认选中当前登录用户所属机构,会
+> 随请求一并传递 `organizationId` 参数,后端补充该参数支持后前端无需任何改动即可自动生效。
+
+56. **`POST /api/core-enterprise/page`(基础配置-核心企业管理)需新增 `organizationId`
+ (数字,机构主键)请求参数**:传入时按"该机构及其下属机构"过滤核心企业列表结果。
+ `CoreEnterpriseVo` 已含 `organizationId` 字段。
+57. **`POST /api/customer-manager/page`(基础配置-客户经理管理)需新增 `organizationId`
+ 请求参数**:规则同第 56 条。`CustomerManagerVo` 已含 `organizationId` 字段。
+58. **`POST /api/enterprise-customer/page`(客户管理-企业客户管理)需新增 `organizationId`
+ 请求参数**:规则同第 56 条。`EnterpriseCustomerVo` 已含 `organizationId` 字段。
+59. **`POST /api/credit-apply/loan-application/list`(授信管理-贷款申请列表)需新增
+ `organizationId` 请求参数**:规则同第 56 条。`LoanApplicationVo` 已含 `organizationId`
+ 字段("关联机构的id,指向所属机构"),补充成本较低,只差查询入参。
+60. **`POST /api/merchant/page`(商户中心-商户管理)需新增 `organizationId` 请求参数**:
+ 规则同第 56 条。`MerchantVo` 已含 `organizationId` 字段。
+
+## Part 4:机构数据隔离改造 —— 无机构关联字段的业务实体需先补充关联关系
+
+> 以下接口对应的数据实体(Vo)**完全不含** `organizationId` 字段,仅通过 `merchantId` /
+> `customerId` / `walletAccountId` 等外键与其他实体间接关联,当前无法确定其"所属机构"。
+> 前端已在对应列表页先接线"所属机构"筛选项(默认选中当前登录用户所属机构并随请求传递
+> `organizationId` 参数),但在后端完成以下关联关系建设并支持该过滤参数前,筛选不会产生
+> 实际效果。请后端评估技术方案(如建立间接关联查询,或在对应 Vo 中补充冗余 `organizationId`
+> 字段)。
+
+61. **`POST /api/wallet-account/page`(钱包管理-账户列表)**:`WalletAccountVo` 仅含
+ `customerId`,无机构关联,需后端建立"钱包账户 -> 客户 -> 所属机构"的关联并支持
+ `organizationId` 过滤参数。
+62. **`POST /api/wallet-management/enterprise-open-application/list`(钱包管理-企业开户
+ 申请)**:`EnterpriseAccountOpenApplicationListVo` 无机构关联字段(该接口连 `id` 字段
+ 都缺失,已在本文档第 23 条登记),需后端先补充机构关联字段/`id` 字段,再支持
+ `organizationId` 过滤参数。
+63. **`POST /api/invoice-management/invoice/list`(商户中心-发票管理)**:`InvoiceVo` 仅含
+ `merchantId`,无机构关联,需后端建立"发票 -> 商户 -> 所属机构"的关联并支持
+ `organizationId` 过滤参数。
+64. **`POST /api/summary-order/page`(订单管理-汇总订单)**:`SummaryOrderVo` 仅含
+ `merchantId`,无机构关联,需后端建立"汇总订单 -> 商户 -> 所属机构"的关联并支持
+ `organizationId` 过滤参数。
+65. **`POST /api/original-order/page`(订单管理-原始订单)**:`OriginalOrderVo` 仅含
+ `merchantId`/`summaryOrderId`,无机构关联,需后端建立"原始订单 -> 商户 -> 所属机构"的
+ 关联并支持 `organizationId` 过滤参数。
+66. **`POST /api/payment-management/query-payment-record`(支付管理-支付记录)**:
+ `PaymentRecordListVo` 仅含 `walletAccountId`,而钱包账户本身也无机构关联字段(见第 61
+ 条),是本次改造中关联链最薄弱的一个,需后端优先评估补充方案(建立"支付记录 -> 钱包
+ 账户 -> 客户 -> 所属机构"的完整关联链)并支持 `organizationId` 过滤参数。
+
+## Part 5:核心企业管理(渠道)页面字段调整 —— 2026-07-17 补充
+
+> 产品侧提供了"核心企业管理"页面的最新原型图,要求页面字段/搜索条件/按钮严格按图实现。经核对,
+> 该页面的"渠道名称/渠道编号"与全局其它 8 处"所属渠道"下拉(`ChannelSelect.vue`)复用的
+> `enterpriseName`/`enterpriseCode` 字段是同一概念(见 Part 1.6 补充说明),无需改动;但原型图新增
+> 了以下字段,当前 `CoreEnterpriseVo`/`CreateCoreEnterpriseBto`/`UpdateCoreEnterpriseBto` 均未提供,
+> 前端已按原型完成 UI 改造并在创建/更新请求中按最大努力一并传递这些字段,列表展示时若接口未返回则
+> 显示占位符"-",待后端补充字段后前端无需再次改动即可自动生效。
+
+67. **`CoreEnterpriseVo`/`CreateCoreEnterpriseBto`/`UpdateCoreEnterpriseBto` 需新增以下字段**:
+ - `appNo`(应用编号,字符串,新增/编辑必填)
+ - `bankName`(开户银行/开户行,字符串,选填)
+ - `bankNo`(银行行号,字符串,选填)
+ - `createdAt`(创建时间,`yyyy-MM-dd HH:mm:ss`,仅 `CoreEnterpriseVo` 需要,由后端自动生成)
+
+ 另外,原型图暂未包含"签名密钥"字段,产品侧明确**本次新增/编辑表单不需要提供签名密钥**,前端
+ 表单未接入该字段;但请后端注意后续版本大概率会补充该字段(用于渠道对接鉴权),建议提前预留
+ 字段位置(如 `signKey`),避免后续需要数据库变更。
+68. **`CoreEnterpriseVo` 原有字段 `businessLicense`/`contactPerson`/`contactPhone`/`status`/
+ `remark` 在本次原型图中均未展示**:前端"核心企业管理"页面的列表列与新增/编辑弹窗已移除这些
+ 字段,新增/编辑请求不再传递。若数据库对这些列存在非空(`NOT NULL`)约束,请后端确认可调整为
+ 允许空值,否则新增请求可能因缺少这些字段而报错。
+69. **`POST /api/core-enterprise/page` 需新增 `enterpriseCode`(渠道编号,模糊匹配)过滤参数**:
+ 原型图查询区包含"渠道编号"输入框,当前接口仅支持 `enterpriseName` 模糊搜索,`organizationId`
+ 过滤已在 Part 3 第 56 条登记,此处补充 `enterpriseCode` 参数需求。
+
+## Part 6:核心企业(渠道)创建接口字段更正 —— 2026-07-20 补充
+
+> 前端新增核心企业时发现请求未能生效(渠道编号/渠道名称等核心字段没有正确传入)。经核实,后端已经
+> 实现了 Part 5 第67条要求的 `appNo`/`bankName`/`bankNo` 字段(感谢及时补充),但**真实字段命名与
+> 前端此前依据的 07-09 版 swagger 快照不一致**:后端同事提供了最新 `CreateCoreEnterpriseBto` 源码
+> 截图,确认真实字段为:
+> - `channelName`(渠道名称)
+> - `channelNo`(渠道编号,注释标注"全局唯一")
+> - `appNo`(应用编号)
+> - `bankName`(开户银行)
+> - `bankNo`(银行行号)
+> - `enterpriseName`(企业名称,**与 `channelName` 是两个独立字段**,并非同一概念)
+> - `organizationId`(所属机构ID)
+>
+> 即原 `enterpriseCode` 字段已不存在,已被 `channelNo` 取代;`enterpriseName` 仍然存在但不再等同于
+> "渠道名称"。Part 1.6 及 Part 5 第67/69条基于旧版 swagger 快照得出的"渠道名称/渠道编号复用
+> `enterpriseName`/`enterpriseCode`,无需改名"结论已过期,以本条为准。
+
+70. **前端已同步修正**:`ChannelList.vue` 新增/编辑表单、列表列、搜索条件均已改为提交/读取
+ `channelName`/`channelNo`(而非 `enterpriseName`/`enterpriseCode`);全局下游读取核心企业列表
+ 的组件(`ChannelSelect.vue` 及其 8 个"所属渠道"下拉调用点、`MerchantForm.vue`/`MerchantList.vue`
+ 的"核心企业"下拉)均已改为优先读取 `channelName`/`channelNo`,并兼容旧字段名
+ `enterpriseName`/`enterpriseCode` 作为兜底,避免历史数据或后端环境未完全升级时选择器/列表显示
+ 空白。
+
+71. **`enterpriseName`(企业名称)字段语义待确认**:后端 Bto 中 `enterpriseName` 是独立于
+ `channelName`(渠道名称)的字段,但当前"核心企业管理"页面原型图未提供单独的"企业名称"输入项。
+ 前端新增/编辑提交时暂时以"渠道名称"的值兜底填充 `enterpriseName`,避免该字段为空导致创建失败
+ (是否有非空校验尚未确认)。请产品/后端确认:①`enterpriseName` 是否确实需要与 `channelName`
+ 区分(例如渠道对应的合作方公司全称 vs 渠道简称/编号别名);②若需要区分,请后端明确业务含义,
+ 前端将在弹窗中补充独立的"企业名称"输入项。
+
+72. **`POST /api/core-enterprise/page` 查询过滤参数命名需要后端确认**:Part 5 第69条要求新增
+ `enterpriseCode` 模糊过滤参数,若查询接口的参数命名已与创建接口同步改为 `channelNo`/
+ `channelName`,请后端明确告知。当前前端查询请求已**同时携带** `channelNo`/`channelName` 与
+ `enterpriseCode`/`enterpriseName` 两套参数名做兼容,待后端确认真实参数名后可移除多余的兼容传参。
+
+73. **强烈建议后端更新/提供最新 swagger 快照或补充 `PROJECT_ID`**:本次问题的根源是前端依据的
+ `swagger_project_scfs_2026-07-09_14-15-23.json` 快照已滞后于后端真实实现,且项目
+ `.toco/CONFIG` 未配置 `PROJECT_ID`,无法通过 MCP 工具在线查询最新接口定义,只能依赖人工截图
+ 核对,效率低且容易遗漏字段(例如本次的 `enterpriseName` 字段语义变化)。建议后端团队:
+ ①在 `.toco/CONFIG` 补充 `PROJECT_ID`;②或在每次接口变更后重新导出并覆盖 swagger 快照文件。
+
+## Part 7:个人客户新增表单"更多信息"字段补充 —— 2026-07-20 补充
+
+> 产品侧提供了"个人客户新增"页面的最新原型截图,要求页面在现有基础上:①原有字段全部改为必填并去掉
+> "职业"输入框;②新增一个可折叠的"更多信息"区块,补充证件类型(从主表单挪入)与19个新字段;③"证件
+> 失效日期"旁增加"长期"勾选框。经核对
+> `CreateIndividualCustomerBto`/`UpdateIndividualCustomerBto`/`IndividualCustomerDetailVo`,截图新增的
+> 19个字段**全部不存在**于现有接口契约,《凡荣e链前端业务需求说明书.md》2.5.1节与已抓取的原型页面
+> (`website_detail/客户管理/个人客户`)中也找不到任何字段/编码依据。前端已按截图完成 UI 改造,新增
+> 字段随创建/更新请求一并提交(后端目前会忽略未声明字段,不会报错,但也不会持久化),待后端补充字段
+> 定义后前端无需再次改动即可自动生效。
+
+74. **`CreateIndividualCustomerBto`/`UpdateIndividualCustomerBto`/`IndividualCustomerDetailVo` 需扩展
+ 以下19个字段**(前端字段名如下,均为新增,建议类型见括号):
+ - `nationality`(国籍,字符串,默认"中国")
+ - `maritalStatus`(婚姻状况,复用已有 `MaritalStatusEnum`)
+ - `residenceStatus`(居住状况,枚举,**取值为前端临时拟定的占位值** `SELF_OWNED`/`RENTED`/`OTHER`,
+ 需后端/产品确认标准编码表后由前端替换)
+ - `residentType`(居民性质,枚举,前端占位值 `PERMANENT`/`NON_PERMANENT`,同上需确认)
+ - `educationLevel`(最高学历,复用已有 `EducationLevelEnum`)
+ - `degree`(最高学位,枚举,前端占位值 `NONE`/`BACHELOR`/`MASTER`/`DOCTOR`,需确认)
+ - `mainIncomeSource`(主要经济来源,枚举,前端占位值 `SALARY`/`BUSINESS`/`OTHER`,需确认)
+ - `annualPersonalIncome`(个人年收入,数字)
+ - `annualFamilyIncome`(家庭年收入,数字)
+ - `employmentStatus`(从业状况,枚举,前端占位值
+ `EMPLOYED`/`SELF_EMPLOYED`/`FREELANCE`/`RETIRED`/`UNEMPLOYED`/`OTHER`,需确认)
+ - `occupationType`(职业类型,枚举,前端占位值
+ `ENTERPRISE_MANAGER`/`TECHNICAL`/`SELF_EMPLOYED`/`FARMER`/`FREELANCER`/`STUDENT`/`RETIRED`/
+ `WHOLESALE_RETAIL_OTHER`/`OTHER`,截图中出现"其他批发与零售服务人员"选项已纳入,**该字段真实
+ 业务上很可能需要对接标准职业分类码表(如 GB/T 6565),前端占位选项远不完整,需后端/产品明确**)
+ - `employerName`(工作单位名称,字符串)
+ - `employerIndustry`(工作单位所属行业,枚举,前端占位值
+ `AGRICULTURE`/`MANUFACTURING`/`WHOLESALE_RETAIL`/`CONSTRUCTION`/`FINANCE`/`IT`/`EDUCATION`/
+ `OTHER`,**同样可能需要对接标准行业分类码表,前端占位选项不完整**)
+ - `positionType`(职务类型,枚举,前端占位值 `LEADER`/`MIDDLE_MANAGER`/`STAFF`/`OTHER`,需确认)
+ - `professionalTitle`(职称,枚举,前端占位值 `SENIOR`/`INTERMEDIATE`/`JUNIOR`/`NONE`,需确认)
+ - `employmentStartDate`(参加本单位时间,日期,`yyyy-MM-dd HH:mm:ss`)
+ - `isAgriculturalCustomer`(是否涉农客户,布尔,默认 `false`)
+ - `residencyArea`(境内境外,枚举,前端占位值 `DOMESTIC`/`OVERSEAS`,默认 `DOMESTIC`,需确认)
+ - `customerStatus`(客户状态,枚举,前端占位值 `FORMAL`/`POTENTIAL`,默认 `FORMAL`;注意本文档 Part 2
+ 第12条曾记录"客户实体本身也无状态属性,不做",本次因产品侧新截图明确要求而重新引入,以本条为准)
+ - `remark`(备注,字符串,多行文本)
+
+ 以上枚举取值均为**前端临时拟定的极简占位选项**(定义于 `src/constants/customerEnums.js`),
+ 非后端已有枚举,后端确认标准编码表后前端会同步替换,请勿直接按前端占位值建表/校验。
+
+75. **"证件失效日期"新增"长期"勾选框,当前用哨兵日期权变**:`certificateExpiryDate` 字段目前仍是
+ 具体日期字符串,没有专用布尔字段表示"长期有效"(常见于46周岁以上居民身份证)。前端勾选"长期"后,
+ 提交时用固定哨兵值 `9999-12-31 00:00:00` 代替具体日期。建议后端后续补充专用布尔字段(如
+ `certificateLongTerm`)承载该语义,避免长期依赖这个约定值(尤其要注意该哨兵值不应被"证件已过期"
+ 之类的日期比较逻辑误判)。
+
+76. **个人客户相关4个接口的请求头新增了 `Channelno`,且全站请求头大小写格式已按最新约定统一修正**:
+ 为配合本次"上传身份证正反面图片需带渠道信息"的需求,前端已将 `src/utils/traceHeaders.js` 修正为
+ 输出 `Appno`/`Channelno`/`Serialno`/`Transdate`/`Transtradetime`(首字母大写、其余小写)5个 header
+ (此前只有 `serialNo`/`transDate`/`transTradeTime` 三个小写驼峰形式,不完整也不符合约定大小写)。
+ `Channelno` 目前只在个人客户新增/编辑涉及的4个接口(`ocr-idcard`/`upload-file`/`create`/`update`)
+ 上,当页面已选定渠道时才携带;编辑模式下若用户未重新选择渠道,则不携带该 header。全站其它接口
+ 请求会统一获得修正后的 `Appno`/`Serialno`/`Transdate`/`Transtradetime`(与渠道无关,全局生效),
+ 请后端确认接口层按此大小写格式正确读取,若后端框架对 header 名大小写不敏感可忽略本条。
+
+## Part 8:个人客户列表页字段/筛选项按最新原型截图补充 —— 2026-07-20 补充
+
+> 产品侧提供了"客户管理 > 个人客户管理"列表页的最新原型截图,要求列表展示"性别""创建人""创建
+> 时间"三列,查询区增加"资料完整""客户状态"两个筛选项,并对"证件号码"做脱敏展示。前端已按截图
+> 完成列展示与查询区改造,脱敏为纯前端展示层处理(不影响提交/查询的真实参数值);但下述字段/参数
+> 后端目前均不提供,前端暂按"展示但内容为空"/"传参但后端可忽略"方式实现,不编造数据,待后端补充后
+> 自动生效。
+
+77. **`IndividualCustomerListVo` 需扩展"性别""创建人""创建时间"三个字段**:当前响应仅含
+ `id,organizationId,customerName,certificateType,certificateNumber,mobilePhone,ocrStatus,
+ customerCode`(见 Part 1 第 1.7 节)。列表页新增的三列字段建议:
+ - `gender`(性别,复用详情接口 `IndividualCustomerDetailVo` 已有的 `MALE`/`FEMALE`/`UNKNOWN` 枚举)
+ - `createBy`(创建人姓名/工号文本;注意详情接口目前只有 `creatorId`,是用户ID不是姓名,列表页与
+ 详情页展示"创建人"都需要后端直接返回可读文本,前端没有"根据用户ID查姓名"的接口可用来反查)
+ - `createTime`(创建时间,格式 `yyyy-MM-dd HH:mm:ss`;详情接口 `IndividualCustomerDetailVo` 已有
+ 该字段,建议列表接口同步补充,避免语义不一致)
+
+ 补充前,前端列表页这三列会因后端未返回对应字段而显示为空,不是缺陷。
+
+78. **个人客户列表查询接口 (`FindIndividualCustomerListQto`) 需扩展"资料完整""客户状态"两个筛选
+ 参数**:前端已在查询区新增以下两个下拉筛选框,并会随请求一并提交,但后端目前既无对应参数也无
+ 对应枚举定义,提交后预期被后端忽略(不生效),不影响其余已支持参数的筛选结果:
+ - `dataCompleteEq`(资料完整,枚举,**前端临时占位值** `COMPLETE`/`INCOMPLETE`,定义于
+ `src/constants/customerEnums.js` 的 `DATA_COMPLETE_OPTIONS`,业务含义待产品/后端确认——例如
+ 是否等价于身份证OCR识别成功、必填字段是否补全等,目前只是从截图外观拟定的占位选项)
+ - `customerStatusEq`(客户状态,复用已有的 `CUSTOMER_STATUS_OPTIONS`——`FORMAL`/`POTENTIAL`,与
+ Part 7 第 74 条记录的 `customerStatus` 是同一套前端占位枚举,同样需要后端确认标准编码表后
+ 前端再替换真实值)
+
+## Part 9:企业客户新增表单"更多信息"/股东高管信息扩展/对外投资关系信息 —— 2026-07-21 补充
+
+> 产品侧提供了"客户管理 > 企业客户管理 > 新增企业客户"页面的最新原型截图,要求:①基础信息区多个字段
+> 由非必填改为必填,法定代表人改为在"股东与高管信息"卡片内逐行勾选(删除独立字段);②新增可折叠的
+> "更多信息"区块,含约30个标量字段与联系信息/地址信息两个可增删行的子表格;③"公司股东与高管信息"由
+> 只读表格重构为可增删的卡片列表,补充多个新字段;④新增"对外投资关系信息"区块(全新结构,原表单不
+> 存在)。经核对 `CreateEnterpriseCustomerBto`/`UpdateEnterpriseCustomerBto`/`EnterpriseCustomerDetailVo`
+> /`EnterpriseRelatedPersonBto`,除 `position`/`shareholdingRatio`/`nationality`/`contactPhone` 外,
+> 本次涉及的字段**基本全部不存在**于现有接口契约。前端已按截图完成 UI 改造,新增标量字段(更多信息 +
+> 联系信息/地址信息)随创建/更新请求一并提交,新增数组字段(股东高管扩展字段、对外投资关系)仅在
+> "新增"模式下随创建请求提交(理由见第81/82条);后端目前会忽略未声明字段,不会报错,也不会持久化,
+> 待后端补充字段定义后前端无需再次改动即可自动生效。
+
+79. **`CreateEnterpriseCustomerBto`/`UpdateEnterpriseCustomerBto`/`EnterpriseCustomerDetailVo` 需扩展
+ "更多信息"区块的以下标量字段**(前端字段名如下,均为新增):
+ - `unitNature`(单位性质,枚举,已于2026-07-21根据后端 `/api/enterprise-customer/create` 实际报错
+ 日志中 `com.scfs.customer_info.common.enums.UnitNatureEnum` 的真实取值订正:
+ `ENTERPRISE_LEGAL_PERSON`/`PUBLIC_INSTITUTION`/`SOCIAL_ORGANIZATION`/`INDIVIDUAL_BUSINESS`/`OTHER`,
+ 定义于 `src/constants/enterpriseEnums.js` 的 `UNIT_NATURE_OPTIONS`,不再是占位值)
+ - `economicComposition`(经济成分,枚举占位,`ECONOMIC_COMPOSITION_OPTIONS`)
+ - `institutionCategory`(机构类别/登记注册类型,枚举占位,`INSTITUTION_CATEGORY_OPTIONS`)
+ - `economicNature`(经济性质经营类型,枚举占位,`ECONOMIC_NATURE_OPTIONS`)
+ - `nationalEconomyCategory`(国民经济门类,枚举,采用 **GB/T 4754 标准20门类真实分类,非占位**,
+ 定义于 `NATIONAL_ECONOMY_CATEGORY_OPTIONS`,可直接按此码表建表)
+ - `registeredCapital`(注册资本,数字)+ `registeredCapitalCurrency`(注册资本币种,枚举,复用
+ `CURRENCY_OPTIONS`,默认"人民币")
+ - `establishmentDate`(企业成立日期,`yyyy-MM-dd HH:mm:ss`)
+ - `paidInCapital`(实收资本,数字)+ `paidInCapitalCurrency`(实收资本币种,同上复用 `CURRENCY_OPTIONS`)
+ - `lastYearEmployeeCount`(上年末企业从业人员,数字,单位人次)
+ - `lastYearTotalAssets`(上年末资产总额,数字)
+ - `lastYearRevenue`(上年营业收入,数字)
+ - `netAssets`(净资产,数字)
+ - `basicAccountBankName`(基本账户开户行名称,字符串)+ `basicAccountNumber`(基本账户账号,字符串)
+ - `accountLicenseNumber`(开户许可证号,字符串)+ `accountLicenseDate`(开户日期,`yyyy-MM-dd HH:mm:ss`)
+ - `paymentCardNumber`(缴款卡号,字符串)
+ - `enterpriseScale`(企业规模,枚举,采用**工信部四级标准分类(大型/中型/小型/微型),非占位**,
+ 定义于 `ENTERPRISE_SCALE_OPTIONS`,可直接按此码表建表)
+ - `foreignExchangeEnterpriseType`(外汇企业类型,枚举占位,`FOREIGN_EXCHANGE_ENTERPRISE_TYPE_OPTIONS`)
+ - `pbocFinancialInstitutionCode`(人行金融机构编码,字符串)
+ - `financialInstitutionIndustryType`(金融机构行业分类,枚举占位,`FINANCIAL_INSTITUTION_INDUSTRY_OPTIONS`)
+ - `interbankCustomerType`(同业客户类型,枚举占位,`INTERBANK_CUSTOMER_TYPE_OPTIONS`)
+ - `businessStatus`(经营状态,枚举占位,`BUSINESS_STATUS_OPTIONS`)
+ - `customerStatus`(客户状态,枚举,复用个人客户已有的 `CUSTOMER_STATUS_OPTIONS`——`FORMAL`/`POTENTIAL`,
+ 与 Part 7 第74条、Part 8 第78条是同一套前端占位枚举)
+ - `isFrozenCustomer`(是否冰点客户,布尔,默认 `false`)+ `frozenType`(冰冻类型,枚举占位,
+ `FROZEN_TYPE_OPTIONS`,仅 `isFrozenCustomer` 为 `true` 时才有意义)
+ - `residencyArea`(境内境外,枚举,`DOMESTIC`/`OVERSEAS`,与个人客户 Part 7 第74条命名保持一致,
+ 默认 `DOMESTIC`)
+ - `isGreenEnterprise`/`isGroupCustomer`/`isIndividualBusiness`/`isListedCompany`/
+ `isSmallMicroEnterprise`/`isTechEnterprise`(是否绿色企业/集团客户/个体工商户/上市公司/
+ 小微企业/科技企业,均为布尔,默认 `false`)
+ - `remark`(备注,字符串,多行文本)
+
+ 以上标注"占位"的枚举取值均为**前端临时拟定的极简占位选项**(定义于
+ `src/constants/enterpriseEnums.js`),非后端已有枚举,请勿直接按前端占位值建表/校验;标注
+ "真实分类,非占位"的 `nationalEconomyCategory`/`enterpriseScale` 采用的是国家标准/部委标准码表,
+ 可直接按该码表在后端建表。
+
+80. **建议新增 `contactInfoBtoList`(联系信息)、`addressInfoBtoList`(地址信息)两个子数组结构**,
+ 均随 create/update 提交,当前后端无对应字段:
+ - `contactInfoBtoList` 每项:`{contactType, contactValue, isPrimary}`,`contactType` 枚举占位
+ (移动电话/固定电话/传真/电子邮箱/其他,定义于 `CONTACT_TYPE_OPTIONS`),`isPrimary` 布尔(主要标志)
+ - `addressInfoBtoList` 每项:`{addressType, country, regionText, detailAddress, isPrimary}`,
+ `addressType` 枚举占位(证件地址/联系地址/注册地址/经营地址/其他,定义于 `ADDRESS_TYPE_OPTIONS`),
+ `country` 为国家代码(默认 `CN`),`regionText` 是省市区级联拼接后的文本(不下传结构化省市区
+ code,见第83条),`isPrimary` 布尔(主要标志)
+
+81. **`EnterpriseRelatedPersonBto` 需在已有 `position`/`shareholdingRatio`/`nationality`/
+ `contactPhone` 基础上补充以下新字段**:
+ - `positionStartDate`(任职时间,`yyyy-MM-dd HH:mm:ss`)
+ - `industryYears`(相关行业从业年限,数字)
+ - `contributionMethod`(出资方式,枚举占位,`CONTRIBUTION_METHOD_OPTIONS`:货币/实物/知识产权/
+ 土地使用权/其他)
+ - `contributionCurrency`(出资币种,复用 `CURRENCY_OPTIONS`,默认"人民币")
+ - `subscribedAmount`(应出资金额,数字)
+ - `paidAmount`(实际出资金额,数字)
+ - `contributionRatio`(出资比例,数字,百分数;注意与已有 `shareholdingRatio` 持股比例含义不同——
+ 持股比例是最终股权占比,出资比例是本次出资占应出资总额的比例,两者均需保留)
+ - `contributionDate`(出资日期,`yyyy-MM-dd HH:mm:ss`)
+ - `remark`(备注,字符串)
+
+ 页面上展示的国籍/性别/职业类型/联系电话/地址信息/客户编号中,只有 `nationality`(国籍)、
+ `contactPhone`(联系电话,前端字段名 `mobilePhone`)是提交到本结构的;性别/职业类型/地址信息/
+ 客户编号属于**个人客户自身的属性**(选中关联人后从个人客户 `detail` 接口只读回填展示),不属于
+ "企业-关联人关系"这层数据,前端不会重复提交到 `EnterpriseRelatedPersonBto`。
+
+ 该扩展字段**仅在"新增企业客户"时随 `enterpriseRelatedPersonBtoList` 提交**,原因见第82条。
+
+82. **股东高管信息、对外投资关系信息均改为可增删的卡片列表,但仍只允许在"新增"模式下编辑并提交,
+ 编辑/详情模式展示提示文案**:现有 `enterpriseRelatedPersonBtoList` 只存在于
+ `CreateEnterpriseCustomerBto`,`UpdateEnterpriseCustomerBto`/`EnterpriseCustomerDetailVo` 均无
+ 此字段(Part 2 第14条已记录该限制),本次未改变这一现状。对外投资关系是全新结构,后端完全不存在,同样
+ 无法确认 update/detail 是否可回显,为避免"编辑时列表总是空"造成用户误以为数据丢失,前端统一
+ 按"仅新增模式可编辑"处理。**建议后端评估是否可以让 `UpdateEnterpriseCustomerBto`/
+ `EnterpriseCustomerDetailVo` 同步支持这两个数组字段**,以便后续开放编辑态维护。
+
+83. **全新结构建议:`enterpriseInvestmentBtoList`(对外投资关系信息)**,后端目前完全没有对应字段,
+ 前端仅在新增模式下随 `createEnterpriseCustomerBto` 提交,每项字段:
+ - `investeeEnterpriseId`(被投资企业客户ID,通过 `EnterpriseCustomerPicker.vue` 选择企业客户获得,
+ **仅支持选企业客户,不支持个人客户**)
+ - `investeeName`(被投资企业名称,选中后只读回填,不可编辑)
+ - `certificateType`(证件类型,固定"营业执照",只读回填)
+ - `certificateNumber`(营业执照号,只读回填)
+ - `certificateExpiryDate`(证件到期日,只读回填)
+ - `shareholdingRatio`(持股状况/本企业持有被投资企业的股权比例,数字,百分数)
+ - `contributionMethod`/`contributionCurrency`/`subscribedAmount`/`paidAmount`/
+ `contributionRatio`/`contributionDate`(出资相关字段,含义与第81条 `EnterpriseRelatedPersonBto`
+ 同名字段一致)
+ - `investorEconomicComposition`(出资人经济成分,枚举,复用第79条 `ECONOMIC_COMPOSITION_OPTIONS`)
+ - `relationType`(关系类型,枚举占位,`INVESTMENT_RELATION_TYPE_OPTIONS`:控股/参股/联营/合营/其他)
+ - `isValid`(是否有效,布尔,默认 `true`)
+ - `relationExpiryDate`(关系到期时间,`yyyy-MM-dd HH:mm:ss`)
+ - `remark`(备注,字符串)
+
+ 截图中的"关联客户编号"列固定展示"暂无关联客户编号"(新增时后端尚未生成该关系记录的编号,纯展示
+ 占位,不对应任何提交字段,不提交)。
+
+84. **证件地址由自由文本改为"省市区级联 + 详细地址"两部分,是纯前端展示层处理,不新增后端字段**:
+ 省市区数据来自静态 npm 包 `china-division`(不依赖后端接口),提交时仍拼接为
+ `${省市区文本}${详细地址}` 写入现有的单一自由文本字段 `certificateAddress`,与个人客户/企业客户
+ "证件地址"既有的自由文本约定保持兼容。地址信息表格(第80条 `addressInfoBtoList`)中的行政区划
+ 同理,只提交拼接后的 `regionText`,不提交结构化省市区 code。**建议后端后续评估是否需要将证件
+ 地址拆分为省(`provinceCode`)/市(`cityCode`)/区(`districtCode`)结构化字段**,非阻塞项,前端
+ 当前方案已能满足截图交互要求。
+
+85. **"是否法定代表人"由股东与高管信息卡片逐行勾选互斥决定,提交时仍复用已有的顶层
+ `legalRepresentativeId` 字段,后端无需改动**:原表单"法定代表人"是独立选择字段,现改为在每张
+ 股东/高管卡片内勾选"是否法定代表人"(同时最多一人勾选"是",前端本地维护互斥),提交时取值为
+ `true` 的那一条关联人的 `individualId`,写入顶层 `legalRepresentativeId` 字段提交;若无人勾选,
+ 该字段为空。此字段本身在 swagger 中已存在,本条仅记录前端交互方式变化,不涉及接口契约变更。
+
+86. **"新增企业客户"页面全部码值汇总(供后端逐项核对/对齐)——2026-07-21 补充**:第79-83条已分别说明各
+ 字段"是否占位",本条按字段汇总**完整的码值:标签对照表**,供后端一次性核对哪些可直接采用、哪些
+ 需要更正为后端已有编码表。除标注"✅已确认"外,其余均为**前端临时拟定的占位值**,后端如已有现成
+ 编码表,请反馈真实取值,前端将比照 `unitNature` 的处理方式(见第79条,已根据 `/api/enterprise-
+ customer/create` 实际报错日志中的 `UnitNatureEnum` 真实取值订正)同步修正。
+
+ **(1) `CreateEnterpriseCustomerBto`/`UpdateEnterpriseCustomerBto` 标量字段枚举**
+
+ | 字段 | 码值:标签 | 状态 |
+ | --- | --- | --- |
+ | `certificateType` | 固定传值 `BUSINESS_LICENSE`(证件类型,企业客户固定为营业执照) | 沿用已有字段,非新增枚举 |
+ | `unitNature`(单位性质) | `ENTERPRISE_LEGAL_PERSON`:企业法人 / `PUBLIC_INSTITUTION`:事业单位 / `SOCIAL_ORGANIZATION`:社会团体 / `INDIVIDUAL_BUSINESS`:个体工商户 / `OTHER`:其他 | ✅已确认(来自后端 `UnitNatureEnum` 报错日志真实取值) |
+ | `economicComposition`(经济成分) | `STATE_OWNED`:全民所有制 / `COLLECTIVE`:集体所有制 / `PRIVATE`:私营 / `FOREIGN_OWNED`:外资 / `SINO_FOREIGN_JOINT_VENTURE`:中外合资 / `SINO_FOREIGN_COOPERATIVE`:中外合作 / `OTHER`:其他 | ⚠️占位 |
+ | `institutionCategory`(机构类别/登记注册类型) | `LIMITED_LIABILITY_COMPANY`:有限责任公司 / `JOINT_STOCK_COMPANY`:股份有限公司 / `STATE_OWNED_ENTERPRISE`:全民所有制企业 / `COLLECTIVE_ENTERPRISE`:集体所有制企业 / `SOLE_PROPRIETORSHIP`:个人独资企业 / `PARTNERSHIP`:合伙企业 / `FOREIGN_INVESTED_ENTERPRISE`:外商投资企业 / `GOVERNMENT_AGENCY`:机关 / `PUBLIC_INSTITUTION`:事业单位 / `SOCIAL_ORGANIZATION`:社会团体 / `OTHER`:其他 | ⚠️占位 |
+ | `economicNature`(经济性质经营类型) | `STATE_OWNED`:国有 / `COLLECTIVE`:集体 / `PRIVATE`:私营 / `FOREIGN_OWNED`:外资 / `JOINT_VENTURE`:合资 / `COOPERATIVE`:合作 / `OTHER`:其他 | ⚠️占位 |
+ | `nationalEconomyCategory`(国民经济门类) | `A`:农、林、牧、渔业 / `B`:采矿业 / `C`:制造业 / `D`:电力、热力、燃气及水生产和供应业 / `E`:建筑业 / `F`:批发和零售业 / `G`:交通运输、仓储和邮政业 / `H`:住宿和餐饮业 / `I`:信息传输、软件和信息技术服务业 / `J`:金融业 / `K`:房地产业 / `L`:租赁和商务服务业 / `M`:科学研究和技术服务业 / `N`:水利、环境和公共设施管理业 / `O`:居民服务、修理和其他服务业 / `P`:教育 / `Q`:卫生和社会工作 / `R`:文化、体育和娱乐业 / `S`:公共管理、社会保障和社会组织 / `T`:国际组织 | ✅已确认(GB/T 4754 国标20门类) |
+ | `enterpriseScale`(企业规模) | `LARGE`:大型 / `MEDIUM`:中型 / `SMALL`:小型 / `MICRO`:微型 | ✅已确认(工信部《中小企业划型标准规定》四级分类) |
+ | `registeredCapitalCurrency`/`paidInCapitalCurrency`(注册资本/实收资本币种,复用同一枚举) | `CNY`:人民币 / `USD`:美元 / `EUR`:欧元 / `HKD`:港币 / `OTHER`:其他 | ⚠️占位 |
+ | `foreignExchangeEnterpriseType`(外汇企业类型) | `WHOLLY_FOREIGN_OWNED`:外商独资企业 / `SINO_FOREIGN_JOINT_VENTURE`:中外合资企业 / `SINO_FOREIGN_COOPERATIVE`:中外合作企业 / `FOREIGN_REP_OFFICE`:外国企业常驻代表机构 / `OTHER`:其他 | ⚠️占位 |
+ | `financialInstitutionIndustryType`(金融机构行业分类) | `BANKING`:银行业 / `SECURITIES`:证券业 / `INSURANCE`:保险业 / `TRUST`:信托业 / `FUND`:基金业 / `FUTURES`:期货业 / `OTHER`:其他 | ⚠️占位 |
+ | `interbankCustomerType`(同业客户类型) | `BANK`:银行同业 / `SECURITIES`:证券同业 / `INSURANCE`:保险同业 / `TRUST`:信托同业 / `OTHER`:其他 | ⚠️占位 |
+ | `businessStatus`(经营状态) | `NORMAL`:正常经营 / `SUSPENDED`:停业 / `DEREGISTERED`:注销 / `REVOKED`:吊销 / `OTHER`:其他 | ⚠️占位 |
+ | `customerStatus`(客户状态,与个人客户 Part 7 第74条、Part 8 第78条共用) | `FORMAL`:正式客户 / `POTENTIAL`:潜在客户 | ⚠️占位 |
+ | `frozenType`(冰冻类型,仅 `isFrozenCustomer=true` 时有意义) | `FULL_FROZEN`:全额冻结 / `PARTIAL_FROZEN`:部分冻结 / `JUDICIAL_FROZEN`:司法冻结 / `OTHER`:其他 | ⚠️占位 |
+ | `residencyArea`(境内境外) | `DOMESTIC`:境内 / `OVERSEAS`:境外 | ⚠️占位 |
+ | `isFrozenCustomer`/`isGreenEnterprise`/`isGroupCustomer`/`isIndividualBusiness`/`isListedCompany`/`isSmallMicroEnterprise`/`isTechEnterprise` | 布尔 `true`/`false`,均默认 `false` | 布尔字段,非字符串枚举 |
+
+ **(2) `contactInfoBtoList`(联系信息子表格,见第80条)**
+
+ | 字段 | 码值:标签 | 状态 |
+ | --- | --- | --- |
+ | `contactType`(联系方式类型) | `MOBILE`:移动电话 / `TELEPHONE`:固定电话 / `FAX`:传真 / `EMAIL`:电子邮箱 / `OTHER`:其他 | ⚠️占位 |
+ | `isPrimary`(主要标志) | 布尔 `true`/`false` | 布尔字段 |
+
+ **(3) `addressInfoBtoList`(地址信息子表格,见第80条)**
+
+ | 字段 | 码值:标签 | 状态 |
+ | --- | --- | --- |
+ | `addressType`(地址类型) | `CERTIFICATE`:证件地址 / `CONTACT`:联系地址 / `REGISTERED`:注册地址 / `BUSINESS`:经营地址 / `OTHER`:其他 | ⚠️占位 |
+ | `country`(国家/地区) | `CN`:中国 / `OTHER`:其他(选"其他"时行政区划退化为自由文本,项目未引入国际地区字典) | ⚠️占位 |
+ | `isPrimary`(主要标志) | 布尔 `true`/`false` | 布尔字段 |
+
+ **(4) `enterpriseRelatedPersonBtoList`(股东与高管信息,见第81条)**
+
+ | 字段 | 码值:标签 | 状态 |
+ | --- | --- | --- |
+ | `relatedType`(关联人类型) | `SHAREHOLDER`:股东 / `EXECUTIVE`:高管 / `BENEFICIARY_OWNER`:受益所有人(**当前硬编码在页面模板中,未抽取到枚举字典文件,尤其需要后端确认**) | ⚠️占位 |
+ | `position`(职务) | `CHAIRMAN`:董事长 / `GENERAL_MANAGER`:总经理 / `DEPUTY_GENERAL_MANAGER`:副总经理 / `FINANCE_HEAD`:财务负责人 / `SUPERVISOR`:监事 / `DIRECTOR`:董事 / `OTHER`:其他 | ⚠️占位 |
+ | `contributionMethod`(出资方式) | `CURRENCY`:货币 / `PHYSICAL`:实物 / `INTELLECTUAL_PROPERTY`:知识产权 / `LAND_USE_RIGHT`:土地使用权 / `OTHER`:其他 | ⚠️占位 |
+ | `contributionCurrency`(出资币种,复用(1)中的币种枚举) | `CNY`/`USD`/`EUR`/`HKD`/`OTHER` | ⚠️占位 |
+ | `isLegalRepresentative`(是否法定代表人,卡片内互斥勾选,不提交到本结构,见第85条) | 布尔 `true`/`false` | 布尔字段 |
+
+ 以下三项是选中关联人后从个人客户 `detail` 接口**只读回填展示**,不提交到 `EnterpriseRelatedPersonBto`(见第81条说明),仅供后端确认前端展示映射是否与个人客户既有枚举一致:
+
+ | 字段 | 码值:标签 |
+ | --- | --- |
+ | 证件类型(展示) | `ID_CARD`:居民身份证 / `PASSPORT`:护照 / `BUSINESS_LICENSE`:营业执照 / `OTHER`:其他 |
+ | 性别(展示) | `MALE`:男 / `FEMALE`:女 / `UNKNOWN`:未知 |
+ | 职业类型(展示,复用个人客户 `OCCUPATION_TYPE_OPTIONS`) | `ENTERPRISE_MANAGER`:企业管理人员 / `TECHNICAL`:专业技术人员 / `SELF_EMPLOYED`:个体经营人员 / `FARMER`:务农人员 / `FREELANCER`:自由职业者 / `STUDENT`:学生 / `RETIRED`:退休人员 / `WHOLESALE_RETAIL_OTHER`:其他批发与零售服务人员 / `OTHER`:其他 |
+
+ **(5) `enterpriseInvestmentBtoList`(对外投资关系信息,全新结构,见第83条)**
+
+ | 字段 | 码值:标签 | 状态 |
+ | --- | --- | --- |
+ | `investorEconomicComposition`(出资人经济成分,复用(1)中 `economicComposition` 枚举) | 同上 `ECONOMIC_COMPOSITION_OPTIONS` | ⚠️占位 |
+ | `relationType`(关系类型) | `CONTROLLING`:控股 / `PARTICIPATING`:参股 / `AFFILIATED`:联营 / `JOINT_OPERATION`:合营 / `OTHER`:其他 | ⚠️占位 |
+ | `contributionMethod`/`contributionCurrency`(出资方式/币种,复用(4)同名枚举) | 同上 | ⚠️占位 |
+ | `isValid`(是否有效,默认 `true`) | 布尔 `true`/`false` | 布尔字段 |
+
+ 以上全部枚举定义于前端 `src/constants/enterpriseEnums.js`(`UNIT_NATURE_OPTIONS` 等)与
+ `src/constants/customerEnums.js`(`CUSTOMER_STATUS_OPTIONS`/`OCCUPATION_TYPE_OPTIONS`),
+ `relatedType`/证件类型展示映射/性别展示映射三项例外,当前直接硬编码在
+ `EnterpriseForm.vue`/`EnterpriseRelatedPersonCard.vue` 组件内,尚未抽取到枚举字典文件。
+ **待后端反馈真实编码表后,前端将统一替换并同步补充到本文档。**
+
+---
+
+## Part 10:钱包管理"个人开户"表单按最新原型截图改造 —— 2026-07-22 补充
+
+> 产品侧提供了"钱包管理 > 个人开户"页面的最新原型截图,要求按截图重排字段顺序与只读/可编辑范围,
+> 补充身份证 OCR 结果与已选客户信息的比对报错、正面免冠照采集、开户协议勾选强制项,并移除"开户
+> 行号"/"开户行名称"两个截图未出现的字段(两者原为选填字段,省略不影响 `create-draft` 提交)。
+> 选择客户环节改为与"客户管理 > 个人客户管理"页面一致的处理方式:先调用 `/api/customer-info/
+> personal/list` 分页查询(复用现有 `PersonalCustomerPicker.vue`),选中后再调用 `/api/customer-
+> info/personal/detail` 取完整字段回填表单,不使用本模块专属但字段未必与个人客户模型对齐的
+> `personal-opening/query-customer` 接口(该接口仍被 `WalletCustomerPicker.vue` 在个人贷款申请
+> 等其他场景使用,`src/api/wallet.js` 中的封装函数予以保留,仅本页面不再调用,详见 1.10 节)。
+> 产品侧同时确认本页面**不需要短信验证码
+> 环节**,前端已移除验证码输入框、发送按钮及 `send-sms-code` 调用。核对 `.../personal-opening/
+> create-draft`、`/api/customer-info/personal/list`、`/api/customer-info/personal/detail`、
+> `/api/customer/ocr-idcard`、`/api/customer/upload-file` 后,本次 `fileType`(01/02/04/13)、
+> `gender`/`certificateType` 枚举、`jobNote` 字段均已在 swagger 中有明确文档依据,**并非新增
+> 缺口**;真正的缺口集中在"人脸识别结果码枚举"、开户协议内容两方面,记录如下:
+
+87. **"正面免冠照 + 去采集"已改用后端新提供的人脸识别接口,但识别结果码枚举未文档化——
+ 2026-07-22 更新**:后端已提供 `POST /api/customer-info/personal/face-recognize`(凡荣e链
+ 222005 接口透传),入参 `{fileData(人脸照片 base64,字段命名含"zip"但经后端工程师确认实际
+ 直传图片 base64 即可,非真正的 zip 压缩包)/idNo(身份证号)/name(姓名)/channelNo}`,前端已
+ 改为选中/拍摄照片后直接调用该接口,传入**已选客户档案**中的 `certificateNumber`/
+ `customerName` 作为 `idNo`/`name`(而非身份证 OCR 识别出的值);响应中 `fileNo` 即识别通过后
+ 可直接用于 `create-draft` 的 `fileList`(`fileType=04`)的文件编号,识别与文件存档一步完成,
+ 不再调用通用的 `upload-file` 接口做二次上传。**遗留缺口**:响应中另有 `recode`/`recodeInfo`
+ 两个字段(经后端工程师确认用于承载识别结果码/说明),但具体枚举取值(如成功码是什么、失败时
+ 各失败原因对应的码值)未提供文档,前端 `src/components/FacePhotoUpload.vue` 暂**只按"响应
+ `data.fileNo` 是否非空"判断识别是否通过**(有 `fileNo` 视为通过,直接用 `recodeInfo` 文本
+ 展示给用户;无 `fileNo` 视为失败,同样用 `recodeInfo`/`message` 展示原因),未对 `recode`
+ 做任何分支判断。建议后端补充 `recode` 的完整枚举取值表,前端将据此细化不同失败原因的提示
+ 文案(例如"人脸与身份证不符" vs "照片质量过低"等更精确的引导)。另外,选择/重新选择客户后,
+ 前端会清空之前已识别通过的人脸照片(`facePhotoFileNo` 置空并强制重新拍摄/上传),因为该
+ `fileNo` 是绑定"上一次识别时传入的 idNo/name"生成的,客户变更后不应继续复用。
+88. **开户协议(截图中的两个协议链接)无后端字段与真实文本/URL**:`create-draft` 的 `fileList`
+ 虽支持 `fileType=13`(开户协议文件),但该字段语义是"上传已签署的协议文件"而非"展示协议
+ 条款文本供客户勾选同意",且后端未提供任何协议文本内容或跳转链接。前端"勾选后才允许点击
+ 确认"的强制项已实现,但协议链接点击后弹出的说明文字为**前端占位文案**,并非真实的《个人
+ 钱包开户协议》等法律文本,亦不随表单提交(`create-draft` 无对应字段)。建议产品侧确认协议
+ 正式文本/链接后由前端替换占位内容,不涉及接口契约变更。
+89. **民族(`ethnic`)字段本次改为只读下拉框展示,但未维护完整的56民族码表**:选中客户后从
+ `/api/customer-info/personal/detail` 响应的 `ethnicity` 字段回填的民族文本,直接作为该
+ 下拉框唯一选项展示(不可编辑、不可选择其他民族),纯粹是为了在视觉上匹配截图"下拉框"样式,
+ **不代表前端已具备标准民族编码字典**。若后续其他表单需要"新增/编辑民族"的下拉选择能力,
+ 需后端补充标准民族码表。
+90. **职业(`occupation`)字段本次改为与"新增个人客户"页一致的 `OCCUPATION_TYPE_OPTIONS`
+ 下拉选择(此前个人开户表单该字段为自由文本框)**:该码表在 Part 7 第74条已记录为前端临时
+ 拟定的占位枚举,非后端真实标准职业分类码表,本条仅说明"个人开户"页面现已复用该占位码表,
+ 并非本次新增独立缺口;选择"其他"时新增的 `jobNote`(职业备注,选"其他"时必填)字段本身在
+ `create-draft` swagger 中已有文档定义,并非前端新增虚构字段。
+
+---
+
+## Part 11:钱包管理新增"个人开户申请"列表页(比照企业开户申请) —— 2026-07-23 补充
+
+> 产品侧要求"钱包管理"下比照已有的"企业开户申请"页面,新增一个独立的"个人开户申请"列表页
+> (`/wallet/personal-open`,原路径改为列表页入口,新增/编辑/查看拆分为 `/create`、`/edit`、
+> `/detail` 三个子路由),支持按申请编号/客户姓名/证件号/申请状态/创建时间/所属机构查询,并提供
+> 查看详情、编辑草稿(仅 `DRAFT` 状态)入口。但当前 swagger(`personal-opening` 分组)只有
+> `create-draft`/`query-customer`/`query-progress`/`mobile/*`,**没有对应企业开户
+> `enterprise-open-application/{list,detail,update}` 三件套的个人开户版本**,前端已按下述假设
+> 契约完成开发,mock-server 亦已同步实现,均需后端确认或补充真实接口。**此外(2026-07-23 排查
+> 补充)本页面涉及的菜单可见性问题不是接口契约缺口,而是后端权限字典/角色绑定的数据缺口,
+> 详见第92条**,两者需后端配合按顺序处理(先接口、后菜单)。
+
+91. **个人开户新增 `list`/`detail`/`update` 三个接口均由后端缺失,前端参照企业开户申请
+ (`enterprise-open-application/{list,detail,update}`)的契约形状自行假设实现**:
+ - `POST /api/wallet-management/personal-opening/list`:假设请求体含
+ `applicationNo`/`customerNameLike`(客户姓名模糊)/`certificateNumber`/`applicationStatus`/
+ `startDate`/`endDate`/`page`/`pageSize`/`orgId`,响应 `{total,page,pageSize,records}`,
+ `records` 内每项含 `applicationNo`/`customerName`/`certificateNumber`/`mobilePhone`/
+ `bankCardNumber`/`channelNo`/`applicationStatus`/`failReason`/`createdAt`/`updatedAt`。
+ - `POST /api/wallet-management/personal-opening/detail`:假设请求 `{applicationNo}`,响应
+ 字段在 `create-draft` 请求体(`accountProperty`/`customerId`/`certificateType`/
+ `certificateNumber`/`certificateEffectiveDate`/`certificateExpiryDate`/`issuingAuthority`/
+ `certificateAddress`/`gender`/`ethnic`/`occupation`/`jobNote`/`mobilePhone`/
+ `bankCardNumber`/`fileList` 等)基础上,补充开户结果相关字段
+ `applicationStatus`/`failReason`/`mainAccountNo`/`customerNo`/`createdAt`/`updatedAt`。
+ - `POST /api/wallet-management/personal-opening/update`:**与企业开户申请第23条同类问题**——
+ 由于 `create-draft` 本身不返回数字 `id`(只返回 `applicationNo`),前端假设 `update` 接口
+ 以 `applicationNo`(字符串)而非数字 `id` 定位记录,且仅允许 `DRAFT` 状态的记录可编辑提交;
+ 若后端实际接口要求数字 `id` 定位,或对已提交(非 `DRAFT`)状态的记录有不同的编辑限制,
+ 需后端确认后前端同步调整。**证件照片字段名与 `create-draft` 不同**:`create-draft` 用
+ `fileList`,而 `update` 后端要求用 `accountOpenApplicationFileBtoList`(2026-07-23 已按
+ 后端要求调整,`PersonalOpenForm.vue` 提交 update 时使用该字段名,mock-server 内部仍归一存回
+ `fileList` 以保证 `detail` 回显一致)。
+ - 上述三个接口 mock-server 已在 `mock-server/routes/wallet.js` 中同步实现(逻辑对齐
+ `enterprise-open-application` 同名接口的简化实现,详见该文件),仅用于本地演示,不代表
+ 真实后端契约,后端接口到位后需删除对应 mock 逻辑并以真实响应为准。
+92. **"个人开户申请"菜单在真实后端环境完全不可见,需后端在权限字典中补充菜单节点并绑定角色
+ (2026-07-23 排查确认,非前端 bug)**:本项目的菜单树**完全由后端 `GET /api/auth/user/
+ permission-detail` 接口驱动**(前端 `src/utils/permissionTreeBuilder.js` 只做按
+ `permissionType==='PAGE'` 过滤 + 按 `parentId` 建树,无任何本地白名单/枚举清单兜底),前端
+ 路由映射(`src/router/componentRegistry.js` 里 `/wallet/personal-open` 的组件映射)已就绪,
+ 但**真实后端的权限字典里从未创建过 `routePath='/wallet/personal-open'` 这个 PAGE 权限节点**
+ (历史原因:阶段4最初设计"个人开户"是从账户列表页"开户"弹窗跳转的非菜单路由,详见
+ `docs/superpowers/specs/2026-07-09-phase4-wallet-management-design.md`;本次 Part 11 才改造
+ 为独立菜单页,但改动仅停留在前端代码,未同步给后端)。需后端/运维在权限管理体系中新增一条
+ 记录并绑定到相应角色,字段参照如下(与"企业开户申请"节点保持同级同构):
+ - `permissionType`: `PAGE`
+ - `permissionName`: 个人开户申请
+ - `routePath`: `/wallet/personal-open`
+ - `parentId`: 与"企业开户申请"(`/wallet/enterprise-open`)节点相同的父节点(即"钱包管理"
+ 一级菜单在生产权限字典中的真实 id,需在生产"权限管理"页面查看后填入,本文档不臆造具体
+ 数值)
+ - `level`/`sortOrder`: 与"企业开户申请"节点同级,建议排在其后(sortOrder 更大)
+ - 创建后需在"角色管理"页面为需要使用本功能的角色勾选该权限节点并保存,否则即使权限字典
+ 里存在该记录,未绑定角色的用户仍看不到菜单。
+ - **强烈建议此步骤在本条目 91 所述的 `list`/`detail`/`update` 三个真实接口确认或补充完成
+ 之后再执行**:若先补齐菜单可见性、后端接口仍缺失,用户点击进入列表页会直接调用不存在的
+ 接口报错,体验上比"看不到入口"更差。
+