edit | blame | history | raw

免费版 + Pro 解锁实施 TODO

日期:2026-06-26
范围:TagLauncher 首期“免费下载 + Pro 一次性买断解锁”

已冻结的实现原则

  1. 免费版保留完整核心价值:
  • 标签整理
  • 基础启动
  • Quick Search
  1. 首期 Pro 功能范围:
  • 全部高级主题
  • 导入 / 导出布局
  • 无限自定义备注
  • 手动自定义应用图标排序结果持久化
  1. 老用户权益规则:
  • originalAppVersion 早于“免费 + Pro 首个正式版本”则自动获得 Pro
  • originalPurchaseDate 仅在版本信息缺失或不可用时兜底
  • 该“首个正式版本”阈值必须收口到单一配置点,发布前再冻结,不允许散落在各业务模块
  1. 免费预览绝不能写脏真实数据:
  • 主题预览不写 appGridThemeID
  • 排序预览不写 containerAppOrder
  • 免费用户触发导入 / 导出时不打开文件面板
  • 免费用户第 6 个新备注不写 appNotes / appNoteMetadata
  1. UI 方案:
  • 不做独立 Pro 页签
  • Data 页顶部放完整 Pro 状态区
  • Theme 页顶部放轻量镜像状态条
  • 高级功能入口使用小型 Pro 胶囊,不做全局 V
  • 遵循现有设置页语言:克制、原生、低营销

已落地的发布参数

  1. Pro 商品 ID:com.taglauncher.pro.lifetime,集中在 ProEntitlementConfig.lifetimeProductID
  2. Pro 价格展示:运行时读取 StoreKit product display price;提交 ASC 时仍需按线上价格最终确认
  3. 免费 + Pro 首个正式版本号:8.1.0,集中在 ProEntitlementConfig.firstFreeProVersion
  4. originalPurchaseDate 兜底日期:当前保持 nil,仅当版本阈值无法判断且后续明确兜底日期时启用

Phase 1:权益中心与购买基础能力

  • [x] 新增统一权益中心 ProEntitlementCenter
  • [x] 建立状态模型:
  • [x] 免费用户
  • [x] 购买获得 Pro
  • [x] 老付费自动 Pro
  • [x] 正在购买 / 正在恢复
  • [x] 购买失败 / 取消 / 无可恢复购买
  • [x] 接入 StoreKit 2 当前权益查询
  • [x] 接入 Transaction.updates
  • [x] 接入购买 Pro
  • [x] 接入恢复购买
  • [x] 加入离线缓存,避免离线启动误丢 Pro
  • [x] 加入 QA 注入开关:
  • [x] TAGLAUNCHER_QA_PRO_STATE=free|pro|legacyPro
  • [x] TAGLAUNCHER_QA_THEME_PREVIEW_SECONDS

Phase 2:Pro 功能门禁

主题

  • [x] 免费主题固定为:默认、深蓝、黑色
  • [x] 其它主题点击进入预览,不直接写持久化主题
  • [x] 预览默认 5 分钟,QA 可缩短
  • [x] 预览结束恢复进入前真实主题
  • [x] Theme 页增加轻量状态条
  • [x] Pro 主题卡增加 Pro 胶囊

备注

  • [x] 统一计算“有非空手写备注的应用数量”
  • [x] 免费用户允许编辑已有备注
  • [x] 免费用户新增第 6 个备注时阻止保存
  • [x] 删除 / 清空备注后释放额度
  • [x] 备注提示文案与剩余额度联动

排序

  • [x] 免费用户允许拖拽排序预览
  • [x] 预览只改内存态,不写 TagEditor.reorderApps
  • [x] 退出预览恢复进入前顺序
  • [x] Pro 用户按现有逻辑正常持久化
  • [x] 明确预览提示,不误导用户“已保存”

导入 / 导出

  • [x] 免费用户点击导入 / 导出时直接拦截
  • [x] 不打开 NSSavePanel / NSOpenPanel
  • [x] 设置页按钮旁增加低噪音 Pro 标识
  • [x] TagDatabase.exportTo/importFrom 也补硬门禁,防止绕过

Phase 3:设置页与提示 UI

  • [x] Data 页顶部新增完整 Pro 状态区
  • [x] 免费态展示:
  • [x] 权益摘要
  • [x] 解锁 Pro
  • [x] 恢复购买
  • [x] 已解锁态展示:
  • [x] Pro 已解锁
  • [x] 如属老用户,显示“感谢早期支持”
  • [x] 处理中状态不弹二级窗,按钮原位 loading
  • [x] 失败 / 取消结果用内联反馈,不打断
  • [x] 拦截弹窗统一语法:
  • [x] 功能名
  • [x] 用户收益
  • [x] 解锁 Pro
  • [x] 恢复购买
  • [x] 关闭

Phase 4:多语言与 QA

  • [x] 补齐 29 个语言包 Pro 文案
  • [x] 禁止任一语种出现其他语种残留
  • [x] 增加静态 QA:
  • [x] 文案键完整性
  • [x] 非中文语言禁止混入中文
  • [x] 非英文语言禁止直接回退英文关键 Pro 文案
  • [x] 增加功能 QA:
  • [x] 免费 / Pro / legacy Pro 三态源码门禁
  • [x] 购买 / 恢复 / 无恢复 / 失败 / 取消状态源码门禁
  • [x] 主题预览不写脏数据
  • [x] 排序预览不写脏数据
  • [x] 备注额度边界
  • [x] 导入导出拦截

本轮首期实现范围

本轮先做:

  1. 权益中心骨架与 QA 注入
  2. 旧付费用户自动 Pro 判定链路
  3. 设置页 Data / Theme 的 Pro UI
  4. 主题、导入导出、备注、排序四类门禁接入
  5. 最小必要 QA 脚本与 changelog 记录

2026-06-26 实施记录

  • 新增 src/Apptag/ProEntitlement.swift:统一 Pro 权益中心、StoreKit 2 当前权益 / 交易更新 / 购买 / 恢复、离线缓存、老用户自动 Pro 和 QA 状态注入。
  • 新增 src/Apptag/ProAccessViews.swift:统一 Pro 胶囊和解锁提示视图。
  • 接入 ApptagApp.swiftAppGridTheme.swiftContentView.swiftPreferencesView.swiftDataLayer.swiftL10n.swift,覆盖主题、导入导出、备注额度、排序持久化和设置页状态入口。
  • 补齐 29 个语言包 pro.* 文案。
  • 新增 Scripts/pro_localization_qa.sh:静态检查 29 语种 Pro 文案键完整、占位符完整、无生成污染和无英文兜底复制。
  • 新增 Scripts/pro_feature_gate_qa.sh:源码门禁 Pro 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、备注额度、排序预览和 Pro UI 提示。

本轮不做:

  1. ASC / IAP 上架资料提交
  2. TestFlight 真机购买证据
  3. 官网 / 支持页口径更新
  4. 后续新 Pro 功能扩展