Showing
4 changed files
with
81 additions
and
4 deletions
This diff is collapsed. Click to expand it.
| ... | @@ -1267,6 +1267,9 @@ | ... | @@ -1267,6 +1267,9 @@ |
| 1267 | | 2026-02-09 | `src/components/PlanFormContainer.vue` | 表单提交时数据为空 | 修复 submit() 时序问题,移除立即重置 | ✅ 已解决 | | 1267 | | 2026-02-09 | `src/components/PlanFormContainer.vue` | 表单提交时数据为空 | 修复 submit() 时序问题,移除立即重置 | ✅ 已解决 | |
| 1268 | | 2026-02-09 | `src/components/PlanFormContainer.vue` | 金额显示为 10000 而非 100.00 | 添加 formatAmounts() 格式化显示(分 → 元) | ✅ 已解决 | | 1268 | | 2026-02-09 | `src/components/PlanFormContainer.vue` | 金额显示为 10000 而非 100.00 | 添加 formatAmounts() 格式化显示(分 → 元) | ✅ 已解决 | |
| 1269 | | 2026-02-10 | `src/api/plan.js` | 后端接口已修复,联调成功 | 接口正常工作 | ✅ 已完成 | | 1269 | | 2026-02-10 | `src/api/plan.js` | 后端接口已修复,联调成功 | 接口正常工作 | ✅ 已完成 | |
| 1270 | +| 2026-02-11 | `src/components/PlanFormContainer.vue` | 前端优化成功判断逻辑 | 修改成功判断从 `res.code === 1` 改为同时检查 `res.code === 1` 和 `res.data?.order_id` | ✅ 已完成 | | ||
| 1271 | +| 2026-02-11 | `src/components/PlanFormContainer.vue` | 错误信息路径修正 | 修改错误信息从 `res.data?.message` 改为 `res.data?.msg`,添加降级方案 | ✅ 已完成 | | ||
| 1272 | +| 2026-02-11 | `src/pages/product-detail/index.vue`, `src/pages/search/index.vue`, `src/pages/product-center/index.vue`, `src/pages/index/index.vue` | 统一页面处理逻辑 | 修改所有页面的 `handlePlanSubmit` 函数,实现完整的错误处理和导航 | ✅ 已完成 | | ||
| 1270 | 1273 | ||
| 1271 | **接口状态**: ✅ 已完成 | 1274 | **接口状态**: ✅ 已完成 |
| 1272 | 1275 | ... | ... |
| ... | @@ -1001,6 +1001,71 @@ export async function fetchProductList(params) { | ... | @@ -1001,6 +1001,71 @@ export async function fetchProductList(params) { |
| 1001 | } | 1001 | } |
| 1002 | ``` | 1002 | ``` |
| 1003 | 1003 | ||
| 1004 | +### ⚠️ 坑: API 成功验证需要检查状态码和必需字段 ⭐ 2026-02-11 新增 | ||
| 1005 | + | ||
| 1006 | +**问题描述**: | ||
| 1007 | + | ||
| 1008 | +在计划书提交功能中,最初只检查 `res.code === 1` 来判断 API 调用是否成功,但这种方式不够严格。 | ||
| 1009 | + | ||
| 1010 | +**错误代码**: | ||
| 1011 | +```javascript | ||
| 1012 | +// ❌ 只检查状态码 | ||
| 1013 | +const res = await addAPI(requestData) | ||
| 1014 | + | ||
| 1015 | +if (res.code === 1) { | ||
| 1016 | + // 可能 res.data 为空或缺少必需字段 | ||
| 1017 | + emit('submit', { success: true }) | ||
| 1018 | +} | ||
| 1019 | +``` | ||
| 1020 | + | ||
| 1021 | +**问题表现**: | ||
| 1022 | +- 即使 API 返回 `{ code: 1, data: null }`,也会判定为成功 | ||
| 1023 | +- 缺少关键业务数据(如 `order_id`)时仍视为成功 | ||
| 1024 | +- 后续流程可能因缺少必需数据而失败 | ||
| 1025 | + | ||
| 1026 | +**正确做法**: | ||
| 1027 | +```javascript | ||
| 1028 | +// ✅ 同时检查状态码和必需字段 | ||
| 1029 | +const res = await addAPI(requestData) | ||
| 1030 | + | ||
| 1031 | +// 判断成功:既要 code === 1,也要有 order_id | ||
| 1032 | +const isSuccess = res.code === 1 && res.data?.order_id | ||
| 1033 | + | ||
| 1034 | +if (isSuccess) { | ||
| 1035 | + emit('submit', { | ||
| 1036 | + success: true, | ||
| 1037 | + order_id: res.data.order_id // 确保必需字段存在 | ||
| 1038 | + }) | ||
| 1039 | +} else { | ||
| 1040 | + // 失败时,从 res.data.msg 或 res.msg 中获取错误信息 | ||
| 1041 | + const errorMsg = res.data?.msg || res.msg || '提交失败,请稍后重试' | ||
| 1042 | + emit('submit', { success: false }) | ||
| 1043 | +} | ||
| 1044 | +``` | ||
| 1045 | + | ||
| 1046 | +**关键原则**: | ||
| 1047 | +1. ✅ **双重验证**:同时检查状态码(`code === 1`)和必需数据字段(如 `order_id`) | ||
| 1048 | +2. ✅ **字段验证**:对于业务关键接口,验证返回数据中是否包含必需字段 | ||
| 1049 | +3. ✅ **错误信息路径**:优先从 `res.data.msg` 获取错误信息,其次才是 `res.msg` | ||
| 1050 | +4. ✅ **明确的数据契约**:在 API 文档中明确成功响应必须包含的字段 | ||
| 1051 | + | ||
| 1052 | +**适用场景**: | ||
| 1053 | +- ✅ 提交类 API(订单提交、表单提交等) | ||
| 1054 | +- ✅ 创建类 API(创建计划书、创建收藏等) | ||
| 1055 | +- ✅ 任何返回业务数据标识符的接口(如 order_id、bill_id 等) | ||
| 1056 | + | ||
| 1057 | +**相关文件**: | ||
| 1058 | +- `src/components/plan/PlanFormContainer.vue:308-350` (已修复) | ||
| 1059 | +- `src/api/plan.js:27-33` (API 契约文档) | ||
| 1060 | + | ||
| 1061 | +**历史记录**: | ||
| 1062 | +- **第 1 次**:发现计划书提交逻辑只检查 `result.success`(接口未返回此字段) | ||
| 1063 | +- **第 2 次**:用户指出应该检查 `order_id` 字段 | ||
| 1064 | +- **第 3 次**:发现错误信息路径应为 `res.data.msg` 而非 `res.data.message` | ||
| 1065 | +- **教训**: ⚠️ **API 成功验证必须检查状态码和必需业务字段** | ||
| 1066 | + | ||
| 1067 | +--- | ||
| 1068 | + | ||
| 1004 | ### ❌ 坑: API 调用使用了 `fn()` 包装(重复 2 次) | 1069 | ### ❌ 坑: API 调用使用了 `fn()` 包装(重复 2 次) |
| 1005 | 1070 | ||
| 1006 | **问题描述**: | 1071 | **问题描述**: | ... | ... |
| ... | @@ -116,12 +116,21 @@ export function useFileOperation() { | ... | @@ -116,12 +116,21 @@ export function useFileOperation() { |
| 116 | showCopyButton = !!item.downloadUrl | 116 | showCopyButton = !!item.downloadUrl |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | - showModal({ | 119 | + // 构建 showModal 参数 |
| 120 | + const modalParams = { | ||
| 120 | title: '提示', | 121 | title: '提示', |
| 121 | content: message + suggestion, | 122 | content: message + suggestion, |
| 122 | - confirmText: showCopyButton ? '复制链接' : '我知道了', | 123 | + confirmText: showCopyButton ? '复制链接' : '我知道了' |
| 123 | - cancelText: showCopyButton ? '关闭' : undefined, | 124 | + } |
| 124 | - showCancel: showCopyButton, | 125 | + |
| 126 | + // 只在有下载链接时才显示取消按钮 | ||
| 127 | + if (showCopyButton) { | ||
| 128 | + modalParams.cancelText = '关闭' | ||
| 129 | + modalParams.showCancel = true | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + showModal({ | ||
| 133 | + ...modalParams, | ||
| 125 | success: (modalRes) => { | 134 | success: (modalRes) => { |
| 126 | console.log('[文件操作] 用户选择:', modalRes.confirm ? '复制链接' : '关闭') | 135 | console.log('[文件操作] 用户选择:', modalRes.confirm ? '复制链接' : '关闭') |
| 127 | 136 | ... | ... |
-
Please register or login to post a comment