fix(platform): 模型选择与计费展示 - 透传渠道信息并标注视频结算来源

This commit is contained in:
ddCat
2026-09-18 23:28:12 +08:00
parent 262540ea36
commit f77bd2bfa0
7 changed files with 105 additions and 5 deletions

View File

@@ -17,7 +17,9 @@ description: 从产品功能快速定位主要代码入口
| 创作工作台 | `web/src/pages/create/index.tsx` | `creation-workspace.tsx`、`creation-conversations.ts`、`creation-types.ts`、`creation-assets.ts`、`creation-references.ts` |
| 登录注册 | `web/src/pages/auth/` | `stores/use-user-store.ts`、`services/api/auth.ts`、后端 `internal/auth/` |
| 积分与计费 | `web/src/components/layout/workspace-wallet-modal.tsx`、`pages/admin/components/platform-finance-panel.tsx` | `services/api/wallet.ts`、`services/api/payments.ts`、后端 `internal/app/finance.go`、`internal/app/payment.go`、`payment-plugins/`、`plugin-packages/official-payment-*` |
| 视频 Token 报价与结算 | `web/src/pages/admin/components/channel-model-price-tier-fields.tsx`、`web/src/components/model-picker.tsx` | `lib/model-pricing.ts`、`services/api/logical-models.ts`;后端 `app/video_token_billing.go` 管像素与时长估算,`app/logical_model_quote.go` 复用准入与价格规则,`app/analytics.go` 提取可信用量,`repository/finance.go` 按订单快照退补差额 |
| 任务中心 | `web/src/pages/tasks/` | `services/api/task-center.ts`、`services/api/task-text-stream.ts` |
| 产品模型与渠道选择 | `web/src/components/model-picker.tsx`、`pages/admin/components/channel-model-editor.tsx` | `lib/model-picker-groups.ts` 只构建跨渠道展示分组;`lib/user-session.ts` 透传渠道展示名;`components/model-logo.tsx` 按需加载原色图标;后端 `app/channel_models.go` 校验写入,`app/model_catalog.go` 发布目录,schema v24 增加 `channel_label` |
| 我的素材 | `web/src/pages/assets/` | `stores/use-asset-store.ts`、`services/image-storage.ts` |
| 技能库 | `web/src/pages/skills/` | `services/api/skills.ts`、`services/skill-runtime.ts`、`components/skills/skill-runtime-picker.tsx` |
| 画布列表 | `web/src/pages/canvas/index.tsx` | `stores/canvas/use-canvas-store.ts` |

View File

@@ -7,6 +7,7 @@
"http-api",
"code-map",
"backend-database",
"video-token-billing",
"task-runtime-stability",
"newapi-channel-2",
"system-update",

View File

@@ -93,6 +93,8 @@ description: 当前项目已实现的核心工作台能力与使用入口
## 系统渠道排序与前台别名
系统渠道模型选择器按产品模型分组:一级显示模型展示名和原色 Logo,二级显示各渠道的展示名及规格价格。管理员在渠道模型的“基本信息”中配置“渠道展示名”(例如“优惠渠道-993”);留空沿用渠道公开名称。同一能力下相同的产品模型标识跨渠道归为一组,调用仍保留用户选中的具体渠道。收起后显示“模型 · 渠道”,不因另一渠道更便宜而自动切换。图标优先使用图标库的原色版本,缺少彩色版本时使用单色版本;缺少配置时显示通用图标,不猜测产品品牌。
后台系统渠道及渠道模型列表通过“设置排序”打开完整列表,支持拖动、上移和下移,点击“保存排序”统一生效;取消不会修改线上顺序。渠道行的“更多”菜单支持复制渠道,复制会生成独立的渠道、模型和价格档,并保留原连接配置与凭证。界面不显示内部排序数字,排序不受筛选及分页影响;并发修改会提示重新加载,避免覆盖其他管理员的调整。系统渠道模式下,用户端模型选择器沿用同一渠道及模型顺序。模型排序独立保存,不改变价格、能力版本或启用状态。
系统渠道可设置可选的前台别名;为空时显示渠道名,设置后公开目录和用户会话只返回别名,后台仍保留原名。别名最长 80 字,支持后台搜索。前台模型目录模式保留其独立配置。

View File

