mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-03 06:52:13 +08:00
fix(billing): allow clearing group quota limits and treat 0 as zero-limit
Previously, v-model.number produced "" when input was cleared, causing JSON decode errors on the backend. Also, normalizeLimit treated 0 as "unlimited" which prevented setting a zero quota. Now "" is converted to null (unlimited) in frontend, and 0 is preserved as a valid limit. Closes Wei-Shaw/sub2api#1021
This commit is contained in:
@@ -832,7 +832,7 @@ func (s *adminServiceImpl) CreateGroup(ctx context.Context, input *CreateGroupIn
|
||||
subscriptionType = SubscriptionTypeStandard
|
||||
}
|
||||
|
||||
// 限额字段:0 和 nil 都表示"无限制"
|
||||
// 限额字段:nil/负数 表示"无限制",0 表示"不允许用量",正数表示具体限额
|
||||
dailyLimit := normalizeLimit(input.DailyLimitUSD)
|
||||
weeklyLimit := normalizeLimit(input.WeeklyLimitUSD)
|
||||
monthlyLimit := normalizeLimit(input.MonthlyLimitUSD)
|
||||
@@ -944,9 +944,9 @@ func (s *adminServiceImpl) CreateGroup(ctx context.Context, input *CreateGroupIn
|
||||
return group, nil
|
||||
}
|
||||
|
||||
// normalizeLimit 将 0 或负数转换为 nil(表示无限制)
|
||||
// normalizeLimit 将负数转换为 nil(表示无限制),0 保留(表示限额为零)
|
||||
func normalizeLimit(limit *float64) *float64 {
|
||||
if limit == nil || *limit <= 0 {
|
||||
if limit == nil || *limit < 0 {
|
||||
return nil
|
||||
}
|
||||
return limit
|
||||
@@ -1058,16 +1058,11 @@ func (s *adminServiceImpl) UpdateGroup(ctx context.Context, id int64, input *Upd
|
||||
if input.SubscriptionType != "" {
|
||||
group.SubscriptionType = input.SubscriptionType
|
||||
}
|
||||
// 限额字段:0 和 nil 都表示"无限制",正数表示具体限额
|
||||
if input.DailyLimitUSD != nil {
|
||||
group.DailyLimitUSD = normalizeLimit(input.DailyLimitUSD)
|
||||
}
|
||||
if input.WeeklyLimitUSD != nil {
|
||||
group.WeeklyLimitUSD = normalizeLimit(input.WeeklyLimitUSD)
|
||||
}
|
||||
if input.MonthlyLimitUSD != nil {
|
||||
group.MonthlyLimitUSD = normalizeLimit(input.MonthlyLimitUSD)
|
||||
}
|
||||
// 限额字段:nil/负数 表示"无限制",0 表示"不允许用量",正数表示具体限额
|
||||
// 前端始终发送这三个字段,无需 nil 守卫
|
||||
group.DailyLimitUSD = normalizeLimit(input.DailyLimitUSD)
|
||||
group.WeeklyLimitUSD = normalizeLimit(input.WeeklyLimitUSD)
|
||||
group.MonthlyLimitUSD = normalizeLimit(input.MonthlyLimitUSD)
|
||||
// 图片生成计费配置:负数表示清除(使用默认价格)
|
||||
if input.ImagePrice1K != nil {
|
||||
group.ImagePrice1K = normalizePrice(input.ImagePrice1K)
|
||||
|
||||
@@ -2382,6 +2382,11 @@ const handleCreateGroup = async () => {
|
||||
sora_storage_quota_bytes: createQuotaGb ? Math.round(createQuotaGb * 1024 * 1024 * 1024) : 0,
|
||||
model_routing: convertRoutingRulesToApiFormat(createModelRoutingRules.value)
|
||||
}
|
||||
// v-model.number 清空输入框时产生 "",转为 null 让后端设为无限制
|
||||
const emptyToNull = (v: any) => v === '' ? null : v
|
||||
requestData.daily_limit_usd = emptyToNull(requestData.daily_limit_usd)
|
||||
requestData.weekly_limit_usd = emptyToNull(requestData.weekly_limit_usd)
|
||||
requestData.monthly_limit_usd = emptyToNull(requestData.monthly_limit_usd)
|
||||
await adminAPI.groups.create(requestData)
|
||||
appStore.showSuccess(t('admin.groups.groupCreated'))
|
||||
closeCreateModal()
|
||||
@@ -2465,6 +2470,11 @@ const handleUpdateGroup = async () => {
|
||||
: editForm.fallback_group_id_on_invalid_request,
|
||||
model_routing: convertRoutingRulesToApiFormat(editModelRoutingRules.value)
|
||||
}
|
||||
// v-model.number 清空输入框时产生 "",转为 null 让后端设为无限制
|
||||
const emptyToNull = (v: any) => v === '' ? null : v
|
||||
payload.daily_limit_usd = emptyToNull(payload.daily_limit_usd)
|
||||
payload.weekly_limit_usd = emptyToNull(payload.weekly_limit_usd)
|
||||
payload.monthly_limit_usd = emptyToNull(payload.monthly_limit_usd)
|
||||
await adminAPI.groups.update(editingGroup.value.id, payload)
|
||||
appStore.showSuccess(t('admin.groups.groupUpdated'))
|
||||
closeEditModal()
|
||||
|
||||
Reference in New Issue
Block a user