Files
daycard-app/开发测试记录-20260714.md
2026-07-26 12:43:59 +08:00

230 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 橘视厅酒店版 App 开发与测试记录
> 日期:2026-07-14
> 项目:MediaApp(橘视厅酒店版)
> 版本:v1.0
---
## 一、概述
本次开发围绕天卡(日卡)激活 → 设备鉴权 → 微信支付 → 发卡 → 播放的完整链路进行联调与修复,并完成了权益持久化/静默鉴权、播放器画面比例、UI 美化等优化。
---
## 二、问题修复记录
### 2.1 激活请求无法到达后端
- **现象**:点击激活后请求未到达后端,错误仅以弹窗形式出现,无法定位原因。
- **修复**:
- 新增 `FileLogger` 工具类,持久化日志到 `Android/data/com.pukka.mediaapp/files/logs/daycard.log`。
- 新增 `FileLoggingInterceptor`,拦截 OkHttp 请求/响应写入日志文件。
- 在 `SignManager`(激活/init/refresh/heartbeat)、`PaymentViewModel`(鉴权/下单/轮询)关键路径加入 `FileLogger` 调用。
- **结果**:通过 `adb pull` 拉取日志后成功定位问题,激活流程恢复正常。
### 2.2 Gson `code` 字段冲突
- **现象**:后端返回的 JSON 中 `code` 字段被 Gson 解析为重复键,导致业务码判断异常。
- **原因**:`BaseResponse` 子类(`CheckBenefitsResponse`、`CreateOrderResponse` 等)各自声明了 `override val code/msg`,与父类产生重复 JSON 字段。
- **修复**:移除所有子类中的 `code`/`msg` 声明,统一继承 `BaseResponse()`。
- **文件**:`DayCardModels.kt`
### 2.3 支付弹窗渲染异常
- **现象**:支付弹窗仅显示"微信扫码支付"6 个字,其余区域空白,所有按钮不可点击。
- **原因**:240dp×240dp 的二维码 `FrameLayout` 在加载/错误状态下未隐藏,将按钮挤出可视区域。
- **修复**:
- 给 `FrameLayout` 添加 `android:id="@+id/flQrcode"`。
- 在 `showPaymentDialog`/加载/错误分支设置 `flQrcode.visibility = GONE`,在 `showQrCode` 中设为 `VISIBLE`。
- **文件**:`dialog_payment.xml`、`DetailActivity.kt`
### 2.4 天卡库存不足提示
- **现象**:天卡卡池为空时,后端返回 HTTP 200 + `{"code":500,"msg":"天卡库存不足,请补充库存后再试"}`,前端需正确识别。
- **修复**:前端按 JSON `code` 字段判断(而非 HTTP 状态码),`code === 500` 且 `msg` 包含"库存不足"时弹出错误提示。
- **备注**:抢卡失败时会产生孤儿订单(status=PENDING),由后端超时定时任务 `DayCardOrderTimeoutTask` 清理为 CANCELLED。
### 2.5 发卡成功但返回播放地址异常
- **现象**:支付成功、发卡成功后,获取播放地址异常。
- **原因**:绑定与鉴权链路问题(橘视厅平台订购关系)。
- **修复**:平台侧订购关系修正后恢复正常。
---
## 三、权益持久化与静默鉴权
### 3.1 背景
成功获取播放地址后,切换其它电影点击播放仍弹出支付提示窗。虽然流程很快走完,但体验不佳。需实现有效期内权益持久化 + 静默鉴权。
### 3.2 实现方案
#### SignManager 权益缓存(`DayCardSignUtil.kt`)
| 方法 | 说明 |
|------|------|
| `cacheBenefits(thirdCardNo, expireAt)` | 缓存卡号 + 过期时间到 SharedPreferences `jst_sign` |
| `getCachedThirdCardNo()` | 读取缓存卡号,过期返回空串 |
| `clearBenefits()` | 清除权益缓存 |
| `parseExpireAtToMillis()` | 解析多种时间格式为毫秒时间戳 |
- 过期时间兜底:解析失败时使用 `SIGN_TTL` 作为默认有效期。
#### PaymentViewModel(`PaymentViewModel.kt`)
- **缓存命中**:`startPaymentFlow()` 开头同步检查 `getCachedThirdCardNo()`,非空则直接发射 `HasPermission`,不发起网络请求、不弹窗。
- **缓存写入**:三处调用 `cacheBenefits()`:
1. `checkBenefits` 返回 ACTIVE 时
2. 轮询支付成功后首次 `checkBenefits` 返回 ACTIVE 时
3. 轮询支付成功后重试 `checkBenefits` 返回 ACTIVE 时
- **缓存清除**:SDK 初始化失败时调用 `clearBenefits()`(卡号可能已失效,下次播放重新鉴权)。
- **修复**:移除了之前重复的 `flowJob = viewModelScope.launch` 嵌套问题。
#### DetailActivity 静默播放(`DetailActivity.kt`)
| 状态 | 原行为 | 新行为 |
|------|--------|--------|
| `CheckingPermission` | 弹支付窗"正在检查播放权限" | 静默,不弹窗不提示 |
| `HasPermission` | 弹窗"已有播放权限" | 直接播放,无弹窗无 Toast |
| `CreatingOrder` | 弹窗加载 | 弹窗加载(仅无权益路径触发) |
| `WaitingForPayment` | 展示二维码 | 展示二维码(不变) |
| `PaymentSuccess` | 弹窗"支付成功" | 关闭弹窗直接播放,无 Toast |
| `Error` | 弹窗显示错误 | 弹窗显示错误,重置播放标志 |
- `playWithThirdCardNo` / `fetchVideoUrlFromSdk`:移除所有加载 Toast,仅保留错误 Toast(LENGTH_LONG)。
- `startPaymentFlow()`:移除"正在检查播放权限..." Toast。
- **最终效果**:天卡有效期内切换电影点播放,完全静默,直接进入播放器。
### 3.3 链路时序
```
首次播放(无缓存):
点击播放 → checkBenefits(网络) → ACTIVE → cacheBenefits → 播放
点击播放 → checkBenefits(网络) → UNBOUND → createOrder → 二维码 → 支付 → 轮询PAID → checkBenefits → cacheBenefits → 播放
后续播放(缓存有效):
点击播放 → getCachedThirdCardNo(本地) → HasPermission → 播放 [全程无网络、无弹窗]
缓存过期/SDK失败:
点击播放 → getCachedThirdCardNo 返回空 → checkBenefits(网络) → 重新走鉴权流程
```
---
## 四、App 名称与播放器
### 4.1 App 名称
- `strings.xml` 中 `app_name` 从"媒资展示"改为"橘视厅酒店版"。
### 4.2 播放器画面比例
- `activity_player.xml` 中 `StyledPlayerView` 的 `resize_mode` 从 `fill`(拉伸填充)改为 `fit`(保持原始比例,不拉伸)。
- 非 16:9 内容会自动上下/左右留黑边。
---
## 五、UI 布局优化
### 5.1 新增 Drawable(8 个)
| 文件 | 用途 |
|------|------|
| `bg_poster_rounded.xml` | 海报四角圆角裁切背景 |
| `bg_poster_rounded_top.xml` | 海报顶部圆角(卡片用) |
| `bg_play_button.xml` | 播放按钮橙色渐变 + 24dp 大圆角 |
| `bg_nav_selected.xml` | 导航选中胶囊背景 |
| `bg_section_bar.xml` | 楼层标题橙色竖条指示器 |
| `bg_button_secondary.xml` | 次要按钮半透明圆角 |
| `bg_dialog.xml` | 支付弹窗渐变背景 + 16dp 圆角 |
| `bg_qrcode_white.xml` | 二维码白底圆角 |
### 5.2 更新 Drawable(4 个)
| 文件 | 变更 |
|------|------|
| `bg_card.xml` | 纯色 → 渐变层次感,圆角 8→10dp |
| `bg_card_focus.xml` | 焦点边框白色 → 橙色 |
| `bg_button_accent.xml` | 纯色 → 渐变,圆角 8→20dp |
| `bg_search_input.xml` | 圆角优化 |
### 5.3 布局优化
| 布局文件 | 优化内容 |
|----------|----------|
| `item_content.xml` | 海报圆角裁切,标题/评分字号增大,间距优化 |
| `activity_detail.xml` | 海报 120→150dp 加圆角,播放按钮渐变大圆角(140×52dp),信息区间加分割线,整体字号增大 |
| `item_nav.xml` | 选中态从下划线改为橙色胶囊背景 |
| `item_section.xml` | 楼层标题前加橙色竖条指示器 |
| `activity_home.xml` | 顶栏底部加分割线 |
| `item_search_result.xml` | 海报圆角,字号增大,间距优化 |
| `activity_list.xml` | 侧边栏间距优化 |
| `dialog_payment.xml` | 渐变背景,二维码白底圆角,主按钮渐变,关闭按钮改次要样式 |
### 5.4 代码优化
| 文件 | 变更 |
|------|------|
| `AdapterUtils.kt` | 焦点边框白色 → 橙色,圆角 8→10dp,聚焦时 `bringToFront` |
| `NavAdapter.kt` | 选中态从 `BottomLineDrawable` 下划线改为 `bg_nav_selected` 胶囊背景 |
---
## 六、测试情况
| 测试项 | 结果 | 备注 |
|--------|------|------|
| 设备激活 | ✅ 通过 | 卸载重装后可正常激活 |
| 鉴权 → 播放(有权益) | ✅ 通过 | 缓存命中后静默播放 |
| 鉴权 → 支付 → 播放(无权益) | ✅ 通过 | 二维码展示 → 支付 → 发卡 → 播放 |
| 天卡库存不足 | ✅ 通过 | 正确提示"天卡库存不足" |
| 切换电影重复播放 | ✅ 通过 | 有效期内不弹窗,直接播放 |
| SDK 初始化失败 | ✅ 通过 | 清除缓存,Toast 提示错误 |
| 播放器 16:9 | ✅ 通过 | 不拉伸,保持原始比例 |
| App 名称显示 | ✅ 通过 | 显示"橘视厅酒店版" |
| UI 布局美观度 | ✅ 通过 | 圆角海报、渐变卡片、橙色焦点态 |
---
## 七、关键文件清单
```
MediaApp/app/src/main/java/com/pukka/mediaapp/
├── network/
│ ├── DayCardSignUtil.kt # SignManager + 权益缓存 + Retrofit 客户端
│ └── DayCardApiService.kt # API 接口定义
├── viewmodel/
│ └── PaymentViewModel.kt # 支付/鉴权流程状态机
├── ui/
│ ├── DetailActivity.kt # 详情页 + 静默播放逻辑
│ ├── VideoPlayerActivity.kt # ExoPlayer 播放器
│ └── adapter/
│ ├── AdapterUtils.kt # 焦点高亮 + 主题色
│ ├── ContentAdapter.kt # 内容卡片适配器
│ └── NavAdapter.kt # 导航适配器
├── model/daycard/
│ └── DayCardModels.kt # 响应模型(BaseResponse 继承)
└── utils/
└── FileLogger.kt # 文件日志工具
MediaApp/app/src/main/res/
├── layout/ # 全部布局文件(已优化)
├── drawable/ # 14 个 drawable(8 新增 + 4 更新 + 2 原有)
├── values/
│ ├── colors.xml # 颜色定义
│ ├── dimens.xml # 尺寸定义
│ ├── strings.xml # 字符串(app_name 已改)
│ └── themes.xml # 主题
```
---
## 八、待办与后续
- [ ] 天卡过期后自动重新走鉴权流程的体验验证(长期测试)
- [ ] 支付弹窗在弱网环境下的超时处理优化
- [ ] UI 在不同分辨率 TV 盒子上的适配验证
- [ ] 考虑权益缓存过期前提前静默刷新(避免过期瞬间首次播放有延迟)