diff --git a/docs/plans/2026-10-17-K7.md b/docs/plans/2026-10-17-K7.md new file mode 100644 index 0000000..7a23bc7 --- /dev/null +++ b/docs/plans/2026-10-17-K7.md @@ -0,0 +1,91 @@ +# 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 接口和已读接口,不自行扩展契约。 diff --git a/docs/plans/INBOX.md b/docs/plans/INBOX.md index 569dbcc..bbb0722 100644 --- a/docs/plans/INBOX.md +++ b/docs/plans/INBOX.md @@ -20,7 +20,7 @@ --- -## [待处理] 2026-10-17 | K7 首页轮播图 + 站内信通知 +## [已处理·待用户验收] 2026-10-17 | K7 首页轮播图 + 站内信通知 **用户指令(2026-10-17)**:「现在做首页轮播图及站内信通知」。 @@ -105,6 +105,119 @@ - 每步「叙述 + 命令 + 原始输出 + 解读」追加到 `docs/plans/PROGRESS.md`;完成后停住写回执。 - 提交作者与提交者统一 `Zhou Weidong <502333560@qq.com>`。 +### 七、K7 完成回执(2026-10-17) + +**结论**:K7-A 轮播增强、K7-B 站内通知、K7-C 测试验收均完成并停止。 +未新增接口,未改后端/Web/specs。 + +#### 7.1 首页轮播 + +- 保持 `feed.banners` 数据源和 `CoverCarousel` 3D 翻转风格。 +- 4.5s 自动轮播;单张不启动 Timer。 +- 触摸/拖拽期间暂停,松手恢复。 +- `active=false` 或 `TickerMode` 不可见时暂停;dispose 取消 Timer。 +- 底部圆点指示器使用 `onPrimary` / `muted` K5 token,带三语语义标签。 +- 图片失败复用 `RemoteImage` 并显示图标占位。 +- 点击继续调用原有 `onOpen`。 + +#### 7.2 站内通知 + +- 新增 `notice.dart`、`notice_api.dart`、`notice_repository.dart`、 + `notices_controller.dart` 和 `NoticesPage`。 +- `GET /app/notices?pageIndex&pageSize=20`,匿名访问。 +- ID 按字符串解析,`total` 按数字解析。 +- 首屏、加载更多、空态、失败重试、下拉刷新均已接入; + 已加载数量 `< total` 时才展示加载更多。 +- 列表展示标题、原始 `type`、locale 时间、两行摘要。 +- 详情弹窗展示完整 `content`,保留换行并支持长内容滚动。 +- 我的页新增“通知”入口;匿名可进入,无登录闸。 +- `noticeEnabled` 属 `/app/config`,本批未接,登记后续。 + +真实 8081 匿名接口验证: + +``` +$ curl -sS 'http://127.0.0.1:8081/app/notices?pageIndex=1&pageSize=20' +{"code":0,"message":"ok","data":{"total":0,"list":[]}} +``` + +#### 7.3 门禁原始结果 + +``` +$ dart analyze lib test +Analyzing lib, test... +No issues found! + +$ flutter test test/discover/cover_carousel_test.dart test/notice +All tests passed! + +$ flutter test +00:14 +284 ~1: All tests passed! + +$ flutter build apk --debug +Running Gradle task 'assembleDebug'... 6.9s +✓ Built build/app/outputs/flutter-apk/app-debug.apk +``` + +`~1` 是既有 live watch 用例在 8081 未启动时按机制跳过。 + +新增覆盖: + +- 自动轮播、单张无 Timer、交互暂停、active/TickerMode、圆点、图片占位、onOpen。 +- 通知 API 字符串 ID、controller 分页/空/失败/刷新。 +- NoticesPage 首屏、加载更多、加载/空/失败三态、详情换行、印尼时间。 +- 320×568 长标题/长内容不溢出;我的页匿名通知入口。 + +#### 7.4 Git + +- 功能提交:`b870956665f5268070c691533cc2a334f2aa7f59` + `feat(flutter): 增加轮播自动播放与站内通知` +- `--no-ff` 合并:`3e8703b`,已推送 + `b7b1c50..3e8703b develop -> develop` +- author/committer 均为 `Zhou Weidong <502333560@qq.com>`;未操作 `main`。 + +#### 7.5 用户真机验证步骤与预期 + +1. 打开发现页顶部轮播,等待 4.5 秒。 + +预期:自动翻到下一张,圆点同步变化;单张 banner 不会自动循环。 + +2. 按住/拖动轮播超过 4.5 秒后松手。 + +预期:按住期间不自动翻页;松手后恢复自动轮播;拖拽仍保持 3D 翻转。 + +3. 暂时断开图片源或使用失败封面。 + +预期:显示深色占位和图片失败图标,不白屏。 + +4. 点击当前 banner。 + +预期:按原有 DRAMA 跳转逻辑进入详情。 + +5. 进入“我的 → 通知”,未登录也可访问。 + +预期:显示通知列表;空数据时显示“暂无通知”;断网时显示失败及重试。 + +6. 有超过 20 条通知时点击“加载更多”。 + +预期:下一页追加到列表,无重复;已加载数量达到 total 后按钮消失。 + +7. 下拉刷新,再点击一条长通知。 + +预期:刷新后列表回到第一页;详情显示标题、发布时间和完整正文; +正文换行保留且长内容可滚动。 + +8. 切换 Bahasa Indonesia 查看通知时间。 + +预期:时间按印尼 Material 格式显示。 + +设备侧截图与真机结果由用户执行。 + +#### 7.6 已知边界 + +- 无已读/未读、红点、FCM、通知设置。 +- 不接 `/app/config noticeEnabled`,通知入口当前常驻。 +- 无独立 banner 接口,未新增首页铃铛。 + --- ## [已处理·待用户验收] 2026-10-17 | K6 客户端 UI:登录页 + 底部导航优化 diff --git a/docs/plans/PROGRESS.md b/docs/plans/PROGRESS.md index 333ccf9..226017d 100644 --- a/docs/plans/PROGRESS.md +++ b/docs/plans/PROGRESS.md @@ -2028,3 +2028,76 @@ ac706a4..b7b1c50 develop -> develop ``` 解读:修复已合并推送;用户设备特定 error 仍需设备日志确认。 + +--- + +## 2026-10-17 K7 首页轮播与站内通知(【Codex】) + +### 21.1 K7 计划与首次红灯 + +叙述:先写 `docs/plans/2026-10-17-K7.md`,从干净 `develop b7b1c50` +创建 `feature/flutter-k7-carousel-notices`。 + +首次轮播/通知测试: + +``` +No named parameter with the name 'active' +Error when reading 'lib/core/data/models/notice.dart': No such file or directory +Error when reading 'lib/core/data/remote/notice_api.dart': No such file or directory +00:00 +0 -3: Some tests failed. +``` + +解读:轮播增强、通知数据层和页面尚不存在,红灯符合预期。 + +### 21.2 轮播绿灯 + +实现 Timer、交互暂停、active/TickerMode、圆点、失败占位与语义后: + +``` +$ flutter test test/discover/cover_carousel_test.dart +00:00 +7: All tests passed! +``` + +### 21.3 通知实现与定向绿灯 + +实现 Notice model/API/repository/controller/Page、我的页入口和三语文案后, +真实匿名接口返回: + +``` +$ curl -sS 'http://127.0.0.1:8081/app/notices?pageIndex=1&pageSize=20' +{"code":0,"message":"ok","data":{"total":0,"list":[]}} +``` + +通知与轮播定向测试: + +``` +$ flutter test test/discover/cover_carousel_test.dart test/notice +All tests passed! +``` + +期间修正 320px 下类型/时间同一行 3.5px 溢出,改为双 Flexible。 + +### 21.4 K7 最终门禁 + +``` +$ dart analyze lib test +Analyzing lib, test... +No issues found! + +$ flutter test +00:14 +284 ~1: All tests passed! + +$ flutter build apk --debug +✓ Built build/app/outputs/flutter-apk/app-debug.apk +``` + +### 21.5 Git + +``` +b870956665f5268070c691533cc2a334f2aa7f59 +feat(flutter): 增加轮播自动播放与站内通知 + +b7b1c50..3e8703b develop -> develop +``` + +解读:K7 已合并推送;author/committer 均为 Zhou Weidong。