8.3 KiB
8.3 KiB
📝 记分本(Point Book)Flutter 纯本地版 PRD
文档信息
- 文档状态:已完成(重构版)
- 适用端:iOS / Android 客户端(Flutter 纯本地架构)
- 变现模式:免费试用 + iOS 苹果内购(IAP 买断/解锁)
- 关联模块:本地训练统计 / 个人资料管理 / 记分管理 / 苹果内购
1. 页面概述
1.1 页面定位与目标
- 定位:记分本业务线的 总入口与本地数据总览页。
- 目标:
- 零门槛使用:无任何登录流程,首次打开即可直接查看本地统计或发起记分。
- 正向数据反馈:直观展示本地累计射箭数据、日均消耗、环值命中分布与落点热力图。
- 内购合规转化:提供免费体验额度,在用户第 N 次点击【开始记分】时,平滑唤起苹果内购付费解锁弹框。
1.2 权限与架构变更
- 数据架构:纯本地架构(Local-First),无后端服务器、无网络 API,所有训练数据与配置均存储于手机本地数据库(Isar/Hive)。
- 用户体系:完全免登录,移除所有手机号获取、微信登录及协议勾选框。
- 排行榜:彻底移除周榜、点赞及任何他人对比功能。
2. 页面流转与初始化逻辑
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)。- 拦截判定流程:
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 |
-
弹出 Toast 提示:“解锁成功!已获得无限记分权益” | 1. 关闭内购弹窗;
-
返回【记分本首页】;
-
再次点击【开始记分】自动解锁放行。 | | 取消支付 (Canceled) | 1. 弹出 Toast 提示:“支付已取消” | 1. 关闭内购弹窗;
-
停留在【记分本首页】。 | | 支付失败 (Error) | 1. 弹出 Toast 提示:“支付失败:[错误信息]” | 1. 关闭 Loading;
-
停留在【记分本首页】。 | | 点击 [恢复购买] | 调起
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):本地实时记录落点与环数,保存时写入本地数据库并扣减试用次数。