21 KiB
企业客户新增/编辑表单增强设计(基础信息必填订正 + 更多信息 + 股东高管信息重构 + 对外投资关系信息)
- 状态: 已与用户完成澄清问答,用户确认设计方向,直接进入 writing-plans
- 上级文档:
2026-07-09-phase3-customer-management-design.md(阶段3客户管理原始设计,本文档是对其"企业客户"部分的增补/局部覆盖) - 触发来源: 用户提供"客户管理 > 企业客户管理 > 新增企业客户"页面最新原型截图,要求:①订正基础字段必填属性;②基础信息下新增"更多信息"折叠区块;③"公司股东与高管信息"交互与字段按截图重做;④新增"对外投资关系信息"区块
- 直接对应文件:
src/views/customer/enterprise/EnterpriseForm.vue(唯一改动的表单组件)、src/api/customer.js、新增src/constants/enterpriseEnums.js、新增src/components/RegionCascader.vue、缺失的后端接口.md
0. 与既有设计的关系/参考先例
个人客户表单在 2026-07-20 已经做过同类改造(《缺失的后端接口.md》Part 7/8):产品截图要求的新字段在后端 swagger 里完全不存在时,前端策略是——按截图完整实现 UI 和交互,新字段用前端占位枚举,随 create/update 请求一并提交(后端会忽略未声明字段,不报错也不落库),同时把所有缺口逐条记录进《缺失的后端接口.md》,不因后端能力不足阻塞前端交付。本次企业客户表单改造延续同一策略,不再逐条与用户确认"要不要做",直接照此模式实现。
经与用户澄清确认的关键决策(详见下文各节引用):
- 省市区级联选择:引入静态省市区数据包(
china-division,仅取其dist/pca-code.json省市区三级数据),封装通用组件,不依赖后端。 - "公司股东与高管信息""对外投资关系信息"均支持新增多条记录,每条一张可删除的卡片。
- 股东高管卡片里国籍/性别/职业类型/联系电话/地址信息/客户编号,选中个人客户后只读回填,不可编辑覆盖。
- "是否法定代表人"改为按股东逐行勾选,同一时间最多一位,互斥。
- "对外投资关系信息"的"客户名称"只能选企业客户(不支持个人客户)。
1. 范围
包含:
EnterpriseForm.vue基础信息区必填属性订正、证件地址改为省市区级联+详细地址- 新增"更多信息"可折叠区块(公司级标量字段 + 联系信息表格 + 地址信息表格 + 若干是否布尔 + 备注)
- "股东与高管信息"由"只读表格+行内下拉"重构为"卡片列表"(可新增多条/单条删除),字段按截图扩展
- 新增"对外投资关系信息"卡片列表区块(全新概念,与股东高管信息平级)
- 新增枚举字典
src/constants/enterpriseEnums.js - 新增通用组件
src/components/RegionCascader.vue(省市区级联,供"证件地址"与"地址信息"表格复用) - 依赖新增:
china-division(仅用其静态 JSON 数据,不引入运行时逻辑) - 《缺失的后端接口.md》新增一节记录所有新增/扩展字段(编号从 79 开始,章节标题为
Part 9)
不包含:
- 不改动企业客户列表页
EnterpriseList.vue(用户需求未提及列表页) - 不新建"个人+企业通用选择器"——对外投资关系信息按用户确认只需企业客户选择,复用/扩展现有企业客户选择弹窗即可
- 不改动股东高管信息/对外投资关系信息在编辑/详情模式下的可用性限制原则:两者继续仅新增模式可编辑,编辑/详情模式沿用"仅支持新增时登记"提示文案(原因见第7节)
- 不引入省市区之外的国际地区数据(国家地区字段仅提供"中国/其他"二选,选"其他"时行政区划退化为自由文本,见 4.1 节)
2. 组件与文件清单
src/
components/
RegionCascader.vue # 新增:省市区级联选择器,基于 china-division 的 pca-code.json
constants/
enterpriseEnums.js # 新增:企业客户"更多信息"+股东高管+对外投资关系 涉及的全部占位/复用枚举
views/customer/enterprise/
EnterpriseForm.vue # 改造:基础信息必填订正、更多信息区块、股东高管信息重构、对外投资关系信息新增
api/customer.js # 不新增接口方法(仍是同一个 create/update),仅在 payload 组装处扩展字段
缺失的后端接口.md # 新增 Part 9
package.json # 新增依赖 china-division
RegionCascader.vue 设计:
- Props:
v-model:value(省市区 code 三元数组,如['330000','330100','330102'])、v-model:text(对应中文名以/连接的展示字符串,如"浙江省/杭州市/上城区",用于提交给后端的可读地址,因为后端目前是自由文本字段,不是 code) - 内部:
import pcaCode from 'china-division/dist/pca-code.json',转换为a-cascader所需的{value, label, children}结构(一次性转换,computed缓存) - 用
a-cascader :options="options" v-model:value="innerValue" change-on-select="false" />,change时同步计算text
3. 基础信息区改造
3.1 必填订正(对照截图逐项核对)
| 字段 | 现状 | 改为 |
|---|---|---|
| 证件照片(营业执照) | 无 required | 维持不必填(截图只有识别提示,无红星) |
| 所属机构 | 已必填 | 维持 |
| 企业名称 | 已必填 | 维持 |
| 营业执照号 | 仅格式校验,非必填 | 改为必填(格式校验规则保留) |
| 证件生效日期 | 无校验 | 改为必填 |
| 证件失效日期 | 无校验 | 改为必填,但勾选"长期"后可不填(复用个人客户 CERTIFICATE_LONG_TERM_DATE 哨兵日期方案,新增"长期"勾选框,交互与 PersonalForm.vue 的 certificateExpiryDate 校验规则完全一致) |
| 手机号码 | 仅格式校验,非必填 | 改为必填 |
| 证件地址 | 无校验,纯文本 | 改为必填,且改为"省市区级联 + 详细地址"两部分(见3.2) |
| 经营范围 | 无校验 | 改为必填 |
| 法定代表人 | 独立选择字段,非必填 | 删除该字段,改为股东高管卡片内"是否法定代表人"勾选(见5.4) |
3.2 证件地址结构调整
- 表单字段拆分为
certificateRegionCode(数组,不提交,仅本地级联控件绑定)、certificateRegionText(省市区文本)、certificateAddress(详细地址,复用现有字段名) - 提交时按后端现有字段
certificateAddress的自由文本约定,拼接为${certificateRegionText}${certificateAddress}(与现有个人客户/企业客户"证件地址"是单一自由文本字段的既有约定保持兼容,不新增后端字段;若后端后续拆分省市区结构化字段,见 Part 9 建议)
4. 更多信息区块(新增,<a-collapse>,默认展开,风格与 PersonalForm.vue 一致)
4.1 标量字段(挂载在企业主表单 form 上,提交时随 create/update 一起发送)
| 分组 | 字段(前端命名) | 类型/组件 | 枚举来源 |
|---|---|---|---|
| 单位性质 | unitNature |
select | enterpriseEnums.UNIT_NATURE_OPTIONS(占位) |
| 经济成分 | economicComposition |
select | ECONOMIC_COMPOSITION_OPTIONS(占位) |
| 机构类别 | institutionCategory |
select | INSTITUTION_CATEGORY_OPTIONS(占位,对应"登记注册类型") |
| 经济性质经营类型 | economicNature |
select | ECONOMIC_NATURE_OPTIONS(占位) |
| 国民经济门类 | nationalEconomyCategory |
select | NATIONAL_ECONOMY_CATEGORY_OPTIONS(采用 GB/T 4754 标准20门类真实分类,非占位) |
| 注册资本 + 币种 | registeredCapital + registeredCapitalCurrency |
input-number + select | 币种复用现有 CURRENCY_OPTIONS(如项目已有则复用,否则新增,默认"人民币") |
| 企业成立日期 | establishmentDate |
date-picker | - |
| 实收资本 + 币种 | paidInCapital + paidInCapitalCurrency |
input-number + select | 同上 |
| 上年末企业从业人员 | lastYearEmployeeCount |
input-number(单位:人次) | - |
| 上年末资产总额 | lastYearTotalAssets |
input-number | - |
| 上年营业收入 | lastYearRevenue |
input-number | - |
| 净资产 | netAssets |
input-number | - |
| 基本账户信息 | basicAccountBankName + basicAccountNumber |
input + input | - |
| 开户信息 | accountLicenseNumber + accountLicenseDate |
input + date-picker | - |
| 缴款卡号 | paymentCardNumber |
input | - |
| 企业规模 | enterpriseScale |
select | ENTERPRISE_SCALE_OPTIONS(采用工信部四级标准:大型/中型/小型/微型,非占位) |
| 外汇企业类型 | foreignExchangeEnterpriseType |
select | FOREIGN_EXCHANGE_ENTERPRISE_TYPE_OPTIONS(占位) |
| 人行金融机构编码 | pbocFinancialInstitutionCode |
input | - |
| 金融机构行业分类 | financialInstitutionIndustryType |
select | FINANCIAL_INSTITUTION_INDUSTRY_OPTIONS(占位) |
| 同业客户类型 | interbankCustomerType |
select | INTERBANK_CUSTOMER_TYPE_OPTIONS(占位) |
| 经营状态 | businessStatus |
select | BUSINESS_STATUS_OPTIONS(占位) |
| 客户状态 | customerStatus |
select,截图当前为空("暂无客户") | 复用个人客户 CUSTOMER_STATUS_OPTIONS(FORMAL/POTENTIAL) |
| 是否冰点客户 + 冰冻类型 | isFrozenCustomer(布尔) + frozenType(冰点=true时才可选) |
radio + select | FROZEN_TYPE_OPTIONS(占位) |
| 境内境外 | residencyArea |
radio | 复用 DOMESTIC/OVERSEAS(与个人客户一致命名) |
| 是否绿色企业 | isGreenEnterprise |
radio(布尔) | - |
| 是否集团客户 | isGroupCustomer |
radio(布尔) | - |
| 是否个体工商户 | isIndividualBusiness |
radio(布尔) | - |
| 是否上市公司 | isListedCompany |
radio(布尔) | - |
| 是否小微企业 | isSmallMicroEnterprise |
radio(布尔) | - |
| 是否科技企业 | isTechEnterprise |
radio(布尔) | - |
| 备注 | remark |
textarea | - |
全部标量字段均为非必填(截图无红星),默认值均为 undefined/false,不做前端强制校验。
4.2 联系信息表格(可增删行,交互模式复用现有"股东高管信息"表格的增删行写法)
- 数据模型
contactInfoList = ref([{ contactType: 'MOBILE', contactValue: '', isPrimary: true }])(默认一行,截图默认展示"移动电话") - 列:联系类型(select,
CONTACT_TYPE_OPTIONS:移动电话/固定电话/传真/电子邮箱/其他)、联系信息(input)、主要标志(select 是/否)、操作(删除链接,至少保留一行不可删空) - 提交字段名:
contactInfoBtoList
4.3 地址信息表格(可增删行)
- 数据模型
addressInfoList = ref([{ addressType: 'CERTIFICATE', country: 'CN', regionCode: [], regionText: '', detailAddress: '', isPrimary: true }])(默认一行"证件地址",国家默认中国) - 列:地址类型(select,
ADDRESS_TYPE_OPTIONS:证件地址/联系地址/注册地址/经营地址/其他)、国家地区(select:中国/其他,选"其他"时行政区划列切换为自由文本输入)、行政区划(复用RegionCascader.vue,仅当国家=中国时可用)、详细地址(input)、主要标志(select 是/否)、操作(删除) - 提交字段名:
addressInfoBtoList
5. 公司股东与高管信息(卡片列表重构)
5.1 交互变化
- 由"a-table 只读表格 + 行内 select"改为"卡片列表":每条已添加的关联人渲染为一张
<a-card>,卡片内是完整字段表单;区块标题右侧"+"按钮点击后打开PersonalCustomerPicker选人,选中后在列表末尾追加一张新卡片;每张卡片右上角"删除"按钮移除该卡片(relatedPersonList.value.splice(index,1)) - 沿用现状:仅新增模式(
isCreate)展示且可编辑;编辑/详情模式展示提示文案(原因:后端enterpriseRelatedPersonBtoList只存在于CreateEnterpriseCustomerBto,Update/Detail均无此字段,见现有设计文档第7节能力缺口8,本次不改变这一限制)
5.2 卡片字段(选中个人客户后只读回填 vs 可编辑,严格按截图区分)
只读回填字段(选中个人客户后从其详情快照,不可编辑,与现状"证件类型/号码/生效日/到期日"一致处理):
- 证件类型、证件号码、证件生效日期、证件失效日期(现状已有,保持不变)
- 国籍(
nationality)、性别(gender)、职业类型(occupationType,展示时用个人客户模块OCCUPATION_TYPE_OPTIONS反查中文标签)、联系电话(mobilePhone)、地址信息(certificateAddress)、客户编号(customerCode)——均来自选中个人客户的detail接口返回(个人客户 2026-07-20 已扩展这些字段,若后端尚未实现则显示为空,不是缺陷)
可编辑字段(卡片内表单项):
- 是否法定代表人:
isLegalRepresentative(radio 是/否)。互斥规则:任一卡片勾选"是"时,其余所有卡片自动置为"否"(前端本地维护,提交时取值为true的那一条的individualId作为顶层legalRepresentativeId提交,若无人勾选则legalRepresentativeId为空) - 关联人类型:
relatedType(现状已有:股东/高管/受益所有人) - 职务:
position(select,enterpriseEnums.POSITION_OPTIONS,复用后端真实已有字段position) - 任职时间:
positionStartDate(date-picker,新增) - 相关行业从业年限:
industryYears(input-number,新增) - 持股状况:
shareholdingRatio(input-number + %,复用后端真实已有字段shareholdingRatio) - 出资相关:出资方式
contributionMethod(select,CONTRIBUTION_METHOD_OPTIONS:货币/实物/知识产权/土地使用权/其他)+ 币种contributionCurrency(默认人民币)+ 应出资金额subscribedAmount+ 实际出资金额paidAmount+ 出资比例contributionRatio(%,与"持股状况"含义不同——持股比例是最终股权占比,出资比例是本次出资占应出资总额的比例,两个字段都保留)+ 出资日期contributionDate - 备注:
remark(新增)
只读展示,不可编辑,不提交:
- 关联客户编号:固定展示"暂无关联客户编号"(新增卡片时后端尚未生成该关系记录的编号,无实际数据来源,纯展示占位,不对应任何提交字段)
5.3 数据模型与提交字段扩展
relatedPersonList 每项字段从现状 {individualId, customerName, relatedType, certificateType, certificateNumber, certificateEffectiveDate, certificateExpiryDate} 扩展为新增:nationality, gender, occupationType, mobilePhone, certificateAddress, customerCode(以上6项均为选人后只读快照,来自个人客户 detail 接口返回值,取不到则留空)+ isLegalRepresentative, position, positionStartDate, industryYears, shareholdingRatio, contributionMethod, contributionCurrency, subscribedAmount, paidAmount, contributionRatio, contributionDate, remark(以上均为用户可编辑项)
提交时 enterpriseRelatedPersonBtoList 逐项组装,在现有5个字段基础上追加:position, shareholdingRatio, nationality, contactPhone(取mobilePhone), positionStartDate, industryYears, contributionMethod, contributionCurrency, subscribedAmount, paidAmount, contributionRatio, contributionDate, remark(nationality/contactPhone/position/shareholdingRatio 是后端 swagger 已声明的真实字段,其余是新增待后端确认的字段,见 Part 9)。gender/occupationType/certificateAddress/customerCode 仅用于页面展示,不重复提交(它们是个人客户自身的属性,不属于"企业-关联人关系"这层数据,提交这些字段没有业务意义)。
6. 对外投资关系信息(全新区块,卡片列表)
6.1 交互
- 与"股东与高管信息"完全相同的卡片列表交互:标题右侧"+"打开企业客户选择弹窗 → 选中后追加卡片 → 每卡片可删除
- 选择器:企业客户选择只能选企业客户(用户已确认),复用现有企业客户列表查询能力封装一个
EnterpriseCustomerPicker.vue(仿照PersonalCustomerPicker.vue的结构,内部用 miniProTable查询fetchEnterpriseCustomerPageApi,查询条件:企业名称/营业执照号/手机号,与EnterpriseList.vue现有查询字段一致) - 仅新增模式(
isCreate)展示且可编辑;编辑/详情模式展示提示文案"对外投资关系信息仅支持新增时登记,当前接口不支持查询或修改,如需变更请联系技术支持核实数据"(与股东高管信息保持一致的处理原则,理由:该结构在后端 swagger 中完全不存在,无法验证 update/detail 是否可回显,为避免"编辑时列表总是空"造成用户误以为数据丢失,统一按"仅新增可编辑"处理,与已有股东高管信息处理原则保持一致)
6.2 卡片字段
选中企业客户后只读回填:
- 证件类型(固定"营业执照")、证件号码(企业营业执照号)、失效时间(证件到期日)
可编辑字段:
- 持股状况:
shareholdingRatio(%,本企业持有被投资企业的股权比例) - 出资相关:出资方式
contributionMethod+ 币种contributionCurrency(默认人民币)+ 应出资金额subscribedAmount+ 实际出资金额paidAmount+ 出资比例contributionRatio(%)+ 出资日期contributionDate - 出资人经济成分:
investorEconomicComposition(select,复用 4.1 节ECONOMIC_COMPOSITION_OPTIONS) - 关系类型:
relationType(select,INVESTMENT_RELATION_TYPE_OPTIONS:控股/参股/联营/合营/其他) - 是否有效:
isValid(radio 是/否,默认是) - 关系到期时间:
relationExpiryDate(date-picker) - 备注:
remark
只读展示,不提交:
- 关联客户编号:固定展示"暂无关联客户编号"(同 5.2 节说明)
6.3 数据模型与提交字段
新增 investmentList = ref([]),每项:{investeeEnterpriseId, investeeName, certificateType, certificateNumber, certificateExpiryDate, shareholdingRatio, contributionMethod, contributionCurrency, subscribedAmount, paidAmount, contributionRatio, contributionDate, investorEconomicComposition, relationType, isValid, relationExpiryDate, remark}
提交字段名:enterpriseInvestmentBtoList(全新数组,后端完全没有对应结构,见 Part 9 建议)
7. 编辑/详情模式统一处理原则
relatedPersonList(股东高管信息)与新增的 investmentList(对外投资关系信息)在编辑/详情模式下均替换为提示文案,不渲染卡片列表与"+"按钮,理由统一为:
- 股东高管信息:已确认的既有限制,
Update/DetailBto/Vo 均无该数组字段 - 对外投资关系信息:后端完全没有此结构,无法确认 update/detail 是否支持,为避免行为不一致与用户误解,统一按同一限制处理
"更多信息"区块的标量字段(单位性质、经济成分……备注)以及联系信息/地址信息表格,在编辑模式下仍可编辑并随 update 提交(与股东高管/对外投资关系不同处理),理由:这些是挂载在企业主体 Bto/Vo 上的字段/子结构,一旦后端补充,天然会随 detail/update 一起生效,不存在"仅 Create Bto 独有数组字段"这种结构性限制,处理方式与个人客户 2026-07-20 改造的"更多信息"标量字段完全一致。
8. 表单校验补充
新增必填规则(3.1节已列出字段),证件失效日期沿用个人客户 certificateLongTerm 校验模式(勾选长期后不强制填日期,否则必填)。"更多信息"、联系信息/地址信息表格、股东高管卡片扩展字段、对外投资关系信息全部字段均不做前端必填校验(截图均无红星标注)。
9. 《缺失的后端接口.md》记录内容(Part 9,编号从79开始)
新增章节 ## Part 9:企业客户新增表单"更多信息"/股东高管信息扩展/对外投资关系信息 —— 2026-07-21 补充,按 Part 7 的行文格式,分条记录:
CreateEnterpriseCustomerBto/UpdateEnterpriseCustomerBto/EnterpriseCustomerDetailVo需扩展 4.1 节列出的约30个标量字段(逐项列出字段名/类型/枚举来源,标注哪些是真实标准分类[国民经济门类/企业规模]、哪些是前端占位)- 建议新增
contactInfoBtoList(联系信息)、addressInfoBtoList(地址信息)两个子数组结构 EnterpriseRelatedPersonBto需在已有position/shareholdingRatio/nationality/contactPhone基础上补充positionStartDate/industryYears/contributionMethod/contributionCurrency/subscribedAmount/paidAmount/contributionRatio/contributionDate/remark等新字段,并说明gender/occupationType/certificateAddress/customerCode属于个人客户自身字段、前端不重复提交- 全新结构建议:
enterpriseInvestmentBtoList(对外投资关系),列出完整字段清单,并说明当前无法确认 update/detail 是否可回显,前端按"仅新增模式可用"处理 - "证件地址"由自由文本拆分省市区+详细地址是纯前端展示层拼接(省市区数据来自静态npm包
china-division,不依赖后端),建议后端后续可考虑拆分省市区结构化字段,但非阻塞项 - "是否法定代表人"由股东逐行勾选互斥决定,提交时仍复用已有的顶层
legalRepresentativeId字段,后端无需改动
10. 自查(占位符/矛盾/歧义/范围)
- 全文无 "TBD/待定" 类占位符;标注"占位枚举/待确认"的字段均已给出前端拟定的具体可用值,不是留白
- 第7节明确区分了"标量字段随 update 提交"与"数组字段仅新增可用"两类字段的不同处理原则,与第5/6节的处理方式一致,无矛盾
- 范围严格对应用户截图与4个明确诉求(必填订正/更多信息/股东高管信息/对外投资关系信息),未扩展到列表页或其它模块
- 与用户澄清问答的5个决策结论均已在对应章节体现(0节已汇总引用),无冲突
设计自查通过,进入 writing-plans 生成实施计划。