92 lines
3.7 KiB
Markdown
92 lines
3.7 KiB
Markdown
# 2026-10-17 K7 首页轮播图 + 站内信通知
|
||
|
||
## 一、目标与边界
|
||
|
||
本批只完成 Flutter 客户端两项能力:
|
||
|
||
- K7-A:增强现有 `CoverCarousel`,继续使用 `feed.banners` 和 3D 翻转风格,
|
||
增加自动轮播、交互暂停、指示器、失败占位和语义。
|
||
- K7-B:新增匿名站内信分页页,接入 `GET /app/notices`,在我的页增加通知入口。
|
||
- K7-C:补轮播/通知/响应式与 locale 时间测试。
|
||
|
||
不做已读未读、红点、FCM、通知设置、`/app/config noticeEnabled`、首页铃铛、
|
||
新 banner 接口、后端、Web 或 specs 修改。
|
||
|
||
## 二、契约口径
|
||
|
||
### Banner
|
||
|
||
- 数据源:`GET /app/home/feed` / `GET /app/discover/feed` 的 `banners[]`。
|
||
- 无独立接口;空列表继续 `SizedBox.shrink()`。
|
||
- 点击继续沿用 `linkType=DRAMA` + `linkValue` 的现有 `onOpen`。
|
||
|
||
### Notices
|
||
|
||
- `GET /app/notices?pageIndex=1&pageSize=20`,匿名。
|
||
- 响应:`{total, list:[{id,title,content,type,publishAt,expireAt}]}`。
|
||
- ID 全部按字符串;`total` 是数字。
|
||
- `list.length` 用于判断当前页是否有数据;是否加载更多按
|
||
“已加载数量 < total”判断。
|
||
- `type` 原样展示,不建立客户端枚举映射。
|
||
|
||
## 三、预计影响文件
|
||
|
||
轮播:
|
||
|
||
- `lib/pages/discover/widgets/cover_carousel.dart`
|
||
- `lib/pages/discover/discover_view.dart`
|
||
- `lib/core/widgets/remote_image.dart`(可选失败图标参数)
|
||
- `test/discover/cover_carousel_test.dart`
|
||
|
||
通知:
|
||
|
||
- `lib/core/data/models/notice.dart`
|
||
- `lib/core/data/remote/notice_api.dart`
|
||
- `lib/core/data/repositories/notice_repository.dart`
|
||
- `lib/core/data/services/notices_controller.dart`
|
||
- `lib/pages/notices/notices_page.dart`
|
||
- `lib/pages/mine/mine_view.dart`
|
||
- `lib/app.dart`(NoticeRepository Provider)
|
||
- `test/notice/**`
|
||
- `lib/l10n/app_{en,zh,id}.arb` 与生成文件
|
||
|
||
## 四、实现口径
|
||
|
||
### 轮播
|
||
|
||
- `Timer.periodic` 4.5s;单张不创建定时器;`dispose` 取消。
|
||
- 使用 `TickerMode.of(context)`/`Visibility` 语义监听页面可见性;
|
||
不可见时取消,恢复时重新启动。
|
||
- pointer down 暂停,up/cancel 恢复;拖拽时沿用现有 3D 翻转。
|
||
- 指示器采用底部圆点,使用 `AppColors.onPrimary` + `muted` 低透明度。
|
||
- 语义标签进入三语 arb。
|
||
- 图片失败使用现有 `RemoteImage` 并显示图标占位。
|
||
|
||
### 通知
|
||
|
||
- `NoticesController` 管理首屏、分页、加载更多、刷新、错误。
|
||
- `NoticesPage` 深色页,保留 K5/K6 主题与 Haptics 不触发滑动振动。
|
||
- 列表项标题/类型/时间/两行摘要;点击打开详情 Dialog。
|
||
- 详情 `content` 用可滚动 `Text` 保留 `\n`,长内容不溢出。
|
||
- `publishAt` / `expireAt` 使用现有 `formatLocalizedDateTime`。
|
||
- 我的页 `_menuCard` 增加通知入口,匿名可进入。
|
||
|
||
## 五、TDD 顺序
|
||
|
||
1. 轮播:自动切页、单张无 Timer、指示器、触摸暂停、点击回调、失败占位。
|
||
2. 通知 API/model:分页字段、字符串 ID、时间解析。
|
||
3. Controller:首屏、追加、加载更多条件、空/失败/刷新。
|
||
4. NoticesPage:三态、列表、分页、详情、长内容、小屏。
|
||
5. 我的页入口与三语文案。
|
||
6. 门禁:`dart analyze lib test`、`flutter test`、
|
||
`flutter build apk --debug`。
|
||
|
||
## 六、风险与待确认
|
||
|
||
- 自动轮播 Timer 与 3D AnimationController 并存,需避免 dispose 后 setState。
|
||
- 页面用 `IndexedStack` 保持状态,需通过 `TickerMode` 判断真实可见性。
|
||
- `total` 可能在分页期间变化,以本次响应 total 与已加载数量比较。
|
||
- 详情长内容必须可滚动,避免小屏 overflow。
|
||
- `noticeEnabled` 属 `/app/config`,本批不接;通知入口暂时常驻,已登记后续。
|
||
- 无独立 banner 接口和已读接口,不自行扩展契约。
|