## Context 本次迭代同时调整认证入口、资产初始化、套餐购买、钱包充值、订单查询和站内通知入口。后端已经通过资产信息、充值校验、订单和通知接口返回策略与业务状态,H5/C 端需要消费这些结果,而不是复制后端规则。当前仓库已经存在部分支付、实名和通知页面,因此提案以增量收敛行为为主。 接口约定以 `docs/所需接口文档/new-api.md` 为准;登录限制接口和通知接口的调用路径同时以 `docs/产品迭代7月份/七月迭代H5_C端改动说明.md` 中列出的既有路径为准。 ## Goals / Non-Goals - Goals: 让登录限制、实名策略、支付方式、强充约束、下架套餐续费、预计到期时间、临期/换货通知及订单标识展示均以后端返回为准。 - Goals: 保持现有 H5/C API 路径和支付入口,完成前端参数和展示规则收敛。 - Non-Goals: 不新增后端接口,不修改订单历史快照,不由 H5/C 调用企微审批回调,也不实现七月说明中列出的排除项。 ## Decisions ### 1. Backend is the source of truth 资产初始化统一读取 `effective_realname_policy`、`realname_required`、`real_name_status`、`allowed_payment_methods`、`estimated_final_expires_at`、`days_until_final_expiry`、`expiry_estimate_status` 和 `is_expiring`。前端不再根据 `asset_type`、卡/设备组合或本地枚举推导实名和支付规则;设备是否已实名也以服务端最终状态为准。 ### 2. Keep login failure before token persistence `POST /api/c/v1/auth/verify-asset` 成功后才允许进入后续微信登录,并保存本次返回的 `asset_token`。业务失败时直接展示后端 `msg`,当前登录尝试不得继续获取或覆盖资产 Token;Token 的签发和吊销仍由服务端负责。 ### 3. Normalize payment payloads at the API boundary 订单和充值页面只提交用户从后端允许列表中选择的 `payment_method`。仅在 `payment_method = wechat` 时提交接口要求的 `app_type`;钱包和支付宝不添加无关的微信字段。金额在 UI 层转换为元,在请求层保持整数分。 支付创建成功后,根据 `pay_config` 或 `payment_link` 进入既有支付处理;返回页面或支付完成后使用订单详情/状态查询确认结果,不能仅凭前端跳转成功判定已支付。 ### 4. Separate catalog visibility from renewal eligibility 普通套餐列表继续只展示可售套餐。老客户续费使用资产信息中的 `current_package_id` 或历史订单中的 `package_ids` 作为已知套餐 ID,复用 `POST /api/c/v1/orders/create`,不创建“下架套餐续费”专用接口。前端不得修改历史订单数据或把下架套餐重新放入普通新客购买列表。 ### 5. Display the final expiry estimate 资产页面优先展示 `estimated_final_expires_at`,并用 `expiry_estimate_status` 判断其是否可展示,用 `days_until_final_expiry` 和 `is_expiring` 控制剩余天数及临期样式。前端不根据当前套餐到期时间自行累加计算最终日期;无可用估算时显示明确的空状态。 ### 6. Reuse the existing customer notification entry 首页或通知入口读取未读数,通知页面读取列表,用户查看/点击通知后调用单条已读接口。套餐临期的 15/7/3 天触发和 0~3 天的优先级由后端通知数据表达,前端只负责按等级排序/展示和更新未读数。换货通知沿用同一套入口,不新增营销、ERP 或业务员提醒通道。 本提案依赖进行中的 `add-personal-notifications` 变更提供通知数据的可见性、分页和幂等已读语义;本提案只定义 H5/C 的消费方式。 ### 7. Preserve server snapshots in order views 订单列表和详情使用后端返回的 `purchase_role` 与 `asset_identifier`。设备显示优先使用 `virtual_no`,为空时使用 `imei`,绝不以 `sn` 代替;缺失数据保持空占位,不由前端伪造。金额继续按分转元展示。 ## Risks / Trade-offs - 后端字段缺失或为空时,页面可能无法给出策略或到期日期;通过统一空状态和错误提示避免前端猜测。 - 同一支付入口可能同时收到 `pay_config` 与 `payment_link` 为空的结果;前端必须保留既有错误处理并允许通过订单状态查询恢复。 - `add-personal-notifications` 与本提案同时推进时,需要先确认通知 API 的返回字段和分页参数一致;本提案不重复修改该服务契约。 - 下架套餐续费依赖资产或历史订单提供合法的套餐 ID;若两者均不存在,应明确提示不可续费,而不是从普通列表猜测套餐。 ## Migration Plan 1. 先更新 API 封装和数据归一化,再逐个接入登录、资产、支付、套餐、通知和订单页面。 2. 使用接口模拟数据覆盖策略冲突、支付方式变化、强充、临期等级、下架套餐和空标识场景。 3. 联调确认支付结果查询、通知已读幂等性及历史订单快照后发布。 4. 若任一后端字段未上线,回退对应 UI 展示入口,不回退到前端硬编码业务规则。 ## Open Questions - None. The proposal follows the July change description and the provided API document; backend response details not listed there remain opaque to the client and are displayed through existing generic error handling.