fix(platform): 模型选择与计费展示 - 透传渠道信息并标注视频结算来源
This commit is contained in:
@@ -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` |
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"http-api",
|
||||
"code-map",
|
||||
"backend-database",
|
||||
"video-token-billing",
|
||||
"task-runtime-stability",
|
||||
"newapi-channel-2",
|
||||
"system-update",
|
||||
|
||||
@@ -93,6 +93,8 @@ description: 当前项目已实现的核心工作台能力与使用入口
|
||||
|
||||
## 系统渠道排序与前台别名
|
||||
|
||||
系统渠道模型选择器按产品模型分组:一级显示模型展示名和原色 Logo,二级显示各渠道的展示名及规格价格。管理员在渠道模型的“基本信息”中配置“渠道展示名”(例如“优惠渠道-993”);留空沿用渠道公开名称。同一能力下相同的产品模型标识跨渠道归为一组,调用仍保留用户选中的具体渠道。收起后显示“模型 · 渠道”,不因另一渠道更便宜而自动切换。图标优先使用图标库的原色版本,缺少彩色版本时使用单色版本;缺少配置时显示通用图标,不猜测产品品牌。
|
||||
|
||||
后台系统渠道及渠道模型列表通过“设置排序”打开完整列表,支持拖动、上移和下移,点击“保存排序”统一生效;取消不会修改线上顺序。渠道行的“更多”菜单支持复制渠道,复制会生成独立的渠道、模型和价格档,并保留原连接配置与凭证。界面不显示内部排序数字,排序不受筛选及分页影响;并发修改会提示重新加载,避免覆盖其他管理员的调整。系统渠道模式下,用户端模型选择器沿用同一渠道及模型顺序。模型排序独立保存,不改变价格、能力版本或启用状态。
|
||||
|
||||
系统渠道可设置可选的前台别名;为空时显示渠道名,设置后公开目录和用户会话只返回别名,后台仍保留原名。别名最长 80 字,支持后台搜索。前台模型目录模式保留其独立配置。
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
) : (
|
||||
|
||||
@@ -363,6 +363,7 @@ export type ModelChannel = {
|
||||
modelCosts?: Array<{
|
||||
model: string;
|
||||
displayName?: string;
|
||||
channelLabel?: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
capability: ModelCapability;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user