plan-entry-architecture.md 18.5 KB

计划书录入功能模块 - 架构设计方案

创建时间: 2026-02-06 设计师: Claude Code 状态: ✅ 已批准 批准时间: 2026-02-06 版本: v2.0 最后更新: 2026-02-06

更新记录

  • v2.0 (2026-02-06): 整合储蓄型产品(GS/GC/FA/LV2),新增提取计划功能
  • v1.0 (2026-02-06): 初始版本,支持人寿保险和重疾保险产品

📋 需求总结

核心需求

  1. 产品驱动:一个产品对应一个计划书模版,用户不需要选择模版类型
  2. 保额配置:支持不同币种(人民币、美元等),币种符号可配置
  3. 年龄选择:使用 NutUI Popup + Picker 多列选择器,3位数字,初始值018,传给后端的值是数字18
  4. 缴费年期:key 和 value 相同(如"整付(0-75 岁)")
  5. 日期选择:使用 DatePicker 日期选择器
  6. 扩展性:产品和模版的映射方式需要考虑未来扩展

用户流程

用户在首页/产品详情页点击"计划书"按钮
  ↓
系统根据产品名称/ID自动选择对应的模版
  ↓
显示计划书录入弹窗(包含动态表单)
  ↓
用户填写表单(性别、年龄、出生年月日、是否吸烟、保额、缴费年期等)
  ↓
提交 → 跳转到计划书提交结果页

🔍 现有实现分析

当前架构

首页 (index.vue)
  └─ 点击"计划书"按钮
      └─ 打开 PlanPopup
          ├─ SchemeA (硬编码)
          └─ SchemeB (硬编码)

问题

  1. ❌ 硬编码模版:通过 currentScheme 变量手动选择 SchemeA 或 SchemeB
  2. ❌ 缺少产品-模版映射:没有根据产品自动选择模版的机制
  3. ❌ 表单组件有限:缺少保额(币种配置)、年龄选择器、日期选择器等组件
  4. ❌ 扩展性差:新增产品或模版需要修改代码

现有表单字段

模版 字段 类型
SchemeA 客户姓名、性别、年龄、行业、年收入、家庭结构、保险需求、期望收益率 Input、Radio、Picker、多选标签
SchemeB 币种、计划、附加计划、性别、年龄、保险期间、交费期间、年交保费 固定值、Radio、Input

产品 API 数据结构

{
  id: 1,
  product_name: "WIOP3E 盈传创富保障计划 3 - 优选版",
  form_sn: "xxx",  // 关联表单sn(可能用来关联模版)
  categories: [...],
  tags: [...],
  documents: [...],
  cover_image: "..."
}

计划书文档定义

第一版模版docs/plan/计划书模版.md):

人寿产品(WIOP3E、WIOP3):

  • 核心信息:性别、年龄、出生年月日、是否吸烟
  • 保额
  • 缴费年期:整付(0-75 岁)、5 年(0-70 岁)、10 年(0-70 岁)

重疾产品(MPC、MBC PRO、MBC2):

  • 核心信息:性别、年龄、出生年月日、是否吸烟
  • 保额
  • 缴费年期:10 年(15 日 - 65 岁)、20 年(15 日 - 65 岁)、25 年(15 日 - 60 岁)

第二版模版docs/plan/计划书模版2.docx):

储蓄型产品(统一逻辑):

  • 产品列表:
    • GS(宏摯傳承保障計劃)
    • GC(宏摯家傳承保險計劃)
    • FA(宏浚傳承保障計劃)
    • LV2(赤霞珠終身壽險計劃2)
  • 核心信息:性别、年龄、出生年月日、是否吸烟
  • 保额
  • 缴费年期:各产品不同(详见配置文件)
  • 提取计划功能(所有储蓄产品通用):
    • 方式 1:年龄指定金额(按年龄提取)
    • 开始年龄(start_age)
    • 提取年期(withdrawal_period)
    • 每年提取金额(annual_amount)
    • 币种(currency):支持 HKD、USD、CNY
    • 增加率(increase_rate):每年提取金额的增长百分比
    • 方式 2:最高固定金额(按年龄提取)
    • 开始年龄(start_age)
    • 提取年期(withdrawal_period)
  • 多币种支持:提取金额支持多币种(HKD、USD、CNY)

