
Notes / 工程笔记
付费页面里,入口参数为什么不能代替真实权益状态
复盘一次付费页面的状态错位:路由参数只说明用户从哪里来,真实权益仍应由可验证的数据源决定。
一个顺手判断,埋下了状态错位
付费页面可以从多个位置打开。为了让页面知道应该先展示哪块内容,入口会携带一个简单参数。
这个参数最初只负责界面定位,后来却被顺手拿来判断用户有没有有效权益:某个入口默认按未开通处理,另一个入口默认按已开通处理。
在单一路径里,它看起来没有问题。一旦用户身份、数据刷新时机和进入页面的方式没有刚好对上,页面就会出现矛盾:用户的真实权益没有变化,界面却因为入口不同给出了不同答案。
这次排查让我先改掉了一个错误前提:路由记录的是用户怎样来到这里,不是用户拥有什么。
入口意图和业务事实不是同一种状态
路由参数适合表达一次性的导航意图,例如:
- 从哪个页面进入;
- 希望优先看到哪个区域;
- 是否需要在加载完成后执行一次界面动作。
权益状态回答的是另一组问题:
- 当前账号是否已经登录;
- 服务端是否确认权益有效;
- 本地拿到的数据是否仍在有效期内;
- 最近一次交易结果是否已经完成校验。
两者的生命周期也不同。导航意图通常在页面打开后就可以消费,权益状态却可能在登录、交易、恢复购买或重新拉取账号信息后变化。
如果把短期入口参数当成长期业务事实,页面第一次打开也许正确,之后的刷新、回退和账号切换都会留下隐患。
三种路径足以暴露问题
我用三条简单路径检查原来的判断:
- 用户直接打开页面,没有携带任何入口参数;
- 已有有效权益的用户从普通提示入口进入;
- 用户停留在页面期间,权益状态完成刷新,但路由没有变化。
原逻辑在这些路径中会得到不一致的界面状态。问题不在某个按钮,而在状态来源选错了。
因此,后续修复没有继续增加入口分支,而是先确定唯一的权威来源:页面只能根据已经校验的账号权益决定业务状态。入口参数仍然保留,但只负责界面落点。
页面需要允许“暂时不知道”
权益请求是异步的。页面刚挂载时,前端可能还没有答案。
如果只使用一个布尔值,false 很容易同时表示:
- 已确认没有有效权益;
- 请求尚未开始;
- 请求仍在进行;
- 请求失败,暂时无法确认。
这些情况在界面上不应该得到同一种结果。我把状态拆成了更明确的阶段:
UNKNOWN
-> LOADING
-> ACTIVE | INACTIVE | ERROR
UNKNOWN 和 LOADING 期间,页面保持中性加载状态;只有拿到有效响应后,才进入 ACTIVE 或 INACTIVE。请求失败则显示可重试状态,而不是猜一个看似安全的默认值。
这一步避免了页面在网络较慢时先闪出错误内容,也避免把“查询失败”误写成“用户没有权益”。
先确认事实,再消费入口意图
调整后的页面初始化顺序变成:
进入页面
-> 读取导航意图
-> 查询当前账号权益
-> 根据权威结果确定业务状态
-> 在允许的范围内应用导航意图
可以把最后一步理解成一个小的选择函数:
selectInitialView({ entitlement, intent })
它只做几件事:
- 已确认的权益结果优先;
- 导航意图只能选择当前用户可以访问的界面;
- 缺少入口参数时使用稳定的默认页面;
- 权益刷新后重新计算,而不是沿用旧入口留下的结果。
这样处理后,入口仍然可以改善体验,却没有权限修改业务事实。
交易回调也不能直接充当最终权益
类似的混用还会出现在交易完成之后。
客户端收到成功回调,能证明某一步交易流程已经完成,但它不一定等于账号权益已经刷新。网络延迟、服务端校验和跨设备同步都可能让两者短暂错开。
更稳妥的链路是:
客户端收到结果
-> 请求服务端校验或刷新账号状态
-> 获取新的权益数据
-> 更新页面
客户端回调负责触发刷新,服务端确认的数据负责决定最终界面。这样即使页面被关闭后重新打开,也不会依赖上一次组件留下的临时变量。
验证时不要只点一条入口
这类问题很容易在单一路径中“看起来已经修好”。我的回归清单至少覆盖:
- 无入口参数时直接打开;
- 从不同页面进入同一付费页;
- 请求较慢和请求失败;
- 页面停留期间重新拉取权益;
- 交易完成后刷新账号状态;
- 退出登录或切换账号后重新进入。
纯状态选择可以用测试固定输入输出,路由与页面表现需要浏览器回归,真实交易和账号同步则要在对应环境中继续确认。
这几个层次不能互相代替。构建通过只能说明代码可以打包,模拟回调也不能证明真实账号已经获得权益。
这次修复留下的判断
以后再看到 source、action 或 from 一类入口字段,我会先问它究竟是命令还是事实。
如果它只说明“这次从哪里进入”或“希望页面做什么”,就不应该参与长期业务状态判断。账号权益、权限和交易结果都需要稳定、可刷新并且能够在页面重建后重新取得的权威来源。
入口参数可以影响体验,但不能替用户身份和真实权益作决定。
Recommended