💰 feat: Add model billing type (quota_type) support across backend & frontend
Summary
• Backend
1. model/model_meta.go
– Added `QuotaType` field to `Model` struct (JSON only, gorm `-`).
2. model/model_groups.go
– Implemented `GetModelQuotaType(modelName)` leveraging cached pricing map.
3. controller/model_meta.go
– Enhanced `fillModelExtra` to populate `QuotaType` using new helper.
• Frontend
1. web/src/components/table/models/ModelsColumnDefs.js
– Introduced `renderQuotaType` helper that visualises billing mode with coloured tags (`teal = per-call`, `violet = per-token`).
– Added “计费类型” column (`quota_type`) to models table.
Why
Providing the billing mode alongside existing pricing/group information gives administrators instant visibility into whether each model is priced per call or per token, aligning UI with new backend metadata.
Notes
No database migration required – `quota_type` is transient, delivered via API. Frontend labels/colours can be adjusted via i18n or theme tokens if necessary.
This commit is contained in:
@@ -147,5 +147,7 @@ func fillModelExtra(m *model.Model) {
|
|||||||
}
|
}
|
||||||
// 填充启用分组
|
// 填充启用分组
|
||||||
m.EnableGroups = model.GetModelEnableGroups(m.ModelName)
|
m.EnableGroups = model.GetModelEnableGroups(m.ModelName)
|
||||||
|
// 填充计费类型
|
||||||
|
m.QuotaType = model.GetModelQuotaType(m.ModelName)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
24
model/model_extra.go
Normal file
24
model/model_extra.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
// GetModelEnableGroups 返回指定模型名称可用的用户分组列表。
|
||||||
|
// 复用缓存的定价映射,避免额外的数据库查询。
|
||||||
|
func GetModelEnableGroups(modelName string) []string {
|
||||||
|
for _, p := range GetPricing() {
|
||||||
|
if p.ModelName == modelName {
|
||||||
|
return p.EnableGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make([]string, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetModelQuotaType 返回指定模型的计费类型(quota_type)。
|
||||||
|
// 复用缓存的定价映射,避免额外数据库查询。
|
||||||
|
// 如果未找到对应模型,默认返回 0。
|
||||||
|
func GetModelQuotaType(modelName string) int {
|
||||||
|
for _, p := range GetPricing() {
|
||||||
|
if p.ModelName == modelName {
|
||||||
|
return p.QuotaType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
// GetModelEnableGroups 返回指定模型名称可用的用户分组列表。
|
|
||||||
// 复用缓存的定价映射,避免额外的数据库查询。
|
|
||||||
func GetModelEnableGroups(modelName string) []string {
|
|
||||||
for _, p := range GetPricing() {
|
|
||||||
if p.ModelName == modelName {
|
|
||||||
return p.EnableGroup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return make([]string, 0)
|
|
||||||
}
|
|
||||||
@@ -39,6 +39,7 @@ type Model struct {
|
|||||||
|
|
||||||
BoundChannels []BoundChannel `json:"bound_channels,omitempty" gorm:"-"`
|
BoundChannels []BoundChannel `json:"bound_channels,omitempty" gorm:"-"`
|
||||||
EnableGroups []string `json:"enable_groups,omitempty" gorm:"-"`
|
EnableGroups []string `json:"enable_groups,omitempty" gorm:"-"`
|
||||||
|
QuotaType int `json:"quota_type" gorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert 创建新的模型元数据记录
|
// Insert 创建新的模型元数据记录
|
||||||
|
|||||||
@@ -98,6 +98,25 @@ const renderEndpoints = (text) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Render quota type
|
||||||
|
const renderQuotaType = (qt, t) => {
|
||||||
|
if (qt === 1) {
|
||||||
|
return (
|
||||||
|
<Tag color='teal' size='small' shape='circle'>
|
||||||
|
{t('按次计费')}
|
||||||
|
</Tag>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (qt === 0) {
|
||||||
|
return (
|
||||||
|
<Tag color='violet' size='small' shape='circle'>
|
||||||
|
{t('按量计费')}
|
||||||
|
</Tag>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return qt ?? '-';
|
||||||
|
};
|
||||||
|
|
||||||
// Render bound channels
|
// Render bound channels
|
||||||
const renderBoundChannels = (channels) => {
|
const renderBoundChannels = (channels) => {
|
||||||
if (!channels || channels.length === 0) return '-';
|
if (!channels || channels.length === 0) return '-';
|
||||||
@@ -213,6 +232,11 @@ export const getModelsColumns = ({
|
|||||||
dataIndex: 'enable_groups',
|
dataIndex: 'enable_groups',
|
||||||
render: renderGroups,
|
render: renderGroups,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('计费类型'),
|
||||||
|
dataIndex: 'quota_type',
|
||||||
|
render: (qt) => renderQuotaType(qt, t),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('创建时间'),
|
title: t('创建时间'),
|
||||||
dataIndex: 'created_time',
|
dataIndex: 'created_time',
|
||||||
|
|||||||
Reference in New Issue
Block a user