# 【后端已上线·前端待加两列·管理后台】通知发送日志：补「通道」中文名 +「发送对象」解析名（不再显示「未知」）

> **关联**: 通知中心 / 自定义推送（#3414 系列收尾）| **服务**: hl-user-service（后端已改并部署测试服）+ 前端 hl-ui
> **提报时间**: 2026-06-05 | **后端**: @wx | **前端待接**: mmg
> **位置**: 管理后台 → 通知中心 → 发送日志（推送日志）列表
> **后端 PR**: #3526（富化字段）+ #3527（发送对象按通道判主体修正），均已合并 dev-v3 + 部署测试服 + API 实测通过

---

## ⚠️ 关键说明

之前「推送日志」页**信息不全**：站内信 / 短信等都混在一起，看不出**是哪种通道**，「发送对象」列大量显示「**未知**」。

后端在**原接口 `GET /admin/notification/logs` 的每条记录里新增 3 个字段**（不改请求、不改分页结构，纯增量），前端只需把这两列展示出来即可：

| 新增字段 | 含义 | 示例值 |
|----------|------|--------|
| `channelLabel` | 通道中文名（直接展示，不用前端再映射） | 站内信 / 站内信(内部员工) / 短信 / 企业微信 / 小程序订阅 / 公众号 |
| `recipientName` | **发送对象**展示名（已后端解析：员工名 / 客人昵称） | 游客9999、wx、admin |
| `recipientType` | 发送对象类型（可做标签） | 员工 / 客人 / 其它 |

---

## 1. 前端要做的事（两列）

在发送日志列表里加（或补全）两列：

| 列 | 取字段 | 说明 |
|----|--------|------|
| **通道** | `channelLabel` | 后端已返中文，直接展示。也可保留 `channel`（英文码）做筛选值 |
| **发送对象** | `recipientName` | 后端已解析好名字；可在前面挂个 `recipientType`（员工/客人）小标签 |

> `recipientName` **后端保证非空**：解析不到名字时回退原始标识（手机号 / openid / id），绝不再显示「未知」。
> 另有 `recipient` 字段是**原始标识**（手机号 / openid / 企微 id / adminId），如要展示副文本（如客人手机号）可用它。

---

## 2. 「发送对象」按通道判主体（#3527 修正点，重要）

一条日志可能**同时带 `adminId`（操作人）和 `userId`（客人）**——比如管理员手动给客人发站内信 / 短信。后端**按通道**决定「发送对象」到底是谁，前端无需关心，直接用 `recipientName` / `recipientType` 即可：

| 通道（channel） | 发送对象主体 | recipientType |
|----------------|-------------|---------------|
| `INAPP` 站内信、`SMS` 短信、`MINIAPP` 小程序订阅、`OA` 公众号 | **客人**（userId 解析昵称/真名） | 客人 |
| `ADMIN_INAPP` 内部员工站内信、`WEWORK` 企业微信 | **内部员工**（adminId 解析用户名/企微名） | 员工 |

> 修正前的 bug：C 端通道（站内信/短信）误把**操作人**（如 wx）显示成发送对象；现已正确显示**客人**。

---

## 3. 通道筛选下拉（channel 取值）

发送日志的「通道」筛选项 `channel` 取值与中文对应如下（`GET /admin/notification/logs?channel=` 传**英文码**）：

| channel（传给后端） | channelLabel（展示） |
|--------------------|----------------------|
| `INAPP` | 站内信 |
| `ADMIN_INAPP` | 站内信(内部员工) |
| `SMS` | 短信 |
| `WEWORK` | 企业微信 |
| `MINIAPP` | 小程序订阅 |
| `OA` | 公众号 |

⚠️ 企业微信筛选请传 **`WEWORK`**（日志通道列存的是 `WEWORK`，不是 `WECHAT_WORK`）。

---

## 4. 接口与实测响应

**请求**（不变，新增字段在响应里）：

```
GET /admin/notification/logs?channel=INAPP&pageNum=1&pageSize=20
Authorization: Bearer {adminToken}
```

**响应**（`data.records[]` 每条，节选三个新字段 + 关键原有字段）：

```json
// 客人站内信：同时有 adminId(操作人) 和 userId(客人)，发送对象=客人
{
  "id": "2062106713514754049",
  "eventCode": "CUSTOM_PUSH",
  "channel": "INAPP",
  "channelLabel": "站内信",
  "userId": "2059154700023836674",
  "adminId": "2021059720172838914",
  "recipient": "2059154700023836674",
  "recipientName": "游客9999",
  "recipientType": "客人",
  "status": 0,
  "createTime": "2026-06-03 17:38:47"
}

// 短信：发送对象=客人，recipient 为手机号
{
  "channel": "SMS",
  "channelLabel": "短信",
  "userId": "2025607151170445314",
  "adminId": "2033349912397299714",
  "recipient": "18547062756",
  "recipientName": "（该客人昵称/真名）",
  "recipientType": "客人",
  "status": 0
}

// 内部员工站内信：发送对象=员工
{
  "channel": "ADMIN_INAPP",
  "channelLabel": "站内信(内部员工)",
  "userId": null,
  "adminId": 1001,
  "recipientName": "admin",
  "recipientType": "员工",
  "status": 0
}

// 企业微信：发送对象=员工
{
  "channel": "WEWORK",
  "channelLabel": "企业微信",
  "userId": null,
  "adminId": "2021059720172838914",
  "recipientName": "wx",
  "recipientType": "员工",
  "status": 0
}
```

> `status`：0=成功，1=失败，2=已过滤，3=已跳过（关联字典 `notification_send_status`）。

---

## 5. 后端状态

- ✅ 6 个通道（站内信 / 内部员工站内信 / 短信 / 企业微信 / 小程序订阅 / 公众号）日志均有 `channelLabel`、`recipientName`、`recipientType`，测试服逐通道实测通过。
- ✅ 「发送对象」按通道判主体（C 端通道显客人、内部通道显员工），已修正操作人误显问题（#3527）。
- ✅ 解析采用批量查询（adminId→用户名、userId→昵称），无 N+1。
- 前端只是**加两列 + 调筛选取值**，无逻辑负担。

## 6. 关联

- 自定义推送选人 / 企微通道：`05_3414_自定义推送选人下拉-客人名字undefined已修+企微通道需切员工数据源-管理后台.md`
- 内部员工站内信主功能：`04_3414_内部员工站内信收件箱-SSE实时推送-管理后台.md`
- 后端：@wx | 前端：**mmg**
