hookehuyr

docs(parse): 完善文档解析工具与审核流程

- 更新 README 解析工具使用说明
- 完善审核流程计划文档
- 添加解析审核记录
- 删除已解析的测试文件
- 新增 parse-audit 审核目录

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
...@@ -78,6 +78,8 @@ pnpm lint ...@@ -78,6 +78,8 @@ pnpm lint
78 -**输出结构补齐** - 解析输出 JSON 结构与稳定 form_sn 规则已明确 78 -**输出结构补齐** - 解析输出 JSON 结构与稳定 form_sn 规则已明确
79 -**审计与摘要** - 解析摘要与审计日志输出已接入 79 -**审计与摘要** - 解析摘要与审计日志输出已接入
80 -**审核流程规划** - 整理审核流程方案并对齐字段与目录规范 80 -**审核流程规划** - 整理审核流程方案并对齐字段与目录规范
81 +-**审核模板落地** - 待审核文件输出完善,默认不写入配置,需显式 --write-config
82 +-**链路与思路** - 补充解析链路与使用思路,明确审核与合并边界
81 83
82 ### 测试与验证 84 ### 测试与验证
83 -**回归测试** - pnpm test 通过,pnpm lint 存在 30 个现存警告 85 -**回归测试** - pnpm test 通过,pnpm lint 存在 30 个现存警告
......
1 +# 产品配置审核 - 计划书模版2.docx
2 +
3 +**解析时间**: 2026/2/14 23:58:54
4 +**原始文件**: 计划书模版2.docx
5 +**数据来源**: docs/to-parse/计划书模版2.docx
6 +
7 +---
8 +
9 +## 📋 产品基本信息
10 +
11 +| 字段 | 提取值 | 需要确认 |
12 +|------|--------|---------|
13 +| 产品名称 | 计划书模版2 | ✅ 请核对产品名称 |
14 +| 产品类型 | savings | ✅ 请确认产品类型 |
15 +| 币种 | USD | ✅ 请确认币种 |
16 +| form_sn | `savings-2-55bcffc2` | ✅ 请确认 form_sn 唯一性 |
17 +| 缴费年期 | ["整付"] | ✅ 请确认缴费年期选项 |
18 +| 年龄范围 | 0-75岁 | ✅ 请确认年龄范围 |
19 +| 保险期间 | 终身 | ✅ 请确认保险期间 |
20 +
21 +
22 +### 💰 储蓄类产品特有字段
23 +
24 +| 字段 | 提取值 | 需要确认 |
25 +|------|--------|---------|
26 +| 提取方式 | ["指定提取金额","最高固定提取金额"] | ✅ 请确认提取方式 |
27 +| 提取期 | ["1年","3年","5年","10年"] | ✅ 请确认提取期选项 |
28 +
29 +
30 +---
31 +
32 +## 🤖 智能字段提取报告
33 +
34 +### 匹配统计
35 +
36 +- ✅ 成功匹配: 3 字段
37 +- ⚠️ 使用默认值: 4 字段
38 +- ❌ 未匹配(需人工补充): 1 字段
39 +
40 +### ✅ 已成功匹配的字段
41 +
42 +- product_type
43 +- payment_periods
44 +- withdrawal_modes
45 +
46 +
47 +### ⚠️ 使用默认值的字段
48 +
49 +- **currency**: 未找到字段 "currency",使用默认值: "USD"
50 +- **age_range**: 未找到字段 "age_range",使用默认值: {"min":0,"max":75}
51 +- **insurance_period**: 未找到字段 "insurance_period",使用默认值: "终身"
52 +- **product_name**: 未找到产品名称,使用文件名: "计划书模版2"
53 +
54 +
55 +
56 +### ❌ 未匹配字段(需要人工补充)
57 +
58 +
59 +#### product_name
60 +
61 +- **原因**: 未找到匹配内容
62 +- **建议值**:
63 + - 从文档标题提取
64 + - 从第一行提取
65 + - 手动输入产品全称
66 +
67 +
68 +
69 +---
70 +
71 +## 🧾 配置预览
72 +
73 +```javascript
74 +{
75 + "product_name": "计划书模版2",
76 + "product_type": "savings",
77 + "currency": "USD",
78 + "form_sn": "savings-2-55bcffc2",
79 + "payment_periods": [
80 + "整付"
81 + ],
82 + "age_range": {
83 + "min": 0,
84 + "max": 75
85 + },
86 + "insurance_period": "终身",
87 + "is_savings": true,
88 + "withdrawal_modes": [
89 + "指定提取金额",
90 + "最高固定提取金额"
91 + ],
92 + "withdrawal_periods": [
93 + "1年",
94 + "3年",
95 + "5年",
96 + "10年"
97 + ]
98 +}
99 +```
100 +
101 +---
102 +
103 +## 📝 表单字段 (form_schema)
104 +
105 +```javascript
106 +{
107 + "base_fields": [],
108 + "withdrawal_fields": [],
109 + "reset_map": {}
110 +}
111 +```
112 +
113 +---
114 +
115 +## 🔄 提交字段映射 (submit_mapping)
116 +
117 +```javascript
118 +{}
119 +```
120 +
121 +---
122 +
123 +## 🧩 生成配置片段
124 +
125 +```javascript
126 +/**
127 + * 计划书模版2
128 + * @added 2026-02-14T15:58:54.707Z
129 + * @source docs/to-parse/计划书模版2.docx
130 + */
131 + 'savings-2-55bcffc2': {
132 + name: '计划书模版2',
133 + component: 'SavingsTemplate',
134 + category: 'savings',
135 + config: {
136 + currency: 'USD',
137 + payment_periods: ["整付"],
138 + age_range: { min: 0, max: 75 },
139 + insurance_period: '终身',
140 + withdrawal_plan: {
141 + enabled: true,
142 + currencies: ['HKD', 'USD', 'CNY'],
143 + default_currency: 'USD',
144 + withdrawal_modes: ["指定提取金额","最高固定提取金额"],
145 + withdrawal_periods: ["1年","3年","5年","10年"]
146 + },
147 + form_schema: savingsFormSchema,
148 + submit_mapping: savingsSubmitMapping
149 + }
150 + }
151 +```
152 +
153 +---
154 +
155 +## ✅ 审核检查清单
156 +
157 +### 基础信息
158 +- [ ] 产品名称正确
159 +- [ ] 产品类型正确(savings/critical-illness/life-insurance)
160 +- [ ] 币种正确(USD/CNY/HKD/EUR)
161 +- [ ] form_sn 唯一且符合命名规范
162 +
163 +### 缴费与年龄
164 +- [ ] 缴费年期选项完整且正确
165 +- [ ] 年龄范围合理
166 +- [ ] 保险期间正确
167 +
168 +### 储蓄类特有(如适用)
169 +- [ ] 提取方式正确
170 +- [ ] 提取期选项完整
171 +- [ ] 表单字段定义完整
172 +- [ ] 提交字段映射正确
173 +
174 +---
175 +
176 +## 📋 审核后操作
177 +
178 +### 确认无误
179 +```bash
180 +# 1. 移动到 approved 目录
181 +mv docs/parse-audit/pending/2026-02-14-计划书模版2.md \
182 + docs/parse-audit/approved/
183 +
184 +# 2. 合并到正式配置
185 +# 手动复制或使用工具合并到 src/config/plan-templates.js
186 +
187 +# 3. 删除待审核文件(可选)
188 +rm docs/parse-audit/pending/2026-02-14-计划书模版2.md
189 +```
190 +
191 +### 需要修改
192 +1. 编辑本文件修正内容
193 +2. 重新提交审核
194 +
195 +### 放弃本次解析
196 +```bash
197 +rm docs/parse-audit/pending/2026-02-14-计划书模版2.md
198 +```
199 +
200 +---
201 +
202 +## 审核状态
203 +
204 +- [ ] 待审核
205 +- [ ] 已通过
206 +- [ ] 已拒绝
207 +
208 +## 审核意见
209 +
210 +```text
211 +```
1 +# 产品配置审核 - 计划书模版3.docx
2 +
3 +**解析时间**: 2026/2/14 23:58:54
4 +**原始文件**: 计划书模版3.docx
5 +**数据来源**: docs/to-parse/计划书模版3.docx
6 +
7 +---
8 +
9 +## 📋 产品基本信息
10 +
11 +| 字段 | 提取值 | 需要确认 |
12 +| -------- | ---------------------- | ------------------------ |
13 +| 产品名称 | 计划书模版3 | ✅ 请核对产品名称 |
14 +| 产品类型 | savings | ✅ 请确认产品类型 |
15 +| 币种 | USD | ✅ 请确认币种 |
16 +| form_sn | `savings-3-8f4f27ad` | ✅ 请确认 form_sn 唯一性 |
17 +| 缴费年期 | ["5年"] | ✅ 请确认缴费年期选项 |
18 +| 年龄范围 | 0-75岁 | ✅ 请确认年龄范围 |
19 +| 保险期间 | 终身 | ✅ 请确认保险期间 |
20 +
21 +### 💰 储蓄类产品特有字段
22 +
23 +| 字段 | 提取值 | 需要确认 |
24 +| -------- | ------------------------------- | ------------------- |
25 +| 提取方式 | ["年龄指定金额","最高固定金额"] | ✅ 请确认提取方式 |
26 +| 提取期 | ["1年","3年","5年","10年"] | ✅ 请确认提取期选项 |
27 +
28 +---
29 +
30 +## 🤖 智能字段提取报告
31 +
32 +### 匹配统计
33 +
34 +- ✅ 成功匹配: 1 字段
35 +- ⚠️ 使用默认值: 5 字段
36 +- ❌ 未匹配(需人工补充): 1 字段
37 +
38 +### ✅ 已成功匹配的字段
39 +
40 +- payment_periods
41 +
42 +### ⚠️ 使用默认值的字段
43 +
44 +- **product_type**: 未找到字段 "product_type",使用默认值: "savings"
45 +- **currency**: 未找到字段 "currency",使用默认值: "USD"
46 +- **age_range**: 未找到字段 "age_range",使用默认值: {"min":0,"max":75}
47 +- **insurance_period**: 未找到字段 "insurance_period",使用默认值: "终身"
48 +- **product_name**: 未找到产品名称,使用文件名: "计划书模版3"
49 +
50 +### ❌ 未匹配字段(需要人工补充)
51 +
52 +#### product_name
53 +
54 +- **原因**: 未找到匹配内容
55 +- **建议值**:
56 + - 从文档标题提取
57 + - 从第一行提取
58 + - 手动输入产品全称
59 +
60 +---
61 +
62 +## 🧾 配置预览
63 +
64 +```javascript
65 +{
66 + "product_name": "计划书模版3",
67 + "product_type": "savings",
68 + "currency": "USD",
69 + "form_sn": "savings-3-8f4f27ad",
70 + "payment_periods": [
71 + "5年"
72 + ],
73 + "age_range": {
74 + "min": 0,
75 + "max": 75
76 + },
77 + "insurance_period": "终身",
78 + "is_savings": true,
79 + "withdrawal_modes": [
80 + "年龄指定金额",
81 + "最高固定金额"
82 + ],
83 + "withdrawal_periods": [
84 + "1年",
85 + "3年",
86 + "5年",
87 + "10年"
88 + ]
89 +}
90 +```
91 +
92 +---
93 +
94 +## 📝 表单字段 (form_schema)
95 +
96 +```javascript
97 +{
98 + "base_fields": [],
99 + "withdrawal_fields": [],
100 + "reset_map": {}
101 +}
102 +```
103 +
104 +---
105 +
106 +## 🔄 提交字段映射 (submit_mapping)
107 +
108 +```javascript
109 +{}
110 +```
111 +
112 +---
113 +
114 +## 🧩 生成配置片段
115 +
116 +```javascript
117 +/**
118 + * 计划书模版3
119 + * @added 2026-02-14T15:58:54.729Z
120 + * @source docs/to-parse/计划书模版3.docx
121 + */
122 + 'savings-3-8f4f27ad': {
123 + name: '计划书模版3',
124 + component: 'SavingsTemplate',
125 + category: 'savings',
126 + config: {
127 + currency: 'USD',
128 + payment_periods: ["5年"],
129 + age_range: { min: 0, max: 75 },
130 + insurance_period: '终身',
131 + withdrawal_plan: {
132 + enabled: true,
133 + currencies: ['HKD', 'USD', 'CNY'],
134 + default_currency: 'USD',
135 + withdrawal_modes: ["年龄指定金额","最高固定金额"],
136 + withdrawal_periods: ["1年","3年","5年","10年"]
137 + },
138 + form_schema: savingsFormSchema,
139 + submit_mapping: savingsSubmitMapping
140 + }
141 + }
142 +```
143 +
144 +---
145 +
146 +## ✅ 审核检查清单
147 +
148 +### 基础信息
149 +
150 +- [ ] 产品名称正确
151 +- [ ] 产品类型正确(savings/critical-illness/life-insurance)
152 +- [ ] 币种正确(USD/CNY/HKD/EUR)
153 +- [ ] form_sn 唯一且符合命名规范
154 +
155 +### 缴费与年龄
156 +
157 +- [ ] 缴费年期选项完整且正确
158 +- [ ] 年龄范围合理
159 +- [ ] 保险期间正确
160 +
161 +### 储蓄类特有(如适用)
162 +
163 +- [ ] 提取方式正确
164 +- [ ] 提取期选项完整
165 +- [ ] 表单字段定义完整
166 +- [ ] 提交字段映射正确
167 +
168 +---
169 +
170 +## 📋 审核后操作
171 +
172 +### 确认无误
173 +
174 +```bash
175 +# 1. 移动到 approved 目录
176 +mv docs/parse-audit/pending/2026-02-14-计划书模版3.md \
177 + docs/parse-audit/approved/
178 +
179 +# 2. 合并到正式配置
180 +# 手动复制或使用工具合并到 src/config/plan-templates.js
181 +
182 +# 3. 删除待审核文件(可选)
183 +rm docs/parse-audit/pending/2026-02-14-计划书模版3.md
184 +```
185 +
186 +### 需要修改
187 +
188 +1. 编辑本文件修正内容
189 +2. 重新提交审核
190 +
191 +### 放弃本次解析
192 +
193 +```bash
194 +rm docs/parse-audit/pending/2026-02-14-计划书模版3.md
195 +```
196 +
197 +---
198 +
199 +## 审核状态
200 +
201 +- [ ] 待审核
202 +- [ ] 已通过
203 +- [ ] 已拒绝
204 +
205 +## 审核意见
206 +
207 +```text
208 +
209 +```
...@@ -11,3 +11,9 @@ ...@@ -11,3 +11,9 @@
11 {"at":"2026-02-14T14:35:12.489Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":6,"success_list":[{"form_sn":"savings-2-148b3acd","product_name":"测试计划书-智享未来2","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":false,"dry_run":false,"updated_count":0,"form_sn_list":[],"conflicts":["savings-2-148b3acd"],"reason":"conflict"}} 11 {"at":"2026-02-14T14:35:12.489Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":6,"success_list":[{"form_sn":"savings-2-148b3acd","product_name":"测试计划书-智享未来2","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":false,"dry_run":false,"updated_count":0,"form_sn_list":[],"conflicts":["savings-2-148b3acd"],"reason":"conflict"}}
12 {"at":"2026-02-14T14:35:32.726Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":2,"success_list":[{"form_sn":"savings-2-148b3acd","product_name":"测试计划书-智享未来2","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":false,"dry_run":false,"updated_count":0,"form_sn_list":[],"conflicts":["savings-2-148b3acd"],"reason":"conflict"}} 12 {"at":"2026-02-14T14:35:32.726Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":2,"success_list":[{"form_sn":"savings-2-148b3acd","product_name":"测试计划书-智享未来2","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":false,"dry_run":false,"updated_count":0,"form_sn_list":[],"conflicts":["savings-2-148b3acd"],"reason":"conflict"}}
13 {"at":"2026-02-14T14:42:10.975Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":28,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":false,"updated_count":1,"form_sn_list":["savings-2-55bcffc2"],"conflicts":[],"reason":null}} 13 {"at":"2026-02-14T14:42:10.975Z","mode":"single","options":{"dry_run":false},"summary":{"total":1,"success":1,"failed":0,"duration_ms":28,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":false,"updated_count":1,"form_sn_list":["savings-2-55bcffc2"],"conflicts":[],"reason":null}}
14 +{"at":"2026-02-14T15:16:37.454Z","mode":"single","options":{"dry_run":true},"summary":{"total":1,"success":1,"failed":0,"duration_ms":39,"success_list":[{"form_sn":"savings-product-54cf664a","product_name":"智享未来储蓄计划书","file":"测试计划书-智享未来2.md"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":1,"form_sn_list":["savings-product-54cf664a"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 智享未来储蓄计划书\n+ * @added 2026-02-14T15:16:37.415Z\n+ * @source docs/to-parse/测试计划书-智享未来2.md\n+ */\n+ 'savings-product-54cf664a': {\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+ }"}}
15 +{"at":"2026-02-14T15:24:05.580Z","mode":"batch","options":{"dry_run":true},"summary":{"total":1,"success":1,"failed":0,"duration_ms":41,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":1,"form_sn_list":["savings-2-55bcffc2"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:24:05.564Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\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+ }"}}
16 +{"at":"2026-02-14T15:29:02.807Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":50,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:29:02.781Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\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+ * 计划书模版3\n+ * @added 2026-02-14T15:29:02.804Z\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: [\"整付\",\"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+ }"}}
17 +{"at":"2026-02-14T15:30:22.307Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":49,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:30:22.283Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\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+ * 计划书模版3\n+ * @added 2026-02-14T15:30:22.304Z\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: [\"整付\",\"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+ }"}}
18 +{"at":"2026-02-14T15:51:38.101Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":47,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:51:38.078Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\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+ * 计划书模版3\n+ * @added 2026-02-14T15:51:38.098Z\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: [\"整付\",\"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+ }"}}
19 +{"at":"2026-02-14T15:58:54.732Z","mode":"batch","options":{"dry_run":true},"summary":{"total":2,"success":2,"failed":0,"duration_ms":51,"success_list":[{"form_sn":"savings-2-55bcffc2","product_name":"计划书模版2","file":"计划书模版2.docx"},{"form_sn":"savings-3-8f4f27ad","product_name":"计划书模版3","file":"计划书模版3.docx"}],"failed_list":[]},"change_summary":{"ok":true,"dry_run":true,"updated_count":2,"form_sn_list":["savings-2-55bcffc2","savings-3-8f4f27ad"],"conflicts":[],"reason":null,"diff_preview":"--- plan-templates.js\n+++ plan-templates.js\n+ /**\n+ * 计划书模版2\n+ * @added 2026-02-14T15:58:54.707Z\n+ * @source docs/to-parse/计划书模版2.docx\n+ */\n+ 'savings-2-55bcffc2': {\n+ name: '计划书模版2',\n+ component: 'SavingsTemplate',\n+ category: 'savings',\n+ config: {\n+ currency: 'USD',\n+ payment_periods: [\"整付\"],\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+ * 计划书模版3\n+ * @added 2026-02-14T15:58:54.729Z\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年\"],\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+ }"}}
......
...@@ -202,22 +202,22 @@ rm docs/parse-audit/pending/${auditFileName} ...@@ -202,22 +202,22 @@ rm docs/parse-audit/pending/${auditFileName}
202 ## 实施计划 202 ## 实施计划
203 203
204 ### 阶段1: 修复审核模板与字段对齐 204 ### 阶段1: 修复审核模板与字段对齐
205 -- [ ] 清理 generateAuditFile 重复定义与模板断裂问题 205 +- [x] 清理 generateAuditFile 重复定义与模板断裂问题
206 -- [ ] 统一字段命名为 product_name/product_type/currency/form_sn 206 +- [x] 统一字段命名为 product_name/product_type/currency/form_sn
207 -- [ ] 优化审核模板展示 form_schema 与 submit_mapping 207 +- [x] 优化审核模板展示 form_schema 与 submit_mapping
208 208
209 ### 阶段2: 审核流程治理 209 ### 阶段2: 审核流程治理
210 -- [ ] 确认 pending/approved 目录结构 210 +- [x] 确认 pending/approved 目录结构
211 -- [ ] 明确审核通过后的合并指引 211 +- [x] 明确审核通过后的合并指引
212 -- [ ] 补齐审核状态与审核意见模板 212 +- [x] 补齐审核状态与审核意见模板
213 213
214 ### 阶段3: 解析策略补齐 214 ### 阶段3: 解析策略补齐
215 -- [ ] 增加标题/币种/类型的启发式补位策略 215 +- [x] 增加标题/币种/类型的启发式补位策略
216 -- [ ] 补齐文档样本验证与失败兜底说明 216 +- [x] 补齐文档样本验证与失败兜底说明
217 217
218 ### 阶段4: 测试验证 218 ### 阶段4: 测试验证
219 -- [ ] 使用实际文档回归生成审核文件 219 +- [x] 使用实际文档回归生成审核文件
220 -- [ ] 校验审核模板完整性与可读性 220 +- [x] 校验审核模板完整性与可读性
221 221
222 --- 222 ---
223 223
......
...@@ -22,16 +22,48 @@ docs/to-parse/ ...@@ -22,16 +22,48 @@ docs/to-parse/
22 # 查看待处理的文档 22 # 查看待处理的文档
23 pnpm run parse:docs:list 23 pnpm run parse:docs:list
24 24
25 -# 解析所有文档 25 +# 解析所有文档(默认仅生成待审核文件,不写入配置)
26 pnpm run parse:docs 26 pnpm run parse:docs
27 27
28 -# 解析指定文档 28 +# 解析指定文档(默认仅生成待审核文件,不写入配置)
29 pnpm run parse:docs:file -- --file="产品说明书.pdf" 29 pnpm run parse:docs:file -- --file="产品说明书.pdf"
30 +
31 +# 解析并写入配置(需要显式开启)
32 +pnpm run parse:docs:file -- --file="产品说明书.pdf" --write-config
30 ``` 33 ```
31 34
32 ### 3. 查看结果 35 ### 3. 查看结果
33 36
34 -解析成功后,配置会自动添加到 `src/config/plan-templates.js` 37 +解析成功后会生成待审核文件,位置如下:
38 +
39 +```
40 +docs/parse-audit/pending/
41 +```
42 +
43 +审核通过后再手动合并到 `src/config/plan-templates.js`,或使用 `--write-config` 明确写入。
44 +
45 +## 🔗 功能链路
46 +
47 +```
48 +文档放入 docs/to-parse/
49 +
50 +markitdown 抽取文本
51 +
52 +启发式推断基础信息(产品名称/类型/币种)
53 +
54 +生成配置代码与待审核文件
55 +
56 +人工审核(pending → approved)
57 +
58 +合并到 src/config/plan-templates.js
59 +```
60 +
61 +## 🧭 使用思路
62 +
63 +1. **先审核再合并**:默认只生成待审核文件,避免直接污染配置。
64 +2. **先读再写**:审核时重点核对产品名称、币种、缴费年期、年龄范围。
65 +3. **分离责任**:解析用于提取线索,最终配置仍由人工确认。
66 +4. **可追溯**:审计日志记录每次解析结果与变更摘要。
35 67
36 ## 📋 支持的文档格式 68 ## 📋 支持的文档格式
37 69
...@@ -64,11 +96,7 @@ docs/parsed-backup/parse-audit.jsonl ...@@ -64,11 +96,7 @@ docs/parsed-backup/parse-audit.jsonl
64 96
65 ## 🔧 配置 AI 服务 97 ## 🔧 配置 AI 服务
66 98
67 -脚本使用 skill 工具调用 AI 服务,支持: 99 +脚本当前使用 markitdown CLI 进行文档抽取,AI 服务仍待接入。
68 -- OpenAI GPT-4o Vision
69 -- Anthropic Claude 3.5 Sonnet
70 -
71 -你需要配置 API Key(首次使用时脚本会提示)
72 100
73 ## ⚠️ 注意事项 101 ## ⚠️ 注意事项
74 102
......
1 -# 智享未来储蓄计划书
2 -
3 -## 产品概述
4 -
5 -**产品名称**: 智享未来储蓄计划
6 -**产品类型**: 储蓄型保险
7 -**保险公司**: 宏利人寿保险
8 -**币种**: 美元 (USD)
9 -
10 ----
11 -
12 -## 产品特点
13 -
14 -### 核心优势
15 -- 保证现金价值,稳健增值
16 -- 灵活提取方式,满足不同人生阶段需求
17 -- 多种缴费年期选择,适应不同财务规划
18 -- 美元/港币/人民币多币种选择
19 -
20 -### 适合人群
21 -- 希望长期稳健增值的客户
22 -- 有子女教育金规划需求的父母
23 -- 有养老规划需求的人士
24 -- 希望灵活运用资金的高净值人士
25 -
26 ----
27 -
28 -## 投保条件
29 -
30 -### 投保年龄
31 -- 最低投保年龄:出生 15 天
32 -- 最高投保年龄:75 岁
33 -
34 -### 缴费年期
35 -- 整付(0-75 岁)
36 -- 3 年期缴
37 -- 5 年期缴
38 -- 10 年期缴
39 -
40 -### 保险期间
41 -- 终身(至 100 岁)
42 -
43 ----
44 -
45 -## 保障利益
46 -
47 -### 身故保险金
48 -若被保险人身故,我们将支付身故保险金予受益人。
49 -
50 -### 现金价值
51 -保单生效后具有现金价值,现金价值随保单年度增长而增加。
52 -
53 -### 红利分配
54 -本公司将根据分红保险业务的投资经营状况决定红利分配金额。
55 -
56 ----
57 -
58 -## 提取计划
59 -
60 -### 提取方式
61 -客户可选择以下提取方式:
62 -
63 -**方式一:年龄指定金额提取**
64 -- 客户可指定从特定年龄开始,每年提取固定金额
65 -- 提取年龄可选:18/20/22/25/30/35/40/45/50/55/60 岁
66 -- 每年提取金额:最低 1,000 美元
67 -
68 -**方式二:最高固定金额提取**
69 -- 客户可选择提取最高固定金额
70 -- 适用于需要大额资金支出的场景
71 -
72 -### 提取周期
73 -- 每年提取
74 -- 每 2 年提取
75 -- 每 3 年提取
76 -- 每 5 年提取
77 -- 每 10 年提取
78 -- 终身提取
79 -
80 -### 支持币种
81 -- 美元 (USD)
82 -- 港币 (HKD)
83 -- 人民币 (CNY)
84 -
85 ----
86 -
87 -## 缴费示例
88 -
89 -### 案例:35 岁男性,整付,年缴保费 50,000 美元
90 -
91 -| 保单年度 | 年缴保费 | 累计保费 | 保证现金价值 |
92 -|---------|---------|---------|-------------|
93 -| 第 1 年 | $50,000 | $50,000 | $45,000 |
94 -| 第 5 年 | $50,000 | $250,000 | $235,000 |
95 -| 第 10 年 | $50,000 | $500,000 | $490,000 |
96 -| 第 20 年 | - | $500,000 | $1,050,000 |
97 -| 第 30 年 | - | $500,000 | $1,650,000 |
98 -
99 -*注:以上数字仅为示例,实际现金价值以保险公司公布为准。
100 -
101 ----
102 -
103 -## 退保规定
104 -
105 -### 犹豫期
106 -保单签收后 15 天内为犹豫期,投保人可无条件解除合同,本公司无息退还已收保费。
107 -
108 -### 退保价值
109 -保单生效后,投保人可申请解除合同,本公司将支付退保金(即当时的现金价值)予投保人。
110 -
111 ----
112 -
113 -## 保费表
114 -
115 -### 整付保费表(美元)
116 -
117 -| 年龄 | 男性 | 女性 |
118 -|-----|------|------|
119 -| 0 岁 | $45,200 | $44,800 |
120 -| 10 岁 | $46,500 | $46,100 |
121 -| 20 岁 | $48,000 | $47,600 |
122 -| 30 岁 | $50,000 | $49,500 |
123 -| 40 岁 | $53,500 | $52,800 |
124 -| 50 岁 | $59,200 | $58,000 |
125 -| 60 岁 | $68,500 | $66,800 |
126 -| 70 岁 | $89,200 | $86,500 |
127 -
128 -### 5 年期缴保费表(美元)
129 -
130 -| 年龄 | 年缴保费 | 总保费 |
131 -|-----|---------|-------|
132 -| 0 岁 | $10,500 | $52,500 |
133 -| 10 岁 | $10,800 | $54,000 |
134 -| 20 岁 | $11,200 | $56,000 |
135 -| 30 岁 | $11,800 | $59,000 |
136 -| 40 岁 | $12,800 | $64,000 |
137 -| 50 岁 | $14,500 | $72,500 |
138 -| 60 岁 | $17,200 | $86,000 |
139 -| 70 岁 | $23,500 | $117,500 |
140 -
141 ----
142 -
143 -## 责任免除
144 -
145 -因下列情形之一导致被保险人身故的,本公司不承担保险责任:
146 -
147 -1. 投保人故意造成被保险人死亡、故意伤害被保险人
148 -2. 被保险人故意自伤、故意犯罪或抗拒依法采取的刑事强制措施
149 -3. 被保险人主动吸食或注射毒品
150 -4. 被保险人在本合同成立或复效之日起 2 年内自杀
151 -5. 战争、军事冲突、暴乱或武装叛乱
152 -6. 核爆炸、核辐射、辐射污染
153 -
154 ----
155 -
156 -## 特别约定
157 -
158 -1. 本合同项下的保险责任自本公司同意承保并收取首期保险费后开始
159 -2. 投保人应如实告知被保险人的健康状况,如故意不履行如实告知义务,本公司有权解除合同
160 -3. 本合同项下的保险金请求权,自被保险人或受益人知道保险事故发生之日起 5 年内不行使而消灭
161 -
162 ----
163 -
164 -## 联系方式
165 -
166 -**客服热线**: 400-888-8888
167 -**公司网址**: www.manulife.com
168 -**营业时间**: 周一至周五 9:00-17:30
169 -
170 ----
171 -
172 -*本计划书仅供参考,具体保险责任及责任免除以保险合同为准*
173 -
174 ----
175 -
176 -**文档版本**: V1.0
177 -**生成日期**: 2026年2月13日
178 -**用途**: 测试文档解析功能
...@@ -30,6 +30,7 @@ import { ...@@ -30,6 +30,7 @@ import {
30 MARKITDOWN_CONFIG, 30 MARKITDOWN_CONFIG,
31 AI_SERVICE_CONFIG 31 AI_SERVICE_CONFIG
32 } from './parse-config.js' 32 } from './parse-config.js'
33 +import { smartExtractFields, generateAuditReport } from './smart-field-extractor.js'
33 34
34 // ========== 配置区 ========== 35 // ========== 配置区 ==========
35 36
...@@ -490,31 +491,46 @@ async function parseDocumentWithAI(docPath) { ...@@ -490,31 +491,46 @@ async function parseDocumentWithAI(docPath) {
490 } 491 }
491 492
492 const content = parse_result.text 493 const content = parse_result.text
494 + const fileName = path.basename(docPath)
493 495
494 - // 步骤 2: 调用 AI 服务从文档内容中提取配置 496 + // 步骤 2: 使用智能字段提取器
495 - // TODO(human): 集成 AI 服务(OpenAI/Anthropic) 497 + console.log('🧠 使用智能字段提取器...')
496 - // 需要配置 API Key 和服务端点 498 + const extractResult = smartExtractFields(content, fileName)
497 - console.log('📝 AI 配置提取: 待集成 AI 服务')
498 499
499 - // 临时方案:生成基础配置(基于文件名和内容启发式推断) 500 + // 生成审核报告
500 - const fileName = path.basename(docPath, path.extname(docPath)) 501 + const auditReport = generateAuditReport(extractResult)
502 + console.log('\n' + auditReport)
503 +
504 + // 构建配置对象
501 const config = { 505 const config = {
502 - product_name: fileName, 506 + ...extractResult.config,
503 - product_type: inferProductType(fileName, content), 507 + is_savings: extractResult.config.product_type === 'savings',
504 - currency: inferCurrency(content),
505 - payment_periods: ['整付', '3年', '5年'],
506 - age_range: { min: 0, max: 75 },
507 - insurance_period: '终身',
508 - is_savings: true,
509 - withdrawal_modes: ['年龄指定金额', '最高固定金额'],
510 - withdrawal_periods: ['1年', '3年', '5年', '10年'],
511 form_schema: { base_fields: [], withdrawal_fields: [], reset_map: {} }, 508 form_schema: { base_fields: [], withdrawal_fields: [], reset_map: {} },
512 submit_mapping: {} 509 submit_mapping: {}
513 } 510 }
514 511
515 - console.log('✅ 解析成功 (启发式推断)') 512 + // 保存匹配详情供后续审核使用
513 + config._extractDetails = {
514 + matched: extractResult.matchDetails.filter(m => m.matched).map(m => m.field),
515 + unmatched: extractResult.unmatched,
516 + warnings: extractResult.warnings
517 + }
518 +
519 + config.form_sn = generateFormSn(config)
520 +
521 + const matchedCount = extractResult.matchDetails.filter(m => m.matched).length
522 + const totalCount = extractResult.matchDetails.length
523 +
524 + console.log(`\n✅ 解析成功 (智能匹配 ${matchedCount}/${totalCount} 字段)`)
525 + console.log(` 产品名称: ${config.product_name}`)
516 console.log(` 产品类型: ${config.product_type}`) 526 console.log(` 产品类型: ${config.product_type}`)
517 console.log(` 币种: ${config.currency}`) 527 console.log(` 币种: ${config.currency}`)
528 + console.log(` 缴费年期: ${JSON.stringify(config.payment_periods)}`)
529 +
530 + if (extractResult.unmatched.length > 0) {
531 + console.log(`\n⚠️ 需要人工补充 ${extractResult.unmatched.length} 个字段,详见审核文件`)
532 + }
533 +
518 return config 534 return config
519 } catch (error) { 535 } catch (error) {
520 console.error(`❌ 解析失败 (${docPath}):`, error.message) 536 console.error(`❌ 解析失败 (${docPath}):`, error.message)
...@@ -629,154 +645,184 @@ async function parseSingleFile(filePath) { ...@@ -629,154 +645,184 @@ async function parseSingleFile(filePath) {
629 /** 645 /**
630 * 生成待审核文件 646 * 生成待审核文件
631 * 647 *
632 - * @description 生成人类可读的 markdown 审核文件 648 + * @description 生成人类可读的 markdown 审核文件,保存到 docs/parse-audit/pending/
633 * @param {string} fileName - 原始文件名 649 * @param {string} fileName - 原始文件名
634 * @param {Object} config - 解析的配置对象 650 * @param {Object} config - 解析的配置对象
635 * @param {string} code - 生成的配置代码 651 * @param {string} code - 生成的配置代码
636 * @returns {Promise<string|null>} 审核文件路径 652 * @returns {Promise<string|null>} 审核文件路径
637 */ 653 */
638 async function generateAuditFile(fileName, config, code) { 654 async function generateAuditFile(fileName, config, code) {
639 - const AUDIT_DIR = path.resolve(process.cwd(), 'docs/parse-audit/pending') 655 + const AUDIT_PENDING_DIR = path.resolve(process.cwd(), 'docs/parse-audit/pending')
640 - ensureDir(AUDIT_DIR) 656 + const AUDIT_APPROVED_DIR = path.resolve(process.cwd(), 'docs/parse-audit/approved')
657 + ensureDir(AUDIT_PENDING_DIR)
658 + ensureDir(AUDIT_APPROVED_DIR)
641 659
642 const date = new Date().toISOString().split('T')[0] 660 const date = new Date().toISOString().split('T')[0]
643 const auditFileName = `${date}-${fileName.replace(/\.[^/.]+$/, '')}.md` 661 const auditFileName = `${date}-${fileName.replace(/\.[^/.]+$/, '')}.md`
644 - const auditFilePath = path.join(AUDIT_DIR, auditFileName) 662 + const auditFilePath = path.join(AUDIT_PENDING_DIR, auditFileName)
663 + const formSn = generateFormSn(config)
664 + const formSchemaPreview = config.form_schema ? JSON.stringify(config.form_schema, null, 2) : '// 请手动补充'
665 + const submitMappingPreview = config.submit_mapping ? JSON.stringify(config.submit_mapping, null, 2) : '// 请手动补充'
666 + const configPreview = {
667 + product_name: config.product_name || '',
668 + product_type: config.product_type || '',
669 + currency: config.currency || '',
670 + form_sn: formSn,
671 + payment_periods: config.payment_periods || [],
672 + age_range: config.age_range || { min: 0, max: 75 },
673 + insurance_period: config.insurance_period || '终身',
674 + is_savings: config.is_savings || config.product_type === 'savings',
675 + withdrawal_modes: config.withdrawal_modes || [],
676 + withdrawal_periods: config.withdrawal_periods || []
677 + }
645 678
646 - const content = `# ${config.product_name || fileName} 679 + // 生成字段提取报告
680 + let extractionReport = ''
681 + if (config._extractDetails) {
682 + const { matched, unmatched, warnings } = config._extractDetails
647 683
648 -## 解析信息 684 + extractionReport = `
685 +---
649 686
650 -- **原始文件**: ${fileName} 687 +## 🤖 智能字段提取报告
651 -- **解析时间**: ${new Date().toLocaleString('zh-CN')}
652 -- **数据来源**: docs/to-parse/${fileName}
653 688
654 ---- 689 +### 匹配统计
655 690
656 -## 配置预览 691 +- ✅ 成功匹配: ${matched.length} 字段
692 +- ⚠️ 使用默认值: ${warnings.length} 字段
693 +- ❌ 未匹配(需人工补充): ${unmatched.length} 字段
657 694
658 -\`\`\`javascript 695 +### ✅ 已成功匹配的字段
659 -const config = \\${JSON.stringify(config, null, 2)}
660 -\`\`
661 696
662 ---- 697 +${matched.map(f => `- ${f}`).join('\n') || '- (无)'}
663 698
664 -## 审核检查清单 699 +${warnings.length > 0 ? `
700 +### ⚠️ 使用默认值的字段
665 701
666 -- [ ] 产品名称是否正确 702 +${warnings.map(w => `- **${w.field}**: ${w.message}`).join('\n')}
667 -- [ ] 产品类型是否正确(${config.product_type || '未知'} 703 +` : ''}
668 -- [ ] 币种是否正确(${config.currency || '未知'}
669 -- [ ] age_range 是否合理(${config.age_range?.min || 0} - ${config.age_range?.max || 75}岁)
670 -- [ ] form_schema 字段是否完整
671 -- [ ] submit_mapping 逻辑是否正确
672 704
673 ---- 705 +${unmatched.length > 0 ? `
706 +### ❌ 未匹配字段(需要人工补充)
674 707
675 -## 下一步 708 +${unmatched.map(item => `
709 +#### ${item.field}
676 710
677 -1. 审核以上配置是否正确 711 +- **原因**: ${item.reason}
678 -2. 确核通过后,执行以下操作: 712 +- **建议值**:
713 +${item.suggestions.map(s => ` - ${s}`).join('\n')}
714 +`).join('\n')}
715 +` : ''}
716 +`
717 + }
679 718
680 -\`\`\`bash 719 + const content = `# 产品配置审核 - ${fileName}
681 -# 1. 移动到 approved 目录
682 -mv docs/parse-audit/pending/${auditFileName} docs/parse-audit/approved/
683 720
684 -# 2. 手动添加配置到 src/config/plan-templates.js 721 +**解析时间**: ${new Date().toLocaleString('zh-CN')}
685 -# 3. 运行 pnpm lint 检 722 +**原始文件**: ${fileName}
686 -\`\` 723 +**数据来源**: docs/to-parse/${fileName}
687 724
688 --- 725 ---
689 726
690 -## 审核状态 727 +## 📋 产品基本信息
728 +
729 +| 字段 | 提取值 | 需要确认 |
730 +|------|--------|---------|
731 +| 产品名称 | ${config.product_name || '未提取'} | ✅ 请核对产品名称 |
732 +| 产品类型 | ${config.product_type || '未提取'} | ✅ 请确认产品类型 |
733 +| 币种 | ${config.currency || 'USD'} | ✅ 请确认币种 |
734 +| form_sn | \`${formSn}\` | ✅ 请确认 form_sn 唯一性 |
735 +| 缴费年期 | ${JSON.stringify(config.payment_periods || [])} | ✅ 请确认缴费年期选项 |
736 +| 年龄范围 | ${config.age_range?.min || 0}-${config.age_range?.max || 75} | 请确认年龄范围 |
737 +| 保险期间 | ${config.insurance_period || '终身'} | 请确认保险期间 |
738 +
739 +${config.is_savings ? `
740 +### 💰 储蓄类产品特有字段
741 +
742 +| 字段 | 提取值 | 需要确认 |
743 +|------|--------|---------|
744 +| 提取方式 | ${JSON.stringify(config.withdrawal_modes || [])} | ✅ 请确认提取方式 |
745 +| 提取期 | ${JSON.stringify(config.withdrawal_periods || [])} | ✅ 请确认提取期选项 |
746 +` : ''}
747 +${extractionReport}
748 +---
691 749
692 -- [ ] 待审核 750 +## 🧾 配置预览
693 -- [ ] 已通过
694 -- [ ] 已拒绝
695 751
696 -## 审核意见 752 +\`\`\`javascript
753 +${JSON.stringify(configPreview, null, 2)}
754 +\`\`\`
697 755
698 -<!-- 审核时请填写 --> 756 +---
699 757
700 -**生成时间**: ${new Date().toLocaleString('zh-CN')} 758 +## 📝 表单字段 (form_schema)
701 -`
702 759
703 -<!-- 审核通过后,请执行以下步骤:--> 760 +\`\`\`javascript
704 -1. 将此文件移动到 \`docs/parse-audit/approved/\` 761 +${formSchemaPreview}
705 -2. 手动将配置添加到 \`src/config/plan-templates.js\` 762 +\`\`\`
706 -3. 运行 \`pnpm lint\` �查
707 -`
708 763
709 --- 764 ---
710 765
711 -**注意**: 766 +## 🔄 提交字段映射 (submit_mapping)
712 -- 请仔细核对配置的每个字段
713 -- 确认产品类型和币种是否符合业务需求
714 -- �查 form_schema 中的字段定义是否完整
715 -`
716 767
717 -` 768 +\`\`\`javascript
769 +${submitMappingPreview}
770 +\`\`\`
718 771
719 - try { 772 +---
720 - fs.writeFileSync(auditFilePath, content, 'utf-8')
721 - return auditFilePath
722 - } catch (error) {
723 - console.error(\`❌ 写入审核文件失败: \${error.message}`)
724 - return null
725 - }
726 -}
727 773
728 -/** 774 +## 🧩 生成配置片段
729 - * 生成待审核文件
730 - *
731 - * @description 生成人类可读的 markdown 审核文件,保存到 docs/parse-audit/pending/
732 - * @param {string} fileName - 原始文件名
733 - * @param {Object} config - 解析的配置对象
734 - * @param {string} code - 生成的配置代码
735 - * @returns {Promise<string|null>} 审核文件路径
736 - */
737 -async function generateAuditFile(fileName, config, code) {
738 - const AUDIT_DIR = path.resolve(process.cwd(), 'docs/parse-audit/pending')
739 - ensureDir(AUDIT_DIR)
740 775
741 - const date = new Date().toISOString().split('T')[0] 776 +\`\`\`javascript
742 - const auditFileName = `${date}-${fileName.replace(/\.[^/.]+$/, '')}.md` 777 +${code.trim()}
743 - const auditFilePath = path.join(AUDIT_DIR, auditFileName) 778 +\`\`\`
779 +
780 +---
744 781
745 - const content = `# ${config.product_name || fileName} 782 +## ✅ 审核检查清单
746 783
747 -## 解析信息 784 +### 基础信息
785 +- [ ] 产品名称正确
786 +- [ ] 产品类型正确(savings/critical-illness/life-insurance)
787 +- [ ] 币种正确(USD/CNY/HKD/EUR)
788 +- [ ] form_sn 唯一且符合命名规范
748 789
749 -- **原始文件**: ${fileName} 790 +### 缴费与年龄
750 -- **解析时间**: ${new Date().toLocaleString('zh-CN')} 791 +- [ ] 缴费年期选项完整且正确
751 -- **数据来源**: docs/to-parse/${fileName} 792 +- [ ] 年龄范围合理
793 +- [ ] 保险期间正确
794 +
795 +### 储蓄类特有(如适用)
796 +- [ ] 提取方式正确
797 +- [ ] 提取期选项完整
798 +- [ ] 表单字段定义完整
799 +- [ ] 提交字段映射正确
752 800
753 --- 801 ---
754 802
755 -## 配置预览 803 +## 📋 审核后操作
756 804
757 -\`\`\`javascript 805 +### 确认无误
758 -{ 806 +\`\`\`bash
759 - "product_name": "${config.product_name || ''}", 807 +# 1. 移动到 approved 目录
760 - "product_type": "${config.product_type || ''}", 808 +mv docs/parse-audit/pending/${auditFileName} \\
761 - "currency": "${config.currency || ''}", 809 + docs/parse-audit/approved/
762 -${Object.entries(config).filter(([k]) =>
763 -!['source_file', 'form_schema', 'submit_mapping'].includes(k)
764 -).map(([k, v]) =>
765 - ` "${k}": ${JSON.stringify(v, null, 2)}`
766 -).join(',\n ')}
767 -\`\`\`
768 810
769 ---- 811 +# 2. 合并到正式配置
812 +# 手动复制或使用工具合并到 src/config/plan-templates.js
813 +
814 +# 3. 删除待审核文件(可选)
815 +rm docs/parse-audit/pending/${auditFileName}
816 +\`\`\`
770 817
771 -## 审核检查清单 818 +### 需要修改
819 +1. 编辑本文件修正内容
820 +2. 重新提交审核
772 821
773 -- [ ] 产品名称是否正确 822 +### 放弃本次解析
774 -- [ ] 产品类型是否正确 823 +\`\`\`bash
775 -- [ ] 币种是否正确 824 +rm docs/parse-audit/pending/${auditFileName}
776 -- [ ] age_range 是否合理 825 +\`\`\`
777 -- [ ] payment_periods / withdrawal_periods 是否完整
778 -- [ ] form_schema 字段是否完整
779 -- [ ] 提取逻辑是否符合需求
780 826
781 --- 827 ---
782 828
...@@ -788,15 +834,9 @@ ${Object.entries(config).filter(([k]) => ...@@ -788,15 +834,9 @@ ${Object.entries(config).filter(([k]) =>
788 834
789 ## 审核意见 835 ## 审核意见
790 836
837 +\`\`\`text
791 \`\`\` 838 \`\`\`
792 - 839 +`
793 -<!-- 审核通过后,请执行以下步骤:
794 -
795 -1. 将此文件移动到 docs/parse-audit/approved/
796 -2. 手动将配置添加到 src/config/plan-templates.js
797 -3. 提交变更
798 -
799 --->
800 840
801 try { 841 try {
802 fs.writeFileSync(auditFilePath, content, 'utf-8') 842 fs.writeFileSync(auditFilePath, content, 'utf-8')
...@@ -1274,7 +1314,8 @@ async function main() { ...@@ -1274,7 +1314,8 @@ async function main() {
1274 // 检查模式 1314 // 检查模式
1275 const listMode = args.includes('--list') 1315 const listMode = args.includes('--list')
1276 const fileMode = args.find(arg => arg.startsWith('--file=')) 1316 const fileMode = args.find(arg => arg.startsWith('--file='))
1277 - const dryRunMode = args.includes('--dry-run') 1317 + const writeMode = args.includes('--write-config')
1318 + const dryRunMode = args.includes('--dry-run') || !writeMode
1278 const rollbackMode = args.find(arg => arg.startsWith('--rollback=')) 1319 const rollbackMode = args.find(arg => arg.startsWith('--rollback='))
1279 const statusMode = args.includes('--status') 1320 const statusMode = args.includes('--status')
1280 1321
......