From b05c370250cf25a3c93165700239b8c3e48b58ce Mon Sep 17 00:00:00 2001 From: chengma Date: Thu, 23 Jul 2026 15:54:06 +0800 Subject: [PATCH] docs: add T-700 subscription expiry flow --- docs/tasks/T-700.md | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs/tasks/T-700.md diff --git a/docs/tasks/T-700.md b/docs/tasks/T-700.md new file mode 100644 index 0000000..e088f21 --- /dev/null +++ b/docs/tasks/T-700.md @@ -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、采集、封面上传、拖拽排序或更新蝦皮逻辑。 +- 不中止已提交的异步生成任务,不限制本地历史查看和导出。 + +## 执行记录 + +- 待完成。