+ {modelCapability === "text" || modelCapability === "image" || modelCapability === "video" ? (
+
+ ) : null}
+
+ {modelCapability === "image" || modelCapability === "video" ? (
+
@@ -477,6 +583,23 @@ export function ChannelModelManager({ channel, onClose, onChanged }: { channel:
);
}
+function SectionHeading({ title, description }: { title: string; description: string }) {
+ return (
+
+ );
+}
+
+function CapabilityConfigField(_: { value?: ModelCapabilityConfig; onChange?: (value: ModelCapabilityConfig) => void }) {
+ return null;
+}
+
+function EnabledConfigField(_: { value?: boolean; onChange?: (value: boolean) => void }) {
+ return null;
+}
+
function capabilityLabel(value: ChannelModel["capability"]) {
return { text: "文本", image: "图片", video: "视频", audio: "音频", "": "待配置" }[value];
}
@@ -502,81 +625,125 @@ function PriceTierFields({
const video = capabilityConfig?.video;
const resolutionOptions = video?.resolutions || [];
const durationOptions = video?.duration.selection === "enum" ? video.duration.values || [] : [];
- const tokenEnabled = Boolean(capability && protocol && modelProtocolSupportsTokenBilling(capability, protocol));
- const isVideo = capability === "video";
- const isImage = capability === "image";
- const selectorColumnClass = isVideo || isImage ? "lg:col-span-3" : "lg:col-span-6";
- const controlsColumnClass = billingMode === "token" && !isVideo ? "lg:col-span-3" : "lg:col-span-5";
+ const tokenEnabled = Boolean(capability && protocol && modelProtocolSupportsTokenBilling(capability, protocol));
+ const isVideo = capability === "video";
+ const isImage = capability === "image";
return (
-
-
-
价格档 {ordinal}
-
} onClick={onRemove} />
+
+
+
+
价格档 {ordinal}
+
请求按以下条件命中后,使用本档模型与价格。
+
+
} onClick={onRemove}>
+ 删除
+
-
-
-
-
- {isVideo ? (
-
-
- ) : null}
- {isVideo ? (
-
- {durationOptions.length ?
- ) : null}
- {isVideo ? (
-
-
-
- ) : null}
- {isImage ? (
-
-
-
- ) : null}
- {isImage ? (
-
-
-
- ) : null}
-
-
-
-
-
-
-
-
- {billingMode === "token" ? (
- isVideo ? (
-
-
+
+
+
+ 01 匹配条件
+
+
+
+
+ 02 计费与状态
+
+
+
+
+
+ {billingMode === "token" ? (
+ isVideo ? (
+
+
+
+ ) : (
+
+
+
+
+
+
+
+
+
+
+
+ )
+ ) : (
+
+
+
+ )}
+
+
+
+ 价格已配置
+ 允许按此价格计费
+
+
+
+
+
+
+
+ 启用价格档
+ 允许参与请求匹配
+
+
+
+
+
- )
- ) : (
-
-
-
- )}
-
-
-
+
@@ -584,32 +751,73 @@ function PriceTierFields({
}
function defaultPriceTier(): PriceTierFormValues {
- return { operation: "*", quality: "*", size: "*", resolution: "*", videoSeconds: 0, imageCount: 0, providerModelKey: "", billingMode: "fixed_request", unitPrice: 0, inputTokenPrice: 0, outputTokenPrice: 0, cachedTokenPrice: 0, priceConfigured: true, enabled: true };
+ return {
+ operation: "*",
+ quality: "*",
+ size: "*",
+ resolution: "*",
+ videoSeconds: 0,
+ imageCount: 0,
+ providerModelKey: "",
+ billingMode: "fixed_request",
+ unitPrice: 0,
+ inputTokenPrice: 0,
+ outputTokenPrice: 0,
+ cachedTokenPrice: 0,
+ priceConfigured: true,
+ enabled: true,
+ };
}
function priceTierToForm(tier: ChannelModelPriceTier): PriceTierFormValues {
return {
- operation: tier.selector?.operation || "*", quality: tier.selector?.quality || "*", size: tier.selector?.size || "*",
- resolution: tier.resolution || "*", videoSeconds: tier.videoSeconds || 0, imageCount: Number(tier.selector?.imageCount || 0), providerModelKey: tier.providerModelKey || "", billingMode: tier.billingMode,
- unitPrice: tier.unitPriceMicrocredits / 1_000_000, inputTokenPrice: tier.inputTokenPriceMicrocredits / 1_000_000,
- outputTokenPrice: tier.outputTokenPriceMicrocredits / 1_000_000, cachedTokenPrice: tier.cachedTokenPriceMicrocredits / 1_000_000,
- priceConfigured: tier.priceConfigured, enabled: tier.enabled,
+ operation: tier.selector?.operation || "*",
+ quality: tier.selector?.quality || "*",
+ size: tier.selector?.size || "*",
+ resolution: tier.resolution || "*",
+ videoSeconds: tier.videoSeconds || 0,
+ imageCount: Number(tier.selector?.imageCount || 0),
+ providerModelKey: tier.providerModelKey || "",
+ billingMode: tier.billingMode,
+ unitPrice: tier.unitPriceMicrocredits / 1_000_000,
+ inputTokenPrice: tier.inputTokenPriceMicrocredits / 1_000_000,
+ outputTokenPrice: tier.outputTokenPriceMicrocredits / 1_000_000,
+ cachedTokenPrice: tier.cachedTokenPriceMicrocredits / 1_000_000,
+ priceConfigured: tier.priceConfigured,
+ enabled: tier.enabled,
};
}
function legacyPriceTierToForm(item: ChannelModel): PriceTierFormValues {
return {
- operation: "*", quality: "*", size: "*", resolution: "*", videoSeconds: 0, imageCount: 0, providerModelKey: item.providerModelKey || "", billingMode: item.billingMode,
- unitPrice: item.unitPriceMicrocredits / 1_000_000, inputTokenPrice: item.inputTokenPriceMicrocredits / 1_000_000,
- outputTokenPrice: item.outputTokenPriceMicrocredits / 1_000_000, cachedTokenPrice: item.cachedTokenPriceMicrocredits / 1_000_000,
- priceConfigured: item.priceConfigured, enabled: item.enabled,
+ operation: "*",
+ quality: "*",
+ size: "*",
+ resolution: "*",
+ videoSeconds: 0,
+ imageCount: 0,
+ providerModelKey: item.providerModelKey || "",
+ billingMode: item.billingMode,
+ unitPrice: item.unitPriceMicrocredits / 1_000_000,
+ inputTokenPrice: item.inputTokenPriceMicrocredits / 1_000_000,
+ outputTokenPrice: item.outputTokenPriceMicrocredits / 1_000_000,
+ cachedTokenPrice: item.cachedTokenPriceMicrocredits / 1_000_000,
+ priceConfigured: item.priceConfigured,
+ enabled: item.enabled,
};
}
function billingSummary(item: ChannelModel) {
- const tiers = item.priceTiers?.filter((tier) => tier.enabled && tier.priceConfigured) || [];
- if (!tiers.length) return
;
- return
{tiers.slice(0, 3).map((tier) =>
{priceTierLabel(tier)}
)}{tiers.length > 3 ?
另有 {tiers.length - 3} 个规格价格档
: null}
;
+ const tiers = item.priceTiers?.filter((tier) => tier.enabled && tier.priceConfigured) || [];
+ if (!tiers.length) return
;
+ return (
+
+ {tiers.slice(0, 3).map((tier) => (
+
{priceTierLabel(tier)}
+ ))}
+ {tiers.length > 3 ?
另有 {tiers.length - 3} 个规格价格档
: null}
+
+ );
}
function priceTierLabel(tier: ChannelModelPriceTier) {
@@ -619,8 +827,8 @@ function priceTierLabel(tier: ChannelModelPriceTier) {
selector.quality && selector.quality !== "*" ? selector.quality.toUpperCase() : "",
selector.size && selector.size !== "*" ? selector.size : "",
tier.resolution === "*" ? "" : tier.resolution.toUpperCase(),
- tier.videoSeconds ? `${tier.videoSeconds} 秒` : "",
- selector.imageCount && selector.imageCount !== "*" ? `${selector.imageCount} 张参考图` : "",
+ tier.videoSeconds ? `${tier.videoSeconds} 秒` : "",
+ selector.imageCount && selector.imageCount !== "*" ? `${selector.imageCount} 张参考图` : "",
].filter(Boolean);
const spec = specParts.length ? specParts.join(" / ") : "默认规格";
if (tier.billingMode === "token") return `${spec} · ${formatCredits(tier.outputTokenPriceMicrocredits)} / 百万 Token`;
@@ -628,30 +836,30 @@ function priceTierLabel(tier: ChannelModelPriceTier) {
}
function operationOptions(capability: EditableCapability | undefined) {
- const options = [{ label: "任意生成方式", value: "*" }];
- if (capability === "image") return [...options, { label: "文生图", value: "text_to_image" }, { label: "图生图", value: "image_to_image" }];
- if (capability === "video") return [...options, { label: "文生视频", value: "text_to_video" }, { label: "图生视频", value: "image_to_video" }, { label: "视频生视频", value: "video_to_video" }];
- if (capability === "text") return [...options, { label: "文本生成", value: "text_generation" }];
- return options;
+ const options = [{ label: "任意生成方式", value: "*" }];
+ if (capability === "image") return [...options, { label: "文生图", value: "text_to_image" }, { label: "图生图", value: "image_to_image" }];
+ if (capability === "video") return [...options, { label: "文生视频", value: "text_to_video" }, { label: "图生视频", value: "image_to_video" }, { label: "视频生视频", value: "video_to_video" }];
+ if (capability === "text") return [...options, { label: "文本生成", value: "text_generation" }];
+ return options;
}
function operationLabel(operation: string) {
- return ({ text_to_image: "文生图", image_to_image: "图生图", text_to_video: "文生视频", image_to_video: "图生视频", video_to_video: "视频生视频", text_generation: "文本生成" } as Record
)[operation] || operation;
+ return ({ text_to_image: "文生图", image_to_image: "图生图", text_to_video: "文生视频", image_to_video: "图生视频", video_to_video: "视频生视频", text_generation: "文本生成" } as Record)[operation] || operation;
}
function skuSelectorFromForm(capability: EditableCapability, tier: PriceTierFormValues) {
- const selector: Record = {};
- if (tier.operation && tier.operation !== "*") selector.operation = tier.operation;
- if (capability === "video") {
- if (tier.resolution && tier.resolution !== "*") selector.vquality = tier.resolution;
- if (Number(tier.videoSeconds) > 0) selector.videoSeconds = String(Number(tier.videoSeconds));
- if (Number(tier.imageCount) > 0) selector.imageCount = String(Number(tier.imageCount));
- }
- if (capability === "image") {
- if (tier.quality && tier.quality !== "*") selector.quality = tier.quality;
- if (tier.size && tier.size !== "*") selector.size = tier.size;
- }
- return selector;
+ const selector: Record = {};
+ if (tier.operation && tier.operation !== "*") selector.operation = tier.operation;
+ if (capability === "video") {
+ if (tier.resolution && tier.resolution !== "*") selector.vquality = tier.resolution;
+ if (Number(tier.videoSeconds) > 0) selector.videoSeconds = String(Number(tier.videoSeconds));
+ if (Number(tier.imageCount) > 0) selector.imageCount = String(Number(tier.imageCount));
+ }
+ if (capability === "image") {
+ if (tier.quality && tier.quality !== "*") selector.quality = tier.quality;
+ if (tier.size && tier.size !== "*") selector.size = tier.size;
+ }
+ return selector;
}
function formatCredits(value: number) {
diff --git a/web/src/pages/admin/components/credit-operations-panel.tsx b/web/src/pages/admin/components/credit-operations-panel.tsx
index 26b4d88d9..fa9452006 100644
--- a/web/src/pages/admin/components/credit-operations-panel.tsx
+++ b/web/src/pages/admin/components/credit-operations-panel.tsx
@@ -15,9 +15,7 @@ type AdjustmentFormValues = { userId: string; amount: number; note: string };
type ResolutionFormValues = { note: string };
type PolicyFormValues = { signupBonus: number; checkinBonus: number; defaultMultiplier: number; modelMultipliers: string };
type BillingResolutionAction = "settle" | "refund";
-type BillingResolutionTarget =
- | { kind: "single"; order: BillingOrder; action: BillingResolutionAction }
- | { kind: "batch"; orderIds: string[]; amountMicrocredits: number; action: BillingResolutionAction };
+type BillingResolutionTarget = { kind: "single"; order: BillingOrder; action: BillingResolutionAction } | { kind: "batch"; orderIds: string[]; amountMicrocredits: number; action: BillingResolutionAction };
export default function CreditOperationsPanel({ users }: { users: AdminReferenceData["users"] }) {
const { message } = App.useApp();
@@ -199,12 +197,17 @@ export default function CreditOperationsPanel({ users }: { users: AdminReference
{
title: "实际结算 / 用量",
width: 190,
- render: (_, order) => order.billingMode === "token" ? (
-
-
{order.status === "settled" ? `${formatCredits(order.actualAmountMicrocredits)} 积分` : "待 usage 结算"}
-
输入 {order.inputTokens} · 输出 {order.outputTokens} · 缓存 {order.cachedTokens}
-
- ) : {order.status === "settled" ? formatCredits(order.actualAmountMicrocredits || order.amountMicrocredits) : "--"},
+ render: (_, order) =>
+ order.billingMode === "token" ? (
+
+
{order.status === "settled" ? `${formatCredits(order.actualAmountMicrocredits)} 积分` : "待 usage 结算"}
+
+ 输入 {order.inputTokens} · 输出 {order.outputTokens} · 缓存 {order.cachedTokens}
+
+
+ ) : (
+ {order.status === "settled" ? formatCredits(order.actualAmountMicrocredits || order.amountMicrocredits) : "--"}
+ ),
},
{
title: "状态",
@@ -226,10 +229,7 @@ export default function CreditOperationsPanel({ users }: { users: AdminReference
!canResolveBillingOrder(order) ? (
处理完成
) : (
- openSingleResolution(order, "settle") }}
- actions={[{ key: "refund", label: "退回积分", danger: true, onClick: () => openSingleResolution(order, "refund") }]}
- />
+ openSingleResolution(order, "settle") }} actions={[{ key: "refund", label: "退回积分", danger: true, onClick: () => openSingleResolution(order, "refund") }]} />
),
},
];
@@ -237,41 +237,77 @@ export default function CreditOperationsPanel({ users }: { users: AdminReference
return (
-
-
+
+
-
积分策略
+
+
积分策略
+
管理注册、签到赠送与模型计费倍率。
+
-
+
-
-
+
+
-
人工调整积分
+
+
人工调整积分
+
针对单个用户增减积分,并保留处理依据。
+
-
@@ -281,43 +317,124 @@ export default function CreditOperationsPanel({ users }: { users: AdminReference
-
+
}
- value={keyword}
- placeholder="搜索用户、模型、场景或请求号"
- onChange={(event) => {
- setKeyword(event.target.value);
- setPage(1);
- }}
- />}
- toolbarActiveFilters={<>{keyword ? { setKeyword(""); setPage(1); }} /> : null}{orderStatus !== "review" ? { setOrderStatus("review"); setPage(1); }} /> : null}>}
+ toolbar={
+ }
+ value={keyword}
+ placeholder="搜索用户、模型、场景或请求号"
+ onChange={(event) => {
+ setKeyword(event.target.value);
+ setPage(1);
+ }}
+ />
+ }
+ toolbarActiveFilters={
+ <>
+ {keyword ? (
+ {
+ setKeyword("");
+ setPage(1);
+ }}
+ />
+ ) : null}
+ {orderStatus !== "review" ? (
+ {
+ setOrderStatus("review");
+ setPage(1);
+ }}
+ />
+ ) : null}
+ >
+ }
toolbarActive={Boolean(keyword || orderStatus !== "review")}
- toolbarFilters={ { setOrderStatus(value); setPage(1); }} options={[{ label: "待核对队列", value: "review" }, { label: "全部历史", value: "all" }, { label: "费用待核对", value: "uncertain" }, { label: "运行中", value: "running" }, { label: "已冻结", value: "reserved" }, { label: "已结算", value: "settled" }, { label: "已退款", value: "refunded" }]} />}
- onReset={() => { setKeyword(""); setOrderStatus("review"); setPage(1); }}
- trailing={} loading={loading} onClick={() => void reload()}>刷新}
- batchActions={ setSelectedOrderIds([])}>} onClick={() => openBatchResolution("settle")}>批量确认扣费} onClick={() => openBatchResolution("refund")}>批量退回积分}
- table={{ className: "app-data-table", rowKey: "id", size: "small", loading, pagination: false, columns, dataSource: orders, rowSelection: {
+ toolbarFilters={
+ {
+ setOrderStatus(value);
+ setPage(1);
+ }}
+ options={[
+ { label: "待核对队列", value: "review" },
+ { label: "全部历史", value: "all" },
+ { label: "费用待核对", value: "uncertain" },
+ { label: "运行中", value: "running" },
+ { label: "已冻结", value: "reserved" },
+ { label: "已结算", value: "settled" },
+ { label: "已退款", value: "refunded" },
+ ]}
+ />
+ }
+ onReset={() => {
+ setKeyword("");
+ setOrderStatus("review");
+ setPage(1);
+ }}
+ trailing={
+ } loading={loading} onClick={() => void reload()}>
+ 刷新
+
+ }
+ batchActions={
+ setSelectedOrderIds([])}>
+ } onClick={() => openBatchResolution("settle")}>
+ 批量确认扣费
+
+ } onClick={() => openBatchResolution("refund")}>
+ 批量退回积分
+
+
+ }
+ table={{
+ className: "app-data-table",
+ rowKey: "id",
+ size: "small",
+ loading,
+ pagination: false,
+ columns,
+ dataSource: orders,
+ rowSelection: {
selectedRowKeys: selectedOrderIds,
preserveSelectedRowKeys: false,
onChange: (keys) => setSelectedOrderIds(keys.map(String)),
getCheckboxProps: (order) => ({ disabled: !canResolveBillingOrder(order), name: `${order.model} ${order.scene || order.capability}` }),
- }, scroll: { x: 1390 } }}
+ },
+ scroll: { x: 1390 },
+ }}
empty={}
- footer={ { setPage(nextPageSize !== pageSize ? 1 : nextPage); setPageSize(nextPageSize); }} />}
+ footer={
+ {
+ setPage(nextPageSize !== pageSize ? 1 : nextPage);
+ setPageSize(nextPageSize);
+ }}
+ />
+ }
/>
{resolutionTarget?.kind === "batch" ? (
- 已选择 {resolutionTarget.orderIds.length} 条订单,涉及冻结积分 {formatCredits(resolutionTarget.amountMicrocredits)}。本次核对依据将写入每条订单的审计记录。
+ 已选择 {resolutionTarget.orderIds.length} 条订单,涉及冻结积分{" "}
+ {formatCredits(resolutionTarget.amountMicrocredits)}。本次核对依据将写入每条订单的审计记录。
) : null}
+ {item.description}
-
toggle(item.key, checked)} aria-label={`开放${item.title}`} />
+ toggle(item.key, checked)}
+ aria-label={`开放${item.title}`}
+ />
))}
@@ -132,6 +139,7 @@ export default function FeatureAvailabilityPanel() {
{item.title}
{item.menu}
+
{item.description}
toggle(item.key, checked)} aria-label={`开放${item.title}`} />
diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css
index 4005c109c..ca250089a 100644
--- a/web/src/styles/globals.css
+++ b/web/src/styles/globals.css
@@ -9709,10 +9709,18 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-secondary-drawer,
.admin-modal-root,
.admin-channel-modal-root {
- --admin-layer-0: #f7f7f5;
+ --admin-layer-0: #eef1f4;
--admin-layer-1: #ffffff;
- --admin-layer-2: #f5f4f2;
- --admin-sidebar: #f0efe9;
+ --admin-layer-2: #f5f7f9;
+ --admin-sidebar: #e9ebef;
+ --admin-text-primary: #1f2328;
+ --admin-text-secondary: #3f4854;
+ --admin-text-muted: #5d6878;
+ --admin-text-placeholder: #6f7b8b;
+ --admin-control-border: color-mix(in srgb, var(--foreground) 27%, transparent);
+ --admin-divider: color-mix(in srgb, var(--foreground) 16%, transparent);
+ --admin-card-border: color-mix(in srgb, var(--foreground) 15%, transparent);
+ --admin-card-shadow: 0 12px 30px color-mix(in srgb, #1f2937 8%, transparent);
--admin-status-success: oklch(0.52 0.14 155);
--admin-status-warning: oklch(0.62 0.14 78);
--admin-status-error: var(--destructive);
@@ -9727,10 +9735,18 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.dark .admin-secondary-drawer,
.dark .admin-modal-root,
.dark .admin-channel-modal-root {
- --admin-layer-0: #0d0d0d;
- --admin-layer-1: #111111;
- --admin-layer-2: #1a1a1a;
- --admin-sidebar: #0a0a0a;
+ --admin-layer-0: #0b0d10;
+ --admin-layer-1: #14171b;
+ --admin-layer-2: #1b1f25;
+ --admin-sidebar: #0f1216;
+ --admin-text-primary: #f2f4f7;
+ --admin-text-secondary: #c3c8d0;
+ --admin-text-muted: #99a2ae;
+ --admin-text-placeholder: #858f9d;
+ --admin-control-border: color-mix(in srgb, var(--foreground) 24%, transparent);
+ --admin-divider: color-mix(in srgb, var(--foreground) 16%, transparent);
+ --admin-card-border: color-mix(in srgb, var(--foreground) 13%, transparent);
+ --admin-card-shadow: 0 16px 34px rgb(0 0 0 / 0.2);
--admin-status-success: oklch(0.72 0.14 155);
--admin-status-warning: oklch(0.78 0.14 78);
--admin-status-info: oklch(0.76 0.13 250);
@@ -9739,20 +9755,21 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
}
.admin-shell .admin-nav-group-label {
- position: relative;
display: flex;
align-items: center;
gap: 8px;
- letter-spacing: 0.08em;
- text-transform: uppercase;
+ margin-bottom: 5px !important;
+ padding-inline: 10px;
+ color: color-mix(in srgb, var(--admin-text-secondary) 84%, transparent) !important;
+ font-size: 12px;
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ line-height: 18px;
}
.admin-shell .admin-nav-group-label::before,
.admin-shell .admin-nav-group-label::after {
- height: 1px;
- flex: 1 1 auto;
- background: color-mix(in srgb, var(--foreground) 12%, transparent);
- content: "";
+ display: none;
}
.admin-shell .admin-nav-group-label span {
@@ -9761,7 +9778,9 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-shell .app-workspace-nav-link {
position: relative;
- color: color-mix(in srgb, var(--foreground) 62%, transparent);
+ height: 34px !important;
+ border-radius: 8px;
+ color: var(--admin-text-secondary);
}
.admin-shell .app-workspace-brand-link {
@@ -9769,8 +9788,9 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
}
.admin-shell .app-workspace-nav-link.is-active {
- background: color-mix(in srgb, var(--foreground) 5%, transparent);
- color: var(--foreground);
+ background: color-mix(in srgb, var(--admin-status-info) 11%, var(--admin-layer-2));
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--admin-status-info) 16%, transparent);
+ color: var(--admin-text-primary);
font-weight: 600;
}
@@ -9779,13 +9799,19 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
}
.admin-shell .app-workspace-nav-link:hover:not(.is-active) {
- background: var(--surface-hover);
- color: var(--foreground);
+ background: var(--admin-layer-2);
+ color: var(--admin-text-primary);
}
.admin-shell .app-workspace-nav-link > svg {
- width: 14px;
- height: 14px;
+ width: 15px;
+ height: 15px;
+ color: var(--admin-text-muted);
+ stroke-width: 1.8;
+}
+
+.admin-shell .app-workspace-nav-link.is-active > svg {
+ color: var(--admin-status-info);
}
.admin-shell .app-workspace-nav-link:focus-visible,
@@ -9798,17 +9824,102 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-shell .app-workspace-sidebar,
.admin-shell .admin-sidebar {
background: var(--admin-sidebar);
+ border-radius: 0 !important;
+ border-right: 1px solid var(--admin-divider);
+ box-shadow: none;
}
/* 管理后台侧栏不复用通用 Tailwind 宽度:通用 sidebar 规则在后面会覆盖 w-*,导致视觉收缩但布局仍占展开宽度。 */
.admin-shell .admin-sidebar {
- width: 212px;
- flex-basis: 212px;
+ width: 224px;
+ flex-basis: 224px;
}
.admin-shell .admin-sidebar.is-collapsed {
- width: var(--workspace-sidebar-collapsed-width, 56px);
- flex-basis: var(--workspace-sidebar-collapsed-width, 56px);
+ width: 64px;
+ flex-basis: 64px;
+}
+
+.admin-shell .admin-sidebar-header {
+ height: 68px;
+ border-bottom: 1px solid var(--admin-divider);
+ background: linear-gradient(160deg, color-mix(in srgb, var(--foreground) 3%, var(--admin-sidebar)), var(--admin-sidebar));
+}
+
+.admin-shell .admin-sidebar-brand-mark {
+ width: 32px;
+ height: 32px;
+ border-radius: 9px;
+ box-shadow: 0 6px 16px color-mix(in srgb, var(--foreground) 12%, transparent);
+}
+
+.admin-shell .admin-sidebar-brand-copy > span:first-child {
+ color: var(--admin-text-primary);
+ font-size: 14px;
+ line-height: 18px;
+}
+
+.admin-shell .admin-sidebar-brand-copy > span:last-child {
+ margin-top: 1px;
+ color: var(--admin-text-muted);
+ font-size: 10px;
+ letter-spacing: 0.06em;
+ line-height: 15px;
+}
+
+.admin-shell .admin-sidebar-toggle {
+ width: 30px;
+ height: 30px;
+ border: 1px solid transparent;
+ border-radius: 8px;
+ color: var(--admin-text-muted);
+}
+
+.admin-shell .admin-sidebar-toggle:hover {
+ border-color: var(--admin-card-border);
+ background: var(--admin-layer-2);
+ color: var(--admin-text-primary);
+}
+
+.admin-shell .admin-sidebar-nav {
+ padding: 6px 10px;
+}
+
+.admin-shell .admin-nav-group {
+ margin-bottom: 0;
+}
+
+.admin-shell .admin-nav-group + .admin-nav-group {
+ margin-top: 12px;
+}
+
+.admin-shell .admin-nav-collapsed-separator {
+ width: 28px;
+ height: 1px;
+ margin: 8px auto;
+ background: var(--admin-divider);
+}
+
+.admin-shell .admin-sidebar-footer {
+ border-top: 1px solid var(--admin-divider);
+ background: linear-gradient(0deg, color-mix(in srgb, var(--foreground) 2%, var(--admin-sidebar)), var(--admin-sidebar));
+ padding: 9px 10px 10px;
+}
+
+.admin-shell .admin-sidebar-footer :is(button, a) {
+ min-height: 34px;
+ border-radius: 8px;
+ color: var(--admin-text-muted);
+}
+
+.admin-shell .admin-sidebar-footer :is(button, a):hover {
+ background: var(--admin-layer-2);
+ color: var(--admin-text-primary);
+}
+
+.admin-shell .admin-sidebar.is-collapsed .admin-sidebar-nav,
+.admin-shell .admin-sidebar.is-collapsed .admin-sidebar-footer {
+ padding-inline: 8px;
}
.admin-shell .app-user-content,
@@ -9857,7 +9968,23 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
}
.admin-page-header {
- min-height: 44px;
+ min-height: 58px;
+ border-bottom: 1px solid var(--admin-divider);
+ padding-bottom: 14px;
+}
+
+.admin-page-title {
+ color: var(--admin-text-primary);
+ font-size: 20px;
+ letter-spacing: -0.02em;
+ line-height: 1.35;
+}
+
+.admin-page-description {
+ margin-top: 3px;
+ color: var(--admin-text-muted);
+ font-size: 12px;
+ line-height: 1.55;
}
.admin-data-table {
@@ -9870,14 +9997,15 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-list-toolbar {
flex: 0 0 auto;
- padding-top: 8px;
- padding-bottom: 8px;
+ padding-top: 10px;
+ padding-bottom: 10px;
}
.admin-list-toolbar-main .app-list-search {
min-width: 180px;
- width: auto !important;
- flex: 1 1 280px;
+ width: min(360px, 100%) !important;
+ max-width: 360px;
+ flex: 0 1 360px;
}
.admin-filter-toggle {
@@ -9940,11 +10068,23 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
background: var(--foreground);
}
+.admin-table-frame {
+ display: flex;
+ min-height: 0;
+ flex: 1 1 auto;
+ flex-direction: column;
+ overflow: hidden;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 10px;
+ background: var(--admin-layer-1);
+ box-shadow: var(--admin-card-shadow);
+}
+
.admin-table-surface {
min-height: 0;
flex: 1 1 auto;
overflow: hidden;
- border-radius: 8px;
+ border-radius: 0;
}
.admin-table-scroll {
@@ -9957,7 +10097,7 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-table-pagination {
flex: 0 0 auto;
min-height: 44px;
- border-top: 1px solid color-mix(in srgb, var(--foreground) 9%, transparent);
+ border-top: 1px solid var(--admin-divider);
background: color-mix(in srgb, var(--admin-layer-1) 92%, transparent);
backdrop-filter: blur(10px);
}
@@ -9975,24 +10115,32 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
position: sticky;
top: 0;
z-index: 3;
- height: 38px;
- padding: 8px 16px !important;
- background: var(--admin-layer-1) !important;
+ height: 42px;
+ padding: 9px 16px !important;
+ background: var(--admin-layer-2) !important;
color: color-mix(in srgb, var(--foreground) 52%, transparent) !important;
font-size: 11px;
- font-weight: 500;
- letter-spacing: 0.06em;
- text-transform: uppercase;
+ font-weight: 600;
+ letter-spacing: 0.035em;
}
.admin-shell .admin-table-surface .ant-table-tbody > tr > td,
.admin-modal-root .admin-table-surface .ant-table-tbody > tr > td {
- height: 48px;
- padding: 10px 16px !important;
+ height: 52px;
+ padding: 11px 16px !important;
font-size: 13px;
font-variant-numeric: tabular-nums;
}
+.admin-shell .admin-table-surface .ant-table-tbody > tr.ant-table-measure-row > td,
+.admin-modal-root .admin-table-surface .ant-table-tbody > tr.ant-table-measure-row > td {
+ height: 0 !important;
+ padding: 0 !important;
+ border: 0 !important;
+ font-size: 0;
+ line-height: 0;
+}
+
.admin-shell .admin-table-surface .ant-table-tbody > tr:hover > td,
.admin-modal-root .admin-table-surface .ant-table-tbody > tr:hover > td {
background: color-mix(in srgb, var(--foreground) 3%, var(--admin-layer-1)) !important;
@@ -10110,47 +10258,70 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
display: inline-flex;
align-items: center;
justify-content: flex-end;
- gap: 8px;
+ gap: 6px;
white-space: nowrap;
}
.admin-row-action.ant-btn {
- height: 24px;
- min-height: 24px;
- padding: 0;
- border: 0;
- border-radius: 0;
- background: transparent !important;
+ height: 30px;
+ min-height: 30px;
+ padding: 0 9px;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 6px;
+ background: var(--admin-layer-1) !important;
box-shadow: none !important;
- color: color-mix(in srgb, var(--foreground) 58%, transparent);
+ color: var(--admin-text-secondary);
font-size: 12px;
- font-weight: 500;
+ font-weight: 550;
line-height: 1;
- transition: none !important;
+ transition: border-color 140ms ease, background-color 140ms ease, color 140ms ease !important;
+}
+
+.admin-row-action.ant-btn .ant-btn-icon {
+ display: grid;
+ margin-inline-end: 0;
+}
+
+.admin-row-action.ant-btn .ant-btn-icon > svg {
+ width: 13px;
+ height: 13px;
}
.admin-row-action.ant-btn:hover:not(:disabled),
.admin-row-action.ant-btn:active:not(:disabled),
.admin-row-action.ant-btn:focus:not(:disabled),
.admin-row-action.ant-btn.ant-dropdown-open {
- background: transparent !important;
- color: var(--foreground);
+ border-color: var(--admin-control-border);
+ background: var(--admin-layer-2) !important;
+ color: var(--admin-text-primary);
}
.admin-row-action-primary.ant-btn {
- color: color-mix(in srgb, var(--foreground) 88%, transparent);
- font-weight: 600;
+ border-color: color-mix(in srgb, var(--admin-status-info) 30%, var(--admin-card-border));
+ background: color-mix(in srgb, var(--admin-status-info) 8%, var(--admin-layer-1)) !important;
+ color: color-mix(in srgb, var(--admin-status-info) 68%, var(--admin-text-primary));
+ font-weight: 650;
+}
+
+.admin-row-action-primary.ant-btn:hover:not(:disabled),
+.admin-row-action-primary.ant-btn:focus:not(:disabled) {
+ border-color: color-mix(in srgb, var(--admin-status-info) 52%, var(--admin-card-border));
+ background: color-mix(in srgb, var(--admin-status-info) 13%, var(--admin-layer-1)) !important;
+ color: var(--admin-text-primary);
}
.admin-row-action-danger.ant-btn {
+ border-color: color-mix(in srgb, var(--destructive) 24%, var(--admin-card-border));
+ background: color-mix(in srgb, var(--destructive) 6%, var(--admin-layer-1)) !important;
color: var(--destructive);
}
.admin-row-action-more.ant-btn {
display: inline-flex;
align-items: center;
- gap: 2px;
- color: color-mix(in srgb, var(--foreground) 54%, transparent);
+ gap: 3px;
+ min-width: 54px;
+ color: var(--admin-text-secondary);
}
.admin-row-action-chevron {
@@ -10231,8 +10402,9 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-stat-tile {
min-width: 0;
- padding: var(--space-3);
- background: linear-gradient(135deg, color-mix(in srgb, var(--foreground) 7%, var(--admin-layer-1)), var(--admin-layer-1) 72%);
+ min-height: 112px;
+ padding: 18px;
+ background: linear-gradient(145deg, color-mix(in srgb, var(--foreground) 6%, var(--admin-layer-1)), var(--admin-layer-1) 70%);
}
.admin-stat-tile + .admin-stat-tile {
@@ -10241,35 +10413,109 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-stat-tile-label {
color: color-mix(in srgb, var(--foreground) 55%, transparent);
- font-size: 11px;
+ font-size: 12px;
+ font-weight: 500;
}
.admin-stat-tile-value {
- margin-top: var(--space-1);
+ margin-top: 7px;
color: var(--foreground);
- font-size: 16px;
+ font-size: 22px;
font-variant-numeric: tabular-nums;
font-weight: 650;
line-height: 1.25;
}
.admin-stat-tile-detail {
- margin-top: var(--space-1);
+ margin-top: 8px;
color: color-mix(in srgb, var(--foreground) 45%, transparent);
font-size: 11px;
}
.admin-settings-section {
- margin-top: 12px;
+ width: 100%;
overflow: hidden;
- border-radius: 10px;
- background: color-mix(in srgb, var(--foreground) 3%, var(--admin-layer-1));
+ border: 1px solid var(--admin-card-border);
+ border-radius: 12px;
+ background: var(--admin-layer-1);
+ box-shadow: var(--admin-card-shadow);
}
.admin-settings-section > :last-child {
min-width: 0;
}
+.admin-settings-section-summary {
+ background: linear-gradient(145deg, color-mix(in srgb, var(--foreground) 4%, var(--admin-layer-1)), var(--admin-layer-1) 72%);
+}
+
+.admin-settings-section-content {
+ background: color-mix(in srgb, var(--admin-layer-1) 96%, var(--admin-layer-2));
+}
+
+.admin-settings-section-footer {
+ border-top: 1px solid var(--admin-divider);
+ background: color-mix(in srgb, var(--admin-layer-2) 56%, var(--admin-layer-1));
+}
+
+.admin-operation-card {
+ overflow: hidden;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 12px;
+ background: var(--admin-layer-1);
+ padding: 18px 20px 20px;
+ box-shadow: var(--admin-card-shadow);
+}
+
+.admin-operation-card-heading {
+ padding-bottom: 13px;
+ border-bottom: 1px solid var(--admin-divider);
+}
+
+.admin-operation-card-heading p {
+ margin-top: 3px;
+ color: var(--admin-text-muted);
+ font-size: 11px;
+ line-height: 1.55;
+}
+
+.admin-analytics-trend-section {
+ overflow: hidden;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 12px;
+ background: var(--admin-layer-1);
+ padding: 18px 20px;
+ box-shadow: var(--admin-card-shadow);
+}
+
+.admin-analytics-empty-chart {
+ display: flex;
+ min-height: 220px;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ color: var(--admin-text-secondary);
+ text-align: center;
+}
+
+.admin-analytics-empty-chart > span {
+ display: grid;
+ width: 42px;
+ height: 42px;
+ margin-bottom: 12px;
+ place-items: center;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 10px;
+ background: var(--admin-layer-2);
+ color: var(--admin-text-muted);
+}
+
+.admin-analytics-empty-chart p {
+ margin-top: 5px;
+ color: var(--admin-text-muted);
+ font-size: 12px;
+}
+
.admin-drawer .ant-drawer-body,
.admin-secondary-drawer .ant-drawer-body {
background: var(--admin-layer-0);
@@ -10307,11 +10553,681 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
overflow-y: auto;
}
+/* 系统渠道模型编辑器:恢复已确认的信息层级、协议参数与价格档布局。 */
+.admin-model-editor-drawer .ant-drawer-header {
+ min-height: 52px;
+ padding-inline: 24px;
+}
+
+.admin-model-editor-drawer .ant-drawer-body {
+ padding: 20px 24px 24px;
+}
+
+.admin-model-editor-form {
+ width: 100%;
+ max-width: 1120px;
+ margin-inline: auto;
+}
+
+.admin-model-editor-section {
+ display: grid;
+ grid-template-columns: minmax(140px, 176px) minmax(0, 1fr);
+ gap: 24px;
+ padding: 20px 22px;
+}
+
+.admin-model-editor-section-heading,
+.admin-model-editor-section-content {
+ min-width: 0;
+}
+
+.admin-model-editor-section-heading h2 {
+ color: var(--foreground);
+ font-size: 15px;
+ font-weight: 650;
+ line-height: 1.4;
+}
+
+.admin-model-editor-section-heading p {
+ margin-top: 6px;
+ color: color-mix(in srgb, var(--foreground) 46%, transparent);
+ font-size: 11px;
+ line-height: 1.65;
+}
+
+.admin-model-editor-section-content > .ant-form-item:last-child,
+.admin-model-editor-section-content > .ant-form-item-row:last-child {
+ margin-bottom: 0;
+}
+
+.admin-model-editor-parameters .admin-model-editor-section-content {
+ overflow: hidden;
+}
+
+.admin-model-identity-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 16px;
+}
+
+.admin-model-editor-drawer .admin-capability-editor {
+ border-radius: 0;
+ background: transparent;
+ padding: 0;
+}
+
+.admin-model-editor-drawer .admin-capability-editor-heading {
+ padding: 0 2px 2px;
+}
+
+.admin-model-editor-drawer .admin-capability-group {
+ border: 1px solid color-mix(in srgb, var(--foreground) 10%, transparent);
+ background: color-mix(in srgb, var(--foreground) 2.5%, var(--admin-layer-1));
+ padding: 14px;
+}
+
+.admin-model-editor-drawer .admin-capability-group > summary {
+ position: relative;
+ padding-right: 20px;
+}
+
+.admin-model-editor-drawer .admin-capability-group > summary::after {
+ position: absolute;
+ top: 5px;
+ right: 2px;
+ width: 7px;
+ height: 7px;
+ border-right: 1px solid currentColor;
+ border-bottom: 1px solid currentColor;
+ content: "";
+ transform: rotate(45deg);
+ transition: transform 140ms ease;
+}
+
+.admin-model-editor-drawer .admin-capability-group:not([open]) > summary::after {
+ transform: rotate(-45deg);
+}
+
+.admin-model-editor-drawer .admin-capability-group-description {
+ color: var(--admin-text-muted) !important;
+ line-height: 1.5;
+}
+
+.admin-model-editor-drawer .admin-capability-block + .admin-capability-block {
+ margin-top: 14px;
+ padding-top: 14px;
+ border-top: 1px solid var(--admin-divider);
+}
+
+.admin-model-editor-drawer .admin-capability-block-title {
+ margin-bottom: 9px;
+ color: var(--admin-text-secondary);
+ font-size: 10px;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+}
+
+.admin-model-editor-drawer .admin-capability-number-field,
+.admin-model-editor-drawer .admin-capability-boolean-field,
+.admin-model-editor-drawer .admin-capability-parameter-field {
+ min-width: 0;
+}
+
+.admin-model-editor-drawer .admin-capability-number-field .ant-input-number {
+ width: 100% !important;
+ min-width: 0;
+}
+
+.admin-capability-reference-grid {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.admin-capability-reference-grid.is-three {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.admin-capability-reference-grid.is-two {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.admin-capability-reference-card,
+.admin-capability-protocol-card {
+ min-width: 0;
+ border: 1px solid color-mix(in srgb, var(--foreground) 10%, transparent);
+ border-radius: 8px;
+ background: color-mix(in srgb, var(--foreground) 2.5%, var(--admin-layer-1));
+ padding: 14px;
+}
+
+.admin-capability-reference-card-heading {
+ min-height: 38px;
+ margin-bottom: 8px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--admin-divider);
+}
+
+.admin-capability-reference-card-heading h3,
+.admin-capability-protocol-card-heading h3 {
+ color: var(--admin-text-primary);
+ font-size: 12px;
+ font-weight: 650;
+ line-height: 1.4;
+}
+
+.admin-capability-reference-card-heading p,
+.admin-capability-protocol-card-heading p {
+ margin-top: 3px;
+ color: var(--admin-text-muted);
+ font-size: 10px;
+ line-height: 1.5;
+}
+
+.admin-capability-reference-fields {
+ display: grid;
+ gap: 4px;
+}
+
+.admin-capability-reference-fields .admin-capability-number-field {
+ display: grid;
+ min-height: 62px;
+ grid-template-columns: minmax(0, 1fr);
+ align-items: end;
+ gap: 5px;
+ border-bottom: 1px solid color-mix(in srgb, var(--foreground) 7%, transparent);
+ padding-block: 4px;
+}
+
+.admin-capability-reference-fields .admin-capability-number-field:last-child {
+ border-bottom: 0;
+}
+
+.admin-capability-reference-fields .admin-capability-field-label {
+ margin-bottom: 0;
+ line-height: 1.4;
+}
+
+.admin-capability-reference-fields .admin-capability-boolean-field {
+ min-height: 48px;
+ margin-top: 4px;
+ padding-block: 6px;
+}
+
+.admin-capability-reference-fields .admin-capability-boolean-field > div:first-child > div:last-child {
+ display: none;
+}
+
+.admin-capability-protocol-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.admin-capability-protocol-card-heading {
+ display: flex;
+ min-height: 46px;
+ align-items: flex-start;
+ gap: 9px;
+ margin-bottom: 12px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid var(--admin-divider);
+}
+
+.admin-capability-protocol-card-heading > span {
+ display: grid;
+ width: 24px;
+ height: 24px;
+ flex: 0 0 auto;
+ place-items: center;
+ border-radius: 6px;
+ background: var(--admin-layer-3);
+ color: var(--admin-text-muted);
+ font-size: 9px;
+ font-weight: 700;
+}
+
+.admin-capability-protocol-card-heading p {
+ margin-top: 2px;
+ line-height: 1.45;
+}
+
+.admin-capability-protocol-fields,
+.admin-capability-spec-grid {
+ display: grid;
+ gap: 10px;
+}
+
+.admin-capability-duration-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px;
+}
+
+.admin-price-tier-card {
+ overflow: hidden;
+ border: 1px solid color-mix(in srgb, var(--foreground) 12%, transparent);
+ border-radius: 8px;
+ background: color-mix(in srgb, var(--foreground) 2%, var(--admin-layer-1));
+}
+
+.admin-price-tier-card-header {
+ display: flex;
+ min-width: 0;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 16px;
+ border-bottom: 1px solid color-mix(in srgb, var(--foreground) 9%, transparent);
+ padding: 12px 14px;
+}
+
+.admin-price-tier-card-body {
+ display: grid;
+ grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
+}
+
+.admin-price-tier-block {
+ padding: 14px;
+}
+
+.admin-price-tier-block + .admin-price-tier-block {
+ border-left: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
+}
+
+.admin-price-tier-block-title {
+ margin-bottom: 10px;
+ color: color-mix(in srgb, var(--foreground) 48%, transparent);
+ font-size: 10px;
+ font-weight: 650;
+ letter-spacing: 0.08em;
+}
+
+.admin-price-tier-block-title > span {
+ margin-right: 5px;
+ color: var(--admin-text-muted);
+}
+
+.admin-price-tier-match-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.admin-price-tier-upstream {
+ grid-column: 1 / -1;
+}
+
+.admin-price-tier-billing-grid {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr);
+ align-items: end;
+ gap: 12px;
+}
+
+.admin-price-tier-billing-mode,
+.admin-price-tier-unit-price,
+.admin-price-tier-token-grid,
+.admin-price-tier-controls {
+ grid-column: 1 / -1;
+}
+
+.admin-price-tier-token-grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 10px;
+}
+
+.admin-price-tier-billing-mode .ant-segmented {
+ border: 1px solid var(--admin-card-border);
+ background: var(--admin-layer-2);
+ padding: 3px;
+}
+
+.admin-price-tier-billing-mode .ant-segmented-item {
+ min-height: 32px;
+ border-radius: 5px;
+}
+
+.admin-price-tier-billing-mode .ant-segmented-item-label {
+ min-height: 32px;
+ padding-inline: 12px;
+ line-height: 32px;
+}
+
+.admin-price-tier-billing-mode .ant-segmented-item-selected {
+ background: var(--admin-layer-1);
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--foreground) 14%, transparent);
+}
+
+.admin-price-tier-unit-price .ant-input-number {
+ width: 100% !important;
+}
+
+.admin-price-tier-controls {
+ display: grid !important;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px !important;
+}
+
+.admin-price-tier-toggle {
+ display: flex;
+ min-width: 0;
+ min-height: 58px;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 7px;
+ background: var(--admin-layer-2);
+ padding: 8px 10px;
+}
+
+.admin-price-tier-toggle > div {
+ display: grid;
+ min-width: 0;
+ gap: 2px;
+}
+
+.admin-price-tier-toggle strong {
+ color: var(--admin-text-primary);
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 1.35;
+}
+
+.admin-price-tier-toggle span {
+ overflow: hidden;
+ color: var(--admin-text-muted);
+ font-size: 9px;
+ line-height: 1.4;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.admin-model-editor-add-tier.ant-btn {
+ min-height: 38px;
+}
+
+.admin-drawer.admin-model-editor-drawer .ant-drawer-footer {
+ border-top: 0;
+ background: var(--admin-layer-0);
+ padding: 8px 24px 12px;
+ backdrop-filter: none;
+}
+
+.admin-model-editor-footer-actions {
+ width: 100%;
+ max-width: 1120px;
+ min-height: 52px;
+ margin-inline: auto;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 10px;
+ background: var(--admin-layer-1);
+ padding: 8px 10px;
+ box-shadow: 0 8px 24px color-mix(in srgb, var(--foreground) 8%, transparent);
+}
+
+.admin-model-editor-footer-primary {
+ min-width: 0;
+}
+
+.admin-model-editor-footer-status {
+ display: flex;
+ min-height: 34px;
+ align-items: center;
+ gap: 8px;
+ margin-right: 4px;
+ border: 1px solid var(--admin-card-border);
+ border-radius: 6px;
+ background: var(--admin-layer-2);
+ padding: 4px 8px;
+}
+
+.admin-model-editor-footer-status > span {
+ width: 6px;
+ height: 6px;
+ flex: 0 0 auto;
+ border-radius: 50%;
+ background: var(--admin-text-muted);
+}
+
+.admin-model-editor-footer-status > span.is-enabled {
+ background: #10a36a;
+}
+
+.admin-model-editor-footer-status > div {
+ display: grid;
+ min-width: 0;
+ margin-right: 4px;
+}
+
+.admin-model-editor-footer-status strong {
+ color: var(--admin-text-primary);
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 1.25;
+}
+
+.admin-model-editor-footer-status small {
+ color: var(--admin-text-muted);
+ font-size: 9px;
+ line-height: 1.2;
+}
+
+:root:not(.dark) .admin-model-editor-drawer .ant-drawer-header,
+:root:not(.dark) .admin-model-editor-drawer .ant-drawer-footer {
+ border-color: #d4dae2;
+ background: #ffffff;
+}
+
+:root:not(.dark) .admin-model-editor-drawer .ant-drawer-body,
+:root:not(.dark) .admin-drawer.admin-model-editor-drawer .ant-drawer-footer {
+ background: #edf1f5;
+}
+
+:root:not(.dark) .admin-model-editor-section {
+ border: 1px solid #d4dae2;
+ background: #ffffff;
+ box-shadow: 0 1px 3px rgb(15 23 42 / 0.055);
+}
+
+:root:not(.dark) .admin-model-editor-drawer :is(.admin-capability-group, .admin-capability-boolean-field, .admin-capability-parameter-field),
+:root:not(.dark) .admin-model-editor-drawer .admin-capability-reference-card,
+:root:not(.dark) .admin-model-editor-drawer .admin-capability-protocol-card,
+:root:not(.dark) .admin-price-tier-toggle,
+:root:not(.dark) .admin-price-tier-billing-mode .ant-segmented {
+ border-color: #cbd3dd;
+ background: #ffffff;
+}
+
+:root:not(.dark) .admin-price-tier-card {
+ border-color: #cbd3dd;
+ background: #f5f7fa;
+}
+
+:root:not(.dark) .admin-model-editor-drawer .admin-capability-reference-card,
+:root:not(.dark) .admin-model-editor-drawer .admin-capability-protocol-card {
+ border-color: #cbd3dd;
+ background: #f5f7fa;
+}
+
+:root:not(.dark) .admin-model-editor-drawer [role="radio"] {
+ border-color: #c3ccd7;
+ background: #ffffff;
+}
+
+:root:not(.dark) .admin-model-editor-drawer [role="radio"]:hover {
+ border-color: #929eac;
+ background: #f8fafc;
+}
+
+:root:not(.dark) .admin-model-editor-drawer [role="radio"][aria-checked="true"] {
+ border-color: #657180;
+ background: #eef3f7;
+ box-shadow: inset 0 0 0 1px rgb(31 41 55 / 0.08);
+}
+
+:root:not(.dark) .admin-model-editor-drawer
+ :is(.ant-input, .ant-input-affix-wrapper, .ant-input-number, .ant-select-selector, .ant-segmented) {
+ background: #ffffff;
+}
+
+:root:not(.dark) .admin-model-editor-section-heading h2 {
+ color: #20262e;
+}
+
+:root:not(.dark) .admin-model-editor-drawer .ant-form-item-label > label {
+ color: #364152;
+ font-weight: 550;
+}
+
+:root:not(.dark) .admin-model-editor-footer-actions {
+ border-color: #d4dae2;
+ background: #ffffff;
+ box-shadow: 0 6px 20px rgb(15 23 42 / 0.08);
+}
+
+:root:not(.dark) .admin-price-tier-billing-mode .ant-segmented-item-selected {
+ background: #e8edf2;
+ box-shadow: inset 0 0 0 1px rgb(31 41 55 / 0.12);
+}
+
+@media (max-width: 899px) {
+ .admin-model-editor-section,
+ .admin-capability-protocol-grid,
+ .admin-price-tier-card-body,
+ .admin-model-identity-grid {
+ grid-template-columns: minmax(0, 1fr);
+ }
+
+ .admin-model-editor-section {
+ gap: 16px;
+ }
+
+ .admin-model-editor-section-heading {
+ padding-bottom: 12px;
+ border-bottom: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
+ }
+
+ .admin-price-tier-block + .admin-price-tier-block {
+ border-top: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
+ border-left: 0;
+ }
+}
+
+/* 管理后台可读性基线:收敛历史页面中过低的文字透明度,并统一表单层级。 */
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root) {
+ color: var(--admin-text-primary);
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(.text-foreground\/30, .text-foreground\/35, .text-foreground\/38, .text-foreground\/40, .text-foreground\/42, .text-foreground\/45) {
+ color: var(--admin-text-muted) !important;
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(.text-foreground\/48, .text-foreground\/50, .text-foreground\/52, .text-foreground\/55) {
+ color: var(--admin-text-secondary) !important;
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(.ant-form-item-label > label, .ant-checkbox-wrapper, .ant-radio-wrapper, .ant-segmented-item-label) {
+ color: var(--admin-text-secondary);
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(.ant-input, .ant-input-affix-wrapper, .ant-input-number, .ant-picker, .ant-select-selector) {
+ border-color: var(--admin-control-border) !important;
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(.ant-input, .ant-input-affix-wrapper input, .ant-input-number-input, .ant-picker-input > input, .ant-select-selection-item) {
+ color: var(--admin-text-primary) !important;
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(input, textarea)::placeholder {
+ color: var(--admin-text-placeholder) !important;
+ opacity: 1;
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ .ant-select-selection-placeholder,
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ .ant-input-number-input::placeholder {
+ color: var(--admin-text-placeholder) !important;
+ opacity: 1;
+}
+
+:is(.admin-shell, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root)
+ :is(.ant-input-disabled, .ant-input-number-disabled, .ant-picker-disabled, .ant-select-disabled .ant-select-selector) {
+ color: var(--admin-text-muted) !important;
+ opacity: 0.82;
+}
+
+.admin-shell .app-workspace-nav-link,
+.admin-shell .admin-sidebar :is(button, a) {
+ color: var(--admin-text-secondary);
+}
+
+.admin-shell .admin-nav-group-label {
+ color: color-mix(in srgb, var(--admin-text-secondary) 84%, transparent) !important;
+}
+
+.admin-shell .admin-table-surface .ant-table-thead > tr > th,
+.admin-modal-root .admin-table-surface .ant-table-thead > tr > th {
+ color: var(--admin-text-muted) !important;
+}
+
+.admin-shell .admin-table-surface .ant-table-tbody > tr > td,
+.admin-modal-root .admin-table-surface .ant-table-tbody > tr > td,
+.admin-shell .admin-pagination-total {
+ color: var(--admin-text-primary);
+}
+
+.admin-shell .admin-table-surface .ant-table-tbody > tr > td,
+.admin-modal-root .admin-table-surface .ant-table-tbody > tr > td,
+.admin-table-pagination,
+.admin-drawer .ant-drawer-footer,
+.admin-secondary-drawer .ant-drawer-footer {
+ border-color: var(--admin-divider);
+}
+
+.admin-model-editor-section-heading p,
+.admin-model-editor-subsection-heading p,
+.admin-price-tier-block-title {
+ color: var(--admin-text-muted);
+}
+
.admin-channel-modal .ant-modal-body {
max-height: min(70vh, 620px);
overflow-y: auto;
}
+@media (min-width: 1024px) {
+ .admin-page-frame {
+ padding: 18px 24px 0;
+ }
+
+ .admin-page-frame-scrollable {
+ padding-bottom: 28px;
+ }
+
+ .admin-page-frame-scrollable > :not(.admin-page-header) {
+ width: 100%;
+ max-width: 1120px;
+ margin-inline: auto;
+ }
+
+ .admin-settings-section:not(.is-stacked) .admin-settings-section-content {
+ border-left: 1px solid var(--admin-divider);
+ }
+
+ .admin-settings-section.is-stacked .admin-settings-section-summary {
+ border-bottom: 1px solid var(--admin-divider);
+ }
+}
+
.admin-shell .admin-monospace {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 12px;
@@ -10343,6 +11259,8 @@ html:not(.dark) .creation-media-preview-modal .ant-modal-container { background:
.admin-list-toolbar-main .app-list-search {
min-width: 0;
+ width: 100% !important;
+ max-width: none;
flex-basis: 100%;
}