Files
arcx-app/docs/prd.md
2026-08-08 10:57:54 +08:00

166 lines
8.3 KiB
Markdown
Raw Permalink 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.
# 📝 记分本(Point BookFlutter 纯本地版 PRD
## 文档信息
- **文档状态**:已完成(重构版)
- **适用端**iOS / Android 客户端(Flutter 纯本地架构)
- **变现模式**:免费试用 + iOS 苹果内购(IAP 买断/解锁)
- **关联模块**:本地训练统计 / 个人资料管理 / 记分管理 / 苹果内购
---
## 1. 页面概述
### 1.1 页面定位与目标
- **定位**:记分本业务线的 **总入口与本地数据总览页**
- **目标**
1. **零门槛使用**:无任何登录流程,首次打开即可直接查看本地统计或发起记分。
2. **正向数据反馈**:直观展示本地累计射箭数据、日均消耗、环值命中分布与落点热力图。
3. **内购合规转化**:提供免费体验额度,在用户第 N 次点击【开始记分】时,平滑唤起苹果内购付费解锁弹框。
### 1.2 权限与架构变更
- **数据架构****纯本地架构(Local-First)**,无后端服务器、无网络 API,所有训练数据与配置均存储于手机本地数据库(Isar/Hive)。
- **用户体系**:**完全免登录**,移除所有手机号获取、微信登录及协议勾选框。
- **排行榜**:**彻底移除**周榜、点赞及任何他人对比功能。
---
## 2. 页面流转与初始化逻辑
```mermaid
graph TD
A[用户打开 App / 进入首页] --> B[加载本地数据库 Isar]
B --> C[读取/初始化本地 UserProfile]
B --> D[读取/初始化本地 AppConfig]
B --> E[读取本地历史 PointRecord 列表]
C --> F[渲染:顶部个人资料卡片]
D --> G[渲染:用户权益/免费剩余次数]
E --> H[渲染:本地统计指标、落点热力图、环值分布图]
```
---
## 3. 核心功能与交互说明
### 3.1 本地个人资料管理(头像与昵称修改)
- **默认生成**:App 首次启动时,本地自动创建默认 Profile:
- **默认昵称**`弓箭手_XXXX`(四位随机数字)。
- **默认头像**:预设本地 Avatar Asset。
- **编辑交互**
- **入口**:点击首页顶部的个人资料卡片或【编辑】图标。
- **修改昵称**:弹出本地输入框,限制 1~12 个字符。
- **修改头像**:支持从手机本地相册选择图片或调起相机拍摄;选中后将图片异步拷贝至 App 本地沙盒目录 `ApplicationDocumentsDirectory/avatar.png`,数据库中仅保存文件路径。
---
### 3.2 个人训练统计卡片(纯本地计算)
- **关键指标**:今日射箭数、今日消耗、运动强度、训练天数、累计射箭数、平均环数。
- **计算规则**
- **无数据时**:指标统一展示为 `-`
- **今日消耗**$\text{今日箭数} \times 1.6$。
- **运动强度**$\frac{\text{今日箭数} \times 5}{60}$(上限封顶为 10)。
- $> 6$:标记为 **重度**
- $4 \sim 6$:标记为 **中度**
- $< 4$:标记为 **轻度**
---
### 3.3 核心业务入口与苹果内购(IAP)拦截
#### 🔹 入口一:【计分记录】
- **交互**:点击直接进入 `本地计分记录列表页`(支持按弓型/距离/靶纸筛选及本地记录滑动删除)。
#### 🔹 入口二:【开始记分】(含免费试用与内购拦截)
- **参数配置**
- `free_trial_limit`: 可配置免费试用次数(默认 `2` 次)。
- `used_trial_count`: 已使用免费试用次数。
- `is_vip_unlocked`: 是否已购买内购解锁(`true` / `false`)。
- **拦截判定流程**
```mermaid
graph TD
Start[点击“开始记分”] --> VIPCheck{is_vip_unlocked == true ?}
VIPCheck -- 是 --> DraftCheck
VIPCheck -- 否 --> TrialCheck{used_trial_count < free_trial_limit ?}
TrialCheck -- 是 (试用额度内) --> DraftCheck
TrialCheck -- 否 (试用额度已满) --> Paywall[阻断进入,弹出收费解锁弹框]
DraftCheck{本地是否存在未完成草稿?} -- 无草稿 --> CreatePage[进入参数选择/新建记分页]
DraftCheck -- 有草稿 --> DraftConfirmDialog[弹出草稿二选一确认框]
DraftConfirmDialog -- 继续编辑 --> EditPage[进入记分编辑页加载草稿]
DraftConfirmDialog -- 重新计分 --> ClearDraft[清空本地草稿] --> CreatePage
```
> **计数更新时机**:当用户在试用期内完成一次完整记分并点击**【保存记分】**成功写入本地数据库后,系统自动执行 `used_trial_count + 1`。
#### 💳 内购解锁弹窗与结果流转
- **弹窗展示**:包含内购商品名称、价格、买断权益说明、`[立即解锁]` 按钮、`[恢复购买]` 按钮及 `[取消/暂不解锁]` 按钮。
- **支付流转规则**
| 用户操作 / 支付状态 | 系统响应 | 页面流转 |
| ------------------------ | ------------------------------------------ | --------------------------- |
| **点击 [立即解锁]** | 调起 Apple App Store 原生支付组件。 | 界面显示原生 Loading 遮罩。 |
| **支付成功 (Purchased)** | 1. 本地数据库更新 `is_vip_unlocked = true` | |
2. 弹出 Toast 提示:“解锁成功!已获得无限记分权益” | 1. 关闭内购弹窗;
3. **返回【记分本首页】**
4. 再次点击【开始记分】自动解锁放行。 |
| **取消支付 (Canceled)** | 1. 弹出 Toast 提示:“支付已取消” | 1. 关闭内购弹窗;
5. **停留在【记分本首页】**。 |
| **支付失败 (Error)** | 1. 弹出 Toast 提示:“支付失败:[错误信息]” | 1. 关闭 Loading
6. **停留在【记分本首页】**。 |
| **点击 [恢复购买]** | 调起 `InAppPurchase.instance.restorePurchases()` | 查到历史购买凭证后更新 `is_vip_unlocked = true` 并提示“权益已恢复”,关闭弹窗并**返回【记分本首页】**。 |
---
### 3.4 本地图像分析模块(热力图与环值分布)
#### 🎯 落点热力图
- **展示条件**:本地存在历史训练数据时展示。
- **生成方式**:读取本地 `PointRecord` 中的 `hitPoints` 坐标数据,使用 Flutter Canvas 在本地预设靶纸底图上直接绘制热力点覆盖层。
#### 📊 个人环值分布图
- **展示条件**:本地存在历史记录时展示。
- **展示形式**:按 `M / X / 1~10 环` 统计本地所有箭数的占比,以柱状图形式呈现。
---
## 4. 边界异常处理与业务细节(QA 关注)
| 场景 | 预期处理机制 | 备注 / 风险点 |
| --------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
| **首次安装 / 无数据** | 统计数据指标展示 `-`,热力图展示纯靶纸背景图,免费次数显示 `0/2`。 | 避免因为数据为空导致本地 Canvas 渲染报错。 |
| **本地草稿覆盖** | 点击“重新计分”会强制删除本地 SQLite/Isar 中的草稿记录,并覆盖写入。 | 需有二次弹窗明确确认,防止误删未保存数据。 |
| **重装 App / 换手机** | 纯本地 App 不支持跨设备数据同步;用户可通过内购弹窗的 **[恢复购买]** 恢复付费权益。 | 需在 App 内“关于我们”或设置页明确告知“数据存储于本地,卸载 App 会清空训练记录”。 |
| **网络离线内购** | 发起购买需要网络连接,若离线调起内购,提示:“无法连接到 App Store,请检查网络设置”。 | - |
---
---
## 5. 关联页面流转汇总
- 📄 **记分本首页** (`PointBookHomeScreen`):本地数据总览、免费次数提示、个人资料编辑入口、内购弹窗触发。
- 📄 **计分记录列表** (`PointBookListPage`):读取本地 Isar 历史列表、草稿展示与记录删除。
- 📄 **新建参数配置** (`PointBookCreatePage`):选择弓型、距离、靶纸类型及组数。
- 📄 **记分编辑/打靶页** (`PointBookEditPage`):本地实时记录落点与环数,保存时写入本地数据库并扣减试用次数。