diff --git a/api/admin/admin.go b/api/admin/admin.go index 620ad11..3593a00 100644 --- a/api/admin/admin.go +++ b/api/admin/admin.go @@ -57,7 +57,6 @@ type IAdminV1 interface { ChannelKeyCreate(ctx context.Context, req *v1.ChannelKeyCreateReq) (res *v1.ChannelKeyCreateRes, err error) ChannelKeyDelete(ctx context.Context, req *v1.ChannelKeyDeleteReq) (res *v1.ChannelKeyDeleteRes, err error) ChannelAbilityBatch(ctx context.Context, req *v1.ChannelAbilityBatchReq) (res *v1.ChannelAbilityBatchRes, err error) - ChannelCostRatioImport(ctx context.Context, req *v1.ChannelCostRatioImportReq) (res *v1.ChannelCostRatioImportRes, err error) ProviderDefaultURL(ctx context.Context, req *v1.ProviderDefaultURLReq) (res *v1.ProviderDefaultURLRes, err error) ChannelKeyList(ctx context.Context, req *v1.ChannelKeyListReq) (res *v1.ChannelKeyListRes, err error) ChannelAbilitiesGet(ctx context.Context, req *v1.ChannelAbilitiesGetReq) (res *v1.ChannelAbilitiesGetRes, err error) diff --git a/api/admin/v1/channel.go b/api/admin/v1/channel.go index 498d1d3..ed5c10e 100644 --- a/api/admin/v1/channel.go +++ b/api/admin/v1/channel.go @@ -169,25 +169,6 @@ type AbilityItem struct { CostRatio float64 `json:"cost_ratio" d:"1" v:"between:0,100" dc:"成本比例:上游实际价/平台基准价,1.0=等价(参与调度 costFactor)"` } -// ChannelCostRatioImportReq 批量导入渠道模型成本比例(CSV 由前端解析为条目) -type ChannelCostRatioImportReq struct { - g.Meta `path:"/channels/cost-ratio-import" method:"post" mime:"json" tags:"管理后台-渠道" summary:"批量导入成本比例"` - Items []CostRatioImportItem `json:"items" v:"required#请提供导入条目" dc:"导入条目列表"` -} - -// CostRatioImportItem 成本比例导入条目 -type CostRatioImportItem struct { - ChannelID int64 `json:"channel_id" v:"required|min:1" dc:"渠道ID"` - ModelName string `json:"model_name" v:"required" dc:"平台标准模型名"` - CostRatio float64 `json:"cost_ratio" v:"required|between:0.0001,100" dc:"成本比例"` -} - -// ChannelCostRatioImportRes 批量导入成本比例响应 -type ChannelCostRatioImportRes struct { - Updated int `json:"updated" dc:"成功更新条数"` - Skipped []string `json:"skipped" dc:"未匹配到能力记录的条目(渠道ID:模型名)"` -} - // ProviderDefaultURLReq 获取供应商默认 URL type ProviderDefaultURLReq struct { g.Meta `path:"/channels/provider-default-urls" method:"get" mime:"json" tags:"管理后台-渠道" summary:"供应商默认地址"` diff --git a/internal/controller/admin/admin_v1_channel.go b/internal/controller/admin/admin_v1_channel.go index 50e0247..45a9b3e 100644 --- a/internal/controller/admin/admin_v1_channel.go +++ b/internal/controller/admin/admin_v1_channel.go @@ -49,6 +49,3 @@ func (c *ControllerV1) ChannelExport(ctx context.Context, req *v1.ChannelExportR func (c *ControllerV1) ChannelClone(ctx context.Context, req *v1.ChannelCloneReq) (res *v1.ChannelCloneRes, err error) { return service.Admin().CloneChannel(ctx, req) } -func (c *ControllerV1) ChannelCostRatioImport(ctx context.Context, req *v1.ChannelCostRatioImportReq) (res *v1.ChannelCostRatioImportRes, err error) { - return service.Admin().ImportChannelCostRatios(ctx, req) -} diff --git a/internal/logic/admin/channel.go b/internal/logic/admin/channel.go index 205a47a..f6e9b54 100644 --- a/internal/logic/admin/channel.go +++ b/internal/logic/admin/channel.go @@ -636,30 +636,6 @@ func (s *sAdmin) GetChannelAbilities(ctx context.Context, req *v1.ChannelAbiliti return &v1.ChannelAbilitiesGetRes{List: list}, nil } -// ImportChannelCostRatios 批量导入渠道模型成本比例(CSV 由前端解析为条目提交)。 -// 只更新已存在的能力记录,未匹配的条目返回在 skipped 中;成功后触发目录失效。 -func (s *sAdmin) ImportChannelCostRatios(ctx context.Context, req *v1.ChannelCostRatioImportReq) (*v1.ChannelCostRatioImportRes, error) { - res := &v1.ChannelCostRatioImportRes{Skipped: make([]string, 0)} - for _, item := range req.Items { - affected, err := dao.ChnAbilities.Ctx(ctx). - Where("channel_id", item.ChannelID). - Where("model_name", item.ModelName). - Data(do.ChnAbilities{CostRatio: item.CostRatio}). - UpdateAndGetAffected() - if err != nil { - return nil, err - } - if affected == 0 { - res.Skipped = append(res.Skipped, fmt.Sprintf("%d:%s", item.ChannelID, item.ModelName)) - continue - } - res.Updated++ - } - // 成本比例参与调度 costFactor,变更后跨实例目录失效 - dispatchadapter.PublishInvalidate(ctx) - return res, nil -} - // GetProviderDefaultURLs 获取供应商默认 API 地址 func (s *sAdmin) GetProviderDefaultURLs(ctx context.Context, _ *v1.ProviderDefaultURLReq) (*v1.ProviderDefaultURLRes, error) { return &v1.ProviderDefaultURLRes{URLs: defaultProviderURLs}, nil diff --git a/internal/service/admin.go b/internal/service/admin.go index 8f066d3..be975b9 100644 --- a/internal/service/admin.go +++ b/internal/service/admin.go @@ -115,9 +115,6 @@ type ( GetChannelKeys(ctx context.Context, req *v1.ChannelKeyListReq) (*v1.ChannelKeyListRes, error) // GetChannelAbilities 获取渠道模型能力列表 GetChannelAbilities(ctx context.Context, req *v1.ChannelAbilitiesGetReq) (*v1.ChannelAbilitiesGetRes, error) - // ImportChannelCostRatios 批量导入渠道模型成本比例(CSV 由前端解析为条目提交)。 - // 只更新已存在的能力记录,未匹配的条目返回在 skipped 中;成功后触发目录失效。 - ImportChannelCostRatios(ctx context.Context, req *v1.ChannelCostRatioImportReq) (*v1.ChannelCostRatioImportRes, error) // GetProviderDefaultURLs 获取供应商默认 API 地址 GetProviderDefaultURLs(ctx context.Context, _ *v1.ProviderDefaultURLReq) (*v1.ProviderDefaultURLRes, error) // GetChannelHealthTrend 获取渠道健康趋势数据 diff --git a/web/admin/src/views/ai/ChannelDetailPage.vue b/web/admin/src/views/ai/ChannelDetailPage.vue index b9247b7..2bc2a13 100644 --- a/web/admin/src/views/ai/ChannelDetailPage.vue +++ b/web/admin/src/views/ai/ChannelDetailPage.vue @@ -228,36 +228,6 @@ function handleUpstreamModelChange(record: any, value: string) { scheduleAbilitySave('上游模型名已更新') } -// CSV 批量导入成本比例:每行 "model_name,cost_ratio"(首行可为表头) -const csvInputRef = ref() -const csvImporting = ref(false) -function triggerCsvImport() { csvInputRef.value?.click() } -async function handleCsvFile(e: Event) { - const input = e.target as HTMLInputElement - const file = input.files?.[0] - input.value = '' - if (!file) return - const text = await file.text() - const items: { channel_id: number; model_name: string; cost_ratio: number }[] = [] - for (const rawLine of text.split(/\r?\n/)) { - const line = rawLine.trim() - if (!line) continue - const [model, ratioStr] = line.split(',').map(s => s?.trim()) - const ratio = Number(ratioStr) - if (!model || !Number.isFinite(ratio) || ratio <= 0) continue // 跳过表头与非法行 - items.push({ channel_id: Number(channelId), model_name: model, cost_ratio: ratio }) - } - if (!items.length) { Message.warning('未解析到有效条目,格式:model_name,cost_ratio'); return } - csvImporting.value = true - try { - const res: any = await request.post('/admin/channels/cost-ratio-import', { items }) - const data = res.data?.data || res.data - const skipped = data?.skipped?.length ? `,未匹配 ${data.skipped.length} 条` : '' - Message.success(`已更新 ${data?.updated ?? 0} 条${skipped}`) - fetchAbilities() - } catch { /* error handled by interceptor */ } finally { csvImporting.value = false } -} - async function handleDeleteAbility(id: number) { const newList = abilitiesData.value.filter(a => a.id !== id) try { @@ -593,15 +563,14 @@ function formatHeaders(headers: Record): string { +
已配置 {{ abilitiesData.length }} 个模型能力 - - - 导入成本比例 - - 添加能力 - -
): string { :pagination="false" row-key="id" /> + +
+
字段说明
+
+
+ 上游模型名:该渠道转发请求时实际调用的上游模型名称。仅当上游名称与平台标准模型名不同时填写(如平台名 gpt-4、上游名 gpt-4-0314);留空表示与平台模型名相同。 +
+
+ 成本比例:该渠道相对基准价的成本系数,1.0 为标准。小于 1(如 0.8)表示更便宜,多渠道择优时更优先调度;大于 1(如 1.5)表示更贵,优先级降低。仅用于渠道调度,不影响对用户的计费。 +
+
+