plan-form-schema-usage.md
7.82 KB
计划书表单 Schema 使用文档
1. 文档目标
用于说明计划书表单的 Schema 配置规范、字段类型、联动规则与提交映射,便于后续新增或扩展不同保险类型时快速落地。
2. 核心思路
- 统一由 Schema 描述字段渲染、校验与联动
- 统一由 submit_mapping 处理字段到 API 字段的映射与金额转换
- 模板组件只负责“渲染与校验”,不再硬编码字段逻辑
3. Schema 结构
// Schema 基础结构
const form_schema = {
// 基础字段
base_fields: [
{
id: 'customer_name',
key: 'customer_name',
type: 'name',
label: '申请人',
placeholder: '请输入申请人',
required: true
}
],
// 提取计划字段(可选)
withdrawal_fields: [],
// 联动清空规则(可选)
reset_map: {}
}
4. 字段类型说明
| type | 组件 | 说明 |
|---|---|---|
| name | NameInput | 姓名输入 |
| radio | RadioGroup | 单选 |
| date | DatePickerGlobal | 日期选择 |
| amount | AmountKeyboard | 金额键盘输入(内部存分) |
| age | AgePickerGlobal | 年龄选择 |
| select | SelectPickerGlobal | 下拉选择 |
| payment_period | PaymentPeriodRadio | 缴费年期 |
| percentage | NutInput | 百分比输入 |
5. 字段属性说明
// 字段属性示例
{
id: 'coverage',
key: 'coverage',
type: 'amount',
label: '年缴保费',
placeholder: '请输入年缴保费',
input_label: '请输入年缴保费金额',
required: true,
// 可从配置读取币种
currency_from: 'currency',
// 控制显示条件
show_when: [{ field: 'withdrawal_mode', equals: '指定提取金额' }],
// 默认值
default: '否',
// 标题分组
section_title: '款项提取(允许减少名义金额)'
}
6. 联动规则与清空逻辑
// 提取模式切换后,按规则清空脏字段
const reset_map = {
withdrawal_mode: {
'最高固定提取金额': ['annual_withdrawal_amount', 'annual_increase_percentage', 'withdrawal_start_age', 'withdrawal_period'],
'指定提取金额': ['withdrawal_start_age', 'withdrawal_period']
}
}
7. 提交字段映射
// submit_mapping 示例(金额字段统一从分转元)
const submit_mapping = {
coverage: { api_field: 'annual_premium', transform: 'fen_to_yuan' },
annual_withdrawal_amount: { api_field: 'annual_withdrawal_amount', transform: 'fen_to_yuan' },
withdrawal_mode: { api_field: 'withdrawal_option' }
}
8. 使用示例
<!-- 储蓄型模板使用示例 -->
<template>
<SavingsTemplate v-model="form_data" :config="template_config" />
</template>
<script setup>
// 表单数据
const form_data = ref({})
// 模板配置(通常来自 plan-templates.js)
const template_config = {
currency: 'USD',
payment_periods: ['整付', '5 年'],
withdrawal_plan: {
enabled: true,
default_currency: 'USD',
withdrawal_periods: ['1年', '2年', '终身']
},
form_schema: {},
submit_mapping: {}
}
</script>
8.1 人寿/重疾模板使用示例
<template>
<LifeInsuranceTemplate v-model="form_data" :config="template_config" />
</template>
<script setup>
const form_data = ref({})
const template_config = {
currency: 'USD',
payment_periods: ['整付(0-75 岁)', '5 年(0-70 岁)'],
form_schema: protectionFormSchema,
submit_mapping: baseSubmitMapping
}
</script>
9. 新增保险类型流程
- 在
src/config/plan-templates.js新增产品项(配置 form_sn) - 为该产品选择已有模板组件或新增模板组件
- 定义
form_schema与submit_mapping - 在模板组件内使用 Schema 渲染(仅需接入通用逻辑)
- 验证校验与提交映射
10. 新增产品配置示例
// 示例:新增储蓄类产品配置
'savings-new': {
name: '示例储蓄产品',
component: 'SavingsTemplate',
category: 'savings',
config: {
currency: 'USD',
payment_periods: ['整付', '5 年'],
withdrawal_plan: {
enabled: true,
default_currency: 'USD',
withdrawal_periods: ['1年', '2年', '终身']
},
form_schema: savingsFormSchema,
submit_mapping: savingsSubmitMapping
}
}
// 示例:新增人寿/重疾类产品配置
'life-insurance-new': {
name: '示例人寿产品',
component: 'LifeInsuranceTemplate',
config: {
currency: 'USD',
payment_periods: ['整付(0-75 岁)'],
form_schema: protectionFormSchema,
submit_mapping: baseSubmitMapping
}
}
11. 常见扩展点
- 新字段:仅在 form_schema 增加字段并补充 submit_mapping
- 新联动:在 show_when 与 reset_map 中定义条件
- 新模板:复用现有字段组件,保持 schema 结构一致
12. 计划书模块入口与配置地图
12.1 页面入口
- 产品详情:
src/pages/product-detail/index.vue(按钮打开计划书弹窗) - 产品中心:
src/pages/product-center/index.vue(列表内“计划书”按钮) - 搜索页:
src/pages/search/index.vue(搜索结果卡片“计划书”按钮) - 计划书列表:
src/pages/plan/index.vue(查看/删除计划书) - 提交结果页:
src/pages/plan-submit-result/index.vue
12.2 组件与模板
- 弹窗容器:
src/components/plan/PlanPopupNew.vue - 计划书容器:
src/components/plan/PlanFormContainer.vue - 模板组件:
src/components/plan/PlanTemplates/LifeInsuranceTemplate.vuesrc/components/plan/PlanTemplates/CriticalIllnessTemplate.vuesrc/components/plan/PlanTemplates/SavingsTemplate.vue
- 字段组件:
src/components/plan/PlanFields/*
12.3 配置与数据处理
- 模板映射:
src/config/plan-templates.js - 字段定义与映射:
src/config/plan-fields.js - 字段转换函数:
src/utils/planFieldTransformers.js - 字段转换入口:
src/composables/useFieldValueTransform.js - 字段联动规则:
src/composables/useFieldDependencies.js - 字段校验工具:
src/utils/planFieldValidation.js - 订单状态常量:
src/config/constants/orderStatus.js
12.4 API 入口
- 计划书 API:
src/api/plan.js- 新增:
addAPI - 列表:
listAPI - 删除:
deleteAPI - 查看:
viewAPI
- 新增:
12.5 技术书/附件预览关联
- 产品详情附件列表:
src/pages/product-detail/index.vue - 文件预览能力:
src/composables/useFileOperation.js
13. 计划书模块使用流程
- 产品详情/产品中心/搜索页获取产品对象(至少包含
id与form_sn,可选plan_config) - 打开
PlanFormContainer并传入product -
PlanFormContainer根据form_sn从plan-templates选择模板并合并plan_config - 模板组件基于
form_schema渲染字段,调用自身validate完成校验 - 提交时使用
submit_mapping生成请求参数,并通过addAPI提交 - 提交完成后通过
usePlanSubmit跳转到提交结果页 - 在计划书列表中用
listAPI拉取数据,使用viewAPI标记为已查看
14. 计划书容器使用示例
<template>
<PlanFormContainer
v-model:visible="show_plan_popup"
:product="selected_product"
@close="show_plan_popup = false"
@submit="handle_plan_submit"
/>
</template>
<script setup>
import { ref } from 'vue'
import PlanFormContainer from '@/components/plan/PlanFormContainer.vue'
import { usePlanSubmit } from '@/composables/usePlanSubmit'
const show_plan_popup = ref(false)
const selected_product = ref(null)
const { handlePlanSubmit: handle_plan_submit } = usePlanSubmit({
getPopupState: () => show_plan_popup.value,
setPopupState: (state) => { show_plan_popup.value = state },
pageName: 'Plan Entry'
})
</script>