From 9f36ffd85f00eb8768f7cc582f72a4706bfce473 Mon Sep 17 00:00:00 2001 From: John Ye Date: Thu, 11 Dec 2025 13:42:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8F=AA=E6=9C=89=20FREE=20+=20PAYGO=20?= =?UTF-8?q?=E6=97=B6=E6=98=BE=E7=A4=BA=20PAYGO=20=E9=A2=9D=E5=BA=A6=20(#22?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 场景:用户只有 FREE + PAYGO 套餐(没有 PLUS/PRO/MAX) 问题:Usage API 不返回 PAYGO,fallback 到 FREE 数据,但 CC 不使用 FREE 额度 解决:添加 has_only_free() 方法判断是否只有 FREE,若是则从 Subscription API 获取 PAYGO 额度显示 Closes #22 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/api/mod.rs | 22 ++++++++++++++++++++ src/core/segments/byebyecode_usage.rs | 30 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/api/mod.rs b/src/api/mod.rs index d705ce4..43249c9 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -163,6 +163,14 @@ impl UsageData { UsageData::Packy(data) => data.credit_limit, } } + + /// 判断是否只有 FREE 套餐(仅 88code 支持) + pub fn has_only_free(&self) -> bool { + match self { + UsageData::Code88(data) => data.has_only_free(), + UsageData::Packy(_) => false, // Packy 不支持 + } + } } impl Code88UsageData { @@ -206,6 +214,20 @@ impl Code88UsageData { pub fn is_exhausted(&self) -> bool { self.current_credits <= 0.0 } + + /// 判断是否只有 FREE 套餐(没有 PLUS/PRO/MAX) + /// 用于判断是否应该显示 PAYGO + pub fn has_only_free(&self) -> bool { + // 检查 subscriptionEntityList 中是否有 PLUS/PRO/MAX 套餐 + // 排除 FREE 和 PAYGO + !self.subscription_entity_list.iter().any(|s| { + if !s.is_active { + return false; + } + let name = s.subscription_name.to_uppercase(); + name != "FREE" && name != "PAYGO" + }) + } } impl PackyUsageData { diff --git a/src/core/segments/byebyecode_usage.rs b/src/core/segments/byebyecode_usage.rs index a4ffb2a..67f0f72 100644 --- a/src/core/segments/byebyecode_usage.rs +++ b/src/core/segments/byebyecode_usage.rs @@ -152,6 +152,36 @@ pub fn collect(config: &Config, input: &InputData) -> Option { metadata.insert("service".to_string(), service_name.to_string()); metadata.insert("dynamic_icon".to_string(), service_name.to_string()); + // 对于 88code:如果只有 FREE 套餐(没有 PLUS/PRO/MAX),检查是否有 PAYGO 可用 + // 场景:用户只有 FREE + PAYGO,没有 PLUS + // Usage API 不返回 PAYGO,所以 fallback 到 FREE 数据,但 CC 不使用 FREE 额度 + if service_name == "88code" && usage.has_only_free() { + let model_id = &input.model.id; + let subscriptions = fetch_subscriptions_sync(&api_key, &subscription_url, Some(model_id)); + + if let Some(subs) = subscriptions { + // 查找有余额的 PAYGO 套餐 + let paygo = subs + .iter() + .filter(|s| s.is_active) + .filter(|s| s.plan_name.to_uppercase() == "PAYGO") + .find(|s| s.current_credits > 0.0); + + if let Some(paygo_sub) = paygo { + // 显示 PAYGO 剩余额度(蓝色) + let paygo_color = "\x1b[38;5;39m"; // 蓝色 + return Some(SegmentData { + primary: format!( + "{}PAYGO{} ${:.2}", + paygo_color, RESET, paygo_sub.current_credits + ), + secondary: String::new(), + metadata, + }); + } + } + } + // 检查额度是否用完(包括超额使用) if usage.is_exhausted() { // 实时获取订阅信息,传入 model 以获取正确的套餐