多阶段提取方案设计.md 17.3 KB

多阶段提取方案设计文档

创建时间: 2026-02-25 状态: ✅ 需求已确认 设计师: Claude Code 版本: 2.0.0 更新内容: 客户确认只需多阶段提取,不需要多方案对比功能


📋 目录

  1. 需求说明(已确认)
  2. 需求背景
  3. 现状分析
  4. 方案设计
  5. 数据结构
  6. 组件设计
  7. Schema 配置
  8. 字段映射
  9. 实施清单
  10. 待确认事项

📖 需求说明(已确认)

✅ 客户已确认:2026-02-25

需求概述

多阶段提取(Multi-Stage Withdrawal)一个提取方案中,包含多个不同阶段的提取计划。

示例(教育+创业+退休组合):

同一个方案内的三个阶段:
├─ 第一阶段:18-21岁,每年5万(教育基金)
├─ 第二阶段:30岁,一笔过40万(创业金/婚嫁金)
└─ 第三阶段:50-100岁,每年7万(退休养老年金)

客户确认要点

  • ✅ 一份计划书里只有一个提取方案,不会有多个
  • ✅ 需要支持在一个方案中设置多个不同阶段的提取计划
  • ✅ 阶段数量建议 1-5 个

需求背景

客户文档中的提取方案

根据客户提供的储蓄类保险文档,提取方案主要分为三种模式:

模式 描述 示例
模式 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. 单阶段定期提取(现有逻辑)- 退休年金计划
  2. 多阶段分时提取(新增)- 教育+创业+退休组合

设计原则

  • 向后兼容:不影响现有单阶段提取功能
  • 纯前端实现:不依赖后端改动
  • 用户友好:提供预设方案快速填充
  • 灵活扩展:支持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>

待确认事项

与客户确认

多阶段提取功能

  • 确认需要"多阶段分时提取"功能 ✅
  • 确认一份计划书只有一个提取方案 ✅
  • 确认最多支持多少个阶段(设计方案:1-5个)
  • 确认预设方案是否满足需求(教育+创业+退休、退休年金、财富传承)
  • 确认后端是否能够接收 withdrawal_stages_json 字段
  • 确认多阶段提取的计划书生成方式

技术细节

  • 确认一笔过提取时的年龄表示方式(start_age = end_age)
  • 确认金额单位(前端:分,后端:元)
  • 确认阶段数量上限(设计方案:5个)

附录

多阶段提取方案示例

示例:教育+创业+退休组合

阶段1 - 教育基金:
  18-21岁,每年提取 5万

阶段2 - 创业金/婚嫁金:
  30岁,一笔过提取 40万

阶段3 - 退休养老年金:
  50-100岁,每年提取 7万

术语说明:"一笔过"是客户使用的术语,等同于"一次性提取",即在特定年龄一次性全额提取保单价值,而非分期提取。

现有系统架构参考

  • 配置文件: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