@@ -178,7 +178,8 @@ export function systemChannelModelChannels(channels: PublicChannelCatalog[]): Mo
return {
model: model.modelKey,
displayName: model.displayName,
description: "",
channelLabel: model.channelLabel,
description: model.description || "",
icon: model.icon || "",
capability: model.capability as ModelCapability,
protocol: model.protocol as any,

View File

@@ -328,7 +328,11 @@ export default function CreditOperationsPanel({ users, activeOperation, onOperat
<div className="text-xs leading-5">
<div className="font-medium tabular-nums">{order.status === "settled" ? `${formatCredits(order.actualAmountMicrocredits)} 积分` : "等待用量结算"}</div>
<div className="text-foreground/50">
输入 {order.inputTokens} · 输出 {order.outputTokens} · 缓存 {order.cachedTokens}
{order.usageSource === "video_formula"
? `公式结算 · ${order.outputTokens.toLocaleString()} 视频 Token`
: order.capability === "video"
? `上游用量 · ${order.outputTokens.toLocaleString()} 视频 Token`
: `输入 ${order.inputTokens} · 输出 ${order.outputTokens} · 缓存 ${order.cachedTokens}`}
</div>
</div>
) : (

View File

@@ -363,6 +363,7 @@ export type ModelChannel = {
modelCosts?: Array<{
model: string;
displayName?: string;
channelLabel?: string;
description?: string;
icon?: string;
capability: ModelCapability;

View File

@@ -9,11 +9,25 @@
padding: 14px 16px;
}
/* Appearance management follows the same full-width settings document used by storage and access pages. */
/* Appearance categories share one draft and command bar. */
.admin-appearance-settings {
padding-bottom: 24px;
}
.admin-appearance-tabs,
.admin-appearance-tabs .ant-tabs-content-holder,
.admin-appearance-tabs .ant-tabs-tabpane {
min-width: 0;
}
.admin-appearance-tabs > .ant-tabs-nav {
margin-bottom: var(--space-4);
}
.admin-appearance-tabs .ant-tabs-tab {
padding-block: var(--space-3);
}
.admin-appearance-settings .admin-settings-section {
border: 1px solid var(--admin-card-border);
}
@@ -724,7 +738,6 @@
.admin-skin-card.is-selected {
border-color: color-mix(in srgb, var(--workspace-accent) 76%, var(--admin-card-border));
background: color-mix(in srgb, var(--workspace-accent) 5%, var(--admin-layer-2));
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--workspace-accent) 36%, transparent);
}
.admin-skin-card-select {
@@ -9124,10 +9137,80 @@
}
.admin-model-editor-references .admin-capability-reference-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
align-items: start;
gap: 10px;
}
.admin-model-editor-modal .admin-capability-reference-card,
.admin-model-editor-modal .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));
}
.admin-model-editor-modal .admin-capability-reference-card-heading,
.admin-model-editor-modal .admin-capability-protocol-card-heading {
display: flex;
min-width: 0;
align-items: flex-start;
gap: 8px;
border-bottom: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
padding: 12px;
}
.admin-model-editor-modal .admin-capability-reference-card-heading h3,
.admin-model-editor-modal .admin-capability-protocol-card-heading h3 {
margin: 0;
color: var(--admin-text-primary);
font-size: 12px;
font-weight: 650;
line-height: 1.4;
}
.admin-model-editor-modal .admin-capability-reference-card-heading p,
.admin-model-editor-modal .admin-capability-protocol-card-heading p {
margin: 2px 0 0;
color: var(--admin-text-muted);
font-size: 11px;
line-height: 1.45;
}
.admin-model-editor-modal .admin-capability-reference-fields,
.admin-model-editor-modal .admin-capability-protocol-fields {
display: grid;
min-width: 0;
gap: 8px;
padding: 10px 12px 12px;
}
.admin-model-editor-modal .admin-capability-protocol-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
align-items: start;
gap: 12px;
}
.admin-model-editor-modal .admin-capability-protocol-card-heading > span {
display: grid;
flex: none;
width: 24px;
height: 24px;
place-items: center;
border-radius: 6px;
background: color-mix(in srgb, var(--foreground) 8%, transparent);
color: var(--admin-text-muted);
font-size: 10px;
font-weight: 700;
letter-spacing: 0.04em;
}
.admin-model-editor-modal .admin-capability-protocol-card-heading > div {
min-width: 0;
}
.admin-model-editor-references .admin-capability-reference-card {
padding: 10px 12px;
}
@@ -9174,6 +9257,10 @@
.admin-model-editor-references .admin-capability-reference-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.admin-model-editor-modal .admin-capability-protocol-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
.admin-price-tier-card {
@@ -9423,6 +9510,9 @@
.admin-model-editor-modal .admin-capability-reference-grid {
grid-template-columns: minmax(0, 1fr);
}
.admin-model-editor-modal .admin-capability-protocol-grid {
grid-template-columns: minmax(0, 1fr);
}
.admin-price-tier-upstream {
grid-column: 1 / -1;
}
@@ -10853,4 +10943,3 @@ html[data-magicui-theme-vt="active"] .admin-shell * {
.admin-banner-type-card[data-banner-type="warning"] .admin-banner-type-card-preview {
background: var(--notice-banner-surface-warning);
}