diff --git a/frontend/src/app/api/consult/route.ts b/frontend/src/app/api/consult/route.ts index 8ecc358f..df81aa0b 100644 --- a/frontend/src/app/api/consult/route.ts +++ b/frontend/src/app/api/consult/route.ts @@ -29,6 +29,7 @@ import { shouldLoadGeneralDailyPanchanga, } from "@/lib/consultation-entrypoint"; import { CreditRpcError } from "@/lib/consultation-billing"; +import { resolveFeaturePricing } from "@/lib/feature-pricing"; import { reserveConsultationModel } from "@/lib/consultation-model-selection"; import { resolveSessionLanguageModel } from "@/lib/model-catalog"; import { createAdminSupabaseClient } from "@/lib/supabase/admin"; @@ -361,12 +362,13 @@ export async function POST(request: Request) { chatSession.model_id, (modelId) => sessionModel?.id === modelId ? sessionModel : null, async (model) => { + const pricing = await resolveFeaturePricing(accounting, "chat.standard", model.id); const { data, error } = await accounting.rpc("reserve_consultation_usage", { p_user_id: userId, p_request_id: requestId, p_session_id: sessionId, p_requested_model_id: model.id, - p_credit_cost: model.creditCost, + p_credit_cost: pricing.credit_cost, }); const reservation = consultationReservationSchema.safeParse(first(data ?? [])); if (error || !reservation.success) { diff --git a/frontend/src/app/api/rectification/agent/route.ts b/frontend/src/app/api/rectification/agent/route.ts index dac11234..1b17f1a6 100644 --- a/frontend/src/app/api/rectification/agent/route.ts +++ b/frontend/src/app/api/rectification/agent/route.ts @@ -24,6 +24,7 @@ import { safePublicEvent } from "@/lib/rectification-agentic/v9/stream-mapping"; import { RECTIFICATION_SKILL_NAME, RECTIFICATION_SKILL_VERSION } from "@/lib/rectification-agentic/v9/case-status"; import { blocksPromptExtraction } from "@/lib/consult-safety"; import { authorizeUsage, completeUsage, releaseUsage } from "@/lib/consultation-billing"; +import { resolveFeaturePricing } from "@/lib/feature-pricing"; import { loadRuntimeFeatureFlags } from "@/lib/feature-flags"; import { isProductEnabled } from "@/lib/product-access"; import { resolveSessionLanguageModel } from "@/lib/model-catalog"; @@ -564,12 +565,13 @@ export async function POST(request: Request) { } try { const billingRequestId = await rectificationBillingRequestId(accounting, userId, caseId); + const pricing = await resolveFeaturePricing(accounting, "rectification", selectedModel.id); const result = await authorizeUsage(accounting, { userId, requestId: billingRequestId, featureKey: "rectification", requestedModelId: selectedModel.id, - creditCost: selectedModel.creditCost, + creditCost: pricing.credit_cost, }); if (result.success) return { success: true, status: 200 }; return { @@ -719,8 +721,16 @@ export async function POST(request: Request) { } catch (error) { const code = error instanceof RectificationToolServiceError ? error.code : "run_failed"; console.error(`[rectification-v9] run failed case=${caseId} code=${code}`); - if (code === "billing_denied" || code.includes("insufficient")) { - send({ type: "error", code: "billing_denied", message: "咨询点数不足,请先兑换后再继续。" }); + if (code === "insufficient_credits" || code.includes("insufficient")) { + send({ type: "error", code: "insufficient_credits", message: "校正点数不足,请先兑换后再继续。" }); + } else if (code === "fair_use_minute") { + send({ type: "error", code, message: "请求频率达到安全上限,请稍后再试。" }); + } else if (code === "fair_use_day") { + send({ type: "error", code, message: "今日请求频率达到安全上限,请明天再试。" }); + } else if (code === "fair_use_billing_period") { + send({ type: "error", code, message: "当前账户触发安全熔断,请稍后再试或联系支持。" }); + } else if (code === "billing_denied") { + send({ type: "error", code, message: "暂时无法确认校正点数,请稍后重试。" }); } else if (code.includes("legacy_skill_identity_unverifiable")) { send({ type: "error", code: "skill_identity_unverifiable", message: "该校正绑定的是无法核验的历史 Skill,请先采用当前注册版本。" }); } else if (code.includes("skill_identity_missing")) { diff --git a/frontend/src/components/admin/feature-pricing-management.tsx b/frontend/src/components/admin/feature-pricing-management.tsx index c86bb33d..66ee6228 100644 --- a/frontend/src/components/admin/feature-pricing-management.tsx +++ b/frontend/src/components/admin/feature-pricing-management.tsx @@ -34,7 +34,6 @@ export function FeaturePricingManagement() { useEffect(() => { let active = true; - setIsLoading(true); adminRequestJson<{ data: Row[] }>("/api/admin/feature-pricing") .then((payload) => { if (active) setRows(payload.data); }) .finally(() => { if (active) setIsLoading(false); });