docs: add T-700 subscription expiry flow

This commit is contained in:
chengma
2026-07-23 15:54:06 +08:00
parent 19b7f78947
commit b05c370250
+69
View File
@@ -0,0 +1,69 @@
---
id: T-700
title: 会员过期强制提示与续费后重新检测
phase: 8
deps: [T-696, T-698]
status: TODO
created: 2026-07-23
---
## 问题 / 背景
桌面端已经具备真实订阅查询和强制门禁分支。强制模式检测到 `expired` 时会禁用除“设置”外的业务 Tab,并阻止新的 AI 生成、AI 帮写和商品套图提交,但当前只在状态栏显示到期原因,没有明确的续费入口。
用户需要在套餐到期时立即知道业务功能为何不可用,并能从默认浏览器进入线上会员中心。打开会员中心后程序仍应保持运行和锁定,让用户续费完成后主动重新检测,不要求修改设置或重启软件。
## 方案
### 1. 强制模式与弹窗触发
- 当前开发测试版本启用真实查询与客户端强制门禁。
- 仅当强制门禁开启,且本次程序运行期间首次进入 `expired` 状态时弹出中文模态框。
- 重复检查仍为 `expired` 时不重复弹窗;恢复为允许工作流的 `active`、`grace` 或 `legacy` 后,再次进入 `expired` 可以重新弹出。
- 网络抖动、接口暂时不可用、Key 无效、未订阅、撤销或账号禁用不复用该过期弹窗,继续使用各自现有中文状态和门禁语义。
- 应先应用业务 Tab 门禁和状态栏提示,再显示弹窗,避免弹窗关闭瞬间出现短暂可操作窗口。
### 2. 过期弹窗
- 标题使用「会员套餐已过期」,正文说明当前账号会员到期、业务功能已暂停,需要前往会员中心续费或更换套餐。
- 提供「前往会员中心」和「退出程序」两个明确操作:
- 「前往会员中心」调用 Qt 桌面服务,在系统默认浏览器打开 `SubscriptionStatus.manage_url`;应用保持打开并停留在受限的设置页。
- 「退出程序」关闭主窗口,沿用现有关闭事件、未保存设置确认和后台 worker 协作取消,不强杀进程。
- `manage_url` 只使用 `subscription._safe_manage_url()` 已接受的同网关主机 HTTPS 地址;地址缺失或不安全时禁用跳转按钮并显示中文说明,绝不猜测会员中心路径或打开其它协议。
- 默认按钮优先为可用的「前往会员中心」;不得把「退出程序」设为易误触的默认动作。关闭弹窗标题栏只关闭提示,业务门禁仍保持。
- 默认浏览器打开失败时显示中文状态反馈,不能暴露完整接口路径、API Key 或原始错误。
### 3. 续费后重新检测
- 设置页增加「重新检测会员状态」按钮,只负责通知主窗口重新执行现有异步订阅检查,不复制订阅请求逻辑。
- 检查运行期间按钮防重复触发;完成后恢复可用。返回 `active/grace/legacy` 时恢复业务 Tab,返回 `expired` 时继续锁定且不重复弹窗。
- 保存设置后的自动重查、启动异步检查、请求 token 隔离和陈旧结果丢弃逻辑保持不变。
## 验收要点
- 强制模式启动检测为 `expired` 时,先只保留“设置”Tab,再弹出一次「会员套餐已过期」。
- 同一次运行中连续返回 `expired` 不重复弹窗;恢复有效后再次到期会重新弹出。
- 点击「前往会员中心」使用默认浏览器打开经过安全过滤的 `manage_url`,应用保持打开且业务功能仍锁定。
- `manage_url` 缺失、非 HTTPS、带账号密码或跨域时不能打开,跳转按钮不可用并有中文说明。
- 点击「退出程序」走主窗口正常关闭流程;存在未保存设置时仍遵守现有保存/放弃/取消确认。
- 点击「重新检测会员状态」复用主窗口现有异步检查;续费后返回有效状态会恢复业务 Tab。
- 观察模式不弹过期框、不限制工作流;已有异步任务查询、下载、历史和导出不受影响。
- 自动验证:
- 订阅状态与安全会员中心地址测试
- 主窗口过期弹窗、去重、浏览器跳转、退出和重新检测定向 GUI 测试
- `py -3.10 -m unittest discover -s tests`
- `py -3.10 -m ruff check app tests main.py`
- `py -3.10 -m compileall app main.py`
- `git diff --check`
## 边界(不改什么)
- 不实现客户端会员中心、登录、支付、订单、退款或套餐购买页面。
- 不修改 cmhub 订阅接口路径、响应 schema、套餐状态或服务端最终授权。
- 不为 `manage_url` 设置硬编码备用网址,不开放 HTTP、外部域名或自定义协议。
- 不修改 AI、CDP、采集、封面上传、拖拽排序或更新蝦皮逻辑。
- 不中止已提交的异步生成任务,不限制本地历史查看和导出。
## 执行记录
- 待完成。