fix: correct MiniMax quota calculation and improve Token Plan display

- Fix MiniMax usage_count being treated as remaining (was inverted)
- Add MiniMax weekly quota tier extraction
- Remove Zhipu TIME_LIMIT (tools usage), keep only TOKENS_LIMIT
- Improve Kimi parsing with extract_reset_time and parse_f64 helpers
- Reuse TierBadge for Token Plan inline rendering
- Clean up unused i18n keys and debug println
This commit is contained in:
Jason
2026-04-05 13:35:54 +08:00
parent bfdac2a22a
commit ca6a187745
7 changed files with 146 additions and 64 deletions
+50 -1
View File
@@ -4,6 +4,8 @@ import { useTranslation } from "react-i18next";
import { type AppId } from "@/lib/api";
import { useUsageQuery } from "@/lib/query/queries";
import { UsageData, Provider } from "@/types";
import { TierBadge } from "@/components/SubscriptionQuotaFooter";
import type { QuotaTier } from "@/types/subscription";
interface UsageFooterProps {
provider: Provider;
@@ -15,6 +17,15 @@ interface UsageFooterProps {
inline?: boolean; // 是否内联显示(在按钮左侧)
}
/** UsageData → QuotaTier 转换(Token Plan 使用) */
function toQuotaTier(data: UsageData): QuotaTier {
return {
name: data.planName || "",
utilization: data.used || 0,
resetsAt: data.extra || null,
};
}
const UsageFooter: React.FC<UsageFooterProps> = ({
provider,
providerId,
@@ -25,6 +36,8 @@ const UsageFooter: React.FC<UsageFooterProps> = ({
inline = false,
}) => {
const { t } = useTranslation();
const isTokenPlan =
provider.meta?.usage_script?.templateType === "token_plan";
// 统一的用量查询(自动查询仅对当前激活的供应商启用)
// OpenCode(累加模式):使用 isInConfig 代替 isCurrent
@@ -108,7 +121,41 @@ const UsageFooter: React.FC<UsageFooterProps> = ({
// 无数据时不显示
if (usageDataList.length === 0) return null;
// 内联模式:仅显示第一个套餐的核心数据(分上下两行)
// ── Token Plan:订阅风格内联渲染(百分比徽章 + 倒计时) ──
if (isTokenPlan && inline) {
return (
<div className="flex flex-col items-end gap-1 text-xs whitespace-nowrap flex-shrink-0">
{/* 第一行:查询时间 + 刷新 */}
<div className="flex items-center gap-2 justify-end">
<span className="text-[10px] text-muted-foreground/70 flex items-center gap-1">
<Clock size={10} />
{lastQueriedAt
? formatRelativeTime(lastQueriedAt, now, t)
: t("usage.never", { defaultValue: "从未更新" })}
</span>
<button
onClick={(e) => {
e.stopPropagation();
refetch();
}}
disabled={loading}
className="p-1 rounded hover:bg-muted transition-colors disabled:opacity-50 flex-shrink-0 text-muted-foreground"
title={t("usage.refreshUsage")}
>
<RefreshCw size={12} className={loading ? "animate-spin" : ""} />
</button>
</div>
{/* 第二行:tier 徽章(复用官方订阅的 TierBadge) */}
<div className="flex items-center gap-2">
{usageDataList.map((data, index) => (
<TierBadge key={index} tier={toQuotaTier(data)} t={t} />
))}
</div>
</div>
);
}
// ── 通用用量:内联模式(原有逻辑) ──
if (inline) {
const firstUsage = usageDataList[0];
const isExpired = firstUsage.isValid === false;
@@ -231,6 +278,8 @@ const UsageFooter: React.FC<UsageFooterProps> = ({
);
};
// ── 通用用量组件 ────────────────────────────────────────────
// 单个套餐数据展示组件
const UsagePlanItem: React.FC<{ data: UsageData }> = ({ data }) => {
const { t } = useTranslation();