多阶段提取方案设计.md
23.9 KB
多阶段提取方案设计文档
创建时间: 2026-02-25 状态: ⏳ 待客户确认需求 设计师: Claude Code 版本: 1.1.0 更新内容: 新增需求说明章节,辨析多阶段与多方案概念
📋 目录
📖 需求说明(待客户确认)
重要说明:以下是我们对客户资料的理解分析,请客户确认实际需求。
概念辨析:多阶段 vs 多方案
客户提供的资料中出现了两个容易混淆的概念,需要明确区分:
1️⃣ 多阶段提取(Multi-Stage Withdrawal)
定义:一个提取方案中,包含多个不同阶段的提取计划。
示例(3岁小公主 - 方案一):
同一个方案内的三个阶段:
├─ 第一阶段:18-21岁,每年5万(教育基金)
├─ 第二阶段:30岁,一笔过40万(创业金/婚嫁金)
└─ 第三阶段:50-100岁,每年7万(退休养老年金)
特点:
- ✅ 这是一个方案
- ✅ 包含多个提取阶段
- ✅ 每个阶段针对不同人生阶段的需求
2️⃣ 多方案(Multiple Scenarios)
定义:同一份计划书中,展示多个备选提取方案供客户选择。
示例(3岁小公主 - 3个方案):
方案一:多阶段分时提取
└─ 教育(18-21岁) + 创业(30岁) + 退休(50-100岁)
方案二:长期定期提取
└─ 9-100岁,每年1.75万
方案三:财富传承
└─ 不提取,展示保单价值增长表
特点:
- ✅ 这是三个独立的方案
- ✅ 每个方案代表不同的提取策略
- ✅ 客户可以在方案之间对比选择
对比总结
| 维度 | 多阶段 | 多方案 |
|---|---|---|
| 是什么 | 一个方案内的多个提取阶段 | 多个独立的备选方案 |
| 为什么 | 满足不同人生阶段的资金需求 | 提供不同风险/收益的提取策略 |
| 数据量 | 1个方案,3-5个阶段 | 3个方案,每个方案可能有多个阶段 |
| 客户选择 | 无需选择,按阶段执行 | 客户需要选择采用哪个方案 |
需要客户确认的问题
问题 1:是否需要多阶段提取?
说明:是否需要在一个方案中设置多个提取阶段(如:教育→创业→退休)?
- 是,需要多阶段提取
- 否,每个方案只需要一种提取方式
问题 2:是否需要多方案?
说明:是否需要在同一份计划书中展示多个备选方案供客户选择?
- 是,需要多方案对比(如:保守方案 vs 积极方案 vs 传承方案)
- 否,每个客户只需要一个方案
问题 3:实施方案选择
如果需要多方案,请选择实施方案:
选项 A:单次提交,多方案对比
- 优点:一次性输入多个方案,计划书可直接对比展示
- 缺点:需要后端改动支持,开发周期较长
选项 B:多次提交,分别生成(推荐)
- 优点:复用现有逻辑,无需后端改动,快速上线
- 缺点:每个方案单独生成,需要人工对比
选项 C:混合方案
- 第一阶段:先实现选项B(快速上线)
- 第二阶段:再升级为选项A(完整体验)
需求背景
客户文档中的提取方案
根据客户提供的储蓄类保险文档,提取方案主要分为三种模式:
| 模式 | 描述 | 示例 |
|---|---|---|
| 模式 A:分阶段提取 | 多个不同年龄段提取不同金额 | 18-21岁教育基金 + 30岁创业金 + 50-100岁退休金 |
| 模式 B:定期定额 | 从某年龄开始每年固定金额 | 43-100岁每年3.75万美金 |
| 模式 C:一笔过/传承 | 在特定年龄一次性全额提取("一笔过"=一次性提取) | 30岁一次性提取40万(创业金/婚嫁金) |
核心差异
现有系统:仅支持单阶段定期提取
客户需求:支持多阶段分时提取(教育+创业+退休组合)
现状分析
现有系统字段
// 单阶段提取字段
withdrawal_enabled: '是' | '否'
withdrawal_mode: '指定提取金额' | '最高固定提取金额'
withdrawal_method: '按年岁'
withdrawal_start_age: 18
withdrawal_period: '10年'
annual_withdrawal_amount: 50000
annual_increase_percentage: 5
支持情况对比
| 提取模式 | 现有系统支持 | 匹配度 |
|---|---|---|
| 模式 A:分阶段提取 | ❌ 不支持 | 0% |
| 模式 B:定期定额 | ✅ 完全支持 | 100% |
| 模式 C:一笔过(一次性提取) | ⚠️ 部分支持(需手动设置开始=结束年龄) | 50% |
方案设计
核心思路
提取模式二选一:
- 单阶段定期提取(现有逻辑)- 退休年金计划
- 多阶段分时提取(新增)- 教育+创业+退休组合
设计原则
- ✅ 向后兼容:不影响现有单阶段提取功能
- ✅ 纯前端实现:不依赖后端改动
- ✅ 用户友好:提供预设方案快速填充
- ✅ 灵活扩展:支持1-5个阶段自定义
数据结构
表单数据结构
formData = {
// ========== 基础字段(不变) ==========
customer_name: '张三',
gender: '男',
birthday: '1990-01-01',
smoker: '否',
age: 30,
coverage: 50000,
payment_period: '5 年',
// ========== 提取计划入口字段 ==========
withdrawal_enabled: '是',
withdrawal_mode: '多阶段分时提取', // '单阶段定期提取' | '多阶段分时提取'
// ========== 单阶段提取字段(现有逻辑复用) ==========
withdrawal_method: '按年岁',
withdrawal_start_age_single: 60,
withdrawal_period_single: '10年',
annual_withdrawal_amount_single: 30000,
annual_increase_percentage: 5,
// ========== 多阶段提取字段(新增) ==========
withdrawal_stages: [
{
stage_id: 1,
stage_name: '教育基金', // 阶段名称
start_age: 18, // 开始年龄
end_age: 21, // 结束年龄(开始=结束表示一笔过)
withdrawal_type: '每年提取', // '每年提取' | '一笔过'
annual_amount: 50000, // 每年金额
lump_sum_amount: null, // 一笔过金额
increase_rate: null // 递增百分比(可选)
},
{
stage_id: 2,
stage_name: '创业金/婚嫁金',
start_age: 30,
end_age: 30, // 开始=结束表示一笔过
withdrawal_type: '一笔过',
annual_amount: null,
lump_sum_amount: 400000,
increase_rate: null
},
{
stage_id: 3,
stage_name: '退休养老年金',
start_age: 50,
end_age: 100,
withdrawal_type: '每年提取',
annual_amount: 70000,
lump_sum_amount: null,
increase_rate: null
}
]
}
字段说明
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
stage_id |
Number | 阶段唯一标识 | Date.now() |
stage_name |
String | 阶段名称 | "教育基金" |
start_age |
Number | 开始年龄 | 18 |
end_age |
Number | 结束年龄 | 21 |
withdrawal_type |
String | 提取方式 | "每年提取" / "一笔过" |
annual_amount |
Number | 每年金额(分) | 5000000 |
lump_sum_amount |
Number | 一笔过金额(分) | 40000000 |
increase_rate |
String | 递增百分比 | "5" |
提取方式说明
"一笔过" = 一次性提取
- 客户术语"一笔过"即"一次性提取"的意思
- 当选择"一笔过"时,用户只需输入开始年龄,无需输入结束年龄
- 示例:30岁一次性提取40万(创业金/婚嫁金)
- 数据表示:
start_age = 30, end_age = 30, withdrawal_type = '一笔过'
"每年提取" = 分期定期提取
- 在指定年龄段内,每年固定提取一定金额
- 示例:18-21岁每年提取5万(教育基金,共4年)
- 数据表示:
start_age = 18, end_age = 21, withdrawal_type = '每年提取'
组件设计
新增组件:WithdrawalStagesEditor.vue
文件位置:src/components/plan/PlanFields/WithdrawalStagesEditor.vue
功能描述:
- 多阶段提取计划编辑器
- 支持添加/删除阶段(1-5个)
- 可折叠卡片展示
- 预设方案快速填充
组件结构:
WithdrawalStagesEditor
├── 阶段卡片列表(v-for)
│ ├── 阶段头部(可点击折叠)
│ │ ├── 阶段标题
│ │ └── 折叠图标
│ └── 阶段内容
│ ├── 阶段名称输入
│ ├── 开始年龄选择器
│ ├── 结束年龄选择器(一笔过时隐藏)
│ ├── 提取方式单选(每年/一笔过)
│ ├── 每年金额输入(每年提取时显示)
│ ├── 一笔过金额输入(一笔过时显示)
│ ├── 递增百分比输入(可选)
│ └── 删除按钮(至少保留1个)
├── 添加阶段按钮(<5个时显示)
└── 快速填充预设方案
├── 教育+创业+退休
├── 退休年金
└── 财富传承
组件接口:
// Props
props: {
modelValue: {
type: Array,
default: () => []
},
currency: {
type: String,
default: 'USD'
}
}
// Events
emits: ['update:modelValue']
// 预设方案模板
presetTemplates = [
{
id: 'education_marriage_retirement',
name: '教育+创业+退休',
stages: [
{ stage_name: '教育基金', start_age: 18, end_age: 21, ... },
{ stage_name: '创业金/婚嫁金', start_age: 30, end_age: 30, ... },
{ stage_name: '退休养老年金', start_age: 50, end_age: 100, ... }
]
}
]
Schema 配置
配置文件位置
src/config/plan-templates.js
Schema 扩展
const savingsFormSchema = {
base_fields: [
// ... 现有基础字段
],
withdrawal_fields: [
// === 入口字段(是否启用提取) ===
{
id: 'withdrawal_enabled',
key: 'withdrawal_enabled',
type: 'radio',
label: '是否希望生成一份允许减少名义金额的提取说明?',
options: ['是', '否'],
required: true,
default: '否'
},
// === 提取模式选择(二选一) ===
{
id: 'withdrawal_mode',
key: 'withdrawal_mode',
type: 'radio',
label: '提取模式',
options: ['单阶段定期提取', '多阶段分时提取'],
required: true,
default: '单阶段定期提取',
section_title: '款项提取(允许减少名义金额)',
show_when: { field: 'withdrawal_enabled', op: 'eq', value: '是' },
clear_when_hidden: true
},
// ========== 单阶段字段(现有逻辑) ==========
{
id: 'withdrawal_method',
key: 'withdrawal_method',
type: 'radio',
label: '提取方式',
options: ['按年岁'],
required: true,
default: '按年岁',
show_when: {
op: 'AND',
conditions: [
{ field: 'withdrawal_enabled', op: 'eq', value: '是' },
{ field: 'withdrawal_mode', op: 'eq', value: '单阶段定期提取' }
]
},
clear_when_hidden: true
},
{
id: 'withdrawal_start_age_single',
key: 'withdrawal_start_age_single',
type: 'age',
label: '由几岁开始',
placeholder: '请输入开始提取年龄',
required: true,
show_when: {
op: 'AND',
conditions: [
{ field: 'withdrawal_enabled', op: 'eq', value: '是' },
{ field: 'withdrawal_mode', op: 'eq', value: '单阶段定期提取' }
]
},
clear_when_hidden: true
},
{
id: 'withdrawal_period_single',
key: 'withdrawal_period_single',
type: 'select',
label: '提取期(年)',
placeholder: '请选择提取期',
required: true,
options_from: 'withdrawal_plan.withdrawal_periods',
show_when: {
op: 'AND',
conditions: [
{ field: 'withdrawal_enabled', op: 'eq', value: '是' },
{ field: 'withdrawal_mode', op: 'eq', value: '单阶段定期提取' }
]
},
clear_when_hidden: true
},
{
id: 'annual_withdrawal_amount_single',
key: 'annual_withdrawal_amount_single',
type: 'amount',
label: '每年提取金额',
placeholder: '请输入每年提取金额',
input_label: '请输入每年提取金额',
required: true,
currency_from: 'withdrawal_plan.default_currency',
show_when: {
op: 'AND',
conditions: [
{ field: 'withdrawal_enabled', op: 'eq', value: '是' },
{ field: 'withdrawal_mode', op: 'eq', value: '单阶段定期提取' }
]
},
clear_when_hidden: true
},
{
id: 'annual_increase_percentage',
key: 'annual_increase_percentage',
type: 'percentage',
label: '每年递增提取之百分比(%)',
placeholder: '请输入递增百分比',
required: false,
show_when: {
op: 'AND',
conditions: [
{ field: 'withdrawal_enabled', op: 'eq', value: '是' },
{ field: 'withdrawal_mode', op: 'eq', value: '单阶段定期提取' }
]
},
clear_when_hidden: true
},
// ========== 多阶段字段(新增) ==========
{
id: 'withdrawal_stages',
key: 'withdrawal_stages',
type: 'multi_stage',
label: '分阶段提取计划',
required: true,
show_when: {
op: 'AND',
conditions: [
{ field: 'withdrawal_enabled', op: 'eq', value: '是' },
{ field: 'withdrawal_mode', op: 'eq', value: '多阶段分时提取' }
]
},
clear_when_hidden: true
}
]
}
字段映射
API 提交映射
const savingsSubmitMapping = {
...baseSubmitMapping,
// 提取计划入口
withdrawal_enabled: { api_field: 'allow_reduce_amount' },
withdrawal_mode: { api_field: 'withdrawal_mode' }, // 'single' | 'multi'
// 单阶段字段映射
withdrawal_method: { api_field: 'withdrawal_method' },
withdrawal_start_age_single: { api_field: 'withdrawal_start_age' },
withdrawal_period_single: { api_field: 'withdrawal_period' },
annual_withdrawal_amount_single: {
api_field: 'annual_withdrawal_amount',
transform: 'fen_to_yuan'
},
annual_increase_percentage: { api_field: 'annual_increase_percentage' },
// 多阶段字段映射(新增)
withdrawal_stages: {
api_field: 'withdrawal_stages_json',
transform: (value) => {
// 将数组转为 JSON 字符串提交
return JSON.stringify(value.map(stage => ({
stage_name: stage.stage_name,
start_age: stage.start_age,
end_age: stage.end_age,
withdrawal_type: stage.withdrawal_type,
annual_amount: stage.annual_amount ? stage.annual_amount / 100 : null, // 分转元
lump_sum_amount: stage.lump_sum_amount ? stage.lump_sum_amount / 100 : null,
increase_rate: stage.increase_rate
})))
}
}
}
实施清单
开发任务
| 序号 | 任务 | 文件 | 工作量 |
|---|---|---|---|
| 1 | 创建多阶段编辑器组件 | src/components/plan/PlanFields/WithdrawalStagesEditor.vue |
2-3小时 |
| 2 | 更新 Schema 配置 | src/config/plan-templates.js |
30分钟 |
| 3 | 注册新组件类型 | src/components/plan/PlanTemplates/SavingsTemplate.vue |
15分钟 |
| 4 | 更新字段映射 | src/config/plan-templates.js |
15分钟 |
| 5 | 表单校验逻辑 |
SavingsTemplate.vue validate() |
30分钟 |
| 6 | 测试调试 | - | 1小时 |
总工作量:约 4-5 小时
组件代码框架
<!-- WithdrawalStagesEditor.vue -->
<template>
<div class="withdrawal-stages-editor">
<!-- 阶段卡片列表 -->
<div v-for="(stage, index) in stages" :key="stage.stage_id" class="stage-card">
<div class="stage-header" @click="toggleCollapse(index)">
<span class="stage-title">阶段 {{ index + 1 }}: {{ stage.stage_name || '未命名' }}</span>
<span class="collapse-icon">{{ collapsed[index] ? '▼' : '▲' }}</span>
</div>
<div v-show="!collapsed[index]" class="stage-content">
<!-- 阶段名称 -->
<nut-input v-model="stage.stage_name" label="阶段名称" placeholder="如:教育基金、创业金" />
<!-- 开始/结束年龄 -->
<PlanFieldAgePicker v-model="stage.start_age" label="开始年龄" :required="true" />
<PlanFieldAgePicker v-if="stage.withdrawal_type !== '一笔过'" v-model="stage.end_age" label="结束年龄" :required="true" />
<!-- 提取方式 -->
<PlanFieldRadio v-model="stage.withdrawal_type" label="提取方式" :options="['每年提取', '一笔过']" :required="true" />
<!-- 金额输入 -->
<PlanFieldAmount v-if="stage.withdrawal_type === '每年提取'" v-model="stage.annual_amount" label="每年提取金额" :currency="currency" :required="true" />
<PlanFieldAmount v-if="stage.withdrawal_type === '一笔过'" v-model="stage.lump_sum_amount" label="提取金额" :currency="currency" :required="true" />
<!-- 删除按钮 -->
<nut-button v-if="stages.length > 1" type="danger" size="small" @click="removeStage(index)">
删除此阶段
</nut-button>
</div>
</div>
<!-- 添加阶段按钮 -->
<nut-button v-if="stages.length < 5" type="primary" block @click="addStage">
+ 添加提取阶段
</nut-button>
<!-- 快速填充 -->
<div class="preset-templates">
<div class="text-sm text-gray-700 mb-2">快速填充:</div>
<nut-button v-for="template in presetTemplates" :key="template.id" size="small" @click="applyTemplate(template)">
{{ template.name }}
</nut-button>
</div>
</div>
</template>
多方案需求分析
说明:如果客户确认需要多方案功能,以下是技术实施建议。
现有系统能力评估
| 功能 | 现有支持 | 客户需求 | 差距 |
|---|---|---|---|
| 单个提取方案 | ✅ 完全支持 | ✅ 需要 | 无 |
| 多阶段分时提取 | ❌ 不支持 | ✅ 需要 | 本文档已设计方案 |
| 多个提取方案 | ❌ 不支持 | ⏳ 待确认 | 需确认后设计 |
多方案架构设计建议
formData = {
// ... 基础字段
withdrawal_enabled: '是',
// 多方案模式
withdrawal_scenarios: [
{
scenario_id: 1,
scenario_name: '方案一:教育+创业+退休',
withdrawal_mode: '多阶段分时提取',
withdrawal_stages: [
{ stage_name: '教育基金', start_age: 18, end_age: 21, withdrawal_type: '每年提取', annual_amount: 50000 },
{ stage_name: '创业金', start_age: 30, end_age: 30, withdrawal_type: '一笔过', lump_sum_amount: 400000 },
{ stage_name: '退休金', start_age: 50, end_age: 100, withdrawal_type: '每年提取', annual_amount: 70000 }
]
},
{
scenario_id: 2,
scenario_name: '方案二:长期年金',
withdrawal_mode: '单阶段定期提取',
withdrawal_start_age: 9,
withdrawal_period: 92, // 9-100岁
annual_withdrawal_amount: 17500
},
{
scenario_id: 3,
scenario_name: '方案三:财富传承',
withdrawal_mode: '不提取',
withdrawal_stages: []
}
]
}
方案 B:多次提交,分别生成方案(推荐)
优点:
- ✅ 表单简单,复用现有逻辑
- ✅ 无需后端改动
- ✅ 用户可灵活组合不同方案
缺点:
- ❌ 每个方案单独生成,无法直接对比
- ❌ 用户需要多次操作
用户流程:
用户填写方案一 → 提交 → 生成计划书1(方案一)
↓
用户点击"添加方案" → 填写方案二 → 提交 → 生成计划书2(方案二)
↓
用户点击"添加方案" → 填写方案三 → 提交 → 生成计划书3(方案三)
↓
计划书列表展示 3 个方案,用户可选择查看/分享
方案 C:混合方案(最佳用户体验)
第一阶段:快速实现
- 支持多次提交(方案B)
- 在计划书列表页添加"同一客户的多个方案"分组展示
第二阶段:完整方案
- 支持单次提交多方案(方案A)
- 计划书生成后可展示方案对比表格
实施建议
短期(MVP)
- 实现多阶段提取(本文档原有方案)
-
支持多次提交不同方案
- 在计划书列表中按客户/产品分组
- 允许用户快速复制已有方案创建新方案
中期(完整多方案)
-
改造表单支持多方案
- 添加"方案管理"组件
- 支持添加/删除/切换方案
-
后端支持多方案数据结构
- 新增
withdrawal_scenarios_json字段
- 新增
- 计划书生成支持方案对比
技术架构调整
// 数据结构扩展
formData = {
// ... 基础字段
// 新增:方案模式
scenario_mode: 'single' | 'multiple', // 单方案 | 多方案
// 单方案模式(现有逻辑复用)
withdrawal_enabled: '是',
withdrawal_mode: '单阶段定期提取' | '多阶段分时提取',
// ... 单方案字段
// 多方案模式(新增)
withdrawal_scenarios: [
{
scenario_id: Date.now(),
scenario_name: '方案一',
withdrawal_mode: '多阶段分时提取',
withdrawal_stages: [...]
},
{
scenario_id: Date.now() + 1,
scenario_name: '方案二',
withdrawal_mode: '单阶段定期提取',
// ... 单方案字段
}
]
}
待确认事项
与客户确认
多阶段提取功能
- 确认是否需要"多阶段分时提取"功能
- 确认最多支持多少个阶段(设计方案:1-5个)
- 确认预设方案是否满足需求(教育+创业+退休、退休年金、财富传承)
-
确认后端是否能够接收
withdrawal_stages_json字段 - 确认多阶段提取的计划书生成方式
多方案功能(重要)
- 确认是否需要在一个计划书中展示多个提取方案
- 确认方案数量上限(客户资料中显示3个方案)
-
确认实施方案:
- 方案A:单次提交多方案(需要后端改动)
- 方案B:多次提交不同方案(快速实现,无需后端改动)
- 方案C:混合方案(先B后A)
-
确认后端是否能够接收
withdrawal_scenarios_json字段
技术细节
- 确认一笔过提取时的年龄表示方式(start_age = end_age)
- 确认金额单位(前端:分,后端:元)
- 确认阶段数量上限(设计方案:5个)
- 确认多方案UI交互设计(Tab切换?卡片列表?)
附录
客户文档提取方案参考
方案一(3岁小公主):
18-21岁:每年 5万(教育基金)
30岁:一笔过 40万(创业金/婚嫁金)← "一笔过" = 一次性提取
50-100岁:每年 7万(退休养老年金)
术语说明:"一笔过"是客户使用的术语,等同于"一次性提取",即在特定年龄一次性全额提取保单价值,而非分期提取。
方案二(37岁):
43-100岁:每年 3.75万(退休年金)
方案三(财富传承):
不填写提取计划,展示保单价值增长表
现有系统架构参考
- 配置文件:
src/config/plan-templates.js - 模板组件:
src/components/plan/PlanTemplates/SavingsTemplate.vue - 字段组件:
src/components/plan/PlanFields/ - 架构文档:
docs/plan/plan-entry-architecture.md - Schema 规范:
docs/plan/plan-config-schema-reference.md
文档版本: 1.0.0 最后更新: 2026-02-25