🏗️ 架构设计方案

方案 A:产品 API 驱动(推荐)⭐

核心思路

后端在产品 API 返回数据中已有 form_sn 字段,用于指定该产品使用的计划书模版。

数据结构设计

1. 产品 API 返回数据(已有字段)

// src/api/get_product.js
{
  id: 1,
  product_name: "WIOP3E 盈传创富保障计划 3 - 优选版",
  form_sn: "life-insurance-wiop3e",  // ✅ 已有字段:计划书模版标识(就是模版名称)
  // 注意:如果需要模版配置(如币种、缴费年期选项),可以新增 plan_config 字段
  // 或者前端根据 form_sn 从配置文件中读取对应的配置
  // ... 其他字段
}

2. 模版配置文件

// src/config/plan-templates.js
export const PLAN_TEMPLATES = {
  // form_sn: life-insurance-wiop3e
  'life-insurance-wiop3e': {
    name: 'WIOP3E 盈传创富保障计划 3 - 优选版',
    component: 'LifeInsuranceTemplate',
    // 模版配置(可选:如果后端不提供 plan_config,则使用这里的配置)
    config: {
      currency: "USD",  // 币种:USD/CNY
      payment_periods: [  // 缴费年期选项
        "整付(0-75 岁)",
        "5 年(0-70 岁)",
        "10 年(0-70 岁)"
      ],
      age_range: { min: 0, max: 75 },  // 年龄范围
      insurance_period: "终身"  // 保险期间
    }
  },

  // form_sn: critical-illness-mpc
  'critical-illness-mpc': {
    name: 'MPC 守护无间重疾',
    component: 'CriticalIllnessTemplate',
    config: {
      currency: "CNY",
      payment_periods: [
        "10 年(15 日 - 65 岁)",
        "20 年(15 日 - 65 岁)",
        "25 年(15 日 - 60 岁)"
      ],
      age_range: { min: 0, max: 65 },
      insurance_period: "终身"
    }
  }
}

3. 功能开关配置(未来扩展用)

// src/config/plan-templates.js

/**
 * 全局功能开关
 * @description 用于控制实验性功能或未来扩展功能的开关
 * @example 开启多币种功能:设置 MULTI_CURRENCY_ENABLED = true
 */
export const FEATURE_FLAGS = {
  // 多币种切换功能(当前:关闭,未来:开启)
  // false: 方案 1 - 固定币种(当前实现)
  // true: 方案 2 - 支持多币种切换(未来扩展)
  MULTI_CURRENCY_ENABLED: false,
}

4. 出生日期驱动年龄(推荐方案)

核心逻辑

用户选择"出生年月日"
  ↓
系统自动计算年龄 = 当前年份 - 出生年份
  ↓
年龄字段自动填充
  ↓
用户可以手动修改年龄(特殊情况)

优势

  • 更准确:出生日期是准确的个人信息
  • 自动计算:避免用户手动输入错误
  • 灵活性:用户可以修改年龄
  • 逻辑简单:不需要复杂的日期限制

实现示例

// 用户选择出生日期
const onBirthdayChange = (birthday) => {
  form.birthday = birthday

  // 自动计算年龄
  const birthYear = new Date(birthday).getFullYear()
  const currentYear = new Date().getFullYear()
  form.age = currentYear - birthYear
}

组件架构

PlanFormContainer (计划书表单容器)
  └─ 根据产品 form_sn 动态加载模版组件
      ├─ LifeInsuranceTemplate (人寿保险模版)
      ├─ CriticalIllnessTemplate (重疾保险模版)
      ├─ SavingsTemplate (储蓄型产品模版)
      └─ 其他模版...

