plan-config-schema-reference.md
19.4 KB
计划书配置 JSON Schema 规范
文档目的:定义计划书配置的完整 JSON Schema,用于后端验证和前端类型检查
作者:Claude Code 创建日期:2026-02-25 版本:1.0.0
目录
配置根对象
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" },
"coverage": { "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
}