# [前端] 游玩项目编辑页加「季节内容」Drawer (对照景区已有的)

> **服务**: 前端 hl-ui (管理端)
> **后端 PR**: #2262 (Closes #2257) 已上线
> **日期**: 2026-05-14
> **影响范围**: 管理端 资源管理 → 游玩项目编辑页(运营配 4 季内容入口)

---

## ⚠️ 关键变化

后端 ActivitySeasonController admin CRUD 已上线测试服, **但前端 `views/resource/playservice/` 目录缺 SeasonDrawer.vue, 运营无处配 4 季内容** → activity_season 表全空 → `/admin/activity/items` 接口 seasons 字段恒返 `[]` → 弹窗无季节标签 + 节点封面无法按季节切换。

景区那边早就有 `views/resource/scenic/SeasonDrawer.vue` (322 行), 游玩项目这边缺一份对照实现。

---

## 现状对比

| 模块 | 编辑页 SeasonDrawer | 后端 API | DB 表 |
|---|---|---|---|
| 景区 | ✅ 已有 `views/resource/scenic/SeasonDrawer.vue` (322 行) | ✅ ScenicSeasonController | ✅ scenic_season 表已配数据 |
| **游玩项目** | ❌ **缺** `views/resource/playservice/SeasonDrawer.vue` | ✅ ActivitySeasonController (PR #2262 已上线) | ⚠️ activity_season 表全空 (因为没入口配) |

---

## 后端 API 已就绪 (PR #2262)

```
GET    /admin/activity/item/{activityId}/seasons              获取 4 季列表
PUT    /admin/activity/item/{activityId}/season/{seasonType}  upsert 单季
DELETE /admin/activity/item/{activityId}/season/{seasonType}  删除单季
```

`seasonType` ∈ `spring/summer/autumn/winter`

幂等：由 `(activity_id, season_type)` 唯一约束保证, PUT 已存在 → 更新, 否则 → 插入。

---

## 前端 4 步操作

### Step 1: `src/api/playservice.js` 加 3 个方法

照搬 `src/api/scenic.js` 同款实现：

```javascript
/** 获取游玩项目全部季节内容 */
export function getActivitySeasonList(activityId) {
  return http.get(`/activity/item/${activityId}/seasons`)
}

/** 保存/更新游玩项目单个季节 (upsert) */
export function updateActivitySeason(activityId, seasonType, data) {
  return http.put(`/activity/item/${activityId}/season/${seasonType}`, data)
}

/** 删除游玩项目单个季节 */
export function deleteActivitySeason(activityId, seasonType) {
  return http.delete(`/activity/item/${activityId}/season/${seasonType}`)
}
```

### Step 2: 复制景区 SeasonDrawer.vue

```
cp src/views/resource/scenic/SeasonDrawer.vue \
   src/views/resource/playservice/SeasonDrawer.vue
```

### Step 3: 内部全局替换

打开新文件 `src/views/resource/playservice/SeasonDrawer.vue`, 替换：

- `scenicId` → `activityId`
- `getScenicSeasonList` → `getActivitySeasonList`
- `updateScenicSeason` → `updateActivitySeason`
- `deleteScenicSeason` → `deleteActivitySeason`
- import 路径从 `@/api/scenic` → `@/api/playservice`

数据流/props/emit/UI 结构完全不变。

### Step 4: 入口按钮

`src/views/resource/playservice/index.vue` 添加触发 SeasonDrawer 的按钮 + 状态变量, 照搬 `src/views/resource/scenic/index.vue` 入口代码。

---

## VO 字段 (与 ScenicSeasonVO 完全对照)

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| seasonId | Long | - | 季节内容 ID (后端返回, 前端不填) |
| activityId | Long | - | 游玩项目 ID (path 参数) |
| seasonType | String | ✅ | spring/summer/autumn/winter |
| seasonName | String | ❌ | 季节别名 ("赏秋季"/"冰雪季"/"樱花季") |
| monthStart | Integer | ✅ | 1-12 |
| monthEnd | Integer | ✅ | 1-12, 可跨年如冬季 12-2 |
| description | String | ❌ | 季节简介 (TEXT) |
| highlights | String | ❌ | 季节亮点短文案 (VARCHAR 500) |
| playGuide | String | ❌ | 该季节游玩攻略 (富文本 MEDIUMTEXT) |
| tips | String | ❌ | 注意事项 (TEXT) |
| coverMaterialId | Long | ❌ | 季节封面素材 ID |
| bannerMaterialIds | List\<Long\> | ❌ | 季节轮播图素材 ID 列表 |
| videoMaterialIds | List\<Long\> | ❌ | 季节视频素材 ID 列表 |

---

## 完成后效果链路

```
运营配 4 季内容
  ↓
activity_season 表有数据
  ↓
/admin/activity/items 接口 seasons[] 非空
  ↓
产品编辑页弹窗游玩项目 tab 显示季节标签 + seasonHighlights 文案
  ↓
节点 resourceCover 按 productLine.seasons[0] 自动切对应季节封面
```

---

## 关联工作 (打包做)

同步还要做这件事 → 见 [14_frontend_admin_list_should_pass_seasons_param.md](./14_frontend_admin_list_should_pass_seasons_param.md) 或 [14_feat_admin_list_productline_resolve_seasons.md](./14_feat_admin_list_productline_resolve_seasons.md):

弹窗 `src/views/product/edit/components/modals/ResourcePickerModal.vue` line 57-62 改 1 行加 `productLineId` 参数, 让弹窗封面按当前产品季节切换。

两件事都做完才有完整效果。

---

## 不影响范围

- 后端 API 已上线, 前端不做不影响其他功能 (只是弹窗无季节标签 + 节点 cover 不切季节)
- 仅影响管理端游玩项目维护 (新增前端入口) + 弹窗显示效果

---

## 相关历史

| PR | Issue | 说明 |
|----|-------|------|
| #2262 | #2257 | 后端 ActivitySeasonController admin CRUD (本任务的数据基础) |
| #2229 | #2227 | 景区季节系列 (含 SeasonDrawer.vue, 本任务参照范本) |
| #2234 | #2232 | 游玩项目季节过滤 + 标签 (但漏前端入口) |

---

## 相关后端 changelog

- [14_feat_admin_activity_season_admin_crud.md](./14_feat_admin_activity_season_admin_crud.md) — 后端 PR #2262 ActivitySeasonController 完整 API 文档
- [14_feat_admin_list_productline_resolve_seasons.md](./14_feat_admin_list_productline_resolve_seasons.md) — 弹窗按 productLineId 自动 resolve seasons (前端打包做的另一件事)
