feat(group-filter): 分组账号过滤控制 — require_oauth_only + require_privacy_set

为 OpenAI/Antigravity/Anthropic/Gemini 分组新增两个布尔控制字段:
- require_oauth_only: 创建/更新账号绑定分组时拒绝 apikey 类型加入
- require_privacy_set: 调度选号时跳过 privacy 未成功设置的账号并标记 error

后端:Ent schema 新增字段 + 迁移、Group CRUD 全链路透传、
      gateway_service 与 openai_account_scheduler 两套调度路径过滤
前端:创建/编辑表单 toggle 开关(OpenAI/Antigravity/Anthropic/Gemini 平台可见)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
QTom
2026-03-27 18:02:48 +08:00
parent 318aa5e0d3
commit aeed2eb9ad
26 changed files with 708 additions and 6 deletions

View File

@@ -8253,6 +8253,8 @@ type GroupMutation struct {
sort_order *int
addsort_order *int
allow_messages_dispatch *bool
require_oauth_only *bool
require_privacy_set *bool
default_mapped_model *string
clearedFields map[string]struct{}
api_keys map[int64]struct{}
@@ -10034,6 +10036,78 @@ func (m *GroupMutation) ResetAllowMessagesDispatch() {
m.allow_messages_dispatch = nil
}
// SetRequireOauthOnly sets the "require_oauth_only" field.
func (m *GroupMutation) SetRequireOauthOnly(b bool) {
m.require_oauth_only = &b
}
// RequireOauthOnly returns the value of the "require_oauth_only" field in the mutation.
func (m *GroupMutation) RequireOauthOnly() (r bool, exists bool) {
v := m.require_oauth_only
if v == nil {
return
}
return *v, true
}
// OldRequireOauthOnly returns the old "require_oauth_only" field's value of the Group entity.
// If the Group object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *GroupMutation) OldRequireOauthOnly(ctx context.Context) (v bool, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldRequireOauthOnly is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldRequireOauthOnly requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldRequireOauthOnly: %w", err)
}
return oldValue.RequireOauthOnly, nil
}
// ResetRequireOauthOnly resets all changes to the "require_oauth_only" field.
func (m *GroupMutation) ResetRequireOauthOnly() {
m.require_oauth_only = nil
}
// SetRequirePrivacySet sets the "require_privacy_set" field.
func (m *GroupMutation) SetRequirePrivacySet(b bool) {
m.require_privacy_set = &b
}
// RequirePrivacySet returns the value of the "require_privacy_set" field in the mutation.
func (m *GroupMutation) RequirePrivacySet() (r bool, exists bool) {
v := m.require_privacy_set
if v == nil {
return
}
return *v, true
}
// OldRequirePrivacySet returns the old "require_privacy_set" field's value of the Group entity.
// If the Group object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *GroupMutation) OldRequirePrivacySet(ctx context.Context) (v bool, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldRequirePrivacySet is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldRequirePrivacySet requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldRequirePrivacySet: %w", err)
}
return oldValue.RequirePrivacySet, nil
}
// ResetRequirePrivacySet resets all changes to the "require_privacy_set" field.
func (m *GroupMutation) ResetRequirePrivacySet() {
m.require_privacy_set = nil
}
// SetDefaultMappedModel sets the "default_mapped_model" field.
func (m *GroupMutation) SetDefaultMappedModel(s string) {
m.default_mapped_model = &s
@@ -10428,7 +10502,7 @@ func (m *GroupMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call
// AddedFields().
func (m *GroupMutation) Fields() []string {
fields := make([]string, 0, 32)
fields := make([]string, 0, 34)
if m.created_at != nil {
fields = append(fields, group.FieldCreatedAt)
}
@@ -10522,6 +10596,12 @@ func (m *GroupMutation) Fields() []string {
if m.allow_messages_dispatch != nil {
fields = append(fields, group.FieldAllowMessagesDispatch)
}
if m.require_oauth_only != nil {
fields = append(fields, group.FieldRequireOauthOnly)
}
if m.require_privacy_set != nil {
fields = append(fields, group.FieldRequirePrivacySet)
}
if m.default_mapped_model != nil {
fields = append(fields, group.FieldDefaultMappedModel)
}
@@ -10595,6 +10675,10 @@ func (m *GroupMutation) Field(name string) (ent.Value, bool) {
return m.SortOrder()
case group.FieldAllowMessagesDispatch:
return m.AllowMessagesDispatch()
case group.FieldRequireOauthOnly:
return m.RequireOauthOnly()
case group.FieldRequirePrivacySet:
return m.RequirePrivacySet()
case group.FieldDefaultMappedModel:
return m.DefaultMappedModel()
}
@@ -10668,6 +10752,10 @@ func (m *GroupMutation) OldField(ctx context.Context, name string) (ent.Value, e
return m.OldSortOrder(ctx)
case group.FieldAllowMessagesDispatch:
return m.OldAllowMessagesDispatch(ctx)
case group.FieldRequireOauthOnly:
return m.OldRequireOauthOnly(ctx)
case group.FieldRequirePrivacySet:
return m.OldRequirePrivacySet(ctx)
case group.FieldDefaultMappedModel:
return m.OldDefaultMappedModel(ctx)
}
@@ -10896,6 +10984,20 @@ func (m *GroupMutation) SetField(name string, value ent.Value) error {
}
m.SetAllowMessagesDispatch(v)
return nil
case group.FieldRequireOauthOnly:
v, ok := value.(bool)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetRequireOauthOnly(v)
return nil
case group.FieldRequirePrivacySet:
v, ok := value.(bool)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetRequirePrivacySet(v)
return nil
case group.FieldDefaultMappedModel:
v, ok := value.(string)
if !ok {
@@ -11333,6 +11435,12 @@ func (m *GroupMutation) ResetField(name string) error {
case group.FieldAllowMessagesDispatch:
m.ResetAllowMessagesDispatch()
return nil
case group.FieldRequireOauthOnly:
m.ResetRequireOauthOnly()
return nil
case group.FieldRequirePrivacySet:
m.ResetRequirePrivacySet()
return nil
case group.FieldDefaultMappedModel:
m.ResetDefaultMappedModel()
return nil