plan-config-schema-reference.md 19.4 KB

计划书配置 JSON Schema 规范

文档目的:定义计划书配置的完整 JSON Schema,用于后端验证和前端类型检查

作者:Claude Code 创建日期:2026-02-25 版本:1.0.0


目录

  1. 配置根对象
  2. FormSchema 规范
  3. SubmitMapping 规范
  4. 字段定义规范
  5. 条件规则规范

配置根对象

TemplateConfig

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "计划书模板配置",
  "type": "object",
  "required": ["form_sn", "name", "component", "config"],
  "properties": {
    "form_sn": {
      "type": "string",
      "description": "产品唯一标识,格式: {category}-{product_code}",
      "pattern": "^(life-insurance|critical-illness|savings)-[a-z0-9-]+$",
      "examples": ["savings-gs", "life-insurance-wiop3e"]
    },
    "name": {
      "type": "string",
      "description": "产品名称",
      "examples": ["宏挚传承保障计划", "WIOP3E 盈传创富保障计划 3"]
    },
    "component": {
      "type": "string",
      "enum": ["LifeInsuranceTemplate", "CriticalIllnessTemplate", "SavingsTemplate"],
      "description": "对应的模板组件名"
    },
    "category": {
      "type": "string",
      "enum": ["life-insurance", "critical-illness", "savings"],
      "description": "产品分类"
    },
    "config": {
      "$ref": "#/definitions/TemplateConfigData"
    }
  },
  "definitions": {
    "TemplateConfigData": {
      "type": "object",
      "required": ["currency", "payment_periods", "age_range", "form_schema"],
      "properties": {
        "currency": {
          "$ref": "#/definitions/CurrencyCode"
        },
        "payment_periods": {
          "type": "array",
          "items": { "type": "string" },
          "description": "缴费年期选项",
          "examples": [["整付", "5 年", "10 年"]]
        },
        "age_range": {
          "$ref": "#/definitions/AgeRange"
        },
        "insurance_period": {
          "type": "string",
          "description": "保险期间",
          "examples": ["终身", "至 100 岁"]
        },
        "withdrawal_plan": {
          "$ref": "#/definitions/WithdrawalPlan"
        },
        "form_schema": {
          "$ref": "#/definitions/FormSchema"
        },
        "submit_mapping": {
          "$ref": "#/definitions/SubmitMapping"
        }
      }
    }
  }
}

辅助定义

{
  "definitions": {
    "CurrencyCode": {
      "type": "string",
      "enum": ["CNY", "USD", "HKD", "EUR"],
      "description": "币种代码"
    },
    "AgeRange": {
      "type": "object",
      "properties": {
        "min": {
          "type": "integer",
          "minimum": 0,
          "description": "最小年龄"
        },
        "max": {
          "type": "integer",
          "maximum": 150,
          "description": "最大年龄"
        }
      },
      "required": ["min", "max"]
    }
  }
}

FormSchema 规范

FormSchema 根对象

{
  "FormSchema": {
    "type": "object",
    "properties": {
      "base_fields": {
        "type": "array",
        "items": { "$ref": "#/definitions/FieldDefinition" },
        "description": "基础字段(所有产品共有)"
      },
      "withdrawal_fields": {
        "type": "array",
        "items": { "$ref": "#/definitions/FieldDefinition" },
        "description": "提取计划字段(储蓄型产品特有)"
      }
    },
    "required": ["base_fields"]
  }
}

字段定义规范

FieldDefinition

{
  "FieldDefinition": {
    "type": "object",
    "required": ["id", "key", "type", "label"],
    "properties": {
      "id": {
        "type": "string",
        "description": "字段唯一标识(用于 v-for key)"
      },
      "key": {
        "type": "string",
        "description": "formData 中的键名"
      },
      "type": {
        "$ref": "#/definitions/FieldType",
        "description": "字段类型(决定使用哪个组件)"
      },
      "label": {
        "type": "string",
        "description": "字段显示标签"
      },
      "placeholder": {
        "type": "string",
        "description": "占位符文本"
      },
      "input_label": {
        "type": "string",
        "description": "金额键盘弹窗标题(amount 类型专用)"
      },
      "required": {
        "type": "boolean",
        "description": "是否必填",
        "default": false
      },
      "default": {
        "description": "默认值",
        "oneOf": [
          { "type": "string" },
          { "type": "boolean" },
          { "type": "number" }
        ]
      },
      "options": {
        "type": "array",
        "items": { "type": "string" },
        "description": "选项列表(radio/select 类型)"
      },
      "options_from": {
        "type": "string",
        "description": "选项来源配置引用",
        "examples": ["payment_periods", "withdrawal_plan.withdrawal_periods"]
      },
      "currency_from": {
        "type": "string",
        "description": "币种来源配置引用",
        "examples": ["currency", "withdrawal_plan.default_currency"]
      },
      "section_title": {
        "type": "string",
        "description": "分组标题(用于字段分组显示)"
      },
      "show_when": {
        "$ref": "#/definitions/ConditionRule",
        "description": "条件显示规则"
      },
      "clear_when_hidden": {
        "description": "隐藏时是否清空值",
        "oneOf": [
          { "type": "boolean" },
          { "type": "null" },
          {
            "type": "object",
            "properties": {
              "clear_self": { "type": "boolean" },
              "clear_dependents": {
                "type": "array",
                "items": { "type": "string" }
              }
            }
          }
        ]
      }
    }
  }
}

