fix: 适配 MoviePilot v3 的统一响应 envelope(仪表盘数值为 0 / 详情页仍 422) - #98
Open
sokouu87 wants to merge 1 commit into
Open
Conversation
v3 用 ResponseAPIRouter 把几乎所有 JSON 响应统一包装成
{"success": ..., "message": ..., "data": <原始响应>},共有 266 个端点
从 v2 的裸响应变成了 envelope。App 没有对应的解包层,导致:
- 仪表盘所有数值显示 0:dashboard/* 在 v2 返回裸 float / 裸 List / 裸对象,
v3 变成 envelope,App 直接把 Map 当数值解析,全部回落默认值。
- 媒体详情页仍然 422:版本探测请求 /api/v1/media/source 的判据是
「200 且响应是 List」,而该端点自身也被包成了 envelope,判据永不成立,
探测结果回落 v2,于是继续按 v2 形态请求详情。
改动:
- ApiClient 增加唯一一处 v3 envelope 解包拦截器。data 为 null 时保持原
envelope(操作型接口依赖 success 判断成败);data 为 Map 时合并原始字段
并按需补 success / message / data(业务同名字段优先,不被覆盖);
data 为 List 或标量时直接解包。仅在探测到 v3 时介入,v2 全程不解包。
- 版本探测请求跳过解包并放宽判据,避免自我递归与误判。
- 修正三处「v3 返回 List 而 App 读 success」的调用点,使其兼容两种形态。
联机验证(真实 v3 服务端):媒体详情、季列表、订阅状态与订阅列表、
仪表盘 CPU / 网络 / 统计、推荐项详情 path 构造共 10 项断言全部通过;
旧形态请求作为对照仍返回 422。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
接 #97。#97 修好了媒体身份契约,但用户在真实 v3 上实测仍然:详情页 422、仪表盘所有数值显示 0。
根因是另一个 #97 完全没覆盖的破坏性变更。
根因
v3 用
ResponseAPIRouter把几乎所有 JSON 响应统一包装成 envelope:{"success": true, "message": "", "data": <原来的裸响应>}对比 v2 与 v3 的
openapi.json,266 个端点从裸响应变成了 envelope。实测(携带合法 token):网页端正常,是因为前端
src/api/client.ts里有统一的 envelope 拦截器;App 没有这一层。两个现象由此而来:
dashboard/*在 v2 返回裸 float / 裸 List / 裸对象,App 把 Map 当数值解析,全部回落默认值。/api/v1/media/source返回 200 且 body 是 List」,而这个探测端点自身也被包成了 envelope(Map),判据永不成立 → 探测回落 v2 → 继续按 v2 形态请求详情。
改动
只有 5 个文件,解包逻辑集中在
ApiClient的一处拦截器里,业务层零散落:data类型nullResponse_NoneType_),现有代码正是读success判断成败MapputIfAbsent补success/message/datasuccess、读data.id三类调用方同时可用;业务同名字段优先,不被 envelope 覆盖Listdashboard/cpu的7.1skipV3EnvelopeUnwrap标记跳过解包(避免自我递归),判据放宽为「200 且能取到来源列表」。success的调用点,修正三处「v3 返回 List 而代码读success」的:message/agent/sessions、site/userdata/{site_id}、dashboard/memory(v3 由[used, usage]变为对象),均改为兼容两种形态。
验证
flutter analyze:0 error,改动文件无新增 warning。另外写了一个联机集成测试,直接打真实 v3 服务端,用 App 自己的解析链路(
normalizeMediaJson+MediaDetail.fromJson+StatisticModel+SubscribeItem+HttpPathBuilderUtil)逐项断言,10 项全部通过:
最后一条是回归对照:旧形态请求确实仍返回 422,证明 v3 分支走的是新形态。
测试文件是临时联机验证用的(依赖真实服务端与 token),没有包含在这个 PR 里。
🤖 Generated with Claude Code