import { createBillingPriceRule, listBillingPriceRules, updateBillingPriceRule, type BillingPriceRuleInput } from "@/lib/server/billing-store"; import type { BillingPriceRule } from "@/lib/types"; export const BILLING_USD_CNY_RATE = 7.2; export const DEFAULT_BILLING_MARKUP_MULTIPLIER = 1.2; export const BILLING_CATALOG_OBSERVED_AT = "2026-08-11"; const BAILIAN_IMAGE_URL = "https://help.aliyun.com/zh/model-studio/wan2-7-image-pro"; const BAILIAN_VIDEO_URL = "https://help.aliyun.com/zh/model-studio/wan2-7-i2v"; const EVOLINK_IMAGE_URL = "https://evolink.ai/zh/gpt-image-2"; const VOLC_ARK_PRICING_URL = "https://www.volcengine.com/docs/82379/1544106?lang=zh"; const JIMENG_PRICING_URL = "https://www.volcengine.com/activity/jimeng"; const EVOLINK_GPT_IMAGE_DIMENSIONS = [ { key: "quality", label: "生成质量", baselineValue: "medium", defaultValue: "medium", tiers: [ { value: "low", label: "快速", standardFactor: 0.11, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "官方口径约为 medium 的 0.11 倍成本。" }, { value: "medium", label: "标准", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "high", label: "精细", standardFactor: 4, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "官方口径约为 medium 的 4 倍成本。" } ] }, { key: "resolution", label: "分辨率", baselineValue: "1K", defaultValue: "1K", tiers: [ { value: "1K", label: "1K", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "2K", label: "2K", standardFactor: 4, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "按像素预算相对 1K 的估算倍率。" }, { value: "4K", label: "4K", standardFactor: 8, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "按平台支持的最大像素预算估算。" } ] }, { key: "aspectRatio", label: "画面比例", baselineValue: "1:1", defaultValue: "1:1", tiers: [ { value: "1:1", label: "1:1", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "4:3", label: "4:3", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "16:9", label: "16:9", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "9:16", label: "9:16", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "other", label: "其他比例", match: {}, standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "同一分辨率档位下按相同比例预算估算。" } ] }, { key: "referenceImageCount", label: "参考图数量", baselineValue: 0, defaultValue: 0, tiers: [ { value: 0, label: "无参考图", standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true }, { value: "1–4", label: "1–4 张", match: { min: 1, max: 4 }, standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "EvoLink 上游按 image input token 计费,当前平台按基础生成成本估算。" }, { value: "5–8", label: "5–8 张", match: { min: 5, max: 8 }, standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "EvoLink 上游按 image input token 计费,当前平台按基础生成成本估算。" }, { value: "9–16", label: "9–16 张", match: { min: 9, max: 16 }, standardFactor: 1, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "EvoLink 上游按 image input token 计费,当前平台按基础生成成本估算。" } ] } ] satisfies NonNullable; export const DEFAULT_BILLING_PRICE_RULES: BillingPriceRuleInput[] = [ { id: "base-volcengine-jimeng-seedream46", provider: "volcengine-visual", capability: "image.generate", reqKey: "jimeng_seedream46_cvtob", unit: "image", standardUnitPriceFen: 20, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "即梦4.6参考基准:公开活动页按 ¥200/1000 张折算;官方实时价格以供应商控制台为准。", source: { url: JIMENG_PRICING_URL, currency: "CNY", unitPrice: 0.2, basis: "公开资源包 ¥200/1000 张折算;非 API 实时刊例价", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-evolink-gpt-image-2", provider: "evolink", capability: "image.generate", reqKey: "gpt-image-2", unit: "image", standardUnitPriceFen: 34, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "EvoLink 按 token 计费;当前以 medium / 1K / 1:1 / 无参考图作为平台标准基准,参数档位另列。", parameterDimensions: EVOLINK_GPT_IMAGE_DIMENSIONS, source: { url: EVOLINK_IMAGE_URL, currency: "USD", unitPrice: 0.047, fxRate: BILLING_USD_CNY_RATE, basis: "页面估算:medium、1K、1:1、无参考图,约 $0.047/张;折算 ¥0.3384,账本按 ¥0.34", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-bailian-wan27-image-pro", provider: "bailian", capability: "image.generate", reqKey: "wan2.7-image-pro", unit: "image", standardUnitPriceFen: 50, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "北京地域官方基础价:¥0.50/张。", source: { url: BAILIAN_IMAGE_URL, currency: "CNY", unitPrice: 0.5, basis: "北京地域,按成功生成图片计费", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-bailian-wan27-i2v-720p", provider: "bailian", capability: "video.generate", reqKey: "wan2.7-i2v-2026-04-25", variantKey: "resolution=720p", unit: "video_second", standardUnitPriceFen: 60, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "北京地域官方基础价:720P ¥0.60/秒。", source: { url: BAILIAN_VIDEO_URL, currency: "CNY", unitPrice: 0.6, basis: "北京地域,720P,按成功视频秒数计费", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-bailian-wan27-i2v-1080p", provider: "bailian", capability: "video.generate", reqKey: "wan2.7-i2v-2026-04-25", variantKey: "resolution=1080p", unit: "video_second", standardUnitPriceFen: 100, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "北京地域官方基础价:1080P ¥1.00/秒。", source: { url: BAILIAN_VIDEO_URL, currency: "CNY", unitPrice: 1, basis: "北京地域,1080P,按成功视频秒数计费", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-seedance-2-0-480p", provider: "seedance", capability: "video.generate", reqKey: "doubao-seedance-2-0-260128", variantKey: "resolution=480p", unit: "video_second", standardUnitPriceFen: 46, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "官方 5 秒、16:9、无输入视频样例折算:¥2.31/5秒≈¥0.46/秒;实际按方舟 token 用量结算。", source: { url: VOLC_ARK_PRICING_URL, currency: "CNY", unitPrice: 0.46, basis: "doubao-seedance-2.0,480P,无输入视频、16:9、5 秒示例折算;实际 token 计费可能随输入变化", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-seedance-2-0-720p", provider: "seedance", capability: "video.generate", reqKey: "doubao-seedance-2-0-260128", variantKey: "resolution=720p", unit: "video_second", standardUnitPriceFen: 99, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "官方 5 秒、16:9、无输入视频样例折算:¥4.97/5秒≈¥0.99/秒;实际按方舟 token 用量结算。", source: { url: VOLC_ARK_PRICING_URL, currency: "CNY", unitPrice: 0.99, basis: "doubao-seedance-2.0,720P,无输入视频、16:9、5 秒示例折算;实际 token 计费可能随输入变化", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-seedance-2-0-1080p", provider: "seedance", capability: "video.generate", reqKey: "doubao-seedance-2-0-260128", variantKey: "resolution=1080p", unit: "video_second", standardUnitPriceFen: 248, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "官方 5 秒、16:9、无输入视频样例折算:¥12.39/5秒≈¥2.48/秒;实际按方舟 token 用量结算。", source: { url: VOLC_ARK_PRICING_URL, currency: "CNY", unitPrice: 2.48, basis: "doubao-seedance-2.0,1080P,无输入视频、16:9、5 秒示例折算;实际 token 计费可能随输入变化", observedAt: BILLING_CATALOG_OBSERVED_AT } }, { id: "base-seedance-2-0-4k", provider: "seedance", capability: "video.generate", reqKey: "doubao-seedance-2-0-260128", variantKey: "resolution=4k", unit: "video_second", standardUnitPriceFen: 505, markupMultiplier: DEFAULT_BILLING_MARKUP_MULTIPLIER, enabled: true, note: "官方 5 秒、16:9、无输入视频样例折算:¥25.27/5秒≈¥5.05/秒;实际按方舟 token 用量结算。", source: { url: VOLC_ARK_PRICING_URL, currency: "CNY", unitPrice: 5.05, basis: "doubao-seedance-2.0,4K,无输入视频、16:9、5 秒示例折算;实际 token 计费可能随输入变化", observedAt: BILLING_CATALOG_OBSERVED_AT } } ]; export async function ensureDefaultBillingPriceRules(): Promise { const existing = await listBillingPriceRules({ includeDisabled: true }); const created: BillingPriceRule[] = []; for (const candidate of DEFAULT_BILLING_PRICE_RULES) { const candidateKey = priceRuleMatchKey(candidate); const existingRule = existing.find((rule) => priceRuleMatchKey(rule) === candidateKey); if (existingRule) { const updated = await updateBillingPriceRule(existingRule.id, { reqKey: candidate.reqKey, variantKey: candidate.variantKey, unit: candidate.unit, standardUnitPriceFen: candidate.standardUnitPriceFen, enabled: candidate.enabled, conditions: candidate.conditions, quantitySource: candidate.quantitySource, priority: candidate.priority, note: candidate.note, source: candidate.source, parameterDimensions: candidate.parameterDimensions }); if (updated) { const index = existing.findIndex((rule) => rule.id === updated.id); if (index >= 0) existing[index] = updated; } continue; } if (existing.some((rule) => rule.provider === candidate.provider && rule.capability === candidate.capability && !rule.reqKey && !rule.variantKey)) continue; try { const rule = await createBillingPriceRule(candidate); created.push(rule); } catch (error) { if (!isConflict(error)) throw error; } } return [...existing, ...created]; } function priceRuleMatchKey(rule: Pick): string { const conditions = Object.fromEntries(Object.entries(rule.conditions || {}).sort(([left], [right]) => left.localeCompare(right))); return [rule.provider, rule.capability, rule.reqKey || "", rule.variantKey || "", JSON.stringify(conditions)].join("\u0000"); } function isConflict(error: unknown): boolean { return typeof error === "object" && error !== null && "status" in error && (error as { status?: unknown }).status === 409; }