FieldType 枚举

{
  "FieldType": {
    "type": "string",
    "enum": [
      "name",
      "text",
      "amount",
      "percentage",
      "date",
      "age",
      "radio",
      "select",
      "payment_period"
    ],
    "description": "字段类型枚举"
  }
}

字段类型与组件映射

type 组件 说明 options_from 支持
name PlanFieldName 姓名输入
text nut-input 普通文本
amount PlanFieldAmount 金额键盘 ✅ currency_from
percentage nut-input 百分比 (0-100)
date PlanFieldDatePicker 日期选择器
age PlanFieldAgePicker 年龄选择器
radio PlanFieldRadio 单选按钮 ✅ options_from
select PlanFieldSelect 下拉选择器 ✅ options_from
payment_period PaymentPeriodRadio 缴费年期专用 ✅ options_from

条件规则规范

ConditionRule

{
  "ConditionRule": {
    "oneOf": [
      { "$ref": "#/definitions/SimpleCondition" },
      { "$ref": "#/definitions/CompositeCondition" }
    ]
  },
  "SimpleCondition": {
    "type": "object",
    "required": ["field", "op", "value"],
    "properties": {
      "field": {
        "type": "string",
        "description": "依赖的字段 key"
      },
      "op": {
        "$ref": "#/definitions/ConditionOperator",
        "description": "比较操作符"
      },
      "value": {
        "description": "比较值",
        "oneOf": [
          { "type": "string" },
          { "type": "number" },
          { "type": "boolean" },
          {
            "type": "array",
            "items": { "type": "string" }
          }
        ]
      }
    }
  },
  "CompositeCondition": {
    "type": "object",
    "required": ["op", "conditions"],
    "properties": {
      "op": {
        "enum": ["AND", "OR"],
        "description": "逻辑操作符"
      },
      "conditions": {
        "type": "array",
        "items": { "$ref": "#/definitions/ConditionRule" },
        "description": "子条件列表"
      }
    }
  },
  "ConditionOperator": {
    "type": "string",
    "enum": ["eq", "ne", "gt", "lt", "gte", "lte", "in"],
    "description": "比较操作符"
  }
}

条件规则示例

{
  "简单条件": {
    "field": "withdrawal_enabled",
    "op": "eq",
    "value": true
  },
  "字符串相等": {
    "field": "withdrawal_mode",
    "op": "eq",
    "value": "指定提取金额"
  },
  "数值范围": {
    "field": "age",
    "op": "gte",
    "value": 18
  },
  "包含于": {
    "field": "product_type",
    "op": "in",
    "value": ["A", "B", "C"]
  },
  "复合条件": {
    "op": "AND",
    "conditions": [
      { "field": "age", "op": "gte", "value": 18 },
      { "field": "age", "op": "lt", "value": 65 }
    ]
  }
}

向后兼容的旧格式

{
  "旧格式(自动转换)": {
    "field": "withdrawal_mode",
    "equals": "指定提取金额"
  },
  "新格式": {
    "field": "withdrawal_mode",
    "op": "eq",
    "value": "指定提取金额"
  }
}

SubmitMapping 规范

SubmitMapping 根对象

{
  "SubmitMapping": {
    "type": "object",
    "patternProperties": {
      "^[a-z_]+$": {
        "oneOf": [
          { "type": "string" },
          { "$ref": "#/definitions/FieldMapping" }
        ]
      }
    },
    "description": "字段键名到 API 字段映射的字典"
  },
  "FieldMapping": {
    "type": "object",
    "required": ["api_field"],
    "properties": {
      "api_field": {
        "type": "string",
        "description": "API 接口字段名"
      },
      "transform": {
        "type": "string",
        "enum": ["fen_to_yuan", "yuan_to_fen", "none"],
        "description": "值转换类型",
        "default": "none"
      }
    }
  }
}

