浏览代码

fix(转账): 列表与详情显示失败原因

用户 2026-09-30 报「转账失败原因没有显示在页面上」。后端那两个字段
(TransferVO.errorCode/errorMsg,经全局 JacksonConfig 的 SNAKE_CASE 出网即
error_code/error_msg)此前一直在写,只是前端从未渲染。

- api/module_payment/account.ts:TransferItem 补 error_code / error_msg 两格,
  注释写明键名形态的来路(后端 camelCase 经全局 SNAKE_CASE)。
- 列表加「失败原因」列,有值显示、无值显示 -,超长省略号 + tooltip。
- 详情抽屉在状态下方补「错误码」「失败原因」两格。

显隐判据是「原因存在」,不是 status === "FAIL":退票单子的原因同样要看,
而成功单子上不该有原因(后端 AccountHandler.backfillFailReason 只在 FAIL
且两列均空时补写、绝不改状态),所以判「有没有值」两端都安全。

端到端验证(前端无测试框架,本仓基线见 memory):
- pnpm ts:check 289 条 → 289 条,错误集合逐条相同(行:列 归一后),新增改动零错误;
- 自建执行级台子 frontend/_verify-account/transfer-error.mjs:真 SFC 编译 +
  真 vue SSR + 真 Element Plus,15 条断言全绿(原因入 HTML、失败行有/成功行无、
  抽屉四格、成功单两格不出现且订单号照常);三个外壳桩(el-table/el-table-column/
  el-drawer)的来路与实测行为写在台子注释里;
- 两向变异:把 row.error_msg 改成 row.errorMsg ⇒ 只有 2 条红;
  把 detailData.error_msg 改成 errorMsg ⇒ 只有 2 条红;去掉抽屉的 v-if ⇒ 只有 1 条红;
  改一个 CSS 类名(无害)⇒ 15 条仍全绿。每次还原都用 sha256 对过记录值。
alphaH 2 周之前
父节点
当前提交
84146fcbcf

+ 4 - 0
frontend/src/api/module_payment/account.ts

@@ -317,6 +317,10 @@ export interface TransferOutSchema {
     bankcard_ext_info?: any;
   };
   status?: string;
+  /** 错误码(支付宝 sub_code);键名对后端 TransferVO.errorCode 经全局 SNAKE_CASE 之后的形态 */
+  error_code?: string;
+  /** 失败原因 —— 只有失败/退票的单子有值,成功单子后端不写 */
+  error_msg?: string;
   order_id?: string;
   pay_fund_order_id?: string;
   /** @deprecated 兼容旧字段 */

+ 11 - 0
frontend/src/views/module_payment/account/components/TransferDetail.vue

@@ -34,6 +34,13 @@
             {{ getStatusLabel(detailData.status) }}
           </el-tag>
         </el-descriptions-item>
+        <!-- 失败/退票才有值,故按「有没有原因」显隐,而不是按状态显隐 -->
+        <el-descriptions-item v-if="detailData.error_code" label="错误码">
+          {{ detailData.error_code }}
+        </el-descriptions-item>
+        <el-descriptions-item v-if="detailData.error_msg" label="失败原因">
+          <span class="error-msg">{{ detailData.error_msg }}</span>
+        </el-descriptions-item>
         <el-descriptions-item label="备注">
           {{ detailData.remark || "" }}
         </el-descriptions-item>
@@ -179,6 +186,10 @@ function handleRefresh() {
     font-weight: 600;
     color: #67c23a;
   }
+
+  .error-msg {
+    color: #f56c6c;
+  }
 }
 
 .drawer-footer {

+ 11 - 0
frontend/src/views/module_payment/account/index.vue

@@ -356,6 +356,13 @@
                   </el-tag>
                 </template>
               </el-table-column>
+              <!-- 失败原因:有值就显示(判据是「原因存在」,不是「状态==FAIL」—— 退票单子的原因同样要看) -->
+              <el-table-column prop="error_msg" label="失败原因" min-width="200" show-overflow-tooltip>
+                <template #default="{ row }">
+                  <span v-if="row.error_msg" class="transfer-error-msg">{{ row.error_msg }}</span>
+                  <span v-else>-</span>
+                </template>
+              </el-table-column>
               <el-table-column prop="order_title" label="转账标题" min-width="150" />
               <el-table-column prop="created_time" label="创建时间" min-width="160">
                 <template #default="{ row }">
@@ -2106,6 +2113,10 @@ async function handleExportTransfer() {
   align-items: center;
 }
 
+.transfer-error-msg {
+  color: #f56c6c;
+}
+
 .mt-4 {
   margin-top: 16px;
 }