动态表单字段组件:
  ├─ AgePicker (年龄选择器)
  ├─ AmountInput (保额输入 + 币种)
  ├─ DatePicker (日期选择器)
  ├─ RadioGroup (单选)
  ├─ SelectPicker (下拉选择)
  └─ WithdrawalPlanSelector (提取计划选择器 - 储蓄产品专用)

提取计划相关组件:
  ├─ WithdrawalPlanSelector.vue (主选择器:方式1/方式2)
  ├─ SpecifiedAmountForm.vue (年龄指定金额表单)
  ├─ FixedAmountForm.vue (最高固定金额表单)
  └─ CurrencySelector.vue (币种选择器)

🎯 推荐方案

选择:方案 A(产品 API 驱动)

理由

  1. 扩展性强:新增产品只需后端配置 plan_template 字段
  2. 维护成本低:产品信息和模版信息都在同一处
  3. 类型安全:前端可以使用 TypeScript 验证模版配置
  4. 支持动态配置:可以通过 CMS 后台管理产品和模版的映射关系

后端配合要求

  1. 产品已有字段form_sn - 模版标识(如 life-insurance-wiop3e

    • ✅ 这个字段已经存在,可以直接使用
  2. 可选增强:如果需要动态配置模版参数(如币种、缴费年期选项),可以新增 plan_config 字段:

    • currency: 币种(USD/CNY)
    • payment_periods: 缴费年期选项数组
    • age_range: 年龄范围({ min, max })
    • insurance_period: 保险期间

注意:如果后端不提供 plan_config,前端会从 src/config/plan-templates.js 配置文件中读取默认配置。


📂 文件结构

src/
├── api/
│   └── plan.js                   # 计划书 API(新增)
│
├── config/
│   └── plan-templates.js         # 计划书模版配置(新增)
│
├── components/
│   ├── PlanFormContainer.vue     # 计划书表单容器(新增)
│   ├── PlanPopup/
│   │   └── index.vue             # 弹窗容器(已有)
│   │
│   ├── PlanTemplates/            # 具体模版组件(新增)
│   │   ├── LifeInsuranceTemplate.vue
│   │   ├── CriticalIllnessTemplate.vue
│   │   ├── SavingsTemplate.vue   # 储蓄型产品模版(GS/GC/FA/LV2)
│   │   └── README.md             # 模版开发文档
│   │
│   └── PlanFields/               # 通用表单字段组件(新增)
│       ├── AgePicker.vue         # 年龄选择器
│       ├── AmountInput.vue       # 保额输入
│       ├── DatePicker.vue        # 日期选择器
│       ├── RadioGroup.vue        # 单选组
│       ├── SelectPicker.vue      # 下拉选择
│       └── WithdrawalPlan/       # 提取计划组件(储蓄产品专用)
│           ├── WithdrawalPlanSelector.vue  # 主选择器
│           ├── SpecifiedAmountForm.vue     # 年龄指定金额表单
│           ├── FixedAmountForm.vue         # 最高固定金额表单
│           └── CurrencySelector.vue        # 币种选择器
│
└── pages/
    ├── index.vue                 # 首页(修改)
    └── product-detail/
        └── index.vue             # 产品详情页(修改)

🔧 表单字段组件设计

1. AgePicker(年龄选择器)

需求

  • 使用 NutUI Popup + Picker 多列样式
  • 年龄范围:0-120 岁
  • 显示格式:3位数字(018)
  • 提交格式:数字(18)

2. AmountInput(保额输入)

需求

  • 支持不同币种(CNY、USD、HKD、EUR)
  • 小数点后2位控制
  • 币种符号可配置

3. DatePicker(出生日期选择器)→ 自动计算年龄

优化方案

  • 用户选择出生年月日
  • 系统自动计算年龄 = 当前年份 - 出生年份
  • 年龄字段自动填充
  • 用户可以手动修改年龄(特殊情况)

4. RadioGroup(单选组)

需求

  • 性别、是否吸烟等单选项

5. SelectPicker(下拉选择)

需求

  • 缴费年期选择
  • key 和 value 相同(如"整付(0-75 岁)")

6. WithdrawalPlanSelector(提取计划选择器)⭐ 储蓄产品专用

业务场景:储蓄型产品(GS/GC/FA/LV2)支持提取计划功能

两种提取方式

方式 1:年龄指定金额(按年龄提取)

字段

  • start_age:开始提取年龄(数字)
  • withdrawal_period:提取年期(数字,单位:年)
  • annual_amount:每年提取金额(数字,单位:分)
  • currency:币种(HKD/USD/CNY)
  • increase_rate:增加率(百分比,如 5 表示 5%)

示例

{
  mode: 'specified_amount',
  start_age: 60,
  withdrawal_period: 10,
  annual_amount: 5000000,  // 50,000.00 HKD
  currency: 'HKD',
  increase_rate: 5  // 每年增长 5%
}

方式 2:最高固定金额(按年龄提取)

字段

  • start_age:开始提取年龄(数字)
  • withdrawal_period:提取年期(数字,单位:年)

示例

{
  mode: 'fixed_amount',
  start_age: 60,
  withdrawal_period: 10
}

组件设计

<template>
  <div>
    <!-- 提取方式选择 -->
    <PlanFieldRadio
      v-model="withdrawalPlan.mode"
      label="提取方式"
      :options="['年龄指定金额', '最高固定金额']"
    />

    <!-- 开始年龄 -->
    <PlanFieldAgePicker
      v-model="withdrawalPlan.start_age"
      label="开始年龄"
      placeholder="请选择开始提取年龄"
    />

    <!-- 提取年期 -->
    <PlanFieldSelect
      v-model="withdrawalPlan.withdrawal_period"
      label="提取年期"
      placeholder="请选择提取年期"
      :options="withdrawalPeriodOptions"
    />

    <!-- 方式1:年龄指定金额 - 额外字段 -->
    <template v-if="withdrawalPlan.mode === '年龄指定金额'">
      <!-- 每年提取金额 -->
      <PlanFieldAmount
        v-model="withdrawalPlan.annual_amount"
        label="每年提取金额"
        placeholder="请输入金额"
        :currency="withdrawalPlan.currency"
      />

      <!-- 币种 -->
      <CurrencySelector
        v-model="withdrawalPlan.currency"
        label="币种"
        :options="['HKD', 'USD', 'CNY']"
      />

      <!-- 增加率 -->
      <div>
        <div class="text-sm text-gray-600 mb-2">增加率(%)</div>
        <nut-input
          v-model="withdrawalPlan.increase_rate"
          type="digit"
          placeholder="请输入增加率"
        />
      </div>
    </template>
  </div>
</template>

📊 数据流

用户点击"计划书"按钮
  ↓
openPlanPopup(productId)
  ↓
查找产品对象
  ↓
获取 product.form_sn(已有字段)
  ↓
根据 form_sn 从 PLAN_TEMPLATES 配置中查找对应模版
  ↓
加载对应的模版组件(如 LifeInsuranceTemplate)
  ↓
显示动态表单(使用 product.plan_config 或配置文件中的默认配置)
  ↓
用户填写表单
  ↓
提交 → handlePlanSubmit(formData)
  ↓
跳转到结果页

🚀 实施步骤

阶段 1:基础架构(2-3天)

  1. 创建模版配置文件

    • 创建 src/config/plan-templates.js
    • 定义模版映射关系(人寿、重疾产品)
    • 添加储蓄型产品配置(GS/GC/FA/LV2)
    • 编写模版配置文档
  2. 创建通用表单字段组件

    • AgePicker.vue - 年龄选择器
    • AmountInput.vue - 保额输入
    • DatePicker.vue - 日期选择器
    • RadioGroup.vue - 单选组
    • SelectPicker.vue - 下拉选择
  3. 创建计划书 API

    • 创建 src/api/plan.js
    • 定义提交计划书 API 接口

阶段 2:模版组件(2-3天)

  1. 创建具体模版组件

    • LifeInsuranceTemplate.vue - 人寿保险模版
    • CriticalIllnessTemplate.vue - 重疾保险模版
    • SavingsTemplate.vue - 储蓄型产品模版(GS/GC/FA/LV2)
  2. 创建表单容器

    • PlanFormContainer.vue - 动态模版容器
  3. 创建提取计划组件(储蓄产品专用)

    • WithdrawalPlanSelector.vue - 主选择器
    • SpecifiedAmountForm.vue - 年龄指定金额表单
    • FixedAmountForm.vue - 最高固定金额表单
    • CurrencySelector.vue - 币种选择器

阶段 3:集成测试(1-2天)

  1. 修改首页

    • 集成 PlanFormContainer
    • 传递产品对象
  2. 修改产品详情页

    • 添加"计划书"按钮
    • 集成 PlanFormContainer
  3. 测试

    • 测试不同产品的模版加载
    • 测试表单验证
    • 测试提交流程

📝 API 接口设计

1. 获取产品详情(已存在,包含 form_sn)

请求

GET /srv/?a=get_product&t=detail&i=1

返回

{
  "code": 1,
  "msg": "success",
  "data": {
    "id": 1,
    "product_name": "WIOP3E 盈传创富保障计划 3 - 优选版",
    "form_sn": "life-insurance-wiop3e",  // ✅ 已有字段,用于指定模版
    // 可选:如果需要动态配置模版参数
    "plan_config": {
      "currency": "USD",
      "payment_periods": [
        "整付(0-75 岁)",
        "5 年(0-70 岁)",
        "10 年(0-70 岁)"
      ],
      "age_range": { "min": 0, "max": 75 },
      "insurance_period": "终身"
    },
    // ... 其他现有字段
  }
}

2. 提交计划书(新增)

请求

POST /srv/?a=submit_plan

{
  "product_id": 1,
  "template": "life-insurance-wiop3e",
  "form_data": {
    "gender": "男",
    "age": 18,
    "birthday": "1990-01-01",
    "smoker": "否",
    "coverage": 100000,  // 单位:分
    "payment_period": "10 年(0-70 岁)"
  }
}

返回

{
  "code": 1,
  "msg": "提交成功",
  "data": {
    "plan_id": 123,
    "status": "processing",  // processing | generated
    "estimated_time": 300  // 预计生成时间(秒)
  }
}

✅ 验收标准

  • 用户点击产品"计划书"按钮,自动显示对应的模版
  • 年龄选择器显示3位数字,提交时转换为数字
  • 保额输入支持不同币种,保留2位小数
  • 日期选择器限制年龄范围
  • 缴费年期选项完整,key 和 value 相同
  • 表单验证正常,必填项有提示
  • 提交成功后跳转到结果页
  • 支持扩展新产品模版(无需修改代码)

📚 参考文档


💡 未来扩展

  1. CMS 后台管理

    • 通过后台管理产品和模版的映射关系
    • 动态配置表单字段
    • 无需修改代码即可新增模版
  2. 表单字段扩展

    • 支持更多字段类型(多选、文件上传等)
    • 支持字段联动(如年龄变化影响保额范围)
    • 支持条件显示(如某些产品显示特定字段)
  3. 预览功能

    • 实时预览计划书
    • 保存草稿功能
    • 历史记录查看
  4. 批量生成

    • 支持批量导入客户信息
    • 批量生成计划书
    • 导出为 Excel/PDF

文档版本: v1.0 创建时间: 2026-02-06 最后更新: 2026-02-06