feat(*): 模型计费与渠道目录 - 支持视频 Token 报价结算和稳定模型展示
This commit is contained in:
@@ -10,7 +10,7 @@ import { defaultModelCapabilityConfig, normalizeModelCapabilityConfig, type Mode
|
||||
import type { ModelProtocolDefinition } from "@/lib/model-protocols";
|
||||
import { createAdminChannelModel, testAdminChannelModel, updateAdminChannelModel, type ChannelModel } from "@/services/api/wallet";
|
||||
import type { ModelChannel } from "@/stores/use-config-store";
|
||||
import { defaultPriceTier, normalizeUpstreamModelKey, priceTierResolutionFromForm, priceTierVideoSecondsFromForm, skuSelectorFromForm } from "./channel-model-price-tier-form";
|
||||
import { defaultPriceTier, normalizeUpstreamModelKey, priceTierPayloadFromForm } from "./channel-model-price-tier-form";
|
||||
import { PriceTierFields } from "./channel-model-price-tier-fields";
|
||||
import { changeChannelModelCapability, editorSectionForField, initialChannelModelValues, validateChannelModelPrices, validateChannelModelProtocol, type ChannelModelFormValues as FormValues, type EditorSection } from "./channel-model-editor-form";
|
||||
|
||||
@@ -106,22 +106,12 @@ export function ChannelModelEditor({
|
||||
modelKey: values.modelKey.trim(),
|
||||
providerModelKey: upstreamModel,
|
||||
displayName: values.displayName?.trim() || values.modelKey.trim(),
|
||||
channelLabel: values.channelLabel?.trim() || "",
|
||||
description: values.description?.trim() || "",
|
||||
icon: values.icon?.trim() || "",
|
||||
capability: values.capability,
|
||||
protocol: values.protocol,
|
||||
priceTiers: values.priceTiers.map((tier) => ({
|
||||
selector: skuSelectorFromForm(values.capability, tier),
|
||||
resolution: priceTierResolutionFromForm(values.capability, tier),
|
||||
videoSeconds: priceTierVideoSecondsFromForm(values.capability, tier),
|
||||
providerModelKey: tier.providerModelKey?.trim() || upstreamModel,
|
||||
billingMode: tier.billingMode,
|
||||
unitPriceMicrocredits: Math.round((tier.unitPrice || 0) * 1_000_000),
|
||||
inputTokenPriceMicrocredits: Math.round((tier.inputTokenPrice || 0) * 1_000_000),
|
||||
outputTokenPriceMicrocredits: Math.round((tier.outputTokenPrice || 0) * 1_000_000),
|
||||
cachedTokenPriceMicrocredits: Math.round((tier.cachedTokenPrice || 0) * 1_000_000),
|
||||
priceConfigured: tier.priceConfigured !== false,
|
||||
enabled: tier.enabled !== false,
|
||||
})),
|
||||
priceTiers: values.priceTiers.map((tier) => priceTierPayloadFromForm(values.capability, tier, upstreamModel)),
|
||||
enabled: values.enabled !== false,
|
||||
capabilityConfig,
|
||||
};
|
||||
@@ -244,7 +234,7 @@ export function ChannelModelEditor({
|
||||
<section className="admin-model-editor-section">
|
||||
<SectionHeading title="模型身份" description="区分产品侧展示标识与上游实际调用 ID。" />
|
||||
<div className="admin-model-editor-section-content admin-model-identity-grid admin-model-identity-grid-with-icon">
|
||||
<Form.Item name="modelKey" label="产品模型标识" rules={[{ required: true, whitespace: true, message: "请输入产品模型标识" }]}>
|
||||
<Form.Item name="modelKey" label="产品模型标识" tooltip="不同渠道使用相同标识时,创作端归为同一个产品模型。不同版本(例如 Fast)应使用不同标识;请勿为分组随意修改已有标识。" rules={[{ required: true, whitespace: true, message: "请输入产品模型标识" }]}>
|
||||
<Input
|
||||
prefix={
|
||||
<span className="grid size-6 place-items-center">
|
||||
@@ -257,9 +247,12 @@ export function ChannelModelEditor({
|
||||
<Form.Item name="providerModelKey" label="上游模型 ID" tooltip="实际发送给供应商;留空时使用产品模型标识。价格档可配置独立上游 ID,命中时优先于此处。">
|
||||
<Input placeholder="留空则使用产品模型标识" />
|
||||
</Form.Item>
|
||||
<Form.Item name="displayName" label="后台显示名称" tooltip="仅用于后台识别,不改变调用 ID。">
|
||||
<Form.Item name="displayName" label="模型展示名" tooltip="创作端一级菜单名称。同一产品模型标识请使用相同名称和 Logo,不改变调用 ID。">
|
||||
<Input placeholder="不填则使用模型标识" />
|
||||
</Form.Item>
|
||||
<Form.Item name="channelLabel" label="渠道展示名" tooltip="创作端二级菜单名称,仅作用于此渠道中的当前模型。留空使用渠道公开名称。" rules={[{ max: 80, message: "渠道展示名不能超过 80 字" }]}>
|
||||
<Input maxLength={80} placeholder="例如:正常渠道、优惠渠道-993、特惠渠道-730" />
|
||||
</Form.Item>
|
||||
<Form.Item name="icon" label="模型 Logo">
|
||||
<ModelIconPicker />
|
||||
</Form.Item>
|
||||
@@ -272,6 +265,9 @@ export function ChannelModelEditor({
|
||||
description="命中的请求会优先使用价格档的上游 ID;修改上方上游模型 ID 时,只有与旧值相同的档位会自动跟随更新,其余保持不变。"
|
||||
/>
|
||||
) : null}
|
||||
<Form.Item name="description" label="模型描述" extra="在创作端二级渠道选项悬浮或聚焦时显示,可说明适用场景、渠道差异和注意事项。" rules={[{ max: 500, message: "模型描述不能超过 500 字" }]}>
|
||||
<Input.TextArea rows={3} maxLength={500} showCount placeholder="填写此渠道模型的使用说明" />
|
||||
</Form.Item>
|
||||
</section>
|
||||
<section className="admin-model-editor-section">
|
||||
<SectionHeading title="能力与协议" description="先选任务类型,再选择对应的调用协议;更换后请核对参数与价格。" />
|
||||
|
||||
Reference in New Issue
Block a user