SubmitMapping 示例

{
  "customer_name": {
    "api_field": "customer_name"
  },
  "gender": {
    "api_field": "customer_gender"
  },
  "coverage": {
    "api_field": "annual_premium",
    "transform": "fen_to_yuan"
  },
  "annual_withdrawal_amount": {
    "api_field": "annual_withdrawal_amount",
    "transform": "fen_to_yuan"
  },
  "withdrawal_start_age_specified": {
    "api_field": "withdrawal_start_age"
  },
  "withdrawal_start_age_fixed": {
    "api_field": "withdrawal_start_age"
  }
}

简写格式

{
  "简写格式(无需转换)": "customer_name",
  "等价于": {
    "api_field": "customer_name"
  }
}

WithdrawalPlan 规范

{
  "WithdrawalPlan": {
    "type": "object",
    "required": ["enabled"],
    "properties": {
      "enabled": {
        "type": "boolean",
        "description": "是否启用提取计划"
      },
      "currencies": {
        "type": "array",
        "items": { "$ref": "#/definitions/CurrencyCode" },
        "description": "支持的币种列表"
      },
      "default_currency": {
        "$ref": "#/definitions/CurrencyCode",
        "description": "默认币种"
      },
      "withdrawal_modes": {
        "type": "array",
        "items": { "type": "string" },
        "description": "提取模式选项",
        "examples": [["指定提取金额", "最高固定提取金额"]]
      },
      "withdrawal_periods": {
        "type": "array",
        "items": { "type": "string" },
        "description": "提取年期选项",
        "examples": [["1年", "2年", "5年", "10年", "终身"]]
      }
    }
  }
}

完整配置示例

储蓄型产品配置

{
  "form_sn": "savings-gs",
  "name": "宏挚传承保障计划",
  "component": "SavingsTemplate",
  "category": "savings",
  "config": {
    "currency": "USD",
    "payment_periods": ["整付", "3 年", "5 年", "10 年", "15 年"],
    "age_range": { "min": 0, "max": 100 },
    "insurance_period": "终身",
    "withdrawal_plan": {
      "enabled": true,
      "currencies": ["HKD", "USD", "CNY"],
      "default_currency": "USD",
      "withdrawal_modes": ["指定提取金额", "最高固定提取金额"],
      "withdrawal_periods": ["1年", "2年", "3年", "5年", "10年", "15年", "20年", "终身"]
    },
    "form_schema": {
      "base_fields": [
        {
          "id": "customer_name",
          "key": "customer_name",
          "type": "name",
          "label": "申请人",
          "placeholder": "请输入申请人",
          "required": true
        },
        {
          "id": "gender",
          "key": "gender",
          "type": "radio",
          "label": "性别",
          "options": ["男", "女"],
          "required": true
        },
        {
          "id": "coverage",
          "key": "coverage",
          "type": "amount",
          "label": "年缴保费",
          "placeholder": "请输入年缴保费",
          "input_label": "请输入年缴保费金额",
          "required": true,
          "currency_from": "currency"
        },
        {
          "id": "payment_period",
          "key": "payment_period",
          "type": "payment_period",
          "label": "缴费年期",
          "required": true,
          "options_from": "payment_periods"
        }
      ],
      "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": "款项提取(允许减少名义金额)",
          "clear_when_hidden": true,
          "show_when": {
            "field": "withdrawal_enabled",
            "op": "eq",
            "value": "是"
          }
        },
        {
          "id": "annual_withdrawal_amount",
          "key": "annual_withdrawal_amount",
          "type": "amount",
          "label": "每年提取金额",
          "placeholder": "请输入每年提取金额",
          "input_label": "请输入每年提取金额",
          "required": true,
          "currency_from": "withdrawal_plan.default_currency",
          "clear_when_hidden": true,
          "show_when": {
            "field": "withdrawal_mode",
            "op": "eq",
            "value": "指定提取金额"
          }
        }
      ]
    },
    "submit_mapping": {
      "customer_name": { "api_field": "customer_name" },
      "gender": { "api_field": "customer_gender" },
      "annual_premium": { "api_field": "annual_premium", "transform": "fen_to_yuan" },
      "payment_period": { "api_field": "payment_years" },
      "withdrawal_enabled": { "api_field": "allow_reduce_amount" },
      "withdrawal_mode": { "api_field": "withdrawal_option" },
      "annual_withdrawal_amount": { "api_field": "annual_withdrawal_amount", "transform": "fen_to_yuan" }
    }
  }
}

验证工具

Python JSON Schema 验证

import json
from jsonschema import validate, ValidationError

