From 21190c640f9ffe2d9d65ef0af6dbc6e7ebf73310 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Thu, 14 May 2026 18:01:51 +0800 Subject: [PATCH] =?UTF-8?q?frontend:=20=E6=B8=B8=E7=8E=A9=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=BC=96=E8=BE=91=E9=A1=B5=E5=8A=A0=20SeasonDrawer=20?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=20mmg=20(=E5=90=8E=E7=AB=AF=20PR=20#2262=20?= =?UTF-8?q?=E5=B7=B2=E4=B8=8A=E7=BA=BF=E4=BD=86=E5=89=8D=E7=AB=AF=E7=BC=BA?= =?UTF-8?q?=E5=85=A5=E5=8F=A3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 景区有 views/resource/scenic/SeasonDrawer.vue (322 行) 让运营配 4 季内容, 游玩项目 目录 views/resource/playservice/ 缺对应 SeasonDrawer → activity_season 表全空 → admin/activity/items 接口 seasons 字段恒返 [] → 弹窗无季节标签 + 节点 cover 无法按季节切换。 文档给出 4 步精确操作: 1. src/api/playservice.js 加 3 方法 (照搬 scenic 同款) 2. 复制 scenic/SeasonDrawer.vue → playservice/SeasonDrawer.vue 3. 全局替换 scenicId → activityId + import @/api/scenic → @/api/playservice 4. playservice/index.vue 加入口按钮 VO 字段清单 + 完成后效果链路 + 关联打包做的另一件事 (ResourcePickerModal 补传 productLineId) 全部写清。 notify @mmg Co-Authored-By: Claude Opus 4.7 (1M context) --- ..._frontend_playservice_add_season_drawer.md | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 changelogs/2026-05/14_frontend_playservice_add_season_drawer.md diff --git a/changelogs/2026-05/14_frontend_playservice_add_season_drawer.md b/changelogs/2026-05/14_frontend_playservice_add_season_drawer.md new file mode 100644 index 0000000..4f8dc06 --- /dev/null +++ b/changelogs/2026-05/14_frontend_playservice_add_season_drawer.md @@ -0,0 +1,155 @@ +# [前端] 游玩项目编辑页加「季节内容」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\ | ❌ | 季节轮播图素材 ID 列表 | +| videoMaterialIds | List\ | ❌ | 季节视频素材 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 (前端打包做的另一件事)