feat(parse): 完成文档解析改造任务并更新任务清单
- 更新任务清单:标记第2步和第3步为已完成 - 验证解析流程:多产品文档检测、智能字段提取、dry-run模式 - 测试结果:4个产品成功解析,耗时54ms Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Showing
10 changed files
with
256 additions
and
48 deletions
| 1 | # 产品配置审核 - 计划书模版2.docx | 1 | # 产品配置审核 - 计划书模版2.docx |
| 2 | 2 | ||
| 3 | -**解析时间**: 2026/2/15 10:20:30 | 3 | +**解析时间**: 2026/2/15 11:18:47 |
| 4 | **原始文件**: 计划书模版2.docx | 4 | **原始文件**: 计划书模版2.docx |
| 5 | **数据来源**: docs/to-parse/计划书模版2.docx | 5 | **数据来源**: docs/to-parse/计划书模版2.docx |
| 6 | 6 | ||
| ... | @@ -116,7 +116,7 @@ | ... | @@ -116,7 +116,7 @@ |
| 116 | ```javascript | 116 | ```javascript |
| 117 | /** | 117 | /** |
| 118 | * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日 | 118 | * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日 |
| 119 | - * @added 2026-02-15T02:20:30.982Z | 119 | + * @added 2026-02-15T03:18:47.616Z |
| 120 | * @source docs/to-parse/计划书模版2.docx | 120 | * @source docs/to-parse/计划书模版2.docx |
| 121 | */ | 121 | */ |
| 122 | 'savings-product-ef3dd50b': { | 122 | 'savings-product-ef3dd50b': { | ... | ... |
| 1 | # 产品配置审核 - 计划书模版2.docx | 1 | # 产品配置审核 - 计划书模版2.docx |
| 2 | 2 | ||
| 3 | -**解析时间**: 2026/2/15 10:20:30 | 3 | +**解析时间**: 2026/2/15 11:18:47 |
| 4 | **原始文件**: 计划书模版2.docx | 4 | **原始文件**: 计划书模版2.docx |
| 5 | **数据来源**: docs/to-parse/计划书模版2.docx | 5 | **数据来源**: docs/to-parse/计划书模版2.docx |
| 6 | 6 | ||
| ... | @@ -114,7 +114,7 @@ | ... | @@ -114,7 +114,7 @@ |
| 114 | ```javascript | 114 | ```javascript |
| 115 | /** | 115 | /** |
| 116 | * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日 | 116 | * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日 |
| 117 | - * @added 2026-02-15T02:20:30.997Z | 117 | + * @added 2026-02-15T03:18:47.644Z |
| 118 | * @source docs/to-parse/计划书模版2.docx | 118 | * @source docs/to-parse/计划书模版2.docx |
| 119 | */ | 119 | */ |
| 120 | 'savings-product-aaaa60f8': { | 120 | 'savings-product-aaaa60f8': { | ... | ... |
| 1 | # 产品配置审核 - 计划书模版2.docx | 1 | # 产品配置审核 - 计划书模版2.docx |
| 2 | 2 | ||
| 3 | -**解析时间**: 2026/2/15 10:20:30 | 3 | +**解析时间**: 2026/2/15 11:18:47 |
| 4 | **原始文件**: 计划书模版2.docx | 4 | **原始文件**: 计划书模版2.docx |
| 5 | **数据来源**: docs/to-parse/计划书模版2.docx | 5 | **数据来源**: docs/to-parse/计划书模版2.docx |
| 6 | 6 | ||
| ... | @@ -114,7 +114,7 @@ | ... | @@ -114,7 +114,7 @@ |
| 114 | ```javascript | 114 | ```javascript |
| 115 | /** | 115 | /** |
| 116 | * 宏浚傳承保障計劃 | 116 | * 宏浚傳承保障計劃 |
| 117 | - * @added 2026-02-15T02:20:30.997Z | 117 | + * @added 2026-02-15T03:18:47.644Z |
| 118 | * @source docs/to-parse/计划书模版2.docx | 118 | * @source docs/to-parse/计划书模版2.docx |
| 119 | */ | 119 | */ |
| 120 | 'savings-product-d1581522': { | 120 | 'savings-product-d1581522': { | ... | ... |
| 1 | # 产品配置审核 - 计划书模版2.docx | 1 | # 产品配置审核 - 计划书模版2.docx |
| 2 | 2 | ||
| 3 | -**解析时间**: 2026/2/15 10:20:30 | 3 | +**解析时间**: 2026/2/15 11:18:47 |
| 4 | **原始文件**: 计划书模版2.docx | 4 | **原始文件**: 计划书模版2.docx |
| 5 | **数据来源**: docs/to-parse/计划书模版2.docx | 5 | **数据来源**: docs/to-parse/计划书模版2.docx |
| 6 | 6 | ||
| ... | @@ -115,7 +115,7 @@ | ... | @@ -115,7 +115,7 @@ |
| 115 | ```javascript | 115 | ```javascript |
| 116 | /** | 116 | /** |
| 117 | * 赤霞珠終身壽險計劃2基本人壽保障選項 | 117 | * 赤霞珠終身壽險計劃2基本人壽保障選項 |
| 118 | - * @added 2026-02-15T02:20:30.997Z | 118 | + * @added 2026-02-15T03:18:47.645Z |
| 119 | * @source docs/to-parse/计划书模版2.docx | 119 | * @source docs/to-parse/计划书模版2.docx |
| 120 | */ | 120 | */ |
| 121 | 'savings-2-031c1237': { | 121 | 'savings-2-031c1237': { | ... | ... |
| ... | @@ -27,3 +27,4 @@ | ... | @@ -27,3 +27,4 @@ |
| 27 | {"at":"2026-02-15T02:10:06.819Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":2,"total_products":5,"success":5,"failed":0,"duration_ms":73,"success_list":[{"form_sn":"savings-product-ef3dd50b","product_name":"宏摯傳承保障計劃 - 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-aaaa60f8","product_name":"宏摯家傳承保險計劃- 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-d1581522","product_name":"宏浚傳承保障計劃","file":"计划书模版2.docx"},{"form_sn":"savings-2-031c1237","product_name":"赤霞珠終身壽險計劃2基本人壽保障選項","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[],"total":5},"change_summary":{"ok":true,"dry_run":true,"updated_count":5,"form_sn_list":["savings-product-ef3dd50b","savings-product-aaaa60f8","savings-product-d1581522","savings-2-031c1237","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:10:06.768Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-ef3dd50b': {\n+ name: '宏摯傳承保障計劃 - 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\",\"10年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"最高固定提取金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:10:06.803Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-aaaa60f8': {\n+ name: '宏摯家傳承保險計劃- 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏浚傳承保障計劃\n+ * @added 2026-02-15T02:10:06.803Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-d1581522': {"}} | 27 | {"at":"2026-02-15T02:10:06.819Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":2,"total_products":5,"success":5,"failed":0,"duration_ms":73,"success_list":[{"form_sn":"savings-product-ef3dd50b","product_name":"宏摯傳承保障計劃 - 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-aaaa60f8","product_name":"宏摯家傳承保險計劃- 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-d1581522","product_name":"宏浚傳承保障計劃","file":"计划书模版2.docx"},{"form_sn":"savings-2-031c1237","product_name":"赤霞珠終身壽險計劃2基本人壽保障選項","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[],"total":5},"change_summary":{"ok":true,"dry_run":true,"updated_count":5,"form_sn_list":["savings-product-ef3dd50b","savings-product-aaaa60f8","savings-product-d1581522","savings-2-031c1237","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:10:06.768Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-ef3dd50b': {\n+ name: '宏摯傳承保障計劃 - 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\",\"10年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"最高固定提取金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:10:06.803Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-aaaa60f8': {\n+ name: '宏摯家傳承保險計劃- 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏浚傳承保障計劃\n+ * @added 2026-02-15T02:10:06.803Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-d1581522': {"}} |
| 28 | {"at":"2026-02-15T02:19:44.455Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":1,"total_products":1,"success":1,"failed":0,"duration_ms":39,"success_list":[{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[],"total":1},"change_summary":{"ok":true,"dry_run":true,"updated_count":1,"form_sn_list":["savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版3\n+ * @added 2026-02-15T02:19:44.438Z\n+ * @source docs/to-parse/计划书模版3.docx\n+ */\n+ 'savings-3-8f4f27ad': {\n+ name: '计划书模版3',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"5年\",\"8年\",\"12年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}} | 28 | {"at":"2026-02-15T02:19:44.455Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":1,"total_products":1,"success":1,"failed":0,"duration_ms":39,"success_list":[{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[],"total":1},"change_summary":{"ok":true,"dry_run":true,"updated_count":1,"form_sn_list":["savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版3\n+ * @added 2026-02-15T02:19:44.438Z\n+ * @source docs/to-parse/计划书模版3.docx\n+ */\n+ 'savings-3-8f4f27ad': {\n+ name: '计划书模版3',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"5年\",\"8年\",\"12年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ }"}} |
| 29 | {"at":"2026-02-15T02:20:31.001Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":1,"total_products":4,"success":4,"failed":0,"duration_ms":47,"success_list":[{"form_sn":"savings-product-ef3dd50b","product_name":"宏摯傳承保障計劃 - 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-aaaa60f8","product_name":"宏摯家傳承保險計劃- 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-d1581522","product_name":"宏浚傳承保障計劃","file":"计划书模版2.docx"},{"form_sn":"savings-2-031c1237","product_name":"赤霞珠終身壽險計劃2基本人壽保障選項","file":"计划书模版2.docx"}],"failed_list":[],"total":4},"change_summary":{"ok":true,"dry_run":true,"updated_count":4,"form_sn_list":["savings-product-ef3dd50b","savings-product-aaaa60f8","savings-product-d1581522","savings-2-031c1237"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:20:30.982Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-ef3dd50b': {\n+ name: '宏摯傳承保障計劃 - 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\",\"10年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"最高固定提取金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:20:30.997Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-aaaa60f8': {\n+ name: '宏摯家傳承保險計劃- 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏浚傳承保障計劃\n+ * @added 2026-02-15T02:20:30.997Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-d1581522': {"}} | 29 | {"at":"2026-02-15T02:20:31.001Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":1,"total_products":4,"success":4,"failed":0,"duration_ms":47,"success_list":[{"form_sn":"savings-product-ef3dd50b","product_name":"宏摯傳承保障計劃 - 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-aaaa60f8","product_name":"宏摯家傳承保險計劃- 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-d1581522","product_name":"宏浚傳承保障計劃","file":"计划书模版2.docx"},{"form_sn":"savings-2-031c1237","product_name":"赤霞珠終身壽險計劃2基本人壽保障選項","file":"计划书模版2.docx"}],"failed_list":[],"total":4},"change_summary":{"ok":true,"dry_run":true,"updated_count":4,"form_sn_list":["savings-product-ef3dd50b","savings-product-aaaa60f8","savings-product-d1581522","savings-2-031c1237"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:20:30.982Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-ef3dd50b': {\n+ name: '宏摯傳承保障計劃 - 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\",\"10年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"最高固定提取金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T02:20:30.997Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-aaaa60f8': {\n+ name: '宏摯家傳承保險計劃- 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏浚傳承保障計劃\n+ * @added 2026-02-15T02:20:30.997Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-d1581522': {"}} |
| 30 | +{"at":"2026-02-15T03:18:47.647Z","mode":"batch","options":{"dry_run":true},"summary":{"total_docs":1,"total_products":4,"success":4,"failed":0,"duration_ms":54,"success_list":[{"form_sn":"savings-product-ef3dd50b","product_name":"宏摯傳承保障計劃 - 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-aaaa60f8","product_name":"宏摯家傳承保險計劃- 性別, 年齡, 出生年月日","file":"计划书模版2.docx"},{"form_sn":"savings-product-d1581522","product_name":"宏浚傳承保障計劃","file":"计划书模版2.docx"},{"form_sn":"savings-2-031c1237","product_name":"赤霞珠終身壽險計劃2基本人壽保障選項","file":"计划书模版2.docx"}],"failed_list":[],"total":4},"change_summary":{"ok":true,"dry_run":true,"updated_count":4,"form_sn_list":["savings-product-ef3dd50b","savings-product-aaaa60f8","savings-product-d1581522","savings-2-031c1237"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 宏摯傳承保障計劃 - 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T03:18:47.616Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-ef3dd50b': {\n+ name: '宏摯傳承保障計劃 - 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\",\"10年\",\"15年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"最高固定提取金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏摯家傳承保險計劃- 性別, 年齡, 出生年月日\n+ * @added 2026-02-15T03:18:47.644Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-aaaa60f8': {\n+ name: '宏摯家傳承保險計劃- 性別, 年齡, 出生年月日',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\",\"3年\",\"5年\"],\n+ age_range: { min: 0, max: 75 },\n+ insurance_period: '终身',\n+ withdrawal_plan: {\n+ enabled: true,\n+ currencies: ['HKD', 'USD', 'CNY'],\n+ default_currency: 'USD',\n+ withdrawal_modes: [\"年龄指定金额\",\"最高固定金额\"],\n+ withdrawal_periods: [\"1年\",\"3年\",\"5年\",\"10年\"]\n+ },\n+ form_schema: savingsFormSchema,\n+ submit_mapping: savingsSubmitMapping\n+ }\n+ },\n+ \n+ /**\n+ * 宏浚傳承保障計劃\n+ * @added 2026-02-15T03:18:47.644Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-product-d1581522': {"}} | ... | ... |
| ... | @@ -9,8 +9,8 @@ | ... | @@ -9,8 +9,8 @@ |
| 9 | ## 📊 总体进度 | 9 | ## 📊 总体进度 |
| 10 | 10 | ||
| 11 | - [x] **第 1 步**: 目标与输出定义 | 11 | - [x] **第 1 步**: 目标与输出定义 |
| 12 | -- [ ] **第 2 步**: 文本抽取管线 | 12 | +- [x] **第 2 步**: 文本抽取管线 |
| 13 | -- [ ] **第 3 步**: 结构化解析与校验 | 13 | +- [x] **第 3 步**: 结构化解析与校验 |
| 14 | - [x] **第 4 步**: 生成与写入稳态化 | 14 | - [x] **第 4 步**: 生成与写入稳态化 |
| 15 | - [x] **第 5 步**: 测试与验证 | 15 | - [x] **第 5 步**: 测试与验证 |
| 16 | - [x] **第 6 步**: 运营与审计 | 16 | - [x] **第 6 步**: 运营与审计 | ... | ... |
| ... | @@ -5,10 +5,16 @@ | ... | @@ -5,10 +5,16 @@ |
| 5 | * @module composables/useFieldDependencies | 5 | * @module composables/useFieldDependencies |
| 6 | * @author Claude Code | 6 | * @author Claude Code |
| 7 | * @created 2026-02-14 | 7 | * @created 2026-02-14 |
| 8 | + * @updated 2026-02-15 - 集成新的条件评估引擎,支持复杂条件 | ||
| 8 | */ | 9 | */ |
| 9 | 10 | ||
| 10 | -import { computed, reactive, isRef } from 'vue' | 11 | +import { computed, reactive, isRef, watch } from 'vue' |
| 11 | import { PLAN_FIELD_DEFINITIONS } from '@/config/plan-fields' | 12 | import { PLAN_FIELD_DEFINITIONS } from '@/config/plan-fields' |
| 13 | +import { | ||
| 14 | + evaluateCondition, | ||
| 15 | + getConditionDependencies, | ||
| 16 | + convertToNewFormat | ||
| 17 | +} from '@/config/plan-conditions' | ||
| 12 | 18 | ||
| 13 | /** | 19 | /** |
| 14 | * �测循环依赖 | 20 | * �测循环依赖 |
| ... | @@ -88,6 +94,7 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF | ... | @@ -88,6 +94,7 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF |
| 88 | /** | 94 | /** |
| 89 | * 检查字段是否应该显示 | 95 | * 检查字段是否应该显示 |
| 90 | * | 96 | * |
| 97 | + * @description 使用新的条件评估引擎,支持复杂条件(AND/OR/NOT/嵌套) | ||
| 91 | * @param {string} fieldKey - 字段键名 | 98 | * @param {string} fieldKey - 字段键名 |
| 92 | * @returns {boolean} 是否显示 | 99 | * @returns {boolean} 是否显示 |
| 93 | */ | 100 | */ |
| ... | @@ -96,28 +103,16 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF | ... | @@ -96,28 +103,16 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF |
| 96 | const definition = definitions[fieldKey] | 103 | const definition = definitions[fieldKey] |
| 97 | if (!definition) return false | 104 | if (!definition) return false |
| 98 | 105 | ||
| 99 | - // 检查是否有 show_when 条件 | 106 | + // 使用新的条件评估引擎评估 show_when |
| 100 | if (definition.show_when) { | 107 | if (definition.show_when) { |
| 101 | - const conditions = definition.show_when | 108 | + // 转换为新格式(向后兼容) |
| 102 | - if (Array.isArray(conditions)) { | 109 | + const normalizedCondition = convertToNewFormat(definition.show_when) |
| 103 | - for (const condition of conditions) { | 110 | + if (!evaluateCondition(normalizedCondition, formData)) { |
| 104 | - if (!condition) continue | ||
| 105 | - const currentValue = formData[condition.field] | ||
| 106 | - if (currentValue !== condition.equals) { | ||
| 107 | return false | 111 | return false |
| 108 | } | 112 | } |
| 109 | } | 113 | } |
| 110 | - } else if (conditions && typeof conditions === 'object') { | ||
| 111 | - for (const [depKey, expectedValue] of Object.entries(conditions)) { | ||
| 112 | - const currentValue = formData[depKey] | ||
| 113 | - if (currentValue !== expectedValue) { | ||
| 114 | - return false | ||
| 115 | - } | ||
| 116 | - } | ||
| 117 | - } | ||
| 118 | - } | ||
| 119 | 114 | ||
| 120 | - // 检查是否被依赖字段影响 | 115 | + // 检查是否被依赖字段影响(旧逻辑,保持兼容) |
| 121 | for (const [key, def] of Object.entries(definitions)) { | 116 | for (const [key, def] of Object.entries(definitions)) { |
| 122 | if (def.affects?.includes(fieldKey)) { | 117 | if (def.affects?.includes(fieldKey)) { |
| 123 | // 依赖字段必须为 true 才显示 | 118 | // 依赖字段必须为 true 才显示 |
| ... | @@ -198,6 +193,88 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF | ... | @@ -198,6 +193,88 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF |
| 198 | // 初始化 | 193 | // 初始化 |
| 199 | initFieldStates() | 194 | initFieldStates() |
| 200 | 195 | ||
| 196 | + /** | ||
| 197 | + * 清理隐藏字段的值 | ||
| 198 | + * | ||
| 199 | + * @description 当字段隐藏时,根据 clear_when_hidden 配置决定是否清空值 | ||
| 200 | + * @param {string} fieldKey - 字段键名 | ||
| 201 | + * @param {Object} definition - 字段定义 | ||
| 202 | + */ | ||
| 203 | + function clearHiddenFieldValue(fieldKey, definition) { | ||
| 204 | + // 默认行为:隐藏时不清空(保持向后兼容) | ||
| 205 | + const clearConfig = definition.clear_when_hidden | ||
| 206 | + | ||
| 207 | + // false 或 undefined:不清空 | ||
| 208 | + if (clearConfig === false || clearConfig === undefined) { | ||
| 209 | + return | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + // true:清空为 undefined | ||
| 213 | + if (clearConfig === true) { | ||
| 214 | + formData[fieldKey] = undefined | ||
| 215 | + return | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + // null:设置为 null | ||
| 219 | + if (clearConfig === null) { | ||
| 220 | + formData[fieldKey] = null | ||
| 221 | + return | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + // 对象配置 | ||
| 225 | + if (typeof clearConfig === 'object') { | ||
| 226 | + // 清空自身 | ||
| 227 | + if (clearConfig.clear_self !== false) { | ||
| 228 | + formData[fieldKey] = undefined | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + // 级联清空依赖字段 | ||
| 232 | + if (Array.isArray(clearConfig.clear_dependents)) { | ||
| 233 | + for (const depKey of clearConfig.clear_dependents) { | ||
| 234 | + if (formData[depKey] !== undefined) { | ||
| 235 | + formData[depKey] = undefined | ||
| 236 | + } | ||
| 237 | + } | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + /** | ||
| 243 | + * 更新字段可见性并处理隐藏字段的清理 | ||
| 244 | + * | ||
| 245 | + * @param {string} fieldKey - 字段键名 | ||
| 246 | + * @param {string} triggerFieldKey - 触发更新的字段键名(可选) | ||
| 247 | + */ | ||
| 248 | + function updateFieldVisibility(fieldKey, triggerFieldKey = null) { | ||
| 249 | + const definitions = getFieldDefinitions() | ||
| 250 | + const definition = definitions[fieldKey] | ||
| 251 | + if (!definition) return | ||
| 252 | + | ||
| 253 | + const wasVisible = fieldVisibility[fieldKey] | ||
| 254 | + const isVisible = isFieldVisible(fieldKey) | ||
| 255 | + fieldVisibility[fieldKey] = isVisible | ||
| 256 | + | ||
| 257 | + // 如果从可见变为不可见,且配置了清理规则,则清理字段值 | ||
| 258 | + if (wasVisible && !isVisible) { | ||
| 259 | + clearHiddenFieldValue(fieldKey, definition) | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + // 更新启用状态 | ||
| 263 | + fieldEnabled[fieldKey] = isFieldEnabled(fieldKey) | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + /** | ||
| 267 | + * 批量更新所有字段的可见性 | ||
| 268 | + * | ||
| 269 | + * @description 通常在表单值变化后调用,重新计算所有字段的可见性 | ||
| 270 | + */ | ||
| 271 | + function refreshAllVisibility() { | ||
| 272 | + const definitions = getFieldDefinitions() | ||
| 273 | + for (const key of Object.keys(definitions)) { | ||
| 274 | + updateFieldVisibility(key) | ||
| 275 | + } | ||
| 276 | + } | ||
| 277 | + | ||
| 201 | return { | 278 | return { |
| 202 | // 状态 | 279 | // 状态 |
| 203 | fieldVisibility, | 280 | fieldVisibility, |
| ... | @@ -208,6 +285,86 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF | ... | @@ -208,6 +285,86 @@ export function useFieldDependencies(formData, fieldDefinitions = PLAN_FIELD_DEF |
| 208 | isFieldVisible, | 285 | isFieldVisible, |
| 209 | isFieldEnabled, | 286 | isFieldEnabled, |
| 210 | updateFieldValue, | 287 | updateFieldValue, |
| 211 | - initFieldStates | 288 | + initFieldStates, |
| 289 | + updateFieldVisibility, | ||
| 290 | + refreshAllVisibility | ||
| 291 | + } | ||
| 292 | +} | ||
| 293 | + | ||
| 294 | +/** | ||
| 295 | + * 过滤隐藏字段(用于提交前) | ||
| 296 | + * | ||
| 297 | + * @description 过滤掉当前不可见的字段,避免提交脏数据 | ||
| 298 | + * @param {Object} formData - 完整的表单数据 | ||
| 299 | + * @param {string[]} visibleFields - 可见字段列表 | ||
| 300 | + * @param {Object} options - 配置选项 | ||
| 301 | + * @param {string[]} options.alwaysInclude - 始终包含的字段(即使不可见) | ||
| 302 | + * @returns {Object} 过滤后的表单数据 | ||
| 303 | + * | ||
| 304 | + * @example | ||
| 305 | + * const filteredData = filterHiddenFields(formData, visibleFields.value) | ||
| 306 | + * await submitAPI(filteredData) | ||
| 307 | + */ | ||
| 308 | +export function filterHiddenFields(formData, visibleFields, options = {}) { | ||
| 309 | + const { alwaysInclude = [] } = options | ||
| 310 | + const filtered = {} | ||
| 311 | + | ||
| 312 | + for (const [key, value] of Object.entries(formData)) { | ||
| 313 | + // 可见字段始终包含 | ||
| 314 | + if (visibleFields.includes(key)) { | ||
| 315 | + filtered[key] = value | ||
| 316 | + continue | ||
| 317 | + } | ||
| 318 | + | ||
| 319 | + // 配置为始终包含的字段 | ||
| 320 | + if (alwaysInclude.includes(key)) { | ||
| 321 | + filtered[key] = value | ||
| 212 | } | 322 | } |
| 323 | + | ||
| 324 | + // 其他不可见字段被过滤掉 | ||
| 325 | + } | ||
| 326 | + | ||
| 327 | + return filtered | ||
| 328 | +} | ||
| 329 | + | ||
| 330 | +/** | ||
| 331 | + * 获取字段的条件依赖关系(用于调试和可视化) | ||
| 332 | + * | ||
| 333 | + * @description 返回字段的条件依赖图 | ||
| 334 | + * @param {Object} fieldDefinitions - 字段定义 | ||
| 335 | + * @returns {Map<string, Set<string>>} 字段到依赖字段的映射 | ||
| 336 | + */ | ||
| 337 | +export function getFieldDependencyGraph(fieldDefinitions = PLAN_FIELD_DEFINITIONS) { | ||
| 338 | + const graph = new Map() | ||
| 339 | + | ||
| 340 | + for (const [key, definition] of Object.entries(fieldDefinitions)) { | ||
| 341 | + const deps = new Set() | ||
| 342 | + | ||
| 343 | + // 从 show_when 提取依赖 | ||
| 344 | + if (definition.show_when) { | ||
| 345 | + const conditionDeps = getConditionDependencies(definition.show_when) | ||
| 346 | + conditionDeps.forEach(d => deps.add(d)) | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + // 从 affects 提取反向依赖 | ||
| 350 | + if (definition.affects) { | ||
| 351 | + for (const affectedKey of definition.affects) { | ||
| 352 | + if (!graph.has(affectedKey)) { | ||
| 353 | + graph.set(affectedKey, new Set()) | ||
| 354 | + } | ||
| 355 | + graph.get(affectedKey).add(key) | ||
| 356 | + } | ||
| 357 | + } | ||
| 358 | + | ||
| 359 | + // 从 depends_on 提取 | ||
| 360 | + if (definition.depends_on) { | ||
| 361 | + deps.add(definition.depends_on) | ||
| 362 | + } | ||
| 363 | + | ||
| 364 | + if (deps.size > 0) { | ||
| 365 | + graph.set(key, deps) | ||
| 366 | + } | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + return graph | ||
| 213 | } | 370 | } | ... | ... |
| ... | @@ -72,6 +72,7 @@ const savingsSubmitMapping = { | ... | @@ -72,6 +72,7 @@ const savingsSubmitMapping = { |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | // 储蓄类表单 Schema(渲染 + 校验 + 联动的唯一入口) | 74 | // 储蓄类表单 Schema(渲染 + 校验 + 联动的唯一入口) |
| 75 | +// @updated 2026-02-15 - 迁移到新的条件规则格式,使用 clear_when_hidden 替代 reset_map | ||
| 75 | const savingsFormSchema = { | 76 | const savingsFormSchema = { |
| 76 | // 基础字段:非提取计划部分 | 77 | // 基础字段:非提取计划部分 |
| 77 | base_fields: [ | 78 | base_fields: [ |
| ... | @@ -83,24 +84,25 @@ const savingsFormSchema = { | ... | @@ -83,24 +84,25 @@ const savingsFormSchema = { |
| 83 | { id: 'payment_period', key: 'payment_period', type: 'payment_period', label: '缴费年期', required: true, options_from: 'payment_periods' } | 84 | { id: 'payment_period', key: 'payment_period', type: 'payment_period', label: '缴费年期', required: true, options_from: 'payment_periods' } |
| 84 | ], | 85 | ], |
| 85 | // 提取计划字段:由 withdrawal_plan 开关控制 | 86 | // 提取计划字段:由 withdrawal_plan 开关控制 |
| 87 | + // 新格式说明: | ||
| 88 | + // - show_when: { field: 'xxx', op: 'eq', value: 'yyy' } 新格式条件 | ||
| 89 | + // - show_when: { field: 'xxx', equals: 'yyy' } 旧格式(向后兼容) | ||
| 90 | + // - clear_when_hidden: true 隐藏时自动清空字段值 | ||
| 86 | withdrawal_fields: [ | 91 | withdrawal_fields: [ |
| 87 | { id: 'withdrawal_enabled', key: 'withdrawal_enabled', type: 'radio', label: '是否希望生成一份允许减少名义金额的提取说明?', options: ['是', '否'], required: true, default: '否' }, | 92 | { id: 'withdrawal_enabled', key: 'withdrawal_enabled', type: 'radio', label: '是否希望生成一份允许减少名义金额的提取说明?', options: ['是', '否'], required: true, default: '否' }, |
| 88 | - { id: 'withdrawal_mode', key: 'withdrawal_mode', type: 'radio', label: '提取选项', options: ['指定提取金额', '最高固定提取金额'], required: true, default: '指定提取金额', section_title: '款项提取(允许减少名义金额)' }, | 93 | + { id: 'withdrawal_mode', key: 'withdrawal_mode', type: 'radio', label: '提取选项', options: ['指定提取金额', '最高固定提取金额'], required: true, default: '指定提取金额', section_title: '款项提取(允许减少名义金额)', clear_when_hidden: true }, |
| 89 | - { id: 'withdrawal_method', key: 'withdrawal_method', type: 'radio', label: '提取方式', options: ['按年岁'], required: true, default: '按年岁', show_when: [{ field: 'withdrawal_mode', equals: '指定提取金额' }] }, | 94 | + // 指定提取金额模式字段 |
| 90 | - { id: 'annual_withdrawal_amount', key: 'annual_withdrawal_amount', type: 'amount', label: '每年提取金额', placeholder: '请输入每年提取金额', input_label: '请输入每年提取金额', required: true, currency_from: 'withdrawal_plan.default_currency', show_when: [{ field: 'withdrawal_mode', equals: '指定提取金额' }] }, | 95 | + { id: 'withdrawal_method', key: 'withdrawal_method', type: 'radio', label: '提取方式', options: ['按年岁'], required: true, default: '按年岁', show_when: { field: 'withdrawal_mode', op: 'eq', value: '指定提取金额' }, clear_when_hidden: true }, |
| 91 | - { id: 'withdrawal_start_age_specified', key: 'withdrawal_start_age_specified', type: 'age', label: '由几岁开始', placeholder: '请输入开始提取年龄', required: true, show_when: [{ field: 'withdrawal_mode', equals: '指定提取金额' }] }, | 96 | + { id: 'annual_withdrawal_amount', key: 'annual_withdrawal_amount', type: 'amount', label: '每年提取金额', placeholder: '请输入每年提取金额', input_label: '请输入每年提取金额', required: true, currency_from: 'withdrawal_plan.default_currency', show_when: { field: 'withdrawal_mode', op: 'eq', value: '指定提取金额' }, clear_when_hidden: true }, |
| 92 | - { id: 'withdrawal_period_specified', key: 'withdrawal_period_specified', type: 'select', label: '提取期(年)', placeholder: '请选择提取期', required: true, options_from: 'withdrawal_plan.withdrawal_periods', show_when: [{ field: 'withdrawal_mode', equals: '指定提取金额' }] }, | 97 | + { id: 'withdrawal_start_age_specified', key: 'withdrawal_start_age_specified', type: 'age', label: '由几岁开始', placeholder: '请输入开始提取年龄', required: true, show_when: { field: 'withdrawal_mode', op: 'eq', value: '指定提取金额' }, clear_when_hidden: true }, |
| 93 | - { id: 'annual_increase_percentage', key: 'annual_increase_percentage', type: 'percentage', label: '每年递增提取之百分比(%)', placeholder: '请输入递增百分比', required: true, show_when: [{ field: 'withdrawal_mode', equals: '指定提取金额' }] }, | 98 | + { id: 'withdrawal_period_specified', key: 'withdrawal_period_specified', type: 'select', label: '提取期(年)', placeholder: '请选择提取期', required: true, options_from: 'withdrawal_plan.withdrawal_periods', show_when: { field: 'withdrawal_mode', op: 'eq', value: '指定提取金额' }, clear_when_hidden: true }, |
| 94 | - { id: 'withdrawal_start_age_fixed', key: 'withdrawal_start_age_fixed', type: 'age', label: '按年岁:由几岁开始', placeholder: '请输入开始提取年龄', required: true, show_when: [{ field: 'withdrawal_mode', equals: '最高固定提取金额' }] }, | 99 | + { id: 'annual_increase_percentage', key: 'annual_increase_percentage', type: 'percentage', label: '每年递增提取之百分比(%)', placeholder: '请输入递增百分比', required: true, show_when: { field: 'withdrawal_mode', op: 'eq', value: '指定提取金额' }, clear_when_hidden: true }, |
| 95 | - { id: 'withdrawal_period_fixed', key: 'withdrawal_period_fixed', type: 'select', label: '按年岁:提取期(年)', placeholder: '请选择提取期', required: true, options_from: 'withdrawal_plan.withdrawal_periods', show_when: [{ field: 'withdrawal_mode', equals: '最高固定提取金额' }] } | 100 | + // 最高固定提取金额模式字段 |
| 96 | - ], | 101 | + { id: 'withdrawal_start_age_fixed', key: 'withdrawal_start_age_fixed', type: 'age', label: '按年岁:由几岁开始', placeholder: '请输入开始提取年龄', required: true, show_when: { field: 'withdrawal_mode', op: 'eq', value: '最高固定提取金额' }, clear_when_hidden: true }, |
| 97 | - // 提取模式切换时的清空逻辑,避免脏字段影响提交 | 102 | + { id: 'withdrawal_period_fixed', key: 'withdrawal_period_fixed', type: 'select', label: '按年岁:提取期(年)', placeholder: '请选择提取期', required: true, options_from: 'withdrawal_plan.withdrawal_periods', show_when: { field: 'withdrawal_mode', op: 'eq', value: '最高固定提取金额' }, clear_when_hidden: true } |
| 98 | - reset_map: { | 103 | + ] |
| 99 | - withdrawal_mode: { | 104 | + // reset_map 已被 clear_when_hidden 替代 |
| 100 | - '最高固定提取金额': ['annual_withdrawal_amount', 'annual_increase_percentage', 'withdrawal_start_age_specified', 'withdrawal_period_specified'], | 105 | + // 当 withdrawal_mode 切换时,不可见的字段会自动清空 |
| 101 | - '指定提取金额': ['withdrawal_start_age_fixed', 'withdrawal_period_fixed'] | ||
| 102 | - } | ||
| 103 | - } | ||
| 104 | } | 106 | } |
| 105 | 107 | ||
| 106 | export const PLAN_TEMPLATES = { | 108 | export const PLAN_TEMPLATES = { | ... | ... |
| 1 | + | ... | ... |
| ... | @@ -234,6 +234,16 @@ function resolveSchemaRefs(config) { | ... | @@ -234,6 +234,16 @@ function resolveSchemaRefs(config) { |
| 234 | } | 234 | } |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | +/** | ||
| 238 | + * 构建表单 Schema 代码 | ||
| 239 | + * | ||
| 240 | + * @description 将 schema 对象转换为代码字符串 | ||
| 241 | + * @param {Object|string} value - schema 值 | ||
| 242 | + * @param {string} fallbackRef - 回退引用名 | ||
| 243 | + * @returns {string} 代码字符串 | ||
| 244 | + * | ||
| 245 | + * @updated 2026-02-15 - 支持新的条件格式 show_when: { field, op, value } | ||
| 246 | + */ | ||
| 237 | function buildSchemaCode(value, fallbackRef) { | 247 | function buildSchemaCode(value, fallbackRef) { |
| 238 | if (!value || isEmptyObject(value)) { | 248 | if (!value || isEmptyObject(value)) { |
| 239 | return fallbackRef | 249 | return fallbackRef |
| ... | @@ -241,13 +251,14 @@ function buildSchemaCode(value, fallbackRef) { | ... | @@ -241,13 +251,14 @@ function buildSchemaCode(value, fallbackRef) { |
| 241 | if (value && typeof value === 'object' && !Array.isArray(value)) { | 251 | if (value && typeof value === 'object' && !Array.isArray(value)) { |
| 242 | const baseFields = value.base_fields | 252 | const baseFields = value.base_fields |
| 243 | const withdrawalFields = value.withdrawal_fields | 253 | const withdrawalFields = value.withdrawal_fields |
| 244 | - const resetMap = value.reset_map | ||
| 245 | const baseFieldsEmpty = Array.isArray(baseFields) && baseFields.length === 0 | 254 | const baseFieldsEmpty = Array.isArray(baseFields) && baseFields.length === 0 |
| 246 | const withdrawalFieldsEmpty = !Array.isArray(withdrawalFields) || withdrawalFields.length === 0 | 255 | const withdrawalFieldsEmpty = !Array.isArray(withdrawalFields) || withdrawalFields.length === 0 |
| 247 | - const resetMapEmpty = !resetMap || (typeof resetMap === 'object' && !Array.isArray(resetMap) && Object.keys(resetMap).length === 0) | 256 | + if (baseFieldsEmpty && withdrawalFieldsEmpty) { |
| 248 | - if (baseFieldsEmpty && withdrawalFieldsEmpty && resetMapEmpty) { | ||
| 249 | return fallbackRef | 257 | return fallbackRef |
| 250 | } | 258 | } |
| 259 | + // 处理字段中的 show_when 格式转换 | ||
| 260 | + const processedValue = processSchemaFields(value) | ||
| 261 | + return JSON.stringify(processedValue, null, 2).replace(/\n/g, '\n ') | ||
| 251 | } | 262 | } |
| 252 | if (typeof value === 'string') { | 263 | if (typeof value === 'string') { |
| 253 | return value | 264 | return value |
| ... | @@ -255,6 +266,42 @@ function buildSchemaCode(value, fallbackRef) { | ... | @@ -255,6 +266,42 @@ function buildSchemaCode(value, fallbackRef) { |
| 255 | return JSON.stringify(value, null, 2).replace(/\n/g, '\n ') | 266 | return JSON.stringify(value, null, 2).replace(/\n/g, '\n ') |
| 256 | } | 267 | } |
| 257 | 268 | ||
| 269 | +/** | ||
| 270 | + * 处理 Schema 字段,转换条件格式 | ||
| 271 | + * | ||
| 272 | + * @private | ||
| 273 | + */ | ||
| 274 | +function processSchemaFields(schema) { | ||
| 275 | + const result = {} | ||
| 276 | + for (const [key, value] of Object.entries(schema)) { | ||
| 277 | + if (key === 'base_fields' || key === 'withdrawal_fields') { | ||
| 278 | + result[key] = value.map(field => processFieldCondition(field)) | ||
| 279 | + } else if (key !== 'reset_map') { | ||
| 280 | + // 忽略 reset_map,不再生成 | ||
| 281 | + result[key] = value | ||
| 282 | + } | ||
| 283 | + } | ||
| 284 | + return result | ||
| 285 | +} | ||
| 286 | + | ||
| 287 | +/** | ||
| 288 | + * 处理字段条件,转换为新格式 | ||
| 289 | + * | ||
| 290 | + * @private | ||
| 291 | + */ | ||
| 292 | +function processFieldCondition(field) { | ||
| 293 | + const result = { ...field } | ||
| 294 | + // 转换 show_when: { field, equals } -> { field, op: 'eq', value } | ||
| 295 | + if (result.show_when && result.show_when.equals !== undefined) { | ||
| 296 | + result.show_when = { | ||
| 297 | + field: result.show_when.field, | ||
| 298 | + op: 'eq', | ||
| 299 | + value: result.show_when.equals | ||
| 300 | + } | ||
| 301 | + } | ||
| 302 | + return result | ||
| 303 | +} | ||
| 304 | + | ||
| 258 | function isEmptyObject(value) { | 305 | function isEmptyObject(value) { |
| 259 | if (!value || typeof value !== 'object' || Array.isArray(value)) { | 306 | if (!value || typeof value !== 'object' || Array.isArray(value)) { |
| 260 | return false | 307 | return false | ... | ... |
-
Please register or login to post a comment