# 定义 Schema (使用上面定义的 JSON Schema)
PLAN_CONFIG_SCHEMA = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "计划书模板配置",
    "type": "object",
    "required": ["form_sn", "name", "component", "config"],
    "properties": {
        "form_sn": {
            "type": "string",
            "pattern": "^(life-insurance|critical-illness|savings)-[a-z0-9-]+$"
        },
        "name": { "type": "string" },
        "component": {
            "type": "string",
            "enum": ["LifeInsuranceTemplate", "CriticalIllnessTemplate", "SavingsTemplate"]
        },
        "config": { "type": "object" }
    }
}

def validate_plan_config(config):
    """验证计划书配置"""
    try:
        validate(instance=config, schema=PLAN_CONFIG_SCHEMA)
        return True, "配置有效"
    except ValidationError as e:
        return False, f"验证失败: {e.message}"

# 使用示例
with open('plan-config.json') as f:
    config = json.load(f)

is_valid, message = validate_plan_config(config)
print(f"验证结果: {is_valid}, {message}")

JavaScript JSON Schema 验证

import Ajv from 'ajv'

const schema = {
  type: 'object',
  required: ['form_sn', 'name', 'component', 'config'],
  properties: {
    form_sn: {
      type: 'string',
      pattern: '^(life-insurance|critical-illness|savings)-[a-z0-9-]+$'
    },
    name: { type: 'string' },
    component: {
      type: 'string',
      enum: ['LifeInsuranceTemplate', 'CriticalIllnessTemplate', 'SavingsTemplate']
    },
    config: { type: 'object' }
  }
}

const ajv = new Ajv()
const validate = ajv.compile(schema)

function validatePlanConfig(config) {
  const valid = validate(config)
  if (!valid) {
    console.error('验证失败:', validate.errors)
    return false
  }
  return true
}

// 使用示例
const config = { /* ... */ }
console.log(validatePlanConfig(config))

TypeScript 类型定义

/**
 * 计划书配置类型定义
 * 用于前端类型检查和后端 API 接口定义
 */

/** 币种代码 */
type CurrencyCode = 'CNY' | 'USD' | 'HKD' | 'EUR'

/** 字段类型 */
type FieldType =
  | 'name'
  | 'text'
  | 'amount'
  | 'percentage'
  | 'date'
  | 'age'
  | 'radio'
  | 'select'
  | 'payment_period'

/** 条件操作符 */
type ConditionOperator = 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'in'

/** 值转换类型 */
type TransformType = 'fen_to_yuan' | 'yuan_to_fen' | 'none'

/** 年龄范围 */
interface AgeRange {
  min: number
  max: number
}

/** 提取计划配置 */
interface WithdrawalPlan {
  enabled: boolean
  currencies?: CurrencyCode[]
  default_currency?: CurrencyCode
  withdrawal_modes?: string[]
  withdrawal_periods?: string[]
}

/** 条件规则 */
type ConditionRule = SimpleCondition | CompositeCondition

interface SimpleCondition {
  field: string
  op: ConditionOperator
  value: string | number | boolean | string[]
}

interface CompositeCondition {
  op: 'AND' | 'OR'
  conditions: ConditionRule[]
}

/** 清空隐藏配置 */
type ClearWhenHidden =
  | boolean
  | null
  | {
      clear_self?: boolean
      clear_dependents?: string[]
    }

/** 字段定义 */
interface FieldDefinition {
  id: string
  key: string
  type: FieldType
  label: string
  placeholder?: string
  input_label?: string
  required?: boolean
  default?: string | boolean | number
  options?: string[]
  options_from?: string
  currency_from?: string
  section_title?: string
  show_when?: ConditionRule
  clear_when_hidden?: ClearWhenHidden
}

/** 表单 Schema */
interface FormSchema {
  base_fields: FieldDefinition[]
  withdrawal_fields?: FieldDefinition[]
}

/** 字段映射 */
interface FieldMapping {
  api_field: string
  transform?: TransformType
}

/** 提交映射(字典) */
type SubmitMapping = Record<string, string | FieldMapping>

/** 模板配置数据 */
interface TemplateConfigData {
  currency: CurrencyCode
  payment_periods: string[]
  age_range: AgeRange
  insurance_period?: string
  withdrawal_plan?: WithdrawalPlan
  form_schema: FormSchema
  submit_mapping: SubmitMapping
}

/** 模板配置(完整) */
interface TemplateConfig {
  form_sn: string
  name: string
  component: 'LifeInsuranceTemplate' | 'CriticalIllnessTemplate' | 'SavingsTemplate'
  category?: 'life-insurance' | 'critical-illness' | 'savings'
  config: TemplateConfigData
}

相关文档