docs(api): 重组接口文档结构
将独立的接口联调文档合并到统一的 API 集成日志中 变更内容: - 将计划书模块接口文档合并到 docs/api-docs/API 集成日志.md - 新增计划书模块(2个接口) • 接口1: 提交计划书表单(待后端开发) • 接口2: 查询计划书状态(待后端开发) - 更新总体进度:27 → 29 个接口 - 更新版本号:v2.5 → v2.6 - 删除独立的 docs/接口联调注意事项.md 文档规范: - 遵循项目统一的接口文档结构 - 所有接口集成记录集中在 API 集成日志中维护 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Showing
2 changed files
with
140 additions
and
448 deletions
| ... | @@ -4,15 +4,30 @@ | ... | @@ -4,15 +4,30 @@ |
| 4 | 4 | ||
| 5 | ## 📊 总体进度 | 5 | ## 📊 总体进度 |
| 6 | 6 | ||
| 7 | -- **总接口数**: 27 | 7 | +- **总接口数**: 29 |
| 8 | -- **已完成**: 15 (55.6%) | 8 | +- **已完成**: 15 (51.7%) |
| 9 | - **联调中**: 0 (0%) | 9 | - **联调中**: 0 (0%) |
| 10 | -- **已废弃**: 3 (11.1%) | 10 | +- **已废弃**: 3 (10.3%) |
| 11 | -- **待联调**: 9 (33.3%) | 11 | +- **待联调**: 9 (31.0%) |
| 12 | +- **待后端开发**: 2 (6.9%) | ||
| 12 | - **有阻塞**: 0 | 13 | - **有阻塞**: 0 |
| 13 | 14 | ||
| 14 | --- | 15 | --- |
| 15 | 16 | ||
| 17 | +**📝 最近更新** (2026-02-09): | ||
| 18 | +- 🆕 **新增计划书模块**: | ||
| 19 | + - 接口1: 提交计划书表单(submitPlanAPI)- 待后端开发 | ||
| 20 | + - 接口2: 查询计划书状态(getPlanStatusAPI)- 规划中 | ||
| 21 | +- ✅ **前端表单已完成**: | ||
| 22 | + - 修复表单提交时数据为空的问题 | ||
| 23 | + - 添加金额字段格式化显示(分 → 元) | ||
| 24 | + - 实现表单验证和数据准备 | ||
| 25 | +- ⚠️ **数据单位规范**: | ||
| 26 | + - 金额字段单位为"分"(非"元") | ||
| 27 | + - 存储格式:整数(如 10000 表示 100.00 元) | ||
| 28 | + - 显示格式:除以 100 并保留 2 位小数 | ||
| 29 | +- 📝 **详细注意事项**:[接口联调注意事项.md](../接口联调注意事项.md) | ||
| 30 | + | ||
| 16 | **📝 最近更新** (2026-02-06): | 31 | **📝 最近更新** (2026-02-06): |
| 17 | - ✅ **搜索模块联调完成**:searchAPI 接口前端已完成集成 | 32 | - ✅ **搜索模块联调完成**:searchAPI 接口前端已完成集成 |
| 18 | - 支持产品和资料的实时搜索 | 33 | - 支持产品和资料的实时搜索 |
| ... | @@ -1146,6 +1161,121 @@ | ... | @@ -1146,6 +1161,121 @@ |
| 1146 | 1161 | ||
| 1147 | --- | 1162 | --- |
| 1148 | 1163 | ||
| 1164 | +### 计划书模块 | ||
| 1165 | + | ||
| 1166 | +#### 接口 1: 提交计划书表单 | ||
| 1167 | + | ||
| 1168 | +**接口信息** | ||
| 1169 | +- **接口名称**: `submitPlanAPI`(待实现) | ||
| 1170 | +- **接口路径**: `/srv/?a=submit_plan`(待确认) | ||
| 1171 | +- **请求方法**: POST | ||
| 1172 | +- **负责页面**: `src/components/PlanFormContainer.vue` | ||
| 1173 | +- **负责人**: 后端团队 | ||
| 1174 | + | ||
| 1175 | +**接口文档更新记录** | ||
| 1176 | + | ||
| 1177 | +| 日期 | 版本 | 变更内容 | 变更原因 | 文档链接 | | ||
| 1178 | +|------|------|---------|---------|---------| | ||
| 1179 | +| 2026-02-09 | v1.0 | 初始版本 | 前端表单已完成,待后端接口开发 | [查看](#) | | ||
| 1180 | + | ||
| 1181 | +**页面调试情况** | ||
| 1182 | + | ||
| 1183 | +| 日期 | 调试页面 | 问题记录 | 解决方案 | 状态 | | ||
| 1184 | +|------|---------|---------|---------|------| | ||
| 1185 | +| 2026-02-09 | `src/components/PlanFormContainer.vue` | 表单提交时数据为空 | 修复 submit() 时序问题,移除立即重置 | ✅ 已解决 | | ||
| 1186 | +| 2026-02-09 | `src/components/PlanFormContainer.vue` | 金额显示为 10000 而非 100.00 | 添加 formatAmounts() 格式化显示(分 → 元) | ✅ 已解决 | | ||
| 1187 | + | ||
| 1188 | +**接口状态**: ⏳ 待后端接口开发 | ||
| 1189 | + | ||
| 1190 | +**数据单位规范**(重要): | ||
| 1191 | +- **金额字段单位**: 分(非元) | ||
| 1192 | +- 金额字段列表: `coverage`, `premium`, `amount`, `total_amount` | ||
| 1193 | +- 存储格式: 整数(如 `10000` 表示 100.00 元) | ||
| 1194 | +- 显示格式: 除以 100 并保留 2 位小数 | ||
| 1195 | + | ||
| 1196 | +**转换公式**: | ||
| 1197 | +```javascript | ||
| 1198 | +// 元 → 分(提交给后端) | ||
| 1199 | +const cents = Math.round(yuan * 100) | ||
| 1200 | + | ||
| 1201 | +// 分 → 元(前端显示) | ||
| 1202 | +const yuan = (cents / 100).toFixed(2) | ||
| 1203 | +``` | ||
| 1204 | + | ||
| 1205 | +**请求参数格式**(待确认): | ||
| 1206 | +```javascript | ||
| 1207 | +{ | ||
| 1208 | + product_id: 1, // 产品ID | ||
| 1209 | + form_sn: 'life-insurance-wiop3e', // 表单模版标识 | ||
| 1210 | + form_data: { // 表单数据 | ||
| 1211 | + coverage: 10000, // 保额(分)← 注意单位 | ||
| 1212 | + gender: 'male', | ||
| 1213 | + age: 30, | ||
| 1214 | + birthday: '1994-01-01', | ||
| 1215 | + smoker: false, | ||
| 1216 | + payment_period: 20 | ||
| 1217 | + } | ||
| 1218 | +} | ||
| 1219 | +``` | ||
| 1220 | + | ||
| 1221 | +**响应格式**(待确认): | ||
| 1222 | +```javascript | ||
| 1223 | +{ | ||
| 1224 | + code: 1, // 1 表示成功 | ||
| 1225 | + data: { | ||
| 1226 | + plan_id: 123, // 计划书ID | ||
| 1227 | + status: 'processing', // 状态:processing(生成中) | generated(已完成) | ||
| 1228 | + download_url: '' // 下载链接(生成完成后才有) | ||
| 1229 | + }, | ||
| 1230 | + msg: '提交成功' | ||
| 1231 | +} | ||
| 1232 | +``` | ||
| 1233 | + | ||
| 1234 | +**备注**: | ||
| 1235 | +- ⚠️ **重要**: 所有金额字段内部存储单位都是"分",不是"元" | ||
| 1236 | +- ✅ 前端已实现表单验证和数据格式化 | ||
| 1237 | +- ✅ 日志输出同时显示格式化数据(元)和原始数据(分),便于调试 | ||
| 1238 | +- ⏳ 后端接口待开发,当前仅为前端测试 | ||
| 1239 | +- 📝 详细注意事项:[接口联调注意事项](../接口联调注意事项.md) | ||
| 1240 | + | ||
| 1241 | +**实现位置**: | ||
| 1242 | +- `src/components/PlanFormContainer.vue:250-285` - submit() 函数 | ||
| 1243 | +- `src/components/PlanFormContainer.vue:220-241` - formatAmounts() 函数 | ||
| 1244 | +- `src/components/PlanFields/AmountKeyboard.vue` - 金额输入组件 | ||
| 1245 | + | ||
| 1246 | +--- | ||
| 1247 | + | ||
| 1248 | +#### 接口 2: 查询计划书状态(待实现) | ||
| 1249 | + | ||
| 1250 | +**接口信息** | ||
| 1251 | +- **接口名称**: `getPlanStatusAPI`(待实现) | ||
| 1252 | +- **接口路径**: `/srv/?a=get_plan_status`(待确认) | ||
| 1253 | +- **请求方法**: GET | ||
| 1254 | +- **负责页面**: 待确认(计划书结果页?) | ||
| 1255 | +- **负责人**: 后端团队 | ||
| 1256 | + | ||
| 1257 | +**接口文档更新记录** | ||
| 1258 | + | ||
| 1259 | +| 日期 | 版本 | 变更内容 | 变更原因 | 文档链接 | | ||
| 1260 | +|------|------|---------|---------|---------| | ||
| 1261 | +| 2026-02-09 | v1.0 | 初始版本 | 接口规划 | [查看](#) | | ||
| 1262 | + | ||
| 1263 | +**页面调试情况** | ||
| 1264 | + | ||
| 1265 | +| 日期 | 调试页面 | 问题记录 | 解决方案 | 状态 | | ||
| 1266 | +|------|---------|---------|---------|------| | ||
| 1267 | +| - | - | - | - | ⏳ 未开始 | | ||
| 1268 | + | ||
| 1269 | +**接口状态**: ⏳ 未开始 | ||
| 1270 | + | ||
| 1271 | +**备注**: | ||
| 1272 | +- 用于轮询查询计划书生成状态 | ||
| 1273 | +- 参数:`plan_id`(计划书ID) | ||
| 1274 | +- 返回生成状态和下载链接 | ||
| 1275 | +- 如需轮询功能,建议使用 `setInterval` 每 2-3 秒查询一次 | ||
| 1276 | + | ||
| 1277 | +--- | ||
| 1278 | + | ||
| 1149 | ## 📌 快速索引 | 1279 | ## 📌 快速索引 |
| 1150 | 1280 | ||
| 1151 | ### 按状态查看 | 1281 | ### 按状态查看 |
| ... | @@ -1203,13 +1333,13 @@ | ... | @@ -1203,13 +1333,13 @@ |
| 1203 | 1333 | ||
| 1204 | --- | 1334 | --- |
| 1205 | 1335 | ||
| 1206 | -**最后更新时间**: 2026-02-06 17:20 | 1336 | +**最后更新时间**: 2026-02-09 00:40 |
| 1207 | -**文档版本**: v2.5 | 1337 | +**文档版本**: v2.6 |
| 1208 | **更新内容**: | 1338 | **更新内容**: |
| 1209 | -- ✅ **搜索模块联调完成**:新增 searchAPI 接口,前端已完成集成 | 1339 | +- 🆕 **新增计划书模块**:计划书表单提交和状态查询接口 |
| 1210 | -- 🆕 **新增可复用卡片组件**:MaterialCard、ProductCard | 1340 | +- ✅ **前端表单完成**:修复数据为空问题,添加金额格式化 |
| 1211 | -- 🔄 **页面重构**:搜索页、首页、周热门资料页使用新组件重构,减少代码重复 | 1341 | +- ⚠️ **数据单位规范**:明确金额字段单位为"分" |
| 1212 | -- 更新总体进度:27个接口(15个已完成,9个待联调,3个已废弃) | 1342 | +- 更新总体进度:29个接口(15个已完成,9个待联调,2个待后端开发,3个已废弃) |
| 1213 | 1343 | ||
| 1214 | **历史版本**: | 1344 | **历史版本**: |
| 1215 | - v2.1 (2026-02-03 21:00): 产品模块联调完成 | 1345 | - v2.1 (2026-02-03 21:00): 产品模块联调完成 | ... | ... |
docs/接口联调注意事项.md
deleted
100644 → 0
| 1 | -# 接口联调注意事项 | ||
| 2 | - | ||
| 3 | -> **文档用途**:记录计划书表单接口联调的关键注意事项和规范 | ||
| 4 | -> | ||
| 5 | -> **最后更新**:2026-02-09 | ||
| 6 | -> **维护者**:Claude Code | ||
| 7 | - | ||
| 8 | -## 📋 目录 | ||
| 9 | - | ||
| 10 | -- [数据单位规范](#数据单位规范) | ||
| 11 | -- [接口联调流程](#接口联调流程) | ||
| 12 | -- [关键注意事项](#关键注意事项) | ||
| 13 | -- [调试技巧](#调试技巧) | ||
| 14 | -- [常见问题](#常见问题) | ||
| 15 | - | ||
| 16 | ---- | ||
| 17 | - | ||
| 18 | -## 数据单位规范 | ||
| 19 | - | ||
| 20 | -### ⚠️ 金额字段单位:分(非元) | ||
| 21 | - | ||
| 22 | -**重要**:所有金额字段内部存储单位都是 **分**,不是元! | ||
| 23 | - | ||
| 24 | -| 字段名 | 类型 | 单位 | 示例 | 显示 | | ||
| 25 | -|--------|------|------|------|------| | ||
| 26 | -| `coverage` | Number | 分 | `10000` | `100.00` 元 | | ||
| 27 | -| `premium` | Number | 分 | `5000` | `50.00` 元 | | ||
| 28 | -| `amount` | Number | 分 | `1000` | `10.00` 元 | | ||
| 29 | -| `total_amount` | Number | 分 | `15000` | `150.00` 元 | | ||
| 30 | - | ||
| 31 | -**转换公式**: | ||
| 32 | -```javascript | ||
| 33 | -// 元 → 分(提交给后端) | ||
| 34 | -const cents = Math.round(yuan * 100) | ||
| 35 | - | ||
| 36 | -// 分 → 元(前端显示) | ||
| 37 | -const yuan = (cents / 100).toFixed(2) | ||
| 38 | -``` | ||
| 39 | - | ||
| 40 | -**为什么使用"分"?** | ||
| 41 | -- ✅ 避免浮点数精度问题(`0.1 + 0.2 !== 0.3`) | ||
| 42 | -- ✅ 整数运算精确可靠 | ||
| 43 | -- ✅ 金融行业标准做法 | ||
| 44 | - | ||
| 45 | ---- | ||
| 46 | - | ||
| 47 | -## 接口联调流程 | ||
| 48 | - | ||
| 49 | -### 1. 提交计划书表单 | ||
| 50 | - | ||
| 51 | -**接口路径**:`/srv/?a=submit_plan`(待确认) | ||
| 52 | - | ||
| 53 | -**请求参数**: | ||
| 54 | -```javascript | ||
| 55 | -{ | ||
| 56 | - product_id: 1, // 产品ID | ||
| 57 | - form_sn: 'life-insurance-wiop3e', // 表单模版标识 | ||
| 58 | - form_data: { // 表单数据 | ||
| 59 | - coverage: 10000, // 保额(分)← 注意单位 | ||
| 60 | - gender: 'male', | ||
| 61 | - age: 30, | ||
| 62 | - birthday: '1994-01-01', | ||
| 63 | - smoker: false, | ||
| 64 | - payment_period: 20, | ||
| 65 | - // ... 其他字段 | ||
| 66 | - } | ||
| 67 | -} | ||
| 68 | -``` | ||
| 69 | - | ||
| 70 | -**响应格式**: | ||
| 71 | -```javascript | ||
| 72 | -{ | ||
| 73 | - code: 1, // 1 表示成功 | ||
| 74 | - data: { | ||
| 75 | - plan_id: 123, // 计划书ID | ||
| 76 | - status: 'processing', // 状态:processing(生成中) | generated(已完成) | ||
| 77 | - download_url: '' // 下载链接(生成完成后才有) | ||
| 78 | - }, | ||
| 79 | - msg: '提交成功' | ||
| 80 | -} | ||
| 81 | -``` | ||
| 82 | - | ||
| 83 | -### 2. 查询计划书状态 | ||
| 84 | - | ||
| 85 | -**接口路径**:`/srv/?a=get_plan_status` | ||
| 86 | - | ||
| 87 | -**请求参数**: | ||
| 88 | -```javascript | ||
| 89 | -{ | ||
| 90 | - plan_id: 123 // 计划书ID | ||
| 91 | -} | ||
| 92 | -``` | ||
| 93 | - | ||
| 94 | -**响应格式**: | ||
| 95 | -```javascript | ||
| 96 | -{ | ||
| 97 | - code: 1, | ||
| 98 | - data: { | ||
| 99 | - plan_id: 123, | ||
| 100 | - status: 'generated', // processing | generated | ||
| 101 | - download_url: 'https://...' // PDF 下载链接 | ||
| 102 | - }, | ||
| 103 | - msg: '' | ||
| 104 | -} | ||
| 105 | -``` | ||
| 106 | - | ||
| 107 | ---- | ||
| 108 | - | ||
| 109 | -## 关键注意事项 | ||
| 110 | - | ||
| 111 | -### ⚠️ 1. 金额字段单位必须是"分" | ||
| 112 | - | ||
| 113 | -**错误示例**: | ||
| 114 | -```javascript | ||
| 115 | -// ❌ 错误:直接发送"元" | ||
| 116 | -{ | ||
| 117 | - coverage: 100.00 // 后端会解析错误或精度丢失 | ||
| 118 | -} | ||
| 119 | -``` | ||
| 120 | - | ||
| 121 | -**正确示例**: | ||
| 122 | -```javascript | ||
| 123 | -// ✅ 正确:发送"分" | ||
| 124 | -{ | ||
| 125 | - coverage: 10000 // 后端接收后再除以100 | ||
| 126 | -} | ||
| 127 | -``` | ||
| 128 | - | ||
| 129 | -### ⚠️ 2. 检查响应码 | ||
| 130 | - | ||
| 131 | -**必须检查 `res.code === 1`**: | ||
| 132 | -```javascript | ||
| 133 | -const res = await submitPlanAPI(params) | ||
| 134 | - | ||
| 135 | -if (res.code === 1) { | ||
| 136 | - // 成功 | ||
| 137 | - console.log('提交成功:', res.data) | ||
| 138 | -} else { | ||
| 139 | - // 失败 | ||
| 140 | - Taro.showToast({ | ||
| 141 | - title: res.msg || '提交失败', | ||
| 142 | - icon: 'none' | ||
| 143 | - }) | ||
| 144 | -} | ||
| 145 | -``` | ||
| 146 | - | ||
| 147 | -### ⚠️ 3. 错误处理 | ||
| 148 | - | ||
| 149 | -**所有 API 调用必须有 `try-catch`**: | ||
| 150 | -```javascript | ||
| 151 | -try { | ||
| 152 | - const res = await submitPlanAPI(params) | ||
| 153 | - | ||
| 154 | - if (res.code === 1) { | ||
| 155 | - Taro.showToast({ title: '提交成功', icon: 'success' }) | ||
| 156 | - } else { | ||
| 157 | - Taro.showToast({ title: res.msg || '提交失败', icon: 'none' }) | ||
| 158 | - } | ||
| 159 | -} catch (err) { | ||
| 160 | - console.error('[SubmitPlan] 提交失败:', err) | ||
| 161 | - Taro.showToast({ | ||
| 162 | - title: '网络异常,请重试', | ||
| 163 | - icon: 'none' | ||
| 164 | - }) | ||
| 165 | -} | ||
| 166 | -``` | ||
| 167 | - | ||
| 168 | -### ⚠️ 4. 加载状态 | ||
| 169 | - | ||
| 170 | -**提交时显示 loading**: | ||
| 171 | -```javascript | ||
| 172 | -const loading = ref(false) | ||
| 173 | - | ||
| 174 | -const submit = async () => { | ||
| 175 | - loading.value = true | ||
| 176 | - | ||
| 177 | - try { | ||
| 178 | - await submitPlanAPI(params) | ||
| 179 | - } finally { | ||
| 180 | - loading.value = false | ||
| 181 | - } | ||
| 182 | -} | ||
| 183 | -``` | ||
| 184 | - | ||
| 185 | ---- | ||
| 186 | - | ||
| 187 | -## 调试技巧 | ||
| 188 | - | ||
| 189 | -### 1. 打印请求数据 | ||
| 190 | - | ||
| 191 | -**提交前打印完整数据**(已实现): | ||
| 192 | -```javascript | ||
| 193 | -console.log('[PlanFormContainer] 提交计划书:', { | ||
| 194 | - product_id: props.product.id, | ||
| 195 | - product_name: props.product.product_name, | ||
| 196 | - form_sn: props.product.form_sn, | ||
| 197 | - form_data: formattedData // ← 格式化后的数据(元) | ||
| 198 | -}) | ||
| 199 | - | ||
| 200 | -console.log('[PlanFormContainer] 原始数据(分):', formData.value) | ||
| 201 | -``` | ||
| 202 | - | ||
| 203 | -**打印效果**: | ||
| 204 | -```javascript | ||
| 205 | -// 格式化后(便于查看) | ||
| 206 | -form_data: { | ||
| 207 | - coverage: '100.00', | ||
| 208 | - gender: 'male', | ||
| 209 | - age: 30 | ||
| 210 | -} | ||
| 211 | - | ||
| 212 | -// 原始数据(实际发送) | ||
| 213 | -form_data: { | ||
| 214 | - coverage: 10000, | ||
| 215 | - gender: 'male', | ||
| 216 | - age: 30 | ||
| 217 | -} | ||
| 218 | -``` | ||
| 219 | - | ||
| 220 | -### 2. 网络请求拦截器 | ||
| 221 | - | ||
| 222 | -**检查 `src/utils/request.js` 中的拦截器配置**: | ||
| 223 | -- ✅ 请求拦截器已自动注入 sessionid | ||
| 224 | -- ✅ 响应拦截器已处理 401 自动刷新 | ||
| 225 | -- ✅ 超时配置:5 秒 | ||
| 226 | - | ||
| 227 | -**查看请求日志**: | ||
| 228 | -```javascript | ||
| 229 | -// request.js 中的日志 | ||
| 230 | -console.log('[Request] URL:', url) | ||
| 231 | -console.log('[Request] Data:', params) | ||
| 232 | -console.log('[Response] Data:', res) | ||
| 233 | -``` | ||
| 234 | - | ||
| 235 | -### 3. 开发者工具 | ||
| 236 | - | ||
| 237 | -**微信开发者工具**: | ||
| 238 | -1. 点击"调试器" → "Network" | ||
| 239 | -2. 找到对应的请求(`submit_plan`) | ||
| 240 | -3. 查看"Headers"和"Payload" | ||
| 241 | -4. 确认金额字段是整数(分) | ||
| 242 | - | ||
| 243 | ---- | ||
| 244 | - | ||
| 245 | -## 常见问题 | ||
| 246 | - | ||
| 247 | -### Q1: 后端接收到的金额是 `0.00`? | ||
| 248 | - | ||
| 249 | -**原因**:前端发送的值是 `100.00`(浮点数),但后端期望的是整数(分)。 | ||
| 250 | - | ||
| 251 | -**解决方案**:确保发送的是整数(分): | ||
| 252 | -```javascript | ||
| 253 | -// ❌ 错误 | ||
| 254 | -form_data: { | ||
| 255 | - coverage: 100.00 // 浮点数 | ||
| 256 | -} | ||
| 257 | - | ||
| 258 | -// ✅ 正确 | ||
| 259 | -form_data: { | ||
| 260 | - coverage: 10000 // 整数 | ||
| 261 | -} | ||
| 262 | -``` | ||
| 263 | - | ||
| 264 | -### Q2: 后端返回的金额如何显示? | ||
| 265 | - | ||
| 266 | -**后端返回的金额单位应该是"分"**: | ||
| 267 | -```javascript | ||
| 268 | -// 后端返回 | ||
| 269 | -{ | ||
| 270 | - code: 1, | ||
| 271 | - data: { | ||
| 272 | - coverage: 10000 // 分 | ||
| 273 | - } | ||
| 274 | -} | ||
| 275 | - | ||
| 276 | -// 前端显示 | ||
| 277 | -const displayYuan = (res.data.coverage / 100).toFixed(2) | ||
| 278 | -// displayYuan = '100.00' | ||
| 279 | -``` | ||
| 280 | - | ||
| 281 | -### Q3: 如何验证金额是否正确? | ||
| 282 | - | ||
| 283 | -**验证方法**: | ||
| 284 | -```javascript | ||
| 285 | -// 输入 100.00 元 | ||
| 286 | -console.log('输入值:', '100.00') | ||
| 287 | - | ||
| 288 | -// 存储的值(分) | ||
| 289 | -console.log('存储值:', 10000) | ||
| 290 | - | ||
| 291 | -// 显示的值(元) | ||
| 292 | -console.log('显示值:', (10000 / 100).toFixed(2)) // '100.00' | ||
| 293 | -``` | ||
| 294 | - | ||
| 295 | ---- | ||
| 296 | - | ||
| 297 | -## 接口联调清单 | ||
| 298 | - | ||
| 299 | -### 提交前检查 | ||
| 300 | - | ||
| 301 | -- [ ] 后端接口地址已配置(`src/utils/config.js`) | ||
| 302 | -- [ ] 请求路径正确(`/srv/?a=xxx`) | ||
| 303 | -- [ ] 请求参数格式已确认 | ||
| 304 | -- [ ] 响应格式已确认(`{ code, data, msg }`) | ||
| 305 | -- [ ] 金额字段单位已确认(分) | ||
| 306 | - | ||
| 307 | -### 提交时验证 | ||
| 308 | - | ||
| 309 | -- [ ] 金额字段是整数(分) | ||
| 310 | -- [ ] 检查 `res.code === 1` | ||
| 311 | -- [ ] 错误提示用户友好 | ||
| 312 | -- [ ] Loading 状态正确显示 | ||
| 313 | - | ||
| 314 | -### 提交后处理 | ||
| 315 | - | ||
| 316 | -- [ ] 成功后跳转到计划书列表页 | ||
| 317 | -- [ ] 失败后停留在表单页 | ||
| 318 | -- [ ] 网络异常有重试机制 | ||
| 319 | -- [ ] 轮询状态(如果是生成中的计划书) | ||
| 320 | - | ||
| 321 | ---- | ||
| 322 | - | ||
| 323 | -## 接口定义示例 | ||
| 324 | - | ||
| 325 | -### 1. 提交计划书 | ||
| 326 | - | ||
| 327 | -**定义位置**:`src/api/index.js` | ||
| 328 | - | ||
| 329 | -```javascript | ||
| 330 | -/** | ||
| 331 | - * 提交计划书表单 | ||
| 332 | - * | ||
| 333 | - * @param {Object} params - 请求参数 | ||
| 334 | - * @param {number} params.product_id - 产品ID | ||
| 335 | - * @param {string} params.form_sn - 表单模版标识 | ||
| 336 | - * @param {Object} params.form_data - 表单数据 | ||
| 337 | - * @returns {Promise<{code: number, data: Object, msg: string}>} | ||
| 338 | - * | ||
| 339 | - * @example | ||
| 340 | - * const res = await submitPlanAPI({ | ||
| 341 | - * product_id: 1, | ||
| 342 | - * form_sn: 'life-insurance-wiop3e', | ||
| 343 | - * form_data: { | ||
| 344 | - * coverage: 10000, // 保额(分) | ||
| 345 | - * gender: 'male', | ||
| 346 | - * age: 30 | ||
| 347 | - * } | ||
| 348 | - * }) | ||
| 349 | - */ | ||
| 350 | -export const submitPlanAPI = (params) => { | ||
| 351 | - return buildApiUrl('submit_plan', params) | ||
| 352 | -} | ||
| 353 | -``` | ||
| 354 | - | ||
| 355 | -### 2. 查询计划书状态 | ||
| 356 | - | ||
| 357 | -```javascript | ||
| 358 | -/** | ||
| 359 | - * 查询计划书生成状态 | ||
| 360 | - * | ||
| 361 | - * @param {Object} params - 请求参数 | ||
| 362 | - * @param {number} params.plan_id - 计划书ID | ||
| 363 | - * @returns {Promise<{code: number, data: Object, msg: string}>} | ||
| 364 | - */ | ||
| 365 | -export const getPlanStatusAPI = (params) => { | ||
| 366 | - return buildApiUrl('get_plan_status', params) | ||
| 367 | -} | ||
| 368 | -``` | ||
| 369 | - | ||
| 370 | ---- | ||
| 371 | - | ||
| 372 | -## 快速参考 | ||
| 373 | - | ||
| 374 | -### 金额转换工具函数 | ||
| 375 | - | ||
| 376 | -**位置**:`src/utils/amount.js`(建议创建) | ||
| 377 | - | ||
| 378 | -```javascript | ||
| 379 | -/** | ||
| 380 | - * 元转分 | ||
| 381 | - * @param {number|string} yuan - 元 | ||
| 382 | - * @returns {number} 分 | ||
| 383 | - */ | ||
| 384 | -export const yuanToCents = (yuan) => { | ||
| 385 | - return Math.round(Number(yuan) * 100) | ||
| 386 | -} | ||
| 387 | - | ||
| 388 | -/** | ||
| 389 | - * 分转元 | ||
| 390 | - * @param {number} cents - 分 | ||
| 391 | - * @returns {string} 元(带2位小数) | ||
| 392 | - */ | ||
| 393 | -export const centsToYuan = (cents) => { | ||
| 394 | - return (cents / 100).toFixed(2) | ||
| 395 | -} | ||
| 396 | - | ||
| 397 | -/** | ||
| 398 | - * 格式化金额显示 | ||
| 399 | - * @param {number} cents - 分 | ||
| 400 | - * @returns {string} 格式化后的金额(如:"10,000.00") | ||
| 401 | - */ | ||
| 402 | -export const formatAmount = (cents) => { | ||
| 403 | - const yuan = (cents / 100).toFixed(2) | ||
| 404 | - const parts = yuan.split('.') | ||
| 405 | - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',') | ||
| 406 | - return parts.join('.') | ||
| 407 | -} | ||
| 408 | -``` | ||
| 409 | - | ||
| 410 | -### 使用示例 | ||
| 411 | - | ||
| 412 | -```javascript | ||
| 413 | -import { yuanToCents, centsToYuan, formatAmount } from '@/utils/amount' | ||
| 414 | - | ||
| 415 | -// 用户输入 | ||
| 416 | -const input = '100.00' | ||
| 417 | -const cents = yuanToCents(input) // 10000 | ||
| 418 | - | ||
| 419 | -// 存储 | ||
| 420 | -formData.value.coverage = cents | ||
| 421 | - | ||
| 422 | -// 显示 | ||
| 423 | -const display = formatAmount(cents) // '10,000.00' 或 '100.00' | ||
| 424 | -``` | ||
| 425 | - | ||
| 426 | ---- | ||
| 427 | - | ||
| 428 | -## 维护日志 | ||
| 429 | - | ||
| 430 | -- **2026-02-09**:创建文档,记录金额字段单位规范和联调注意事项 | ||
| 431 | - | ||
| 432 | ---- | ||
| 433 | - | ||
| 434 | -## 相关文档 | ||
| 435 | - | ||
| 436 | -- [项目 CLAUDE.md](../CLAUDE.md) - 项目开发规范 | ||
| 437 | -- [API 集成日志](../api-integration-log.md) - API 联调记录 | ||
| 438 | -- [变更日志](../CHANGELOG.md) - 版本更新历史 |
-
Please register or login to post a comment