父节点
e4605c3755
当前提交
60544ca71c
@ -0,0 +1,136 @@
|
|||||||
|
---
|
||||||
|
date: 2026-05-14
|
||||||
|
type: frontend-feature
|
||||||
|
module: admin-product-v2-itinerary-scenic-picker
|
||||||
|
priority: medium
|
||||||
|
backend_pr: "#2229"
|
||||||
|
backend_issue: "#2227"
|
||||||
|
notify: ["@mmg"]
|
||||||
|
status: pending
|
||||||
|
---
|
||||||
|
|
||||||
|
# 产品设计选景区按产品线季节过滤 + 节点展示季节标签
|
||||||
|
|
||||||
|
## 需求
|
||||||
|
|
||||||
|
产品设计行程编辑器的「**从资源库添加活动 → 景区景点**」弹窗当前列出全部景区,无视产品线季节。期望:
|
||||||
|
|
||||||
|
1. 弹窗景区列表按当前产品线的 `seasons` 过滤 — 比如产品线是秋季就只看到秋季景区
|
||||||
|
2. 列表行的**景区缩略图**按季节切换(春→春景图、秋→秋景图)
|
||||||
|
3. **节点上**(已添加进行程的景区卡片)显示该景区配置的所有季节标签(可多个)
|
||||||
|
|
||||||
|
## 后端已就位 (PR #2229 已合并并部署测试服)
|
||||||
|
|
||||||
|
### 数据基础
|
||||||
|
|
||||||
|
景区已有独立 `scenic_season` 子表,每季节可配封面/轮播/视频。产品线 `seasons` 已是 `List<String>`(JSON 数组多选)。
|
||||||
|
|
||||||
|
### 接口变更
|
||||||
|
|
||||||
|
#### 1. `GET /admin/scenic/spots` — 景区列表
|
||||||
|
|
||||||
|
**新增 query 参数:**
|
||||||
|
|
||||||
|
| 字段 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| `seasons` | `List<String>` | 否 | 多选 OR 过滤,枚举 `spring/summer/autumn/winter`。传任一交集景区即返回。空/不传 = 不过滤 |
|
||||||
|
|
||||||
|
请求格式(数组多参):
|
||||||
|
```http
|
||||||
|
GET /admin/scenic/spots?seasons=spring&seasons=autumn&pageSize=20
|
||||||
|
```
|
||||||
|
|
||||||
|
**`ScenicSpotListVO` 新增 2 个字段:**
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `seasons` | `List<String>` | 该景区在 `scenic_season` 配置的全部季节(distinct,枚举 `spring/summer/autumn/winter`)。**节点标签直接读这个**。 |
|
||||||
|
|
||||||
|
> ⚠️ **已有的 `coverUrl` 字段含义变更**: 当 query 含 `seasons` 时,`coverUrl` 返回 **query.seasons[0] 对应的 `scenic_season.cover_material_id`** 物化 URL;该季节未配/物化失败回落到主表 `coverMaterialId`。无 query.seasons 时维持主表 cover(行为不变)。
|
||||||
|
|
||||||
|
#### 真实响应示例
|
||||||
|
|
||||||
|
**请求**: `GET /admin/scenic/spots?seasons=winter&pageSize=2`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"total": 17,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"scenicId": 3001000000000000019,
|
||||||
|
"name": "中俄边境公路(卡线)",
|
||||||
|
"cityName": "鄂温克族自治旗",
|
||||||
|
"coverUrl": "https://images.unsplash.com/photo-1511131341194-...?w=800&q=80",
|
||||||
|
"seasons": ["spring", "summer", "autumn", "winter"],
|
||||||
|
"tags": [{"tagId":"3","tagName":"摄影打卡","tagColor":"#409EFF","tagType":0}],
|
||||||
|
"honors": ["AAA","最美边境公路"],
|
||||||
|
"highlights": "...",
|
||||||
|
"longitude": 119.756219,
|
||||||
|
"latitude": 49.153445,
|
||||||
|
"rating": 0.0,
|
||||||
|
"viewCount": 31200,
|
||||||
|
"sortOrder": 19,
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
同一 scenicId 在 `seasons=spring` 时 `coverUrl` 会变成春景图,无 query 时变回主表 OSS 封面 — 已测试服真测验证切换正确。
|
||||||
|
|
||||||
|
**反例**(不存在的季节):
|
||||||
|
```http
|
||||||
|
GET /admin/scenic/spots?seasons=xxx
|
||||||
|
→ { "code": 200, "data": { "total": 0, "records": [] } }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 行程节点 VO 透传 `seasons`
|
||||||
|
|
||||||
|
| VO 类 | 端 | 字段 | 状态 |
|
||||||
|
|-------|-----|------|------|
|
||||||
|
| `InternalProductDetailVO.NodeItem` | admin | `seasons: List<String>` | ✅ 已落地,SCENIC 节点会回填 |
|
||||||
|
| `MpProductDetailInternalVO.ItineraryNodeItem` | mp | `seasons` | ⚠️ M2 占位,**当前永远 null**(注释已标注) |
|
||||||
|
|
||||||
|
> Mp 端 itinerary 当前走 M2 占位降级返空数组,等 M2 节点详情上线后才填充。**短期 Mp 端不要依赖 seasons 字段**。
|
||||||
|
|
||||||
|
## 前端实现建议
|
||||||
|
|
||||||
|
### 弹窗「从资源库添加活动 → 景区景点」
|
||||||
|
|
||||||
|
1. 弹窗打开时取当前编辑的产品线 `seasons`(产品线详情接口已返),**调景区列表时透传**:
|
||||||
|
```js
|
||||||
|
const params = new URLSearchParams()
|
||||||
|
productLineSeasons.forEach(s => params.append('seasons', s))
|
||||||
|
await api.get(`/admin/scenic/spots?${params}&pageSize=20`)
|
||||||
|
```
|
||||||
|
2. 列表行的**缩略图**直接用 VO 返回的 `coverUrl`(后端已按 `seasons[0]` 切换好)。
|
||||||
|
3. 列表行的**季节标签**渲染 `vo.seasons` 数组,建议 4 色:
|
||||||
|
- `spring` → 春绿 `#67C23A`
|
||||||
|
- `summer` → 夏蓝 `#409EFF`
|
||||||
|
- `autumn` → 秋橙 `#E6A23C`
|
||||||
|
- `winter` → 冬蓝灰 `#909399`
|
||||||
|
|
||||||
|
### 已选节点(行程卡片上)
|
||||||
|
|
||||||
|
行程节点详情 admin 端 `InternalProductDetailVO.NodeItem.seasons` 已有 — 在景区节点卡片上渲染同样的 4 色季节标签(可多个)。
|
||||||
|
|
||||||
|
### 兜底
|
||||||
|
|
||||||
|
- 老景区数据没配 `scenic_season` 的,`vo.seasons` 返 `[]` 空数组,前端不渲染标签即可。
|
||||||
|
- `coverUrl` 任何时候都不会因为新逻辑变 null(已做回落)。
|
||||||
|
|
||||||
|
## 涉及前端文件 (仅供参考定位)
|
||||||
|
|
||||||
|
- 弹窗组件: 大概率在 `D:\work2\hl-ui\src\views\product-v2\` 下的 itinerary editor 子组件
|
||||||
|
- 景区资源 picker: 搜 `从资源库添加活动` / `ScenicResourcePicker` / `scenic-spot-list`
|
||||||
|
|
||||||
|
## 工单 & PR
|
||||||
|
|
||||||
|
- Backend Issue: #2227
|
||||||
|
- Backend PR: #2229 (squash merged dev,已部署测试服)
|
||||||
|
- 测试服真测通过: 过滤 (66→18 autumn/17 winter/0 xxx) ✅ / OR 多选 ✅ / 季节封面切换 ✅ / VO seasons 按 scenic_id 分组 ✅
|
||||||
正在加载...
x
在新工单中引用
屏蔽一个用户