Ver Fonte

fix(乐收赢): 订单页「回调轨迹」两列补中文映射 —— 处理后/验签之前裸显英文枚举

## 缺陷

`frontend/src/views/module_payment/collection/order/index.vue` 的「回调轨迹」表里,
「处理」列是裸的 `prop="process_status"`(连 template 都没有),「验签」列直接把
`row.verify_status` 插值。两列都把库里的英文枚举原样吐给用户:
RECEIVED / DUPLICATE / SUCCESS / FAIL …

同页别的列都有标签函数(`statusLabel` / `sceneLabel` / `tradeTypeLabel`),
所以这是漏做,不是设计。用户 2026-09-29 据此提问时看到的正是 `DUPLICATE` / `RECEIVED`。

## 改法

两张映射表 + 两个标签函数,取值与后端**逐一对应**:

    PROCESS_LABEL  10 词   RECEIVED / APPLIED / DUPLICATE / REJECTED / ORDER_NOT_FOUND /
                           REFUND_NOT_FOUND / UNKNOWN_RESULT_CODE /
                           LATE_PAYMENT_AFTER_TERMINAL / LATE_REFUND_AFTER_TERMINAL /
                           HELD_FOR_RECONCILE
    VERIFY_LABEL    2 词   SUCCESS / FAIL

「处理」列里**四类标红**:终态后到账 / 终态后退款 / 扣住待对账 / 未知结果码。

★ `DUPLICATE` **刻意不标红**:后端 `LsyNotifyService` 特意把「良性重复回调」与
「账实不符」(`LATE_*_AFTER_TERMINAL`)拆成两个词,正是为了让这处能分开看;
界面上把它们渲染成一模一样的黑字,等于把那处区分又抹掉,真正的告警会淹在噪声里。

## 验证

词表对齐(`logs/_lsy-notify-label-check.py`,正文 `logs/_lsy-notify-label-check.txt`):

    Java 侧   括号配对抠出 12 个 logNotify 调用点
              ⇒ process_status 10 词 / verify_status 2 词
    Vue 侧    PROCESS_LABEL 10 键 / VERIFY_LABEL 2 键
    差集      两个方向都是空
    ★ 这 10 词与库列注释(`db/lsy-notify-process-status-comment.sql`)那句**一字不差**
      —— 两个独立来源互印

    负对照甲  抽掉 APPLIED    ⇒ 量具报出 ['APPLIED']
    负对照乙  删掉 vue 里一行  ⇒ 抠词 10→9、差集 ['RECEIVED'](证明抠词真在读文件)

★ 抠 `logNotify(...)` 用**括号配对**而非 `find(");")`:本文件里有若干调用以
  `null);` / `str(...)));` 收尾,压根没有 `");`,后者会一路吞到下一个调用的结尾,
  把别处的词也算进来 —— 是一把会给出「合情合理的假读数」的坏量具。

类型检查(在 `frontend/` 里跑 `npm run ts:check`):

    改后      289 条,与历史基线**逐条相同**,本文件 0 命中
    正对照    同一文件注入一条假类型错误 ⇒ 289→290,多出的正是该文件探针行
              (证明「本文件 0 命中」是真读数,不是量具根本没读它)
    还原      sha256 回到 4be10d0dd4169ca312a1acea57074ea9da37b9ea22d60ffef963db7d21600add

本仓 `frontend/` 无测试框架且 `ts:check` 有非零历史基线(命令恒 exit 2),
所以只能同机前后差分 + 两向变异,见 memory「前端验证基线非零」。
alphaH há 2 semanas atrás
pai
commit
e7993eeb34

+ 57 - 2
frontend/src/views/module_payment/collection/order/index.vue

@@ -124,11 +124,18 @@
         <el-table-column prop="verify_status" label="验签" width="80">
           <template #default="{ row }">
             <el-tag :type="row.verify_status === 'SUCCESS' ? 'success' : 'danger'" size="small">
-              {{ row.verify_status }}
+              {{ verifyLabel(row.verify_status) }}
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column prop="process_status" label="处理" width="130" />
+        <el-table-column prop="process_status" label="处理" width="130">
+          <template #default="{ row }">
+            <el-tag v-if="isProcessAlert(row.process_status)" type="danger" size="small">
+              {{ processLabel(row.process_status) }}
+            </el-tag>
+            <span v-else>{{ processLabel(row.process_status) }}</span>
+          </template>
+        </el-table-column>
         <el-table-column label="原文" min-width="200">
           <template #default="{ row }">
             <el-popover placement="left" :width="600" trigger="click">
@@ -180,6 +187,32 @@ const SCENE_LABEL: Record<string, string> = {
   H5: "H5",
 };
 
+/**
+ * `pay_lsy_notify_log.process_status` 的取值 → 中文。
+ *
+ * ★ 这 10 个词是**从 `LsyNotifyService` 全部 `logNotify(...)` 调用点逐个点出来的**,
+ *   并与库里的列注释(`db/lsy-notify-process-status-comment.sql` 那句 10 词表)对过,
+ *   两边一致。后端加词时这里必须同步 —— 漏一个就会让那一行退回显示英文(靠 `|| v` 兜底),
+ *   不报错、只是看不懂。
+ */
+const PROCESS_LABEL: Record<string, string> = {
+  RECEIVED: "已收到",
+  APPLIED: "已回写",
+  DUPLICATE: "重复回调",
+  REJECTED: "验签失败",
+  ORDER_NOT_FOUND: "订单不存在",
+  REFUND_NOT_FOUND: "退款单不存在",
+  UNKNOWN_RESULT_CODE: "未知结果码",
+  LATE_PAYMENT_AFTER_TERMINAL: "终态后到账",
+  LATE_REFUND_AFTER_TERMINAL: "终态后退款",
+  HELD_FOR_RECONCILE: "扣住待对账",
+};
+
+const VERIFY_LABEL: Record<string, string> = {
+  SUCCESS: "通过",
+  FAIL: "失败",
+};
+
 /** 查询参数用 camelCase:后端 `@RequestParam` 未写 name,线上名即 `pageNo` / `pageSize` */
 const query = reactive({
   pageNo: 1,
@@ -214,6 +247,28 @@ function statusTagType(v: string) {
 function tradeTypeLabel(v: string) {
   return ({ "0": "退款", "1": "交易", "2": "云订单关单" } as Record<string, string>)[v] || v || "-";
 }
+function processLabel(v: string) {
+  return PROCESS_LABEL[v] || v || "-";
+}
+function verifyLabel(v: string) {
+  return VERIFY_LABEL[v] || v || "-";
+}
+/**
+ * 「处理」列里**需要人看一眼**的四类,标红。
+ *
+ * ★ `DUPLICATE` **不在**其中,这是刻意的:良性重复回调是幂等正常工作的证据,
+ *   标红会把真正的告警淹掉。后端 `LsyNotifyService` 特意把「良性重复」与
+ *   「账实不符」(LATE_*_AFTER_TERMINAL)拆成两个词,就是为了这处能分开看;
+ *   在界面上把它们渲染成一模一样的黑字,等于把那处区分又抹掉了。
+ */
+function isProcessAlert(v: string) {
+  return (
+    v === "LATE_PAYMENT_AFTER_TERMINAL" ||
+    v === "LATE_REFUND_AFTER_TERMINAL" ||
+    v === "HELD_FOR_RECONCILE" ||
+    v === "UNKNOWN_RESULT_CODE"
+  );
+}
 
 async function loadData() {
   loading.value = true;