# 后端 feat 通知 — 产品节点选资源时, 资源亮点(highlights)默认带到节点 description

**日期**: 2026-05-12
**类型**: 后端新增功能 (PR #2096)
**模块**: 产品「行程编排」节点保存
**通知**: @mmg
**前端是否需改动**: **不需要** — 默认值后端自动填, 现有编辑器不动即可看到
**严重性**: P2

---

## 背景

产品「行程编排」选景区/活动/服务做节点时, 之前节点 `description` (卖点/描述) 字段需要人工再写一遍, 即使资源端已经填了亮点。本次复用现有字段做"默认值带过来"。

## 字段映射 (全部复用现有字段, 无新加)

| 端 | 卖点字段 | 图标字段 |
|----|---------|---------|
| 资源 (景区/活动/服务) | `highlights` (已有) | `cover_material_id` (已有) |
| 节点 product_itinerary_node | `description` (已有) | `emojiIcon` (已有 lucide 名) |

## 新增逻辑

节点保存时若满足:
- `node.resourceId` 非空 (选了一个资源)
- `node.description` 为空或未传 (用户没自己写卖点)
- `resource.highlights` 非空 (资源端有亮点)

→ 自动把 `resource.highlights` 复制到 `node.description`。

**用户后续可改, 改后不回写资源** (节点 description 是独立快照, 资源端亮点改了不影响已存在的节点)。

**显式传值优先**: 如果前端在请求中显式传了 `description`, 后端不会覆盖。

## API 变化

### 资源端内部 Feign 接口

`GET /internal/mp/resource/batch-details` 返回 `ResourceDetailDTO` **新增 highlights 字段**:
```json
{
  "resourceId": "2029818530992472065",
  "resourceType": "SCENIC_SPOT",
  "name": "呼籁自有营地",
  "description": "呼籁自有营地, 坐落于...",
  "highlights": "私密专属、原生态草原、旅拍圣地、BBQ体验",   // ← 新增
  "cover": "...",
  ...
}
```

### 产品节点保存接口

`PUT /admin/product/item/{id}/itinerary` 行为变化:
- 节点不传 description + 选了资源 → 后端用资源 highlights 自动填
- 其他场景行为不变

### 产品节点查询接口

`GET /admin/product/item/{id}` (admin) + 等 MP 接口 - 字段结构不变。`node.description` 字段可能比之前更常有值(自动带的)。

---

## 测试服实测

部署版本: dev `b02f0ab0` 之后的 PR #2096 commit

| 场景 | 期望 | 实测 |
|------|------|------|
| 节点不传 description + 选景区(highlights="私密专属、...BBQ体验") | description=资源 highlights | ✅ PASS |
| 节点显式传 description="我自己写的卖点" | description=用户输入, 不被覆盖 | ✅ PASS |
| 资源端 Internal Feign 返回 ResourceDetailDTO | 含 highlights 字段 | ✅ PASS |

---

## 前端 mmg 优化建议 (非必须)

如果想做"选了资源后, 前端立即显示资源 highlights 作为 description placeholder", 可以:
- 前端编辑节点选完资源后, 调 `GET /admin/scenic/spot/{id}` (或对应资源详情接口) 读 `highlights`, 作为 description 输入框 placeholder
- 用户开始打字时 placeholder 消失, 用户保存空 description 时后端会用 highlights 填

但后端已经自动落了, **前端不改也完全正常工作**。
