Browse Source

1. 拆分角色知识库接口
2. 在操作服务器和账号相关动作时,清理定时任务缓存
3. 优化sop阶段排序

boweniac 5 tháng trước cách đây
mục cha
commit
3c82a0f3f6
45 tập tin đã thay đổi với 6150 bổ sung20 xóa
  1. 2 1
      desc/all.api
  2. 2 2
      desc/wechat/agent.api
  3. 75 0
      desc/wechat/agent_base.api
  4. 1 0
      ent/agent_query.go
  5. 227 0
      ent/agentbase.go
  6. 142 0
      ent/agentbase/agentbase.go
  7. 578 0
      ent/agentbase/where.go
  8. 1172 0
      ent/agentbase_create.go
  9. 88 0
      ent/agentbase_delete.go
  10. 606 0
      ent/agentbase_query.go
  11. 853 0
      ent/agentbase_update.go
  12. 167 8
      ent/client.go
  13. 2 0
      ent/ent.go
  14. 12 0
      ent/hook/hook.go
  15. 30 0
      ent/intercept/intercept.go
  16. 34 3
      ent/migrate/schema.go
  17. 1101 0
      ent/mutation.go
  18. 82 0
      ent/pagination.go
  19. 3 0
      ent/predicate/predicate.go
  20. 27 0
      ent/runtime/runtime.go
  21. 55 0
      ent/schema/agent_base.go
  22. 1 0
      ent/server_query.go
  23. 216 0
      ent/set_not_nil.go
  24. 3 0
      ent/tx.go
  25. 12 2
      ent/wx.go
  26. 11 0
      ent/wx/wx.go
  27. 5 0
      ent/wx_query.go
  28. 44 0
      internal/handler/agent_base/create_agent_base_handler.go
  29. 44 0
      internal/handler/agent_base/delete_agent_base_handler.go
  30. 44 0
      internal/handler/agent_base/get_agent_base_by_id_handler.go
  31. 44 0
      internal/handler/agent_base/get_agent_base_list_handler.go
  32. 44 0
      internal/handler/agent_base/update_agent_base_handler.go
  33. 35 0
      internal/handler/routes.go
  34. 1 1
      internal/logic/WechatServer/delete_server_logic.go
  35. 1 0
      internal/logic/WechatServer/update_server_logic.go
  36. 1 0
      internal/logic/Wx/check_wx_logic.go
  37. 6 0
      internal/logic/Wx/get_wx_list_logic.go
  38. 54 0
      internal/logic/agent_base/create_agent_base_logic.go
  39. 43 0
      internal/logic/agent_base/delete_agent_base_logic.go
  40. 66 0
      internal/logic/agent_base/get_agent_base_by_id_logic.go
  41. 59 0
      internal/logic/agent_base/get_agent_base_list_logic.go
  42. 47 0
      internal/logic/agent_base/update_agent_base_logic.go
  43. 62 0
      internal/logic/base/init_api_data.go
  44. 4 1
      internal/logic/sop_task/get_sop_task_by_id_logic.go
  45. 44 2
      internal/types/types.go

+ 2 - 1
desc/all.api

@@ -21,4 +21,5 @@ import "./wechat/work_experience.api"
 import "./wechat/tutorial.api"
 import "./wechat/token.api"
 import "./wechat/employee_config.api"
-import "./wechat/category.api"
+import "./wechat/category.api"
+import "./wechat/agent_base.api"

+ 2 - 2
desc/wechat/agent.api

@@ -219,7 +219,7 @@ type (
 
 	// Get collection list request params | Collection列表请求参数
 	DataListReq {
-		PageNum   *int    `json:"pageNum" validate:"required,number,gt=0"`
+		PageNum   *int    `json:"page" validate:"required,number,gt=0"`
 
 		PageSize  *int    `json:"pageSize" validate:"required,number,lt=100000"`
 
@@ -261,7 +261,7 @@ type (
 	// Data create request | 信息返回体
 	UpdateDataInfoReq {
 		// ID
-		DataId *string `json:"dataId" validate:"required"`
+		DataId *string `json:"id" validate:"required"`
 
 		// Q
 		Q *string `json:"q" validate:"required"`

+ 75 - 0
desc/wechat/agent_base.api

@@ -0,0 +1,75 @@
+import "../base.api"
+import "./agent.api"
+
+type (
+    // The data of agent base information | AgentBase信息
+    AgentBaseInfo {
+        Id        *string    `json:"id,optional"`
+    }
+
+    // The response data of agent base list | AgentBase列表数据
+    AgentBaseListResp {
+        BaseDataInfo
+
+        // AgentBase list data | AgentBase列表数据
+        Data AgentBaseListInfo `json:"data"`
+    }
+
+    // AgentBase list data | AgentBase列表数据
+    AgentBaseListInfo {
+        BaseListInfo
+
+        // The API list data | AgentBase列表数据
+        Data  []AgentBaseInfo  `json:"data"`
+    }
+
+    // Get agent base list request params | AgentBase列表请求参数
+    AgentBaseListReq {
+        PageInfo
+
+        // q 
+        Q  *string `json:"q,optional"`
+
+        // a 
+        A  *string `json:"a,optional"`
+
+        // dataset_id 
+        DatasetId  *string `json:"datasetId,optional"`
+    }
+
+    // AgentBase information response | AgentBase信息返回体
+    AgentBaseInfoResp {
+        BaseDataInfo
+
+        // AgentBase information | AgentBase数据
+        Data AgentBaseInfo `json:"data"`
+    }
+)
+
+@server(
+    jwt: Auth
+    group: agent_base
+    middleware: Authority
+)
+
+service Wechat {
+    // Create agent base information | 创建AgentBase
+    @handler createAgentBase
+    post /agent_base/create (CreateDataInfoReq) returns (BaseDataInfo)
+
+    // Update agent base information | 更新AgentBase
+    @handler updateAgentBase
+    post /agent_base/update (UpdateDataInfoReq) returns (BaseDataInfo)
+
+    // Delete agent base information | 删除AgentBase信息
+    @handler deleteAgentBase
+    post /agent_base/delete (DeleteDataReq) returns (BaseDataInfo)
+
+    // Get agent base list | 获取AgentBase列表
+    @handler getAgentBaseList
+    post /agent_base/list (DataListReq) returns (DataListResp)
+
+    // Get agent base by ID | 通过ID获取AgentBase
+    @handler getAgentBaseById
+    post /agent_base (DataDetailReq) returns (DataDetailResp)
+}

+ 1 - 0
ent/agent_query.go

@@ -412,6 +412,7 @@ func (aq *AgentQuery) loadWxAgent(ctx context.Context, query *WxQuery, nodes []*
 			init(nodes[i])
 		}
 	}
+	query.withFKs = true
 	if len(query.ctx.Fields) > 0 {
 		query.ctx.AppendFieldOnce(wx.FieldAgentID)
 	}

+ 227 - 0
ent/agentbase.go

@@ -0,0 +1,227 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+	"wechat-api/ent/agentbase"
+
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/sql"
+)
+
+// AgentBase is the model entity for the AgentBase schema.
+type AgentBase struct {
+	config `json:"-"`
+	// ID of the ent.
+	// id
+	ID string `json:"id,omitempty"`
+	// q
+	Q string `json:"q,omitempty"`
+	// a
+	A string `json:"a,omitempty"`
+	// chunk_index
+	ChunkIndex uint64 `json:"chunk_index,omitempty"`
+	// indexes
+	Indexes []string `json:"indexes,omitempty"`
+	// dataset_id
+	DatasetID string `json:"dataset_id,omitempty"`
+	// collection_id
+	CollectionID string `json:"collection_id,omitempty"`
+	// source_name
+	SourceName string `json:"source_name,omitempty"`
+	// can_write
+	CanWrite []bool `json:"can_write,omitempty"`
+	// is_owner
+	IsOwner []bool `json:"is_owner,omitempty"`
+	// Edges holds the relations/edges for other nodes in the graph.
+	// The values are being populated by the AgentBaseQuery when eager-loading is set.
+	Edges        AgentBaseEdges `json:"edges"`
+	selectValues sql.SelectValues
+}
+
+// AgentBaseEdges holds the relations/edges for other nodes in the graph.
+type AgentBaseEdges struct {
+	// WxAgent holds the value of the wx_agent edge.
+	WxAgent []*Wx `json:"wx_agent,omitempty"`
+	// loadedTypes holds the information for reporting if a
+	// type was loaded (or requested) in eager-loading or not.
+	loadedTypes [1]bool
+}
+
+// WxAgentOrErr returns the WxAgent value or an error if the edge
+// was not loaded in eager-loading.
+func (e AgentBaseEdges) WxAgentOrErr() ([]*Wx, error) {
+	if e.loadedTypes[0] {
+		return e.WxAgent, nil
+	}
+	return nil, &NotLoadedError{edge: "wx_agent"}
+}
+
+// scanValues returns the types for scanning values from sql.Rows.
+func (*AgentBase) scanValues(columns []string) ([]any, error) {
+	values := make([]any, len(columns))
+	for i := range columns {
+		switch columns[i] {
+		case agentbase.FieldIndexes, agentbase.FieldCanWrite, agentbase.FieldIsOwner:
+			values[i] = new([]byte)
+		case agentbase.FieldChunkIndex:
+			values[i] = new(sql.NullInt64)
+		case agentbase.FieldID, agentbase.FieldQ, agentbase.FieldA, agentbase.FieldDatasetID, agentbase.FieldCollectionID, agentbase.FieldSourceName:
+			values[i] = new(sql.NullString)
+		default:
+			values[i] = new(sql.UnknownType)
+		}
+	}
+	return values, nil
+}
+
+// assignValues assigns the values that were returned from sql.Rows (after scanning)
+// to the AgentBase fields.
+func (ab *AgentBase) assignValues(columns []string, values []any) error {
+	if m, n := len(values), len(columns); m < n {
+		return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
+	}
+	for i := range columns {
+		switch columns[i] {
+		case agentbase.FieldID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field id", values[i])
+			} else if value.Valid {
+				ab.ID = value.String
+			}
+		case agentbase.FieldQ:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field q", values[i])
+			} else if value.Valid {
+				ab.Q = value.String
+			}
+		case agentbase.FieldA:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field a", values[i])
+			} else if value.Valid {
+				ab.A = value.String
+			}
+		case agentbase.FieldChunkIndex:
+			if value, ok := values[i].(*sql.NullInt64); !ok {
+				return fmt.Errorf("unexpected type %T for field chunk_index", values[i])
+			} else if value.Valid {
+				ab.ChunkIndex = uint64(value.Int64)
+			}
+		case agentbase.FieldIndexes:
+			if value, ok := values[i].(*[]byte); !ok {
+				return fmt.Errorf("unexpected type %T for field indexes", values[i])
+			} else if value != nil && len(*value) > 0 {
+				if err := json.Unmarshal(*value, &ab.Indexes); err != nil {
+					return fmt.Errorf("unmarshal field indexes: %w", err)
+				}
+			}
+		case agentbase.FieldDatasetID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field dataset_id", values[i])
+			} else if value.Valid {
+				ab.DatasetID = value.String
+			}
+		case agentbase.FieldCollectionID:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field collection_id", values[i])
+			} else if value.Valid {
+				ab.CollectionID = value.String
+			}
+		case agentbase.FieldSourceName:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field source_name", values[i])
+			} else if value.Valid {
+				ab.SourceName = value.String
+			}
+		case agentbase.FieldCanWrite:
+			if value, ok := values[i].(*[]byte); !ok {
+				return fmt.Errorf("unexpected type %T for field can_write", values[i])
+			} else if value != nil && len(*value) > 0 {
+				if err := json.Unmarshal(*value, &ab.CanWrite); err != nil {
+					return fmt.Errorf("unmarshal field can_write: %w", err)
+				}
+			}
+		case agentbase.FieldIsOwner:
+			if value, ok := values[i].(*[]byte); !ok {
+				return fmt.Errorf("unexpected type %T for field is_owner", values[i])
+			} else if value != nil && len(*value) > 0 {
+				if err := json.Unmarshal(*value, &ab.IsOwner); err != nil {
+					return fmt.Errorf("unmarshal field is_owner: %w", err)
+				}
+			}
+		default:
+			ab.selectValues.Set(columns[i], values[i])
+		}
+	}
+	return nil
+}
+
+// Value returns the ent.Value that was dynamically selected and assigned to the AgentBase.
+// This includes values selected through modifiers, order, etc.
+func (ab *AgentBase) Value(name string) (ent.Value, error) {
+	return ab.selectValues.Get(name)
+}
+
+// QueryWxAgent queries the "wx_agent" edge of the AgentBase entity.
+func (ab *AgentBase) QueryWxAgent() *WxQuery {
+	return NewAgentBaseClient(ab.config).QueryWxAgent(ab)
+}
+
+// Update returns a builder for updating this AgentBase.
+// Note that you need to call AgentBase.Unwrap() before calling this method if this AgentBase
+// was returned from a transaction, and the transaction was committed or rolled back.
+func (ab *AgentBase) Update() *AgentBaseUpdateOne {
+	return NewAgentBaseClient(ab.config).UpdateOne(ab)
+}
+
+// Unwrap unwraps the AgentBase entity that was returned from a transaction after it was closed,
+// so that all future queries will be executed through the driver which created the transaction.
+func (ab *AgentBase) Unwrap() *AgentBase {
+	_tx, ok := ab.config.driver.(*txDriver)
+	if !ok {
+		panic("ent: AgentBase is not a transactional entity")
+	}
+	ab.config.driver = _tx.drv
+	return ab
+}
+
+// String implements the fmt.Stringer.
+func (ab *AgentBase) String() string {
+	var builder strings.Builder
+	builder.WriteString("AgentBase(")
+	builder.WriteString(fmt.Sprintf("id=%v, ", ab.ID))
+	builder.WriteString("q=")
+	builder.WriteString(ab.Q)
+	builder.WriteString(", ")
+	builder.WriteString("a=")
+	builder.WriteString(ab.A)
+	builder.WriteString(", ")
+	builder.WriteString("chunk_index=")
+	builder.WriteString(fmt.Sprintf("%v", ab.ChunkIndex))
+	builder.WriteString(", ")
+	builder.WriteString("indexes=")
+	builder.WriteString(fmt.Sprintf("%v", ab.Indexes))
+	builder.WriteString(", ")
+	builder.WriteString("dataset_id=")
+	builder.WriteString(ab.DatasetID)
+	builder.WriteString(", ")
+	builder.WriteString("collection_id=")
+	builder.WriteString(ab.CollectionID)
+	builder.WriteString(", ")
+	builder.WriteString("source_name=")
+	builder.WriteString(ab.SourceName)
+	builder.WriteString(", ")
+	builder.WriteString("can_write=")
+	builder.WriteString(fmt.Sprintf("%v", ab.CanWrite))
+	builder.WriteString(", ")
+	builder.WriteString("is_owner=")
+	builder.WriteString(fmt.Sprintf("%v", ab.IsOwner))
+	builder.WriteByte(')')
+	return builder.String()
+}
+
+// AgentBases is a parsable slice of AgentBase.
+type AgentBases []*AgentBase

+ 142 - 0
ent/agentbase/agentbase.go

@@ -0,0 +1,142 @@
+// Code generated by ent, DO NOT EDIT.
+
+package agentbase
+
+import (
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+)
+
+const (
+	// Label holds the string label denoting the agentbase type in the database.
+	Label = "agent_base"
+	// FieldID holds the string denoting the id field in the database.
+	FieldID = "id"
+	// FieldQ holds the string denoting the q field in the database.
+	FieldQ = "q"
+	// FieldA holds the string denoting the a field in the database.
+	FieldA = "a"
+	// FieldChunkIndex holds the string denoting the chunk_index field in the database.
+	FieldChunkIndex = "chunk_index"
+	// FieldIndexes holds the string denoting the indexes field in the database.
+	FieldIndexes = "indexes"
+	// FieldDatasetID holds the string denoting the dataset_id field in the database.
+	FieldDatasetID = "dataset_id"
+	// FieldCollectionID holds the string denoting the collection_id field in the database.
+	FieldCollectionID = "collection_id"
+	// FieldSourceName holds the string denoting the source_name field in the database.
+	FieldSourceName = "source_name"
+	// FieldCanWrite holds the string denoting the can_write field in the database.
+	FieldCanWrite = "can_write"
+	// FieldIsOwner holds the string denoting the is_owner field in the database.
+	FieldIsOwner = "is_owner"
+	// EdgeWxAgent holds the string denoting the wx_agent edge name in mutations.
+	EdgeWxAgent = "wx_agent"
+	// Table holds the table name of the agentbase in the database.
+	Table = "agent_base"
+	// WxAgentTable is the table that holds the wx_agent relation/edge.
+	WxAgentTable = "wx"
+	// WxAgentInverseTable is the table name for the Wx entity.
+	// It exists in this package in order to avoid circular dependency with the "wx" package.
+	WxAgentInverseTable = "wx"
+	// WxAgentColumn is the table column denoting the wx_agent relation/edge.
+	WxAgentColumn = "agent_base_wx_agent"
+)
+
+// Columns holds all SQL columns for agentbase fields.
+var Columns = []string{
+	FieldID,
+	FieldQ,
+	FieldA,
+	FieldChunkIndex,
+	FieldIndexes,
+	FieldDatasetID,
+	FieldCollectionID,
+	FieldSourceName,
+	FieldCanWrite,
+	FieldIsOwner,
+}
+
+// ValidColumn reports if the column name is valid (part of the table columns).
+func ValidColumn(column string) bool {
+	for i := range Columns {
+		if column == Columns[i] {
+			return true
+		}
+	}
+	return false
+}
+
+var (
+	// DefaultQ holds the default value on creation for the "q" field.
+	DefaultQ string
+	// DefaultA holds the default value on creation for the "a" field.
+	DefaultA string
+	// ChunkIndexValidator is a validator for the "chunk_index" field. It is called by the builders before save.
+	ChunkIndexValidator func(uint64) error
+	// DefaultDatasetID holds the default value on creation for the "dataset_id" field.
+	DefaultDatasetID string
+	// DefaultCollectionID holds the default value on creation for the "collection_id" field.
+	DefaultCollectionID string
+	// DefaultSourceName holds the default value on creation for the "source_name" field.
+	DefaultSourceName string
+)
+
+// OrderOption defines the ordering options for the AgentBase queries.
+type OrderOption func(*sql.Selector)
+
+// ByID orders the results by the id field.
+func ByID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldID, opts...).ToFunc()
+}
+
+// ByQ orders the results by the q field.
+func ByQ(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldQ, opts...).ToFunc()
+}
+
+// ByA orders the results by the a field.
+func ByA(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldA, opts...).ToFunc()
+}
+
+// ByChunkIndex orders the results by the chunk_index field.
+func ByChunkIndex(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldChunkIndex, opts...).ToFunc()
+}
+
+// ByDatasetID orders the results by the dataset_id field.
+func ByDatasetID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldDatasetID, opts...).ToFunc()
+}
+
+// ByCollectionID orders the results by the collection_id field.
+func ByCollectionID(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldCollectionID, opts...).ToFunc()
+}
+
+// BySourceName orders the results by the source_name field.
+func BySourceName(opts ...sql.OrderTermOption) OrderOption {
+	return sql.OrderByField(FieldSourceName, opts...).ToFunc()
+}
+
+// ByWxAgentCount orders the results by wx_agent count.
+func ByWxAgentCount(opts ...sql.OrderTermOption) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborsCount(s, newWxAgentStep(), opts...)
+	}
+}
+
+// ByWxAgent orders the results by wx_agent terms.
+func ByWxAgent(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborTerms(s, newWxAgentStep(), append([]sql.OrderTerm{term}, terms...)...)
+	}
+}
+func newWxAgentStep() *sqlgraph.Step {
+	return sqlgraph.NewStep(
+		sqlgraph.From(Table, FieldID),
+		sqlgraph.To(WxAgentInverseTable, FieldID),
+		sqlgraph.Edge(sqlgraph.O2M, false, WxAgentTable, WxAgentColumn),
+	)
+}

+ 578 - 0
ent/agentbase/where.go

@@ -0,0 +1,578 @@
+// Code generated by ent, DO NOT EDIT.
+
+package agentbase
+
+import (
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+)
+
+// ID filters vertices based on their ID field.
+func ID(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldID, id))
+}
+
+// IDEQ applies the EQ predicate on the ID field.
+func IDEQ(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldID, id))
+}
+
+// IDNEQ applies the NEQ predicate on the ID field.
+func IDNEQ(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldID, id))
+}
+
+// IDIn applies the In predicate on the ID field.
+func IDIn(ids ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldID, ids...))
+}
+
+// IDNotIn applies the NotIn predicate on the ID field.
+func IDNotIn(ids ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldID, ids...))
+}
+
+// IDGT applies the GT predicate on the ID field.
+func IDGT(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldID, id))
+}
+
+// IDGTE applies the GTE predicate on the ID field.
+func IDGTE(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldID, id))
+}
+
+// IDLT applies the LT predicate on the ID field.
+func IDLT(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldID, id))
+}
+
+// IDLTE applies the LTE predicate on the ID field.
+func IDLTE(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldID, id))
+}
+
+// IDEqualFold applies the EqualFold predicate on the ID field.
+func IDEqualFold(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEqualFold(FieldID, id))
+}
+
+// IDContainsFold applies the ContainsFold predicate on the ID field.
+func IDContainsFold(id string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContainsFold(FieldID, id))
+}
+
+// Q applies equality check predicate on the "q" field. It's identical to QEQ.
+func Q(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldQ, v))
+}
+
+// A applies equality check predicate on the "a" field. It's identical to AEQ.
+func A(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldA, v))
+}
+
+// ChunkIndex applies equality check predicate on the "chunk_index" field. It's identical to ChunkIndexEQ.
+func ChunkIndex(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldChunkIndex, v))
+}
+
+// DatasetID applies equality check predicate on the "dataset_id" field. It's identical to DatasetIDEQ.
+func DatasetID(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldDatasetID, v))
+}
+
+// CollectionID applies equality check predicate on the "collection_id" field. It's identical to CollectionIDEQ.
+func CollectionID(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldCollectionID, v))
+}
+
+// SourceName applies equality check predicate on the "source_name" field. It's identical to SourceNameEQ.
+func SourceName(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldSourceName, v))
+}
+
+// QEQ applies the EQ predicate on the "q" field.
+func QEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldQ, v))
+}
+
+// QNEQ applies the NEQ predicate on the "q" field.
+func QNEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldQ, v))
+}
+
+// QIn applies the In predicate on the "q" field.
+func QIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldQ, vs...))
+}
+
+// QNotIn applies the NotIn predicate on the "q" field.
+func QNotIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldQ, vs...))
+}
+
+// QGT applies the GT predicate on the "q" field.
+func QGT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldQ, v))
+}
+
+// QGTE applies the GTE predicate on the "q" field.
+func QGTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldQ, v))
+}
+
+// QLT applies the LT predicate on the "q" field.
+func QLT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldQ, v))
+}
+
+// QLTE applies the LTE predicate on the "q" field.
+func QLTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldQ, v))
+}
+
+// QContains applies the Contains predicate on the "q" field.
+func QContains(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContains(FieldQ, v))
+}
+
+// QHasPrefix applies the HasPrefix predicate on the "q" field.
+func QHasPrefix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasPrefix(FieldQ, v))
+}
+
+// QHasSuffix applies the HasSuffix predicate on the "q" field.
+func QHasSuffix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasSuffix(FieldQ, v))
+}
+
+// QIsNil applies the IsNil predicate on the "q" field.
+func QIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldQ))
+}
+
+// QNotNil applies the NotNil predicate on the "q" field.
+func QNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldQ))
+}
+
+// QEqualFold applies the EqualFold predicate on the "q" field.
+func QEqualFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEqualFold(FieldQ, v))
+}
+
+// QContainsFold applies the ContainsFold predicate on the "q" field.
+func QContainsFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContainsFold(FieldQ, v))
+}
+
+// AEQ applies the EQ predicate on the "a" field.
+func AEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldA, v))
+}
+
+// ANEQ applies the NEQ predicate on the "a" field.
+func ANEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldA, v))
+}
+
+// AIn applies the In predicate on the "a" field.
+func AIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldA, vs...))
+}
+
+// ANotIn applies the NotIn predicate on the "a" field.
+func ANotIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldA, vs...))
+}
+
+// AGT applies the GT predicate on the "a" field.
+func AGT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldA, v))
+}
+
+// AGTE applies the GTE predicate on the "a" field.
+func AGTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldA, v))
+}
+
+// ALT applies the LT predicate on the "a" field.
+func ALT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldA, v))
+}
+
+// ALTE applies the LTE predicate on the "a" field.
+func ALTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldA, v))
+}
+
+// AContains applies the Contains predicate on the "a" field.
+func AContains(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContains(FieldA, v))
+}
+
+// AHasPrefix applies the HasPrefix predicate on the "a" field.
+func AHasPrefix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasPrefix(FieldA, v))
+}
+
+// AHasSuffix applies the HasSuffix predicate on the "a" field.
+func AHasSuffix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasSuffix(FieldA, v))
+}
+
+// AIsNil applies the IsNil predicate on the "a" field.
+func AIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldA))
+}
+
+// ANotNil applies the NotNil predicate on the "a" field.
+func ANotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldA))
+}
+
+// AEqualFold applies the EqualFold predicate on the "a" field.
+func AEqualFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEqualFold(FieldA, v))
+}
+
+// AContainsFold applies the ContainsFold predicate on the "a" field.
+func AContainsFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContainsFold(FieldA, v))
+}
+
+// ChunkIndexEQ applies the EQ predicate on the "chunk_index" field.
+func ChunkIndexEQ(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldChunkIndex, v))
+}
+
+// ChunkIndexNEQ applies the NEQ predicate on the "chunk_index" field.
+func ChunkIndexNEQ(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldChunkIndex, v))
+}
+
+// ChunkIndexIn applies the In predicate on the "chunk_index" field.
+func ChunkIndexIn(vs ...uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldChunkIndex, vs...))
+}
+
+// ChunkIndexNotIn applies the NotIn predicate on the "chunk_index" field.
+func ChunkIndexNotIn(vs ...uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldChunkIndex, vs...))
+}
+
+// ChunkIndexGT applies the GT predicate on the "chunk_index" field.
+func ChunkIndexGT(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldChunkIndex, v))
+}
+
+// ChunkIndexGTE applies the GTE predicate on the "chunk_index" field.
+func ChunkIndexGTE(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldChunkIndex, v))
+}
+
+// ChunkIndexLT applies the LT predicate on the "chunk_index" field.
+func ChunkIndexLT(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldChunkIndex, v))
+}
+
+// ChunkIndexLTE applies the LTE predicate on the "chunk_index" field.
+func ChunkIndexLTE(v uint64) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldChunkIndex, v))
+}
+
+// IndexesIsNil applies the IsNil predicate on the "indexes" field.
+func IndexesIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldIndexes))
+}
+
+// IndexesNotNil applies the NotNil predicate on the "indexes" field.
+func IndexesNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldIndexes))
+}
+
+// DatasetIDEQ applies the EQ predicate on the "dataset_id" field.
+func DatasetIDEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldDatasetID, v))
+}
+
+// DatasetIDNEQ applies the NEQ predicate on the "dataset_id" field.
+func DatasetIDNEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldDatasetID, v))
+}
+
+// DatasetIDIn applies the In predicate on the "dataset_id" field.
+func DatasetIDIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldDatasetID, vs...))
+}
+
+// DatasetIDNotIn applies the NotIn predicate on the "dataset_id" field.
+func DatasetIDNotIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldDatasetID, vs...))
+}
+
+// DatasetIDGT applies the GT predicate on the "dataset_id" field.
+func DatasetIDGT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldDatasetID, v))
+}
+
+// DatasetIDGTE applies the GTE predicate on the "dataset_id" field.
+func DatasetIDGTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldDatasetID, v))
+}
+
+// DatasetIDLT applies the LT predicate on the "dataset_id" field.
+func DatasetIDLT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldDatasetID, v))
+}
+
+// DatasetIDLTE applies the LTE predicate on the "dataset_id" field.
+func DatasetIDLTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldDatasetID, v))
+}
+
+// DatasetIDContains applies the Contains predicate on the "dataset_id" field.
+func DatasetIDContains(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContains(FieldDatasetID, v))
+}
+
+// DatasetIDHasPrefix applies the HasPrefix predicate on the "dataset_id" field.
+func DatasetIDHasPrefix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasPrefix(FieldDatasetID, v))
+}
+
+// DatasetIDHasSuffix applies the HasSuffix predicate on the "dataset_id" field.
+func DatasetIDHasSuffix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasSuffix(FieldDatasetID, v))
+}
+
+// DatasetIDIsNil applies the IsNil predicate on the "dataset_id" field.
+func DatasetIDIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldDatasetID))
+}
+
+// DatasetIDNotNil applies the NotNil predicate on the "dataset_id" field.
+func DatasetIDNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldDatasetID))
+}
+
+// DatasetIDEqualFold applies the EqualFold predicate on the "dataset_id" field.
+func DatasetIDEqualFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEqualFold(FieldDatasetID, v))
+}
+
+// DatasetIDContainsFold applies the ContainsFold predicate on the "dataset_id" field.
+func DatasetIDContainsFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContainsFold(FieldDatasetID, v))
+}
+
+// CollectionIDEQ applies the EQ predicate on the "collection_id" field.
+func CollectionIDEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldCollectionID, v))
+}
+
+// CollectionIDNEQ applies the NEQ predicate on the "collection_id" field.
+func CollectionIDNEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldCollectionID, v))
+}
+
+// CollectionIDIn applies the In predicate on the "collection_id" field.
+func CollectionIDIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldCollectionID, vs...))
+}
+
+// CollectionIDNotIn applies the NotIn predicate on the "collection_id" field.
+func CollectionIDNotIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldCollectionID, vs...))
+}
+
+// CollectionIDGT applies the GT predicate on the "collection_id" field.
+func CollectionIDGT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldCollectionID, v))
+}
+
+// CollectionIDGTE applies the GTE predicate on the "collection_id" field.
+func CollectionIDGTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldCollectionID, v))
+}
+
+// CollectionIDLT applies the LT predicate on the "collection_id" field.
+func CollectionIDLT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldCollectionID, v))
+}
+
+// CollectionIDLTE applies the LTE predicate on the "collection_id" field.
+func CollectionIDLTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldCollectionID, v))
+}
+
+// CollectionIDContains applies the Contains predicate on the "collection_id" field.
+func CollectionIDContains(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContains(FieldCollectionID, v))
+}
+
+// CollectionIDHasPrefix applies the HasPrefix predicate on the "collection_id" field.
+func CollectionIDHasPrefix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasPrefix(FieldCollectionID, v))
+}
+
+// CollectionIDHasSuffix applies the HasSuffix predicate on the "collection_id" field.
+func CollectionIDHasSuffix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasSuffix(FieldCollectionID, v))
+}
+
+// CollectionIDIsNil applies the IsNil predicate on the "collection_id" field.
+func CollectionIDIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldCollectionID))
+}
+
+// CollectionIDNotNil applies the NotNil predicate on the "collection_id" field.
+func CollectionIDNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldCollectionID))
+}
+
+// CollectionIDEqualFold applies the EqualFold predicate on the "collection_id" field.
+func CollectionIDEqualFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEqualFold(FieldCollectionID, v))
+}
+
+// CollectionIDContainsFold applies the ContainsFold predicate on the "collection_id" field.
+func CollectionIDContainsFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContainsFold(FieldCollectionID, v))
+}
+
+// SourceNameEQ applies the EQ predicate on the "source_name" field.
+func SourceNameEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEQ(FieldSourceName, v))
+}
+
+// SourceNameNEQ applies the NEQ predicate on the "source_name" field.
+func SourceNameNEQ(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNEQ(FieldSourceName, v))
+}
+
+// SourceNameIn applies the In predicate on the "source_name" field.
+func SourceNameIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIn(FieldSourceName, vs...))
+}
+
+// SourceNameNotIn applies the NotIn predicate on the "source_name" field.
+func SourceNameNotIn(vs ...string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotIn(FieldSourceName, vs...))
+}
+
+// SourceNameGT applies the GT predicate on the "source_name" field.
+func SourceNameGT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGT(FieldSourceName, v))
+}
+
+// SourceNameGTE applies the GTE predicate on the "source_name" field.
+func SourceNameGTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldGTE(FieldSourceName, v))
+}
+
+// SourceNameLT applies the LT predicate on the "source_name" field.
+func SourceNameLT(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLT(FieldSourceName, v))
+}
+
+// SourceNameLTE applies the LTE predicate on the "source_name" field.
+func SourceNameLTE(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldLTE(FieldSourceName, v))
+}
+
+// SourceNameContains applies the Contains predicate on the "source_name" field.
+func SourceNameContains(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContains(FieldSourceName, v))
+}
+
+// SourceNameHasPrefix applies the HasPrefix predicate on the "source_name" field.
+func SourceNameHasPrefix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasPrefix(FieldSourceName, v))
+}
+
+// SourceNameHasSuffix applies the HasSuffix predicate on the "source_name" field.
+func SourceNameHasSuffix(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldHasSuffix(FieldSourceName, v))
+}
+
+// SourceNameIsNil applies the IsNil predicate on the "source_name" field.
+func SourceNameIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldSourceName))
+}
+
+// SourceNameNotNil applies the NotNil predicate on the "source_name" field.
+func SourceNameNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldSourceName))
+}
+
+// SourceNameEqualFold applies the EqualFold predicate on the "source_name" field.
+func SourceNameEqualFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldEqualFold(FieldSourceName, v))
+}
+
+// SourceNameContainsFold applies the ContainsFold predicate on the "source_name" field.
+func SourceNameContainsFold(v string) predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldContainsFold(FieldSourceName, v))
+}
+
+// CanWriteIsNil applies the IsNil predicate on the "can_write" field.
+func CanWriteIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldCanWrite))
+}
+
+// CanWriteNotNil applies the NotNil predicate on the "can_write" field.
+func CanWriteNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldCanWrite))
+}
+
+// IsOwnerIsNil applies the IsNil predicate on the "is_owner" field.
+func IsOwnerIsNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldIsNull(FieldIsOwner))
+}
+
+// IsOwnerNotNil applies the NotNil predicate on the "is_owner" field.
+func IsOwnerNotNil() predicate.AgentBase {
+	return predicate.AgentBase(sql.FieldNotNull(FieldIsOwner))
+}
+
+// HasWxAgent applies the HasEdge predicate on the "wx_agent" edge.
+func HasWxAgent() predicate.AgentBase {
+	return predicate.AgentBase(func(s *sql.Selector) {
+		step := sqlgraph.NewStep(
+			sqlgraph.From(Table, FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, WxAgentTable, WxAgentColumn),
+		)
+		sqlgraph.HasNeighbors(s, step)
+	})
+}
+
+// HasWxAgentWith applies the HasEdge predicate on the "wx_agent" edge with a given conditions (other predicates).
+func HasWxAgentWith(preds ...predicate.Wx) predicate.AgentBase {
+	return predicate.AgentBase(func(s *sql.Selector) {
+		step := newWxAgentStep()
+		sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
+			for _, p := range preds {
+				p(s)
+			}
+		})
+	})
+}
+
+// And groups predicates with the AND operator between them.
+func And(predicates ...predicate.AgentBase) predicate.AgentBase {
+	return predicate.AgentBase(sql.AndPredicates(predicates...))
+}
+
+// Or groups predicates with the OR operator between them.
+func Or(predicates ...predicate.AgentBase) predicate.AgentBase {
+	return predicate.AgentBase(sql.OrPredicates(predicates...))
+}
+
+// Not applies the not operator on the given predicate.
+func Not(p predicate.AgentBase) predicate.AgentBase {
+	return predicate.AgentBase(sql.NotPredicates(p))
+}

+ 1172 - 0
ent/agentbase_create.go

@@ -0,0 +1,1172 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"wechat-api/ent/agentbase"
+	"wechat-api/ent/wx"
+
+	"entgo.io/ent/dialect"
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// AgentBaseCreate is the builder for creating a AgentBase entity.
+type AgentBaseCreate struct {
+	config
+	mutation *AgentBaseMutation
+	hooks    []Hook
+	conflict []sql.ConflictOption
+}
+
+// SetQ sets the "q" field.
+func (abc *AgentBaseCreate) SetQ(s string) *AgentBaseCreate {
+	abc.mutation.SetQ(s)
+	return abc
+}
+
+// SetNillableQ sets the "q" field if the given value is not nil.
+func (abc *AgentBaseCreate) SetNillableQ(s *string) *AgentBaseCreate {
+	if s != nil {
+		abc.SetQ(*s)
+	}
+	return abc
+}
+
+// SetA sets the "a" field.
+func (abc *AgentBaseCreate) SetA(s string) *AgentBaseCreate {
+	abc.mutation.SetA(s)
+	return abc
+}
+
+// SetNillableA sets the "a" field if the given value is not nil.
+func (abc *AgentBaseCreate) SetNillableA(s *string) *AgentBaseCreate {
+	if s != nil {
+		abc.SetA(*s)
+	}
+	return abc
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (abc *AgentBaseCreate) SetChunkIndex(u uint64) *AgentBaseCreate {
+	abc.mutation.SetChunkIndex(u)
+	return abc
+}
+
+// SetIndexes sets the "indexes" field.
+func (abc *AgentBaseCreate) SetIndexes(s []string) *AgentBaseCreate {
+	abc.mutation.SetIndexes(s)
+	return abc
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (abc *AgentBaseCreate) SetDatasetID(s string) *AgentBaseCreate {
+	abc.mutation.SetDatasetID(s)
+	return abc
+}
+
+// SetNillableDatasetID sets the "dataset_id" field if the given value is not nil.
+func (abc *AgentBaseCreate) SetNillableDatasetID(s *string) *AgentBaseCreate {
+	if s != nil {
+		abc.SetDatasetID(*s)
+	}
+	return abc
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (abc *AgentBaseCreate) SetCollectionID(s string) *AgentBaseCreate {
+	abc.mutation.SetCollectionID(s)
+	return abc
+}
+
+// SetNillableCollectionID sets the "collection_id" field if the given value is not nil.
+func (abc *AgentBaseCreate) SetNillableCollectionID(s *string) *AgentBaseCreate {
+	if s != nil {
+		abc.SetCollectionID(*s)
+	}
+	return abc
+}
+
+// SetSourceName sets the "source_name" field.
+func (abc *AgentBaseCreate) SetSourceName(s string) *AgentBaseCreate {
+	abc.mutation.SetSourceName(s)
+	return abc
+}
+
+// SetNillableSourceName sets the "source_name" field if the given value is not nil.
+func (abc *AgentBaseCreate) SetNillableSourceName(s *string) *AgentBaseCreate {
+	if s != nil {
+		abc.SetSourceName(*s)
+	}
+	return abc
+}
+
+// SetCanWrite sets the "can_write" field.
+func (abc *AgentBaseCreate) SetCanWrite(b []bool) *AgentBaseCreate {
+	abc.mutation.SetCanWrite(b)
+	return abc
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (abc *AgentBaseCreate) SetIsOwner(b []bool) *AgentBaseCreate {
+	abc.mutation.SetIsOwner(b)
+	return abc
+}
+
+// SetID sets the "id" field.
+func (abc *AgentBaseCreate) SetID(s string) *AgentBaseCreate {
+	abc.mutation.SetID(s)
+	return abc
+}
+
+// AddWxAgentIDs adds the "wx_agent" edge to the Wx entity by IDs.
+func (abc *AgentBaseCreate) AddWxAgentIDs(ids ...uint64) *AgentBaseCreate {
+	abc.mutation.AddWxAgentIDs(ids...)
+	return abc
+}
+
+// AddWxAgent adds the "wx_agent" edges to the Wx entity.
+func (abc *AgentBaseCreate) AddWxAgent(w ...*Wx) *AgentBaseCreate {
+	ids := make([]uint64, len(w))
+	for i := range w {
+		ids[i] = w[i].ID
+	}
+	return abc.AddWxAgentIDs(ids...)
+}
+
+// Mutation returns the AgentBaseMutation object of the builder.
+func (abc *AgentBaseCreate) Mutation() *AgentBaseMutation {
+	return abc.mutation
+}
+
+// Save creates the AgentBase in the database.
+func (abc *AgentBaseCreate) Save(ctx context.Context) (*AgentBase, error) {
+	abc.defaults()
+	return withHooks(ctx, abc.sqlSave, abc.mutation, abc.hooks)
+}
+
+// SaveX calls Save and panics if Save returns an error.
+func (abc *AgentBaseCreate) SaveX(ctx context.Context) *AgentBase {
+	v, err := abc.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (abc *AgentBaseCreate) Exec(ctx context.Context) error {
+	_, err := abc.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (abc *AgentBaseCreate) ExecX(ctx context.Context) {
+	if err := abc.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// defaults sets the default values of the builder before save.
+func (abc *AgentBaseCreate) defaults() {
+	if _, ok := abc.mutation.Q(); !ok {
+		v := agentbase.DefaultQ
+		abc.mutation.SetQ(v)
+	}
+	if _, ok := abc.mutation.A(); !ok {
+		v := agentbase.DefaultA
+		abc.mutation.SetA(v)
+	}
+	if _, ok := abc.mutation.DatasetID(); !ok {
+		v := agentbase.DefaultDatasetID
+		abc.mutation.SetDatasetID(v)
+	}
+	if _, ok := abc.mutation.CollectionID(); !ok {
+		v := agentbase.DefaultCollectionID
+		abc.mutation.SetCollectionID(v)
+	}
+	if _, ok := abc.mutation.SourceName(); !ok {
+		v := agentbase.DefaultSourceName
+		abc.mutation.SetSourceName(v)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (abc *AgentBaseCreate) check() error {
+	if _, ok := abc.mutation.ChunkIndex(); !ok {
+		return &ValidationError{Name: "chunk_index", err: errors.New(`ent: missing required field "AgentBase.chunk_index"`)}
+	}
+	if v, ok := abc.mutation.ChunkIndex(); ok {
+		if err := agentbase.ChunkIndexValidator(v); err != nil {
+			return &ValidationError{Name: "chunk_index", err: fmt.Errorf(`ent: validator failed for field "AgentBase.chunk_index": %w`, err)}
+		}
+	}
+	return nil
+}
+
+func (abc *AgentBaseCreate) sqlSave(ctx context.Context) (*AgentBase, error) {
+	if err := abc.check(); err != nil {
+		return nil, err
+	}
+	_node, _spec := abc.createSpec()
+	if err := sqlgraph.CreateNode(ctx, abc.driver, _spec); err != nil {
+		if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	if _spec.ID.Value != nil {
+		if id, ok := _spec.ID.Value.(string); ok {
+			_node.ID = id
+		} else {
+			return nil, fmt.Errorf("unexpected AgentBase.ID type: %T", _spec.ID.Value)
+		}
+	}
+	abc.mutation.id = &_node.ID
+	abc.mutation.done = true
+	return _node, nil
+}
+
+func (abc *AgentBaseCreate) createSpec() (*AgentBase, *sqlgraph.CreateSpec) {
+	var (
+		_node = &AgentBase{config: abc.config}
+		_spec = sqlgraph.NewCreateSpec(agentbase.Table, sqlgraph.NewFieldSpec(agentbase.FieldID, field.TypeString))
+	)
+	_spec.OnConflict = abc.conflict
+	if id, ok := abc.mutation.ID(); ok {
+		_node.ID = id
+		_spec.ID.Value = id
+	}
+	if value, ok := abc.mutation.Q(); ok {
+		_spec.SetField(agentbase.FieldQ, field.TypeString, value)
+		_node.Q = value
+	}
+	if value, ok := abc.mutation.A(); ok {
+		_spec.SetField(agentbase.FieldA, field.TypeString, value)
+		_node.A = value
+	}
+	if value, ok := abc.mutation.ChunkIndex(); ok {
+		_spec.SetField(agentbase.FieldChunkIndex, field.TypeUint64, value)
+		_node.ChunkIndex = value
+	}
+	if value, ok := abc.mutation.Indexes(); ok {
+		_spec.SetField(agentbase.FieldIndexes, field.TypeJSON, value)
+		_node.Indexes = value
+	}
+	if value, ok := abc.mutation.DatasetID(); ok {
+		_spec.SetField(agentbase.FieldDatasetID, field.TypeString, value)
+		_node.DatasetID = value
+	}
+	if value, ok := abc.mutation.CollectionID(); ok {
+		_spec.SetField(agentbase.FieldCollectionID, field.TypeString, value)
+		_node.CollectionID = value
+	}
+	if value, ok := abc.mutation.SourceName(); ok {
+		_spec.SetField(agentbase.FieldSourceName, field.TypeString, value)
+		_node.SourceName = value
+	}
+	if value, ok := abc.mutation.CanWrite(); ok {
+		_spec.SetField(agentbase.FieldCanWrite, field.TypeJSON, value)
+		_node.CanWrite = value
+	}
+	if value, ok := abc.mutation.IsOwner(); ok {
+		_spec.SetField(agentbase.FieldIsOwner, field.TypeJSON, value)
+		_node.IsOwner = value
+	}
+	if nodes := abc.mutation.WxAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges = append(_spec.Edges, edge)
+	}
+	return _node, _spec
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.AgentBase.Create().
+//		SetQ(v).
+//		OnConflict(
+//			// Update the row with the new values
+//			// the was proposed for insertion.
+//			sql.ResolveWithNewValues(),
+//		).
+//		// Override some of the fields with custom
+//		// update values.
+//		Update(func(u *ent.AgentBaseUpsert) {
+//			SetQ(v+v).
+//		}).
+//		Exec(ctx)
+func (abc *AgentBaseCreate) OnConflict(opts ...sql.ConflictOption) *AgentBaseUpsertOne {
+	abc.conflict = opts
+	return &AgentBaseUpsertOne{
+		create: abc,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.AgentBase.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (abc *AgentBaseCreate) OnConflictColumns(columns ...string) *AgentBaseUpsertOne {
+	abc.conflict = append(abc.conflict, sql.ConflictColumns(columns...))
+	return &AgentBaseUpsertOne{
+		create: abc,
+	}
+}
+
+type (
+	// AgentBaseUpsertOne is the builder for "upsert"-ing
+	//  one AgentBase node.
+	AgentBaseUpsertOne struct {
+		create *AgentBaseCreate
+	}
+
+	// AgentBaseUpsert is the "OnConflict" setter.
+	AgentBaseUpsert struct {
+		*sql.UpdateSet
+	}
+)
+
+// SetQ sets the "q" field.
+func (u *AgentBaseUpsert) SetQ(v string) *AgentBaseUpsert {
+	u.Set(agentbase.FieldQ, v)
+	return u
+}
+
+// UpdateQ sets the "q" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateQ() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldQ)
+	return u
+}
+
+// ClearQ clears the value of the "q" field.
+func (u *AgentBaseUpsert) ClearQ() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldQ)
+	return u
+}
+
+// SetA sets the "a" field.
+func (u *AgentBaseUpsert) SetA(v string) *AgentBaseUpsert {
+	u.Set(agentbase.FieldA, v)
+	return u
+}
+
+// UpdateA sets the "a" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateA() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldA)
+	return u
+}
+
+// ClearA clears the value of the "a" field.
+func (u *AgentBaseUpsert) ClearA() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldA)
+	return u
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (u *AgentBaseUpsert) SetChunkIndex(v uint64) *AgentBaseUpsert {
+	u.Set(agentbase.FieldChunkIndex, v)
+	return u
+}
+
+// UpdateChunkIndex sets the "chunk_index" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateChunkIndex() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldChunkIndex)
+	return u
+}
+
+// AddChunkIndex adds v to the "chunk_index" field.
+func (u *AgentBaseUpsert) AddChunkIndex(v uint64) *AgentBaseUpsert {
+	u.Add(agentbase.FieldChunkIndex, v)
+	return u
+}
+
+// SetIndexes sets the "indexes" field.
+func (u *AgentBaseUpsert) SetIndexes(v []string) *AgentBaseUpsert {
+	u.Set(agentbase.FieldIndexes, v)
+	return u
+}
+
+// UpdateIndexes sets the "indexes" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateIndexes() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldIndexes)
+	return u
+}
+
+// ClearIndexes clears the value of the "indexes" field.
+func (u *AgentBaseUpsert) ClearIndexes() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldIndexes)
+	return u
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (u *AgentBaseUpsert) SetDatasetID(v string) *AgentBaseUpsert {
+	u.Set(agentbase.FieldDatasetID, v)
+	return u
+}
+
+// UpdateDatasetID sets the "dataset_id" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateDatasetID() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldDatasetID)
+	return u
+}
+
+// ClearDatasetID clears the value of the "dataset_id" field.
+func (u *AgentBaseUpsert) ClearDatasetID() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldDatasetID)
+	return u
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (u *AgentBaseUpsert) SetCollectionID(v string) *AgentBaseUpsert {
+	u.Set(agentbase.FieldCollectionID, v)
+	return u
+}
+
+// UpdateCollectionID sets the "collection_id" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateCollectionID() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldCollectionID)
+	return u
+}
+
+// ClearCollectionID clears the value of the "collection_id" field.
+func (u *AgentBaseUpsert) ClearCollectionID() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldCollectionID)
+	return u
+}
+
+// SetSourceName sets the "source_name" field.
+func (u *AgentBaseUpsert) SetSourceName(v string) *AgentBaseUpsert {
+	u.Set(agentbase.FieldSourceName, v)
+	return u
+}
+
+// UpdateSourceName sets the "source_name" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateSourceName() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldSourceName)
+	return u
+}
+
+// ClearSourceName clears the value of the "source_name" field.
+func (u *AgentBaseUpsert) ClearSourceName() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldSourceName)
+	return u
+}
+
+// SetCanWrite sets the "can_write" field.
+func (u *AgentBaseUpsert) SetCanWrite(v []bool) *AgentBaseUpsert {
+	u.Set(agentbase.FieldCanWrite, v)
+	return u
+}
+
+// UpdateCanWrite sets the "can_write" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateCanWrite() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldCanWrite)
+	return u
+}
+
+// ClearCanWrite clears the value of the "can_write" field.
+func (u *AgentBaseUpsert) ClearCanWrite() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldCanWrite)
+	return u
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (u *AgentBaseUpsert) SetIsOwner(v []bool) *AgentBaseUpsert {
+	u.Set(agentbase.FieldIsOwner, v)
+	return u
+}
+
+// UpdateIsOwner sets the "is_owner" field to the value that was provided on create.
+func (u *AgentBaseUpsert) UpdateIsOwner() *AgentBaseUpsert {
+	u.SetExcluded(agentbase.FieldIsOwner)
+	return u
+}
+
+// ClearIsOwner clears the value of the "is_owner" field.
+func (u *AgentBaseUpsert) ClearIsOwner() *AgentBaseUpsert {
+	u.SetNull(agentbase.FieldIsOwner)
+	return u
+}
+
+// UpdateNewValues updates the mutable fields using the new values that were set on create except the ID field.
+// Using this option is equivalent to using:
+//
+//	client.AgentBase.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(agentbase.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *AgentBaseUpsertOne) UpdateNewValues() *AgentBaseUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
+		if _, exists := u.create.mutation.ID(); exists {
+			s.SetIgnore(agentbase.FieldID)
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.AgentBase.Create().
+//	    OnConflict(sql.ResolveWithIgnore()).
+//	    Exec(ctx)
+func (u *AgentBaseUpsertOne) Ignore() *AgentBaseUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
+	return u
+}
+
+// DoNothing configures the conflict_action to `DO NOTHING`.
+// Supported only by SQLite and PostgreSQL.
+func (u *AgentBaseUpsertOne) DoNothing() *AgentBaseUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the AgentBaseCreate.OnConflict
+// documentation for more info.
+func (u *AgentBaseUpsertOne) Update(set func(*AgentBaseUpsert)) *AgentBaseUpsertOne {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&AgentBaseUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetQ sets the "q" field.
+func (u *AgentBaseUpsertOne) SetQ(v string) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetQ(v)
+	})
+}
+
+// UpdateQ sets the "q" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateQ() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateQ()
+	})
+}
+
+// ClearQ clears the value of the "q" field.
+func (u *AgentBaseUpsertOne) ClearQ() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearQ()
+	})
+}
+
+// SetA sets the "a" field.
+func (u *AgentBaseUpsertOne) SetA(v string) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetA(v)
+	})
+}
+
+// UpdateA sets the "a" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateA() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateA()
+	})
+}
+
+// ClearA clears the value of the "a" field.
+func (u *AgentBaseUpsertOne) ClearA() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearA()
+	})
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (u *AgentBaseUpsertOne) SetChunkIndex(v uint64) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetChunkIndex(v)
+	})
+}
+
+// AddChunkIndex adds v to the "chunk_index" field.
+func (u *AgentBaseUpsertOne) AddChunkIndex(v uint64) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.AddChunkIndex(v)
+	})
+}
+
+// UpdateChunkIndex sets the "chunk_index" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateChunkIndex() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateChunkIndex()
+	})
+}
+
+// SetIndexes sets the "indexes" field.
+func (u *AgentBaseUpsertOne) SetIndexes(v []string) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetIndexes(v)
+	})
+}
+
+// UpdateIndexes sets the "indexes" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateIndexes() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateIndexes()
+	})
+}
+
+// ClearIndexes clears the value of the "indexes" field.
+func (u *AgentBaseUpsertOne) ClearIndexes() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearIndexes()
+	})
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (u *AgentBaseUpsertOne) SetDatasetID(v string) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetDatasetID(v)
+	})
+}
+
+// UpdateDatasetID sets the "dataset_id" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateDatasetID() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateDatasetID()
+	})
+}
+
+// ClearDatasetID clears the value of the "dataset_id" field.
+func (u *AgentBaseUpsertOne) ClearDatasetID() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearDatasetID()
+	})
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (u *AgentBaseUpsertOne) SetCollectionID(v string) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetCollectionID(v)
+	})
+}
+
+// UpdateCollectionID sets the "collection_id" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateCollectionID() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateCollectionID()
+	})
+}
+
+// ClearCollectionID clears the value of the "collection_id" field.
+func (u *AgentBaseUpsertOne) ClearCollectionID() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearCollectionID()
+	})
+}
+
+// SetSourceName sets the "source_name" field.
+func (u *AgentBaseUpsertOne) SetSourceName(v string) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetSourceName(v)
+	})
+}
+
+// UpdateSourceName sets the "source_name" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateSourceName() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateSourceName()
+	})
+}
+
+// ClearSourceName clears the value of the "source_name" field.
+func (u *AgentBaseUpsertOne) ClearSourceName() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearSourceName()
+	})
+}
+
+// SetCanWrite sets the "can_write" field.
+func (u *AgentBaseUpsertOne) SetCanWrite(v []bool) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetCanWrite(v)
+	})
+}
+
+// UpdateCanWrite sets the "can_write" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateCanWrite() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateCanWrite()
+	})
+}
+
+// ClearCanWrite clears the value of the "can_write" field.
+func (u *AgentBaseUpsertOne) ClearCanWrite() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearCanWrite()
+	})
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (u *AgentBaseUpsertOne) SetIsOwner(v []bool) *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetIsOwner(v)
+	})
+}
+
+// UpdateIsOwner sets the "is_owner" field to the value that was provided on create.
+func (u *AgentBaseUpsertOne) UpdateIsOwner() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateIsOwner()
+	})
+}
+
+// ClearIsOwner clears the value of the "is_owner" field.
+func (u *AgentBaseUpsertOne) ClearIsOwner() *AgentBaseUpsertOne {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearIsOwner()
+	})
+}
+
+// Exec executes the query.
+func (u *AgentBaseUpsertOne) Exec(ctx context.Context) error {
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for AgentBaseCreate.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *AgentBaseUpsertOne) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// Exec executes the UPSERT query and returns the inserted/updated ID.
+func (u *AgentBaseUpsertOne) ID(ctx context.Context) (id string, err error) {
+	if u.create.driver.Dialect() == dialect.MySQL {
+		// In case of "ON CONFLICT", there is no way to get back non-numeric ID
+		// fields from the database since MySQL does not support the RETURNING clause.
+		return id, errors.New("ent: AgentBaseUpsertOne.ID is not supported by MySQL driver. Use AgentBaseUpsertOne.Exec instead")
+	}
+	node, err := u.create.Save(ctx)
+	if err != nil {
+		return id, err
+	}
+	return node.ID, nil
+}
+
+// IDX is like ID, but panics if an error occurs.
+func (u *AgentBaseUpsertOne) IDX(ctx context.Context) string {
+	id, err := u.ID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// AgentBaseCreateBulk is the builder for creating many AgentBase entities in bulk.
+type AgentBaseCreateBulk struct {
+	config
+	err      error
+	builders []*AgentBaseCreate
+	conflict []sql.ConflictOption
+}
+
+// Save creates the AgentBase entities in the database.
+func (abcb *AgentBaseCreateBulk) Save(ctx context.Context) ([]*AgentBase, error) {
+	if abcb.err != nil {
+		return nil, abcb.err
+	}
+	specs := make([]*sqlgraph.CreateSpec, len(abcb.builders))
+	nodes := make([]*AgentBase, len(abcb.builders))
+	mutators := make([]Mutator, len(abcb.builders))
+	for i := range abcb.builders {
+		func(i int, root context.Context) {
+			builder := abcb.builders[i]
+			builder.defaults()
+			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
+				mutation, ok := m.(*AgentBaseMutation)
+				if !ok {
+					return nil, fmt.Errorf("unexpected mutation type %T", m)
+				}
+				if err := builder.check(); err != nil {
+					return nil, err
+				}
+				builder.mutation = mutation
+				var err error
+				nodes[i], specs[i] = builder.createSpec()
+				if i < len(mutators)-1 {
+					_, err = mutators[i+1].Mutate(root, abcb.builders[i+1].mutation)
+				} else {
+					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
+					spec.OnConflict = abcb.conflict
+					// Invoke the actual operation on the latest mutation in the chain.
+					if err = sqlgraph.BatchCreate(ctx, abcb.driver, spec); err != nil {
+						if sqlgraph.IsConstraintError(err) {
+							err = &ConstraintError{msg: err.Error(), wrap: err}
+						}
+					}
+				}
+				if err != nil {
+					return nil, err
+				}
+				mutation.id = &nodes[i].ID
+				mutation.done = true
+				return nodes[i], nil
+			})
+			for i := len(builder.hooks) - 1; i >= 0; i-- {
+				mut = builder.hooks[i](mut)
+			}
+			mutators[i] = mut
+		}(i, ctx)
+	}
+	if len(mutators) > 0 {
+		if _, err := mutators[0].Mutate(ctx, abcb.builders[0].mutation); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (abcb *AgentBaseCreateBulk) SaveX(ctx context.Context) []*AgentBase {
+	v, err := abcb.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return v
+}
+
+// Exec executes the query.
+func (abcb *AgentBaseCreateBulk) Exec(ctx context.Context) error {
+	_, err := abcb.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (abcb *AgentBaseCreateBulk) ExecX(ctx context.Context) {
+	if err := abcb.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
+// of the `INSERT` statement. For example:
+//
+//	client.AgentBase.CreateBulk(builders...).
+//		OnConflict(
+//			// Update the row with the new values
+//			// the was proposed for insertion.
+//			sql.ResolveWithNewValues(),
+//		).
+//		// Override some of the fields with custom
+//		// update values.
+//		Update(func(u *ent.AgentBaseUpsert) {
+//			SetQ(v+v).
+//		}).
+//		Exec(ctx)
+func (abcb *AgentBaseCreateBulk) OnConflict(opts ...sql.ConflictOption) *AgentBaseUpsertBulk {
+	abcb.conflict = opts
+	return &AgentBaseUpsertBulk{
+		create: abcb,
+	}
+}
+
+// OnConflictColumns calls `OnConflict` and configures the columns
+// as conflict target. Using this option is equivalent to using:
+//
+//	client.AgentBase.Create().
+//		OnConflict(sql.ConflictColumns(columns...)).
+//		Exec(ctx)
+func (abcb *AgentBaseCreateBulk) OnConflictColumns(columns ...string) *AgentBaseUpsertBulk {
+	abcb.conflict = append(abcb.conflict, sql.ConflictColumns(columns...))
+	return &AgentBaseUpsertBulk{
+		create: abcb,
+	}
+}
+
+// AgentBaseUpsertBulk is the builder for "upsert"-ing
+// a bulk of AgentBase nodes.
+type AgentBaseUpsertBulk struct {
+	create *AgentBaseCreateBulk
+}
+
+// UpdateNewValues updates the mutable fields using the new values that
+// were set on create. Using this option is equivalent to using:
+//
+//	client.AgentBase.Create().
+//		OnConflict(
+//			sql.ResolveWithNewValues(),
+//			sql.ResolveWith(func(u *sql.UpdateSet) {
+//				u.SetIgnore(agentbase.FieldID)
+//			}),
+//		).
+//		Exec(ctx)
+func (u *AgentBaseUpsertBulk) UpdateNewValues() *AgentBaseUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
+		for _, b := range u.create.builders {
+			if _, exists := b.mutation.ID(); exists {
+				s.SetIgnore(agentbase.FieldID)
+			}
+		}
+	}))
+	return u
+}
+
+// Ignore sets each column to itself in case of conflict.
+// Using this option is equivalent to using:
+//
+//	client.AgentBase.Create().
+//		OnConflict(sql.ResolveWithIgnore()).
+//		Exec(ctx)
+func (u *AgentBaseUpsertBulk) Ignore() *AgentBaseUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
+	return u
+}
+
+// DoNothing configures the conflict_action to `DO NOTHING`.
+// Supported only by SQLite and PostgreSQL.
+func (u *AgentBaseUpsertBulk) DoNothing() *AgentBaseUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.DoNothing())
+	return u
+}
+
+// Update allows overriding fields `UPDATE` values. See the AgentBaseCreateBulk.OnConflict
+// documentation for more info.
+func (u *AgentBaseUpsertBulk) Update(set func(*AgentBaseUpsert)) *AgentBaseUpsertBulk {
+	u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
+		set(&AgentBaseUpsert{UpdateSet: update})
+	}))
+	return u
+}
+
+// SetQ sets the "q" field.
+func (u *AgentBaseUpsertBulk) SetQ(v string) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetQ(v)
+	})
+}
+
+// UpdateQ sets the "q" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateQ() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateQ()
+	})
+}
+
+// ClearQ clears the value of the "q" field.
+func (u *AgentBaseUpsertBulk) ClearQ() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearQ()
+	})
+}
+
+// SetA sets the "a" field.
+func (u *AgentBaseUpsertBulk) SetA(v string) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetA(v)
+	})
+}
+
+// UpdateA sets the "a" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateA() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateA()
+	})
+}
+
+// ClearA clears the value of the "a" field.
+func (u *AgentBaseUpsertBulk) ClearA() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearA()
+	})
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (u *AgentBaseUpsertBulk) SetChunkIndex(v uint64) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetChunkIndex(v)
+	})
+}
+
+// AddChunkIndex adds v to the "chunk_index" field.
+func (u *AgentBaseUpsertBulk) AddChunkIndex(v uint64) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.AddChunkIndex(v)
+	})
+}
+
+// UpdateChunkIndex sets the "chunk_index" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateChunkIndex() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateChunkIndex()
+	})
+}
+
+// SetIndexes sets the "indexes" field.
+func (u *AgentBaseUpsertBulk) SetIndexes(v []string) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetIndexes(v)
+	})
+}
+
+// UpdateIndexes sets the "indexes" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateIndexes() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateIndexes()
+	})
+}
+
+// ClearIndexes clears the value of the "indexes" field.
+func (u *AgentBaseUpsertBulk) ClearIndexes() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearIndexes()
+	})
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (u *AgentBaseUpsertBulk) SetDatasetID(v string) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetDatasetID(v)
+	})
+}
+
+// UpdateDatasetID sets the "dataset_id" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateDatasetID() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateDatasetID()
+	})
+}
+
+// ClearDatasetID clears the value of the "dataset_id" field.
+func (u *AgentBaseUpsertBulk) ClearDatasetID() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearDatasetID()
+	})
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (u *AgentBaseUpsertBulk) SetCollectionID(v string) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetCollectionID(v)
+	})
+}
+
+// UpdateCollectionID sets the "collection_id" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateCollectionID() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateCollectionID()
+	})
+}
+
+// ClearCollectionID clears the value of the "collection_id" field.
+func (u *AgentBaseUpsertBulk) ClearCollectionID() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearCollectionID()
+	})
+}
+
+// SetSourceName sets the "source_name" field.
+func (u *AgentBaseUpsertBulk) SetSourceName(v string) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetSourceName(v)
+	})
+}
+
+// UpdateSourceName sets the "source_name" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateSourceName() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateSourceName()
+	})
+}
+
+// ClearSourceName clears the value of the "source_name" field.
+func (u *AgentBaseUpsertBulk) ClearSourceName() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearSourceName()
+	})
+}
+
+// SetCanWrite sets the "can_write" field.
+func (u *AgentBaseUpsertBulk) SetCanWrite(v []bool) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetCanWrite(v)
+	})
+}
+
+// UpdateCanWrite sets the "can_write" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateCanWrite() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateCanWrite()
+	})
+}
+
+// ClearCanWrite clears the value of the "can_write" field.
+func (u *AgentBaseUpsertBulk) ClearCanWrite() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearCanWrite()
+	})
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (u *AgentBaseUpsertBulk) SetIsOwner(v []bool) *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.SetIsOwner(v)
+	})
+}
+
+// UpdateIsOwner sets the "is_owner" field to the value that was provided on create.
+func (u *AgentBaseUpsertBulk) UpdateIsOwner() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.UpdateIsOwner()
+	})
+}
+
+// ClearIsOwner clears the value of the "is_owner" field.
+func (u *AgentBaseUpsertBulk) ClearIsOwner() *AgentBaseUpsertBulk {
+	return u.Update(func(s *AgentBaseUpsert) {
+		s.ClearIsOwner()
+	})
+}
+
+// Exec executes the query.
+func (u *AgentBaseUpsertBulk) Exec(ctx context.Context) error {
+	if u.create.err != nil {
+		return u.create.err
+	}
+	for i, b := range u.create.builders {
+		if len(b.conflict) != 0 {
+			return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the AgentBaseCreateBulk instead", i)
+		}
+	}
+	if len(u.create.conflict) == 0 {
+		return errors.New("ent: missing options for AgentBaseCreateBulk.OnConflict")
+	}
+	return u.create.Exec(ctx)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (u *AgentBaseUpsertBulk) ExecX(ctx context.Context) {
+	if err := u.create.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 88 - 0
ent/agentbase_delete.go

@@ -0,0 +1,88 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"wechat-api/ent/agentbase"
+	"wechat-api/ent/predicate"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// AgentBaseDelete is the builder for deleting a AgentBase entity.
+type AgentBaseDelete struct {
+	config
+	hooks    []Hook
+	mutation *AgentBaseMutation
+}
+
+// Where appends a list predicates to the AgentBaseDelete builder.
+func (abd *AgentBaseDelete) Where(ps ...predicate.AgentBase) *AgentBaseDelete {
+	abd.mutation.Where(ps...)
+	return abd
+}
+
+// Exec executes the deletion query and returns how many vertices were deleted.
+func (abd *AgentBaseDelete) Exec(ctx context.Context) (int, error) {
+	return withHooks(ctx, abd.sqlExec, abd.mutation, abd.hooks)
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (abd *AgentBaseDelete) ExecX(ctx context.Context) int {
+	n, err := abd.Exec(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return n
+}
+
+func (abd *AgentBaseDelete) sqlExec(ctx context.Context) (int, error) {
+	_spec := sqlgraph.NewDeleteSpec(agentbase.Table, sqlgraph.NewFieldSpec(agentbase.FieldID, field.TypeString))
+	if ps := abd.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	affected, err := sqlgraph.DeleteNodes(ctx, abd.driver, _spec)
+	if err != nil && sqlgraph.IsConstraintError(err) {
+		err = &ConstraintError{msg: err.Error(), wrap: err}
+	}
+	abd.mutation.done = true
+	return affected, err
+}
+
+// AgentBaseDeleteOne is the builder for deleting a single AgentBase entity.
+type AgentBaseDeleteOne struct {
+	abd *AgentBaseDelete
+}
+
+// Where appends a list predicates to the AgentBaseDelete builder.
+func (abdo *AgentBaseDeleteOne) Where(ps ...predicate.AgentBase) *AgentBaseDeleteOne {
+	abdo.abd.mutation.Where(ps...)
+	return abdo
+}
+
+// Exec executes the deletion query.
+func (abdo *AgentBaseDeleteOne) Exec(ctx context.Context) error {
+	n, err := abdo.abd.Exec(ctx)
+	switch {
+	case err != nil:
+		return err
+	case n == 0:
+		return &NotFoundError{agentbase.Label}
+	default:
+		return nil
+	}
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (abdo *AgentBaseDeleteOne) ExecX(ctx context.Context) {
+	if err := abdo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}

+ 606 - 0
ent/agentbase_query.go

@@ -0,0 +1,606 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"database/sql/driver"
+	"fmt"
+	"math"
+	"wechat-api/ent/agentbase"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/wx"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/schema/field"
+)
+
+// AgentBaseQuery is the builder for querying AgentBase entities.
+type AgentBaseQuery struct {
+	config
+	ctx         *QueryContext
+	order       []agentbase.OrderOption
+	inters      []Interceptor
+	predicates  []predicate.AgentBase
+	withWxAgent *WxQuery
+	// intermediate query (i.e. traversal path).
+	sql  *sql.Selector
+	path func(context.Context) (*sql.Selector, error)
+}
+
+// Where adds a new predicate for the AgentBaseQuery builder.
+func (abq *AgentBaseQuery) Where(ps ...predicate.AgentBase) *AgentBaseQuery {
+	abq.predicates = append(abq.predicates, ps...)
+	return abq
+}
+
+// Limit the number of records to be returned by this query.
+func (abq *AgentBaseQuery) Limit(limit int) *AgentBaseQuery {
+	abq.ctx.Limit = &limit
+	return abq
+}
+
+// Offset to start from.
+func (abq *AgentBaseQuery) Offset(offset int) *AgentBaseQuery {
+	abq.ctx.Offset = &offset
+	return abq
+}
+
+// Unique configures the query builder to filter duplicate records on query.
+// By default, unique is set to true, and can be disabled using this method.
+func (abq *AgentBaseQuery) Unique(unique bool) *AgentBaseQuery {
+	abq.ctx.Unique = &unique
+	return abq
+}
+
+// Order specifies how the records should be ordered.
+func (abq *AgentBaseQuery) Order(o ...agentbase.OrderOption) *AgentBaseQuery {
+	abq.order = append(abq.order, o...)
+	return abq
+}
+
+// QueryWxAgent chains the current query on the "wx_agent" edge.
+func (abq *AgentBaseQuery) QueryWxAgent() *WxQuery {
+	query := (&WxClient{config: abq.config}).Query()
+	query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
+		if err := abq.prepareQuery(ctx); err != nil {
+			return nil, err
+		}
+		selector := abq.sqlQuery(ctx)
+		if err := selector.Err(); err != nil {
+			return nil, err
+		}
+		step := sqlgraph.NewStep(
+			sqlgraph.From(agentbase.Table, agentbase.FieldID, selector),
+			sqlgraph.To(wx.Table, wx.FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, agentbase.WxAgentTable, agentbase.WxAgentColumn),
+		)
+		fromU = sqlgraph.SetNeighbors(abq.driver.Dialect(), step)
+		return fromU, nil
+	}
+	return query
+}
+
+// First returns the first AgentBase entity from the query.
+// Returns a *NotFoundError when no AgentBase was found.
+func (abq *AgentBaseQuery) First(ctx context.Context) (*AgentBase, error) {
+	nodes, err := abq.Limit(1).All(setContextOp(ctx, abq.ctx, "First"))
+	if err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nil, &NotFoundError{agentbase.Label}
+	}
+	return nodes[0], nil
+}
+
+// FirstX is like First, but panics if an error occurs.
+func (abq *AgentBaseQuery) FirstX(ctx context.Context) *AgentBase {
+	node, err := abq.First(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return node
+}
+
+// FirstID returns the first AgentBase ID from the query.
+// Returns a *NotFoundError when no AgentBase ID was found.
+func (abq *AgentBaseQuery) FirstID(ctx context.Context) (id string, err error) {
+	var ids []string
+	if ids, err = abq.Limit(1).IDs(setContextOp(ctx, abq.ctx, "FirstID")); err != nil {
+		return
+	}
+	if len(ids) == 0 {
+		err = &NotFoundError{agentbase.Label}
+		return
+	}
+	return ids[0], nil
+}
+
+// FirstIDX is like FirstID, but panics if an error occurs.
+func (abq *AgentBaseQuery) FirstIDX(ctx context.Context) string {
+	id, err := abq.FirstID(ctx)
+	if err != nil && !IsNotFound(err) {
+		panic(err)
+	}
+	return id
+}
+
+// Only returns a single AgentBase entity found by the query, ensuring it only returns one.
+// Returns a *NotSingularError when more than one AgentBase entity is found.
+// Returns a *NotFoundError when no AgentBase entities are found.
+func (abq *AgentBaseQuery) Only(ctx context.Context) (*AgentBase, error) {
+	nodes, err := abq.Limit(2).All(setContextOp(ctx, abq.ctx, "Only"))
+	if err != nil {
+		return nil, err
+	}
+	switch len(nodes) {
+	case 1:
+		return nodes[0], nil
+	case 0:
+		return nil, &NotFoundError{agentbase.Label}
+	default:
+		return nil, &NotSingularError{agentbase.Label}
+	}
+}
+
+// OnlyX is like Only, but panics if an error occurs.
+func (abq *AgentBaseQuery) OnlyX(ctx context.Context) *AgentBase {
+	node, err := abq.Only(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// OnlyID is like Only, but returns the only AgentBase ID in the query.
+// Returns a *NotSingularError when more than one AgentBase ID is found.
+// Returns a *NotFoundError when no entities are found.
+func (abq *AgentBaseQuery) OnlyID(ctx context.Context) (id string, err error) {
+	var ids []string
+	if ids, err = abq.Limit(2).IDs(setContextOp(ctx, abq.ctx, "OnlyID")); err != nil {
+		return
+	}
+	switch len(ids) {
+	case 1:
+		id = ids[0]
+	case 0:
+		err = &NotFoundError{agentbase.Label}
+	default:
+		err = &NotSingularError{agentbase.Label}
+	}
+	return
+}
+
+// OnlyIDX is like OnlyID, but panics if an error occurs.
+func (abq *AgentBaseQuery) OnlyIDX(ctx context.Context) string {
+	id, err := abq.OnlyID(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return id
+}
+
+// All executes the query and returns a list of AgentBases.
+func (abq *AgentBaseQuery) All(ctx context.Context) ([]*AgentBase, error) {
+	ctx = setContextOp(ctx, abq.ctx, "All")
+	if err := abq.prepareQuery(ctx); err != nil {
+		return nil, err
+	}
+	qr := querierAll[[]*AgentBase, *AgentBaseQuery]()
+	return withInterceptors[[]*AgentBase](ctx, abq, qr, abq.inters)
+}
+
+// AllX is like All, but panics if an error occurs.
+func (abq *AgentBaseQuery) AllX(ctx context.Context) []*AgentBase {
+	nodes, err := abq.All(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return nodes
+}
+
+// IDs executes the query and returns a list of AgentBase IDs.
+func (abq *AgentBaseQuery) IDs(ctx context.Context) (ids []string, err error) {
+	if abq.ctx.Unique == nil && abq.path != nil {
+		abq.Unique(true)
+	}
+	ctx = setContextOp(ctx, abq.ctx, "IDs")
+	if err = abq.Select(agentbase.FieldID).Scan(ctx, &ids); err != nil {
+		return nil, err
+	}
+	return ids, nil
+}
+
+// IDsX is like IDs, but panics if an error occurs.
+func (abq *AgentBaseQuery) IDsX(ctx context.Context) []string {
+	ids, err := abq.IDs(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return ids
+}
+
+// Count returns the count of the given query.
+func (abq *AgentBaseQuery) Count(ctx context.Context) (int, error) {
+	ctx = setContextOp(ctx, abq.ctx, "Count")
+	if err := abq.prepareQuery(ctx); err != nil {
+		return 0, err
+	}
+	return withInterceptors[int](ctx, abq, querierCount[*AgentBaseQuery](), abq.inters)
+}
+
+// CountX is like Count, but panics if an error occurs.
+func (abq *AgentBaseQuery) CountX(ctx context.Context) int {
+	count, err := abq.Count(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return count
+}
+
+// Exist returns true if the query has elements in the graph.
+func (abq *AgentBaseQuery) Exist(ctx context.Context) (bool, error) {
+	ctx = setContextOp(ctx, abq.ctx, "Exist")
+	switch _, err := abq.FirstID(ctx); {
+	case IsNotFound(err):
+		return false, nil
+	case err != nil:
+		return false, fmt.Errorf("ent: check existence: %w", err)
+	default:
+		return true, nil
+	}
+}
+
+// ExistX is like Exist, but panics if an error occurs.
+func (abq *AgentBaseQuery) ExistX(ctx context.Context) bool {
+	exist, err := abq.Exist(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return exist
+}
+
+// Clone returns a duplicate of the AgentBaseQuery builder, including all associated steps. It can be
+// used to prepare common query builders and use them differently after the clone is made.
+func (abq *AgentBaseQuery) Clone() *AgentBaseQuery {
+	if abq == nil {
+		return nil
+	}
+	return &AgentBaseQuery{
+		config:      abq.config,
+		ctx:         abq.ctx.Clone(),
+		order:       append([]agentbase.OrderOption{}, abq.order...),
+		inters:      append([]Interceptor{}, abq.inters...),
+		predicates:  append([]predicate.AgentBase{}, abq.predicates...),
+		withWxAgent: abq.withWxAgent.Clone(),
+		// clone intermediate query.
+		sql:  abq.sql.Clone(),
+		path: abq.path,
+	}
+}
+
+// WithWxAgent tells the query-builder to eager-load the nodes that are connected to
+// the "wx_agent" edge. The optional arguments are used to configure the query builder of the edge.
+func (abq *AgentBaseQuery) WithWxAgent(opts ...func(*WxQuery)) *AgentBaseQuery {
+	query := (&WxClient{config: abq.config}).Query()
+	for _, opt := range opts {
+		opt(query)
+	}
+	abq.withWxAgent = query
+	return abq
+}
+
+// GroupBy is used to group vertices by one or more fields/columns.
+// It is often used with aggregate functions, like: count, max, mean, min, sum.
+//
+// Example:
+//
+//	var v []struct {
+//		Q string `json:"q,omitempty"`
+//		Count int `json:"count,omitempty"`
+//	}
+//
+//	client.AgentBase.Query().
+//		GroupBy(agentbase.FieldQ).
+//		Aggregate(ent.Count()).
+//		Scan(ctx, &v)
+func (abq *AgentBaseQuery) GroupBy(field string, fields ...string) *AgentBaseGroupBy {
+	abq.ctx.Fields = append([]string{field}, fields...)
+	grbuild := &AgentBaseGroupBy{build: abq}
+	grbuild.flds = &abq.ctx.Fields
+	grbuild.label = agentbase.Label
+	grbuild.scan = grbuild.Scan
+	return grbuild
+}
+
+// Select allows the selection one or more fields/columns for the given query,
+// instead of selecting all fields in the entity.
+//
+// Example:
+//
+//	var v []struct {
+//		Q string `json:"q,omitempty"`
+//	}
+//
+//	client.AgentBase.Query().
+//		Select(agentbase.FieldQ).
+//		Scan(ctx, &v)
+func (abq *AgentBaseQuery) Select(fields ...string) *AgentBaseSelect {
+	abq.ctx.Fields = append(abq.ctx.Fields, fields...)
+	sbuild := &AgentBaseSelect{AgentBaseQuery: abq}
+	sbuild.label = agentbase.Label
+	sbuild.flds, sbuild.scan = &abq.ctx.Fields, sbuild.Scan
+	return sbuild
+}
+
+// Aggregate returns a AgentBaseSelect configured with the given aggregations.
+func (abq *AgentBaseQuery) Aggregate(fns ...AggregateFunc) *AgentBaseSelect {
+	return abq.Select().Aggregate(fns...)
+}
+
+func (abq *AgentBaseQuery) prepareQuery(ctx context.Context) error {
+	for _, inter := range abq.inters {
+		if inter == nil {
+			return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
+		}
+		if trv, ok := inter.(Traverser); ok {
+			if err := trv.Traverse(ctx, abq); err != nil {
+				return err
+			}
+		}
+	}
+	for _, f := range abq.ctx.Fields {
+		if !agentbase.ValidColumn(f) {
+			return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+		}
+	}
+	if abq.path != nil {
+		prev, err := abq.path(ctx)
+		if err != nil {
+			return err
+		}
+		abq.sql = prev
+	}
+	return nil
+}
+
+func (abq *AgentBaseQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AgentBase, error) {
+	var (
+		nodes       = []*AgentBase{}
+		_spec       = abq.querySpec()
+		loadedTypes = [1]bool{
+			abq.withWxAgent != nil,
+		}
+	)
+	_spec.ScanValues = func(columns []string) ([]any, error) {
+		return (*AgentBase).scanValues(nil, columns)
+	}
+	_spec.Assign = func(columns []string, values []any) error {
+		node := &AgentBase{config: abq.config}
+		nodes = append(nodes, node)
+		node.Edges.loadedTypes = loadedTypes
+		return node.assignValues(columns, values)
+	}
+	for i := range hooks {
+		hooks[i](ctx, _spec)
+	}
+	if err := sqlgraph.QueryNodes(ctx, abq.driver, _spec); err != nil {
+		return nil, err
+	}
+	if len(nodes) == 0 {
+		return nodes, nil
+	}
+	if query := abq.withWxAgent; query != nil {
+		if err := abq.loadWxAgent(ctx, query, nodes,
+			func(n *AgentBase) { n.Edges.WxAgent = []*Wx{} },
+			func(n *AgentBase, e *Wx) { n.Edges.WxAgent = append(n.Edges.WxAgent, e) }); err != nil {
+			return nil, err
+		}
+	}
+	return nodes, nil
+}
+
+func (abq *AgentBaseQuery) loadWxAgent(ctx context.Context, query *WxQuery, nodes []*AgentBase, init func(*AgentBase), assign func(*AgentBase, *Wx)) error {
+	fks := make([]driver.Value, 0, len(nodes))
+	nodeids := make(map[string]*AgentBase)
+	for i := range nodes {
+		fks = append(fks, nodes[i].ID)
+		nodeids[nodes[i].ID] = nodes[i]
+		if init != nil {
+			init(nodes[i])
+		}
+	}
+	query.withFKs = true
+	query.Where(predicate.Wx(func(s *sql.Selector) {
+		s.Where(sql.InValues(s.C(agentbase.WxAgentColumn), fks...))
+	}))
+	neighbors, err := query.All(ctx)
+	if err != nil {
+		return err
+	}
+	for _, n := range neighbors {
+		fk := n.agent_base_wx_agent
+		if fk == nil {
+			return fmt.Errorf(`foreign-key "agent_base_wx_agent" is nil for node %v`, n.ID)
+		}
+		node, ok := nodeids[*fk]
+		if !ok {
+			return fmt.Errorf(`unexpected referenced foreign-key "agent_base_wx_agent" returned %v for node %v`, *fk, n.ID)
+		}
+		assign(node, n)
+	}
+	return nil
+}
+
+func (abq *AgentBaseQuery) sqlCount(ctx context.Context) (int, error) {
+	_spec := abq.querySpec()
+	_spec.Node.Columns = abq.ctx.Fields
+	if len(abq.ctx.Fields) > 0 {
+		_spec.Unique = abq.ctx.Unique != nil && *abq.ctx.Unique
+	}
+	return sqlgraph.CountNodes(ctx, abq.driver, _spec)
+}
+
+func (abq *AgentBaseQuery) querySpec() *sqlgraph.QuerySpec {
+	_spec := sqlgraph.NewQuerySpec(agentbase.Table, agentbase.Columns, sqlgraph.NewFieldSpec(agentbase.FieldID, field.TypeString))
+	_spec.From = abq.sql
+	if unique := abq.ctx.Unique; unique != nil {
+		_spec.Unique = *unique
+	} else if abq.path != nil {
+		_spec.Unique = true
+	}
+	if fields := abq.ctx.Fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, agentbase.FieldID)
+		for i := range fields {
+			if fields[i] != agentbase.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
+			}
+		}
+	}
+	if ps := abq.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if limit := abq.ctx.Limit; limit != nil {
+		_spec.Limit = *limit
+	}
+	if offset := abq.ctx.Offset; offset != nil {
+		_spec.Offset = *offset
+	}
+	if ps := abq.order; len(ps) > 0 {
+		_spec.Order = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	return _spec
+}
+
+func (abq *AgentBaseQuery) sqlQuery(ctx context.Context) *sql.Selector {
+	builder := sql.Dialect(abq.driver.Dialect())
+	t1 := builder.Table(agentbase.Table)
+	columns := abq.ctx.Fields
+	if len(columns) == 0 {
+		columns = agentbase.Columns
+	}
+	selector := builder.Select(t1.Columns(columns...)...).From(t1)
+	if abq.sql != nil {
+		selector = abq.sql
+		selector.Select(selector.Columns(columns...)...)
+	}
+	if abq.ctx.Unique != nil && *abq.ctx.Unique {
+		selector.Distinct()
+	}
+	for _, p := range abq.predicates {
+		p(selector)
+	}
+	for _, p := range abq.order {
+		p(selector)
+	}
+	if offset := abq.ctx.Offset; offset != nil {
+		// limit is mandatory for offset clause. We start
+		// with default value, and override it below if needed.
+		selector.Offset(*offset).Limit(math.MaxInt32)
+	}
+	if limit := abq.ctx.Limit; limit != nil {
+		selector.Limit(*limit)
+	}
+	return selector
+}
+
+// AgentBaseGroupBy is the group-by builder for AgentBase entities.
+type AgentBaseGroupBy struct {
+	selector
+	build *AgentBaseQuery
+}
+
+// Aggregate adds the given aggregation functions to the group-by query.
+func (abgb *AgentBaseGroupBy) Aggregate(fns ...AggregateFunc) *AgentBaseGroupBy {
+	abgb.fns = append(abgb.fns, fns...)
+	return abgb
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (abgb *AgentBaseGroupBy) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, abgb.build.ctx, "GroupBy")
+	if err := abgb.build.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*AgentBaseQuery, *AgentBaseGroupBy](ctx, abgb.build, abgb, abgb.build.inters, v)
+}
+
+func (abgb *AgentBaseGroupBy) sqlScan(ctx context.Context, root *AgentBaseQuery, v any) error {
+	selector := root.sqlQuery(ctx).Select()
+	aggregation := make([]string, 0, len(abgb.fns))
+	for _, fn := range abgb.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	if len(selector.SelectedColumns()) == 0 {
+		columns := make([]string, 0, len(*abgb.flds)+len(abgb.fns))
+		for _, f := range *abgb.flds {
+			columns = append(columns, selector.C(f))
+		}
+		columns = append(columns, aggregation...)
+		selector.Select(columns...)
+	}
+	selector.GroupBy(selector.Columns(*abgb.flds...)...)
+	if err := selector.Err(); err != nil {
+		return err
+	}
+	rows := &sql.Rows{}
+	query, args := selector.Query()
+	if err := abgb.build.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}
+
+// AgentBaseSelect is the builder for selecting fields of AgentBase entities.
+type AgentBaseSelect struct {
+	*AgentBaseQuery
+	selector
+}
+
+// Aggregate adds the given aggregation functions to the selector query.
+func (abs *AgentBaseSelect) Aggregate(fns ...AggregateFunc) *AgentBaseSelect {
+	abs.fns = append(abs.fns, fns...)
+	return abs
+}
+
+// Scan applies the selector query and scans the result into the given value.
+func (abs *AgentBaseSelect) Scan(ctx context.Context, v any) error {
+	ctx = setContextOp(ctx, abs.ctx, "Select")
+	if err := abs.prepareQuery(ctx); err != nil {
+		return err
+	}
+	return scanWithInterceptors[*AgentBaseQuery, *AgentBaseSelect](ctx, abs.AgentBaseQuery, abs, abs.inters, v)
+}
+
+func (abs *AgentBaseSelect) sqlScan(ctx context.Context, root *AgentBaseQuery, v any) error {
+	selector := root.sqlQuery(ctx)
+	aggregation := make([]string, 0, len(abs.fns))
+	for _, fn := range abs.fns {
+		aggregation = append(aggregation, fn(selector))
+	}
+	switch n := len(*abs.selector.flds); {
+	case n == 0 && len(aggregation) > 0:
+		selector.Select(aggregation...)
+	case n != 0 && len(aggregation) > 0:
+		selector.AppendSelect(aggregation...)
+	}
+	rows := &sql.Rows{}
+	query, args := selector.Query()
+	if err := abs.driver.Query(ctx, query, args, rows); err != nil {
+		return err
+	}
+	defer rows.Close()
+	return sql.ScanSlice(rows, v)
+}

+ 853 - 0
ent/agentbase_update.go

@@ -0,0 +1,853 @@
+// Code generated by ent, DO NOT EDIT.
+
+package ent
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"wechat-api/ent/agentbase"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/wx"
+
+	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
+	"entgo.io/ent/dialect/sql/sqljson"
+	"entgo.io/ent/schema/field"
+)
+
+// AgentBaseUpdate is the builder for updating AgentBase entities.
+type AgentBaseUpdate struct {
+	config
+	hooks    []Hook
+	mutation *AgentBaseMutation
+}
+
+// Where appends a list predicates to the AgentBaseUpdate builder.
+func (abu *AgentBaseUpdate) Where(ps ...predicate.AgentBase) *AgentBaseUpdate {
+	abu.mutation.Where(ps...)
+	return abu
+}
+
+// SetQ sets the "q" field.
+func (abu *AgentBaseUpdate) SetQ(s string) *AgentBaseUpdate {
+	abu.mutation.SetQ(s)
+	return abu
+}
+
+// SetNillableQ sets the "q" field if the given value is not nil.
+func (abu *AgentBaseUpdate) SetNillableQ(s *string) *AgentBaseUpdate {
+	if s != nil {
+		abu.SetQ(*s)
+	}
+	return abu
+}
+
+// ClearQ clears the value of the "q" field.
+func (abu *AgentBaseUpdate) ClearQ() *AgentBaseUpdate {
+	abu.mutation.ClearQ()
+	return abu
+}
+
+// SetA sets the "a" field.
+func (abu *AgentBaseUpdate) SetA(s string) *AgentBaseUpdate {
+	abu.mutation.SetA(s)
+	return abu
+}
+
+// SetNillableA sets the "a" field if the given value is not nil.
+func (abu *AgentBaseUpdate) SetNillableA(s *string) *AgentBaseUpdate {
+	if s != nil {
+		abu.SetA(*s)
+	}
+	return abu
+}
+
+// ClearA clears the value of the "a" field.
+func (abu *AgentBaseUpdate) ClearA() *AgentBaseUpdate {
+	abu.mutation.ClearA()
+	return abu
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (abu *AgentBaseUpdate) SetChunkIndex(u uint64) *AgentBaseUpdate {
+	abu.mutation.ResetChunkIndex()
+	abu.mutation.SetChunkIndex(u)
+	return abu
+}
+
+// SetNillableChunkIndex sets the "chunk_index" field if the given value is not nil.
+func (abu *AgentBaseUpdate) SetNillableChunkIndex(u *uint64) *AgentBaseUpdate {
+	if u != nil {
+		abu.SetChunkIndex(*u)
+	}
+	return abu
+}
+
+// AddChunkIndex adds u to the "chunk_index" field.
+func (abu *AgentBaseUpdate) AddChunkIndex(u int64) *AgentBaseUpdate {
+	abu.mutation.AddChunkIndex(u)
+	return abu
+}
+
+// SetIndexes sets the "indexes" field.
+func (abu *AgentBaseUpdate) SetIndexes(s []string) *AgentBaseUpdate {
+	abu.mutation.SetIndexes(s)
+	return abu
+}
+
+// AppendIndexes appends s to the "indexes" field.
+func (abu *AgentBaseUpdate) AppendIndexes(s []string) *AgentBaseUpdate {
+	abu.mutation.AppendIndexes(s)
+	return abu
+}
+
+// ClearIndexes clears the value of the "indexes" field.
+func (abu *AgentBaseUpdate) ClearIndexes() *AgentBaseUpdate {
+	abu.mutation.ClearIndexes()
+	return abu
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (abu *AgentBaseUpdate) SetDatasetID(s string) *AgentBaseUpdate {
+	abu.mutation.SetDatasetID(s)
+	return abu
+}
+
+// SetNillableDatasetID sets the "dataset_id" field if the given value is not nil.
+func (abu *AgentBaseUpdate) SetNillableDatasetID(s *string) *AgentBaseUpdate {
+	if s != nil {
+		abu.SetDatasetID(*s)
+	}
+	return abu
+}
+
+// ClearDatasetID clears the value of the "dataset_id" field.
+func (abu *AgentBaseUpdate) ClearDatasetID() *AgentBaseUpdate {
+	abu.mutation.ClearDatasetID()
+	return abu
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (abu *AgentBaseUpdate) SetCollectionID(s string) *AgentBaseUpdate {
+	abu.mutation.SetCollectionID(s)
+	return abu
+}
+
+// SetNillableCollectionID sets the "collection_id" field if the given value is not nil.
+func (abu *AgentBaseUpdate) SetNillableCollectionID(s *string) *AgentBaseUpdate {
+	if s != nil {
+		abu.SetCollectionID(*s)
+	}
+	return abu
+}
+
+// ClearCollectionID clears the value of the "collection_id" field.
+func (abu *AgentBaseUpdate) ClearCollectionID() *AgentBaseUpdate {
+	abu.mutation.ClearCollectionID()
+	return abu
+}
+
+// SetSourceName sets the "source_name" field.
+func (abu *AgentBaseUpdate) SetSourceName(s string) *AgentBaseUpdate {
+	abu.mutation.SetSourceName(s)
+	return abu
+}
+
+// SetNillableSourceName sets the "source_name" field if the given value is not nil.
+func (abu *AgentBaseUpdate) SetNillableSourceName(s *string) *AgentBaseUpdate {
+	if s != nil {
+		abu.SetSourceName(*s)
+	}
+	return abu
+}
+
+// ClearSourceName clears the value of the "source_name" field.
+func (abu *AgentBaseUpdate) ClearSourceName() *AgentBaseUpdate {
+	abu.mutation.ClearSourceName()
+	return abu
+}
+
+// SetCanWrite sets the "can_write" field.
+func (abu *AgentBaseUpdate) SetCanWrite(b []bool) *AgentBaseUpdate {
+	abu.mutation.SetCanWrite(b)
+	return abu
+}
+
+// AppendCanWrite appends b to the "can_write" field.
+func (abu *AgentBaseUpdate) AppendCanWrite(b []bool) *AgentBaseUpdate {
+	abu.mutation.AppendCanWrite(b)
+	return abu
+}
+
+// ClearCanWrite clears the value of the "can_write" field.
+func (abu *AgentBaseUpdate) ClearCanWrite() *AgentBaseUpdate {
+	abu.mutation.ClearCanWrite()
+	return abu
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (abu *AgentBaseUpdate) SetIsOwner(b []bool) *AgentBaseUpdate {
+	abu.mutation.SetIsOwner(b)
+	return abu
+}
+
+// AppendIsOwner appends b to the "is_owner" field.
+func (abu *AgentBaseUpdate) AppendIsOwner(b []bool) *AgentBaseUpdate {
+	abu.mutation.AppendIsOwner(b)
+	return abu
+}
+
+// ClearIsOwner clears the value of the "is_owner" field.
+func (abu *AgentBaseUpdate) ClearIsOwner() *AgentBaseUpdate {
+	abu.mutation.ClearIsOwner()
+	return abu
+}
+
+// AddWxAgentIDs adds the "wx_agent" edge to the Wx entity by IDs.
+func (abu *AgentBaseUpdate) AddWxAgentIDs(ids ...uint64) *AgentBaseUpdate {
+	abu.mutation.AddWxAgentIDs(ids...)
+	return abu
+}
+
+// AddWxAgent adds the "wx_agent" edges to the Wx entity.
+func (abu *AgentBaseUpdate) AddWxAgent(w ...*Wx) *AgentBaseUpdate {
+	ids := make([]uint64, len(w))
+	for i := range w {
+		ids[i] = w[i].ID
+	}
+	return abu.AddWxAgentIDs(ids...)
+}
+
+// Mutation returns the AgentBaseMutation object of the builder.
+func (abu *AgentBaseUpdate) Mutation() *AgentBaseMutation {
+	return abu.mutation
+}
+
+// ClearWxAgent clears all "wx_agent" edges to the Wx entity.
+func (abu *AgentBaseUpdate) ClearWxAgent() *AgentBaseUpdate {
+	abu.mutation.ClearWxAgent()
+	return abu
+}
+
+// RemoveWxAgentIDs removes the "wx_agent" edge to Wx entities by IDs.
+func (abu *AgentBaseUpdate) RemoveWxAgentIDs(ids ...uint64) *AgentBaseUpdate {
+	abu.mutation.RemoveWxAgentIDs(ids...)
+	return abu
+}
+
+// RemoveWxAgent removes "wx_agent" edges to Wx entities.
+func (abu *AgentBaseUpdate) RemoveWxAgent(w ...*Wx) *AgentBaseUpdate {
+	ids := make([]uint64, len(w))
+	for i := range w {
+		ids[i] = w[i].ID
+	}
+	return abu.RemoveWxAgentIDs(ids...)
+}
+
+// Save executes the query and returns the number of nodes affected by the update operation.
+func (abu *AgentBaseUpdate) Save(ctx context.Context) (int, error) {
+	return withHooks(ctx, abu.sqlSave, abu.mutation, abu.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (abu *AgentBaseUpdate) SaveX(ctx context.Context) int {
+	affected, err := abu.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return affected
+}
+
+// Exec executes the query.
+func (abu *AgentBaseUpdate) Exec(ctx context.Context) error {
+	_, err := abu.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (abu *AgentBaseUpdate) ExecX(ctx context.Context) {
+	if err := abu.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (abu *AgentBaseUpdate) check() error {
+	if v, ok := abu.mutation.ChunkIndex(); ok {
+		if err := agentbase.ChunkIndexValidator(v); err != nil {
+			return &ValidationError{Name: "chunk_index", err: fmt.Errorf(`ent: validator failed for field "AgentBase.chunk_index": %w`, err)}
+		}
+	}
+	return nil
+}
+
+func (abu *AgentBaseUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	if err := abu.check(); err != nil {
+		return n, err
+	}
+	_spec := sqlgraph.NewUpdateSpec(agentbase.Table, agentbase.Columns, sqlgraph.NewFieldSpec(agentbase.FieldID, field.TypeString))
+	if ps := abu.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := abu.mutation.Q(); ok {
+		_spec.SetField(agentbase.FieldQ, field.TypeString, value)
+	}
+	if abu.mutation.QCleared() {
+		_spec.ClearField(agentbase.FieldQ, field.TypeString)
+	}
+	if value, ok := abu.mutation.A(); ok {
+		_spec.SetField(agentbase.FieldA, field.TypeString, value)
+	}
+	if abu.mutation.ACleared() {
+		_spec.ClearField(agentbase.FieldA, field.TypeString)
+	}
+	if value, ok := abu.mutation.ChunkIndex(); ok {
+		_spec.SetField(agentbase.FieldChunkIndex, field.TypeUint64, value)
+	}
+	if value, ok := abu.mutation.AddedChunkIndex(); ok {
+		_spec.AddField(agentbase.FieldChunkIndex, field.TypeUint64, value)
+	}
+	if value, ok := abu.mutation.Indexes(); ok {
+		_spec.SetField(agentbase.FieldIndexes, field.TypeJSON, value)
+	}
+	if value, ok := abu.mutation.AppendedIndexes(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, agentbase.FieldIndexes, value)
+		})
+	}
+	if abu.mutation.IndexesCleared() {
+		_spec.ClearField(agentbase.FieldIndexes, field.TypeJSON)
+	}
+	if value, ok := abu.mutation.DatasetID(); ok {
+		_spec.SetField(agentbase.FieldDatasetID, field.TypeString, value)
+	}
+	if abu.mutation.DatasetIDCleared() {
+		_spec.ClearField(agentbase.FieldDatasetID, field.TypeString)
+	}
+	if value, ok := abu.mutation.CollectionID(); ok {
+		_spec.SetField(agentbase.FieldCollectionID, field.TypeString, value)
+	}
+	if abu.mutation.CollectionIDCleared() {
+		_spec.ClearField(agentbase.FieldCollectionID, field.TypeString)
+	}
+	if value, ok := abu.mutation.SourceName(); ok {
+		_spec.SetField(agentbase.FieldSourceName, field.TypeString, value)
+	}
+	if abu.mutation.SourceNameCleared() {
+		_spec.ClearField(agentbase.FieldSourceName, field.TypeString)
+	}
+	if value, ok := abu.mutation.CanWrite(); ok {
+		_spec.SetField(agentbase.FieldCanWrite, field.TypeJSON, value)
+	}
+	if value, ok := abu.mutation.AppendedCanWrite(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, agentbase.FieldCanWrite, value)
+		})
+	}
+	if abu.mutation.CanWriteCleared() {
+		_spec.ClearField(agentbase.FieldCanWrite, field.TypeJSON)
+	}
+	if value, ok := abu.mutation.IsOwner(); ok {
+		_spec.SetField(agentbase.FieldIsOwner, field.TypeJSON, value)
+	}
+	if value, ok := abu.mutation.AppendedIsOwner(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, agentbase.FieldIsOwner, value)
+		})
+	}
+	if abu.mutation.IsOwnerCleared() {
+		_spec.ClearField(agentbase.FieldIsOwner, field.TypeJSON)
+	}
+	if abu.mutation.WxAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := abu.mutation.RemovedWxAgentIDs(); len(nodes) > 0 && !abu.mutation.WxAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := abu.mutation.WxAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
+	if n, err = sqlgraph.UpdateNodes(ctx, abu.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{agentbase.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return 0, err
+	}
+	abu.mutation.done = true
+	return n, nil
+}
+
+// AgentBaseUpdateOne is the builder for updating a single AgentBase entity.
+type AgentBaseUpdateOne struct {
+	config
+	fields   []string
+	hooks    []Hook
+	mutation *AgentBaseMutation
+}
+
+// SetQ sets the "q" field.
+func (abuo *AgentBaseUpdateOne) SetQ(s string) *AgentBaseUpdateOne {
+	abuo.mutation.SetQ(s)
+	return abuo
+}
+
+// SetNillableQ sets the "q" field if the given value is not nil.
+func (abuo *AgentBaseUpdateOne) SetNillableQ(s *string) *AgentBaseUpdateOne {
+	if s != nil {
+		abuo.SetQ(*s)
+	}
+	return abuo
+}
+
+// ClearQ clears the value of the "q" field.
+func (abuo *AgentBaseUpdateOne) ClearQ() *AgentBaseUpdateOne {
+	abuo.mutation.ClearQ()
+	return abuo
+}
+
+// SetA sets the "a" field.
+func (abuo *AgentBaseUpdateOne) SetA(s string) *AgentBaseUpdateOne {
+	abuo.mutation.SetA(s)
+	return abuo
+}
+
+// SetNillableA sets the "a" field if the given value is not nil.
+func (abuo *AgentBaseUpdateOne) SetNillableA(s *string) *AgentBaseUpdateOne {
+	if s != nil {
+		abuo.SetA(*s)
+	}
+	return abuo
+}
+
+// ClearA clears the value of the "a" field.
+func (abuo *AgentBaseUpdateOne) ClearA() *AgentBaseUpdateOne {
+	abuo.mutation.ClearA()
+	return abuo
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (abuo *AgentBaseUpdateOne) SetChunkIndex(u uint64) *AgentBaseUpdateOne {
+	abuo.mutation.ResetChunkIndex()
+	abuo.mutation.SetChunkIndex(u)
+	return abuo
+}
+
+// SetNillableChunkIndex sets the "chunk_index" field if the given value is not nil.
+func (abuo *AgentBaseUpdateOne) SetNillableChunkIndex(u *uint64) *AgentBaseUpdateOne {
+	if u != nil {
+		abuo.SetChunkIndex(*u)
+	}
+	return abuo
+}
+
+// AddChunkIndex adds u to the "chunk_index" field.
+func (abuo *AgentBaseUpdateOne) AddChunkIndex(u int64) *AgentBaseUpdateOne {
+	abuo.mutation.AddChunkIndex(u)
+	return abuo
+}
+
+// SetIndexes sets the "indexes" field.
+func (abuo *AgentBaseUpdateOne) SetIndexes(s []string) *AgentBaseUpdateOne {
+	abuo.mutation.SetIndexes(s)
+	return abuo
+}
+
+// AppendIndexes appends s to the "indexes" field.
+func (abuo *AgentBaseUpdateOne) AppendIndexes(s []string) *AgentBaseUpdateOne {
+	abuo.mutation.AppendIndexes(s)
+	return abuo
+}
+
+// ClearIndexes clears the value of the "indexes" field.
+func (abuo *AgentBaseUpdateOne) ClearIndexes() *AgentBaseUpdateOne {
+	abuo.mutation.ClearIndexes()
+	return abuo
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (abuo *AgentBaseUpdateOne) SetDatasetID(s string) *AgentBaseUpdateOne {
+	abuo.mutation.SetDatasetID(s)
+	return abuo
+}
+
+// SetNillableDatasetID sets the "dataset_id" field if the given value is not nil.
+func (abuo *AgentBaseUpdateOne) SetNillableDatasetID(s *string) *AgentBaseUpdateOne {
+	if s != nil {
+		abuo.SetDatasetID(*s)
+	}
+	return abuo
+}
+
+// ClearDatasetID clears the value of the "dataset_id" field.
+func (abuo *AgentBaseUpdateOne) ClearDatasetID() *AgentBaseUpdateOne {
+	abuo.mutation.ClearDatasetID()
+	return abuo
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (abuo *AgentBaseUpdateOne) SetCollectionID(s string) *AgentBaseUpdateOne {
+	abuo.mutation.SetCollectionID(s)
+	return abuo
+}
+
+// SetNillableCollectionID sets the "collection_id" field if the given value is not nil.
+func (abuo *AgentBaseUpdateOne) SetNillableCollectionID(s *string) *AgentBaseUpdateOne {
+	if s != nil {
+		abuo.SetCollectionID(*s)
+	}
+	return abuo
+}
+
+// ClearCollectionID clears the value of the "collection_id" field.
+func (abuo *AgentBaseUpdateOne) ClearCollectionID() *AgentBaseUpdateOne {
+	abuo.mutation.ClearCollectionID()
+	return abuo
+}
+
+// SetSourceName sets the "source_name" field.
+func (abuo *AgentBaseUpdateOne) SetSourceName(s string) *AgentBaseUpdateOne {
+	abuo.mutation.SetSourceName(s)
+	return abuo
+}
+
+// SetNillableSourceName sets the "source_name" field if the given value is not nil.
+func (abuo *AgentBaseUpdateOne) SetNillableSourceName(s *string) *AgentBaseUpdateOne {
+	if s != nil {
+		abuo.SetSourceName(*s)
+	}
+	return abuo
+}
+
+// ClearSourceName clears the value of the "source_name" field.
+func (abuo *AgentBaseUpdateOne) ClearSourceName() *AgentBaseUpdateOne {
+	abuo.mutation.ClearSourceName()
+	return abuo
+}
+
+// SetCanWrite sets the "can_write" field.
+func (abuo *AgentBaseUpdateOne) SetCanWrite(b []bool) *AgentBaseUpdateOne {
+	abuo.mutation.SetCanWrite(b)
+	return abuo
+}
+
+// AppendCanWrite appends b to the "can_write" field.
+func (abuo *AgentBaseUpdateOne) AppendCanWrite(b []bool) *AgentBaseUpdateOne {
+	abuo.mutation.AppendCanWrite(b)
+	return abuo
+}
+
+// ClearCanWrite clears the value of the "can_write" field.
+func (abuo *AgentBaseUpdateOne) ClearCanWrite() *AgentBaseUpdateOne {
+	abuo.mutation.ClearCanWrite()
+	return abuo
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (abuo *AgentBaseUpdateOne) SetIsOwner(b []bool) *AgentBaseUpdateOne {
+	abuo.mutation.SetIsOwner(b)
+	return abuo
+}
+
+// AppendIsOwner appends b to the "is_owner" field.
+func (abuo *AgentBaseUpdateOne) AppendIsOwner(b []bool) *AgentBaseUpdateOne {
+	abuo.mutation.AppendIsOwner(b)
+	return abuo
+}
+
+// ClearIsOwner clears the value of the "is_owner" field.
+func (abuo *AgentBaseUpdateOne) ClearIsOwner() *AgentBaseUpdateOne {
+	abuo.mutation.ClearIsOwner()
+	return abuo
+}
+
+// AddWxAgentIDs adds the "wx_agent" edge to the Wx entity by IDs.
+func (abuo *AgentBaseUpdateOne) AddWxAgentIDs(ids ...uint64) *AgentBaseUpdateOne {
+	abuo.mutation.AddWxAgentIDs(ids...)
+	return abuo
+}
+
+// AddWxAgent adds the "wx_agent" edges to the Wx entity.
+func (abuo *AgentBaseUpdateOne) AddWxAgent(w ...*Wx) *AgentBaseUpdateOne {
+	ids := make([]uint64, len(w))
+	for i := range w {
+		ids[i] = w[i].ID
+	}
+	return abuo.AddWxAgentIDs(ids...)
+}
+
+// Mutation returns the AgentBaseMutation object of the builder.
+func (abuo *AgentBaseUpdateOne) Mutation() *AgentBaseMutation {
+	return abuo.mutation
+}
+
+// ClearWxAgent clears all "wx_agent" edges to the Wx entity.
+func (abuo *AgentBaseUpdateOne) ClearWxAgent() *AgentBaseUpdateOne {
+	abuo.mutation.ClearWxAgent()
+	return abuo
+}
+
+// RemoveWxAgentIDs removes the "wx_agent" edge to Wx entities by IDs.
+func (abuo *AgentBaseUpdateOne) RemoveWxAgentIDs(ids ...uint64) *AgentBaseUpdateOne {
+	abuo.mutation.RemoveWxAgentIDs(ids...)
+	return abuo
+}
+
+// RemoveWxAgent removes "wx_agent" edges to Wx entities.
+func (abuo *AgentBaseUpdateOne) RemoveWxAgent(w ...*Wx) *AgentBaseUpdateOne {
+	ids := make([]uint64, len(w))
+	for i := range w {
+		ids[i] = w[i].ID
+	}
+	return abuo.RemoveWxAgentIDs(ids...)
+}
+
+// Where appends a list predicates to the AgentBaseUpdate builder.
+func (abuo *AgentBaseUpdateOne) Where(ps ...predicate.AgentBase) *AgentBaseUpdateOne {
+	abuo.mutation.Where(ps...)
+	return abuo
+}
+
+// Select allows selecting one or more fields (columns) of the returned entity.
+// The default is selecting all fields defined in the entity schema.
+func (abuo *AgentBaseUpdateOne) Select(field string, fields ...string) *AgentBaseUpdateOne {
+	abuo.fields = append([]string{field}, fields...)
+	return abuo
+}
+
+// Save executes the query and returns the updated AgentBase entity.
+func (abuo *AgentBaseUpdateOne) Save(ctx context.Context) (*AgentBase, error) {
+	return withHooks(ctx, abuo.sqlSave, abuo.mutation, abuo.hooks)
+}
+
+// SaveX is like Save, but panics if an error occurs.
+func (abuo *AgentBaseUpdateOne) SaveX(ctx context.Context) *AgentBase {
+	node, err := abuo.Save(ctx)
+	if err != nil {
+		panic(err)
+	}
+	return node
+}
+
+// Exec executes the query on the entity.
+func (abuo *AgentBaseUpdateOne) Exec(ctx context.Context) error {
+	_, err := abuo.Save(ctx)
+	return err
+}
+
+// ExecX is like Exec, but panics if an error occurs.
+func (abuo *AgentBaseUpdateOne) ExecX(ctx context.Context) {
+	if err := abuo.Exec(ctx); err != nil {
+		panic(err)
+	}
+}
+
+// check runs all checks and user-defined validators on the builder.
+func (abuo *AgentBaseUpdateOne) check() error {
+	if v, ok := abuo.mutation.ChunkIndex(); ok {
+		if err := agentbase.ChunkIndexValidator(v); err != nil {
+			return &ValidationError{Name: "chunk_index", err: fmt.Errorf(`ent: validator failed for field "AgentBase.chunk_index": %w`, err)}
+		}
+	}
+	return nil
+}
+
+func (abuo *AgentBaseUpdateOne) sqlSave(ctx context.Context) (_node *AgentBase, err error) {
+	if err := abuo.check(); err != nil {
+		return _node, err
+	}
+	_spec := sqlgraph.NewUpdateSpec(agentbase.Table, agentbase.Columns, sqlgraph.NewFieldSpec(agentbase.FieldID, field.TypeString))
+	id, ok := abuo.mutation.ID()
+	if !ok {
+		return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "AgentBase.id" for update`)}
+	}
+	_spec.Node.ID.Value = id
+	if fields := abuo.fields; len(fields) > 0 {
+		_spec.Node.Columns = make([]string, 0, len(fields))
+		_spec.Node.Columns = append(_spec.Node.Columns, agentbase.FieldID)
+		for _, f := range fields {
+			if !agentbase.ValidColumn(f) {
+				return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
+			}
+			if f != agentbase.FieldID {
+				_spec.Node.Columns = append(_spec.Node.Columns, f)
+			}
+		}
+	}
+	if ps := abuo.mutation.predicates; len(ps) > 0 {
+		_spec.Predicate = func(selector *sql.Selector) {
+			for i := range ps {
+				ps[i](selector)
+			}
+		}
+	}
+	if value, ok := abuo.mutation.Q(); ok {
+		_spec.SetField(agentbase.FieldQ, field.TypeString, value)
+	}
+	if abuo.mutation.QCleared() {
+		_spec.ClearField(agentbase.FieldQ, field.TypeString)
+	}
+	if value, ok := abuo.mutation.A(); ok {
+		_spec.SetField(agentbase.FieldA, field.TypeString, value)
+	}
+	if abuo.mutation.ACleared() {
+		_spec.ClearField(agentbase.FieldA, field.TypeString)
+	}
+	if value, ok := abuo.mutation.ChunkIndex(); ok {
+		_spec.SetField(agentbase.FieldChunkIndex, field.TypeUint64, value)
+	}
+	if value, ok := abuo.mutation.AddedChunkIndex(); ok {
+		_spec.AddField(agentbase.FieldChunkIndex, field.TypeUint64, value)
+	}
+	if value, ok := abuo.mutation.Indexes(); ok {
+		_spec.SetField(agentbase.FieldIndexes, field.TypeJSON, value)
+	}
+	if value, ok := abuo.mutation.AppendedIndexes(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, agentbase.FieldIndexes, value)
+		})
+	}
+	if abuo.mutation.IndexesCleared() {
+		_spec.ClearField(agentbase.FieldIndexes, field.TypeJSON)
+	}
+	if value, ok := abuo.mutation.DatasetID(); ok {
+		_spec.SetField(agentbase.FieldDatasetID, field.TypeString, value)
+	}
+	if abuo.mutation.DatasetIDCleared() {
+		_spec.ClearField(agentbase.FieldDatasetID, field.TypeString)
+	}
+	if value, ok := abuo.mutation.CollectionID(); ok {
+		_spec.SetField(agentbase.FieldCollectionID, field.TypeString, value)
+	}
+	if abuo.mutation.CollectionIDCleared() {
+		_spec.ClearField(agentbase.FieldCollectionID, field.TypeString)
+	}
+	if value, ok := abuo.mutation.SourceName(); ok {
+		_spec.SetField(agentbase.FieldSourceName, field.TypeString, value)
+	}
+	if abuo.mutation.SourceNameCleared() {
+		_spec.ClearField(agentbase.FieldSourceName, field.TypeString)
+	}
+	if value, ok := abuo.mutation.CanWrite(); ok {
+		_spec.SetField(agentbase.FieldCanWrite, field.TypeJSON, value)
+	}
+	if value, ok := abuo.mutation.AppendedCanWrite(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, agentbase.FieldCanWrite, value)
+		})
+	}
+	if abuo.mutation.CanWriteCleared() {
+		_spec.ClearField(agentbase.FieldCanWrite, field.TypeJSON)
+	}
+	if value, ok := abuo.mutation.IsOwner(); ok {
+		_spec.SetField(agentbase.FieldIsOwner, field.TypeJSON, value)
+	}
+	if value, ok := abuo.mutation.AppendedIsOwner(); ok {
+		_spec.AddModifier(func(u *sql.UpdateBuilder) {
+			sqljson.Append(u, agentbase.FieldIsOwner, value)
+		})
+	}
+	if abuo.mutation.IsOwnerCleared() {
+		_spec.ClearField(agentbase.FieldIsOwner, field.TypeJSON)
+	}
+	if abuo.mutation.WxAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := abuo.mutation.RemovedWxAgentIDs(); len(nodes) > 0 && !abuo.mutation.WxAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := abuo.mutation.WxAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agentbase.WxAgentTable,
+			Columns: []string{agentbase.WxAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(wx.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
+	_node = &AgentBase{config: abuo.config}
+	_spec.Assign = _node.assignValues
+	_spec.ScanValues = _node.scanValues
+	if err = sqlgraph.UpdateNode(ctx, abuo.driver, _spec); err != nil {
+		if _, ok := err.(*sqlgraph.NotFoundError); ok {
+			err = &NotFoundError{agentbase.Label}
+		} else if sqlgraph.IsConstraintError(err) {
+			err = &ConstraintError{msg: err.Error(), wrap: err}
+		}
+		return nil, err
+	}
+	abuo.mutation.done = true
+	return _node, nil
+}

+ 167 - 8
ent/client.go

@@ -12,6 +12,7 @@ import (
 	"wechat-api/ent/migrate"
 
 	"wechat-api/ent/agent"
+	"wechat-api/ent/agentbase"
 	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/category"
 	"wechat-api/ent/contact"
@@ -46,6 +47,8 @@ type Client struct {
 	Schema *migrate.Schema
 	// Agent is the client for interacting with the Agent builders.
 	Agent *AgentClient
+	// AgentBase is the client for interacting with the AgentBase builders.
+	AgentBase *AgentBaseClient
 	// BatchMsg is the client for interacting with the BatchMsg builders.
 	BatchMsg *BatchMsgClient
 	// Category is the client for interacting with the Category builders.
@@ -94,6 +97,7 @@ func NewClient(opts ...Option) *Client {
 func (c *Client) init() {
 	c.Schema = migrate.NewSchema(c.driver)
 	c.Agent = NewAgentClient(c.config)
+	c.AgentBase = NewAgentBaseClient(c.config)
 	c.BatchMsg = NewBatchMsgClient(c.config)
 	c.Category = NewCategoryClient(c.config)
 	c.Contact = NewContactClient(c.config)
@@ -205,6 +209,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
 		ctx:               ctx,
 		config:            cfg,
 		Agent:             NewAgentClient(cfg),
+		AgentBase:         NewAgentBaseClient(cfg),
 		BatchMsg:          NewBatchMsgClient(cfg),
 		Category:          NewCategoryClient(cfg),
 		Contact:           NewContactClient(cfg),
@@ -243,6 +248,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
 		ctx:               ctx,
 		config:            cfg,
 		Agent:             NewAgentClient(cfg),
+		AgentBase:         NewAgentBaseClient(cfg),
 		BatchMsg:          NewBatchMsgClient(cfg),
 		Category:          NewCategoryClient(cfg),
 		Contact:           NewContactClient(cfg),
@@ -290,9 +296,10 @@ func (c *Client) Close() error {
 // In order to add hooks to a specific client, call: `client.Node.Use(...)`.
 func (c *Client) Use(hooks ...Hook) {
 	for _, n := range []interface{ Use(...Hook) }{
-		c.Agent, c.BatchMsg, c.Category, c.Contact, c.Employee, c.EmployeeConfig,
-		c.Label, c.LabelRelationship, c.Message, c.MessageRecords, c.Msg, c.Server,
-		c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial, c.WorkExperience, c.Wx,
+		c.Agent, c.AgentBase, c.BatchMsg, c.Category, c.Contact, c.Employee,
+		c.EmployeeConfig, c.Label, c.LabelRelationship, c.Message, c.MessageRecords,
+		c.Msg, c.Server, c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial,
+		c.WorkExperience, c.Wx,
 	} {
 		n.Use(hooks...)
 	}
@@ -302,9 +309,10 @@ func (c *Client) Use(hooks ...Hook) {
 // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
 func (c *Client) Intercept(interceptors ...Interceptor) {
 	for _, n := range []interface{ Intercept(...Interceptor) }{
-		c.Agent, c.BatchMsg, c.Category, c.Contact, c.Employee, c.EmployeeConfig,
-		c.Label, c.LabelRelationship, c.Message, c.MessageRecords, c.Msg, c.Server,
-		c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial, c.WorkExperience, c.Wx,
+		c.Agent, c.AgentBase, c.BatchMsg, c.Category, c.Contact, c.Employee,
+		c.EmployeeConfig, c.Label, c.LabelRelationship, c.Message, c.MessageRecords,
+		c.Msg, c.Server, c.SopNode, c.SopStage, c.SopTask, c.Token, c.Tutorial,
+		c.WorkExperience, c.Wx,
 	} {
 		n.Intercept(interceptors...)
 	}
@@ -315,6 +323,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
 	switch m := m.(type) {
 	case *AgentMutation:
 		return c.Agent.mutate(ctx, m)
+	case *AgentBaseMutation:
+		return c.AgentBase.mutate(ctx, m)
 	case *BatchMsgMutation:
 		return c.BatchMsg.mutate(ctx, m)
 	case *CategoryMutation:
@@ -507,6 +517,155 @@ func (c *AgentClient) mutate(ctx context.Context, m *AgentMutation) (Value, erro
 	}
 }
 
+// AgentBaseClient is a client for the AgentBase schema.
+type AgentBaseClient struct {
+	config
+}
+
+// NewAgentBaseClient returns a client for the AgentBase from the given config.
+func NewAgentBaseClient(c config) *AgentBaseClient {
+	return &AgentBaseClient{config: c}
+}
+
+// Use adds a list of mutation hooks to the hooks stack.
+// A call to `Use(f, g, h)` equals to `agentbase.Hooks(f(g(h())))`.
+func (c *AgentBaseClient) Use(hooks ...Hook) {
+	c.hooks.AgentBase = append(c.hooks.AgentBase, hooks...)
+}
+
+// Intercept adds a list of query interceptors to the interceptors stack.
+// A call to `Intercept(f, g, h)` equals to `agentbase.Intercept(f(g(h())))`.
+func (c *AgentBaseClient) Intercept(interceptors ...Interceptor) {
+	c.inters.AgentBase = append(c.inters.AgentBase, interceptors...)
+}
+
+// Create returns a builder for creating a AgentBase entity.
+func (c *AgentBaseClient) Create() *AgentBaseCreate {
+	mutation := newAgentBaseMutation(c.config, OpCreate)
+	return &AgentBaseCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// CreateBulk returns a builder for creating a bulk of AgentBase entities.
+func (c *AgentBaseClient) CreateBulk(builders ...*AgentBaseCreate) *AgentBaseCreateBulk {
+	return &AgentBaseCreateBulk{config: c.config, builders: builders}
+}
+
+// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
+// a builder and applies setFunc on it.
+func (c *AgentBaseClient) MapCreateBulk(slice any, setFunc func(*AgentBaseCreate, int)) *AgentBaseCreateBulk {
+	rv := reflect.ValueOf(slice)
+	if rv.Kind() != reflect.Slice {
+		return &AgentBaseCreateBulk{err: fmt.Errorf("calling to AgentBaseClient.MapCreateBulk with wrong type %T, need slice", slice)}
+	}
+	builders := make([]*AgentBaseCreate, rv.Len())
+	for i := 0; i < rv.Len(); i++ {
+		builders[i] = c.Create()
+		setFunc(builders[i], i)
+	}
+	return &AgentBaseCreateBulk{config: c.config, builders: builders}
+}
+
+// Update returns an update builder for AgentBase.
+func (c *AgentBaseClient) Update() *AgentBaseUpdate {
+	mutation := newAgentBaseMutation(c.config, OpUpdate)
+	return &AgentBaseUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOne returns an update builder for the given entity.
+func (c *AgentBaseClient) UpdateOne(ab *AgentBase) *AgentBaseUpdateOne {
+	mutation := newAgentBaseMutation(c.config, OpUpdateOne, withAgentBase(ab))
+	return &AgentBaseUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// UpdateOneID returns an update builder for the given id.
+func (c *AgentBaseClient) UpdateOneID(id string) *AgentBaseUpdateOne {
+	mutation := newAgentBaseMutation(c.config, OpUpdateOne, withAgentBaseID(id))
+	return &AgentBaseUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// Delete returns a delete builder for AgentBase.
+func (c *AgentBaseClient) Delete() *AgentBaseDelete {
+	mutation := newAgentBaseMutation(c.config, OpDelete)
+	return &AgentBaseDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
+}
+
+// DeleteOne returns a builder for deleting the given entity.
+func (c *AgentBaseClient) DeleteOne(ab *AgentBase) *AgentBaseDeleteOne {
+	return c.DeleteOneID(ab.ID)
+}
+
+// DeleteOneID returns a builder for deleting the given entity by its id.
+func (c *AgentBaseClient) DeleteOneID(id string) *AgentBaseDeleteOne {
+	builder := c.Delete().Where(agentbase.ID(id))
+	builder.mutation.id = &id
+	builder.mutation.op = OpDeleteOne
+	return &AgentBaseDeleteOne{builder}
+}
+
+// Query returns a query builder for AgentBase.
+func (c *AgentBaseClient) Query() *AgentBaseQuery {
+	return &AgentBaseQuery{
+		config: c.config,
+		ctx:    &QueryContext{Type: TypeAgentBase},
+		inters: c.Interceptors(),
+	}
+}
+
+// Get returns a AgentBase entity by its id.
+func (c *AgentBaseClient) Get(ctx context.Context, id string) (*AgentBase, error) {
+	return c.Query().Where(agentbase.ID(id)).Only(ctx)
+}
+
+// GetX is like Get, but panics if an error occurs.
+func (c *AgentBaseClient) GetX(ctx context.Context, id string) *AgentBase {
+	obj, err := c.Get(ctx, id)
+	if err != nil {
+		panic(err)
+	}
+	return obj
+}
+
+// QueryWxAgent queries the wx_agent edge of a AgentBase.
+func (c *AgentBaseClient) QueryWxAgent(ab *AgentBase) *WxQuery {
+	query := (&WxClient{config: c.config}).Query()
+	query.path = func(context.Context) (fromV *sql.Selector, _ error) {
+		id := ab.ID
+		step := sqlgraph.NewStep(
+			sqlgraph.From(agentbase.Table, agentbase.FieldID, id),
+			sqlgraph.To(wx.Table, wx.FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, agentbase.WxAgentTable, agentbase.WxAgentColumn),
+		)
+		fromV = sqlgraph.Neighbors(ab.driver.Dialect(), step)
+		return fromV, nil
+	}
+	return query
+}
+
+// Hooks returns the client hooks.
+func (c *AgentBaseClient) Hooks() []Hook {
+	return c.hooks.AgentBase
+}
+
+// Interceptors returns the client interceptors.
+func (c *AgentBaseClient) Interceptors() []Interceptor {
+	return c.inters.AgentBase
+}
+
+func (c *AgentBaseClient) mutate(ctx context.Context, m *AgentBaseMutation) (Value, error) {
+	switch m.Op() {
+	case OpCreate:
+		return (&AgentBaseCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdate:
+		return (&AgentBaseUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpUpdateOne:
+		return (&AgentBaseUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
+	case OpDelete, OpDeleteOne:
+		return (&AgentBaseDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
+	default:
+		return nil, fmt.Errorf("ent: unknown AgentBase mutation op: %q", m.Op())
+	}
+}
+
 // BatchMsgClient is a client for the BatchMsg schema.
 type BatchMsgClient struct {
 	config
@@ -3270,12 +3429,12 @@ func (c *WxClient) mutate(ctx context.Context, m *WxMutation) (Value, error) {
 // hooks and interceptors per client, for fast access.
 type (
 	hooks struct {
-		Agent, BatchMsg, Category, Contact, Employee, EmployeeConfig, Label,
+		Agent, AgentBase, BatchMsg, Category, Contact, Employee, EmployeeConfig, Label,
 		LabelRelationship, Message, MessageRecords, Msg, Server, SopNode, SopStage,
 		SopTask, Token, Tutorial, WorkExperience, Wx []ent.Hook
 	}
 	inters struct {
-		Agent, BatchMsg, Category, Contact, Employee, EmployeeConfig, Label,
+		Agent, AgentBase, BatchMsg, Category, Contact, Employee, EmployeeConfig, Label,
 		LabelRelationship, Message, MessageRecords, Msg, Server, SopNode, SopStage,
 		SopTask, Token, Tutorial, WorkExperience, Wx []ent.Interceptor
 	}

+ 2 - 0
ent/ent.go

@@ -9,6 +9,7 @@ import (
 	"reflect"
 	"sync"
 	"wechat-api/ent/agent"
+	"wechat-api/ent/agentbase"
 	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/category"
 	"wechat-api/ent/contact"
@@ -92,6 +93,7 @@ func checkColumn(table, column string) error {
 	initCheck.Do(func() {
 		columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
 			agent.Table:             agent.ValidColumn,
+			agentbase.Table:         agentbase.ValidColumn,
 			batchmsg.Table:          batchmsg.ValidColumn,
 			category.Table:          category.ValidColumn,
 			contact.Table:           contact.ValidColumn,

+ 12 - 0
ent/hook/hook.go

@@ -20,6 +20,18 @@ func (f AgentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error
 	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.AgentMutation", m)
 }
 
+// The AgentBaseFunc type is an adapter to allow the use of ordinary
+// function as AgentBase mutator.
+type AgentBaseFunc func(context.Context, *ent.AgentBaseMutation) (ent.Value, error)
+
+// Mutate calls f(ctx, m).
+func (f AgentBaseFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
+	if mv, ok := m.(*ent.AgentBaseMutation); ok {
+		return f(ctx, mv)
+	}
+	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.AgentBaseMutation", m)
+}
+
 // The BatchMsgFunc type is an adapter to allow the use of ordinary
 // function as BatchMsg mutator.
 type BatchMsgFunc func(context.Context, *ent.BatchMsgMutation) (ent.Value, error)

+ 30 - 0
ent/intercept/intercept.go

@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"wechat-api/ent"
 	"wechat-api/ent/agent"
+	"wechat-api/ent/agentbase"
 	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/category"
 	"wechat-api/ent/contact"
@@ -113,6 +114,33 @@ func (f TraverseAgent) Traverse(ctx context.Context, q ent.Query) error {
 	return fmt.Errorf("unexpected query type %T. expect *ent.AgentQuery", q)
 }
 
+// The AgentBaseFunc type is an adapter to allow the use of ordinary function as a Querier.
+type AgentBaseFunc func(context.Context, *ent.AgentBaseQuery) (ent.Value, error)
+
+// Query calls f(ctx, q).
+func (f AgentBaseFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
+	if q, ok := q.(*ent.AgentBaseQuery); ok {
+		return f(ctx, q)
+	}
+	return nil, fmt.Errorf("unexpected query type %T. expect *ent.AgentBaseQuery", q)
+}
+
+// The TraverseAgentBase type is an adapter to allow the use of ordinary function as Traverser.
+type TraverseAgentBase func(context.Context, *ent.AgentBaseQuery) error
+
+// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
+func (f TraverseAgentBase) Intercept(next ent.Querier) ent.Querier {
+	return next
+}
+
+// Traverse calls f(ctx, q).
+func (f TraverseAgentBase) Traverse(ctx context.Context, q ent.Query) error {
+	if q, ok := q.(*ent.AgentBaseQuery); ok {
+		return f(ctx, q)
+	}
+	return fmt.Errorf("unexpected query type %T. expect *ent.AgentBaseQuery", q)
+}
+
 // The BatchMsgFunc type is an adapter to allow the use of ordinary function as a Querier.
 type BatchMsgFunc func(context.Context, *ent.BatchMsgQuery) (ent.Value, error)
 
@@ -604,6 +632,8 @@ func NewQuery(q ent.Query) (Query, error) {
 	switch q := q.(type) {
 	case *ent.AgentQuery:
 		return &query[*ent.AgentQuery, predicate.Agent, agent.OrderOption]{typ: ent.TypeAgent, tq: q}, nil
+	case *ent.AgentBaseQuery:
+		return &query[*ent.AgentBaseQuery, predicate.AgentBase, agentbase.OrderOption]{typ: ent.TypeAgentBase, tq: q}, nil
 	case *ent.BatchMsgQuery:
 		return &query[*ent.BatchMsgQuery, predicate.BatchMsg, batchmsg.OrderOption]{typ: ent.TypeBatchMsg, tq: q}, nil
 	case *ent.CategoryQuery:

+ 34 - 3
ent/migrate/schema.go

@@ -37,6 +37,25 @@ var (
 			},
 		},
 	}
+	// AgentBaseColumns holds the columns for the "agent_base" table.
+	AgentBaseColumns = []*schema.Column{
+		{Name: "id", Type: field.TypeString, Comment: "id"},
+		{Name: "q", Type: field.TypeString, Nullable: true, Comment: "q", Default: ""},
+		{Name: "a", Type: field.TypeString, Nullable: true, Comment: "a", Default: ""},
+		{Name: "chunk_index", Type: field.TypeUint64, Comment: "chunk_index"},
+		{Name: "indexes", Type: field.TypeJSON, Nullable: true, Comment: "indexes"},
+		{Name: "dataset_id", Type: field.TypeString, Nullable: true, Comment: "dataset_id", Default: ""},
+		{Name: "collection_id", Type: field.TypeString, Nullable: true, Comment: "collection_id", Default: ""},
+		{Name: "source_name", Type: field.TypeString, Nullable: true, Comment: "source_name", Default: ""},
+		{Name: "can_write", Type: field.TypeJSON, Nullable: true, Comment: "can_write"},
+		{Name: "is_owner", Type: field.TypeJSON, Nullable: true, Comment: "is_owner"},
+	}
+	// AgentBaseTable holds the schema information for the "agent_base" table.
+	AgentBaseTable = &schema.Table{
+		Name:       "agent_base",
+		Columns:    AgentBaseColumns,
+		PrimaryKey: []*schema.Column{AgentBaseColumns[0]},
+	}
 	// BatchMsgColumns holds the columns for the "batch_msg" table.
 	BatchMsgColumns = []*schema.Column{
 		{Name: "id", Type: field.TypeUint64, Increment: true},
@@ -631,6 +650,7 @@ var (
 		{Name: "block_list", Type: field.TypeJSON, Comment: "黑名单"},
 		{Name: "group_block_list", Type: field.TypeJSON, Comment: "群黑名单"},
 		{Name: "agent_id", Type: field.TypeUint64, Comment: "模式ID", Default: 0},
+		{Name: "agent_base_wx_agent", Type: field.TypeString, Nullable: true},
 		{Name: "server_id", Type: field.TypeUint64, Nullable: true, Comment: "服务器id", Default: 0},
 	}
 	// WxTable holds the schema information for the "wx" table.
@@ -646,8 +666,14 @@ var (
 				OnDelete:   schema.NoAction,
 			},
 			{
-				Symbol:     "wx_server_wxs",
+				Symbol:     "wx_agent_base_wx_agent",
 				Columns:    []*schema.Column{WxColumns[21]},
+				RefColumns: []*schema.Column{AgentBaseColumns[0]},
+				OnDelete:   schema.SetNull,
+			},
+			{
+				Symbol:     "wx_server_wxs",
+				Columns:    []*schema.Column{WxColumns[22]},
 				RefColumns: []*schema.Column{ServerColumns[0]},
 				OnDelete:   schema.SetNull,
 			},
@@ -656,7 +682,7 @@ var (
 			{
 				Name:    "wx_server_id_port",
 				Unique:  true,
-				Columns: []*schema.Column{WxColumns[21], WxColumns[5]},
+				Columns: []*schema.Column{WxColumns[22], WxColumns[5]},
 			},
 			{
 				Name:    "wx_wxid",
@@ -683,6 +709,7 @@ var (
 	// Tables holds all the tables in the schema.
 	Tables = []*schema.Table{
 		AgentTable,
+		AgentBaseTable,
 		BatchMsgTable,
 		CategoryTable,
 		ContactTable,
@@ -708,6 +735,9 @@ func init() {
 	AgentTable.Annotation = &entsql.Annotation{
 		Table: "agent",
 	}
+	AgentBaseTable.Annotation = &entsql.Annotation{
+		Table: "agent_base",
+	}
 	BatchMsgTable.Annotation = &entsql.Annotation{
 		Table: "batch_msg",
 	}
@@ -769,7 +799,8 @@ func init() {
 		Table: "work_experience",
 	}
 	WxTable.ForeignKeys[0].RefTable = AgentTable
-	WxTable.ForeignKeys[1].RefTable = ServerTable
+	WxTable.ForeignKeys[1].RefTable = AgentBaseTable
+	WxTable.ForeignKeys[2].RefTable = ServerTable
 	WxTable.Annotation = &entsql.Annotation{
 		Table: "wx",
 	}

+ 1101 - 0
ent/mutation.go

@@ -9,6 +9,7 @@ import (
 	"sync"
 	"time"
 	"wechat-api/ent/agent"
+	"wechat-api/ent/agentbase"
 	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/category"
 	"wechat-api/ent/contact"
@@ -44,6 +45,7 @@ const (
 
 	// Node types.
 	TypeAgent             = "Agent"
+	TypeAgentBase         = "AgentBase"
 	TypeBatchMsg          = "BatchMsg"
 	TypeCategory          = "Category"
 	TypeContact           = "Contact"
@@ -1178,6 +1180,1105 @@ func (m *AgentMutation) ResetEdge(name string) error {
 	return fmt.Errorf("unknown Agent edge %s", name)
 }
 
+// AgentBaseMutation represents an operation that mutates the AgentBase nodes in the graph.
+type AgentBaseMutation struct {
+	config
+	op              Op
+	typ             string
+	id              *string
+	q               *string
+	a               *string
+	chunk_index     *uint64
+	addchunk_index  *int64
+	indexes         *[]string
+	appendindexes   []string
+	dataset_id      *string
+	collection_id   *string
+	source_name     *string
+	can_write       *[]bool
+	appendcan_write []bool
+	is_owner        *[]bool
+	appendis_owner  []bool
+	clearedFields   map[string]struct{}
+	wx_agent        map[uint64]struct{}
+	removedwx_agent map[uint64]struct{}
+	clearedwx_agent bool
+	done            bool
+	oldValue        func(context.Context) (*AgentBase, error)
+	predicates      []predicate.AgentBase
+}
+
+var _ ent.Mutation = (*AgentBaseMutation)(nil)
+
+// agentbaseOption allows management of the mutation configuration using functional options.
+type agentbaseOption func(*AgentBaseMutation)
+
+// newAgentBaseMutation creates new mutation for the AgentBase entity.
+func newAgentBaseMutation(c config, op Op, opts ...agentbaseOption) *AgentBaseMutation {
+	m := &AgentBaseMutation{
+		config:        c,
+		op:            op,
+		typ:           TypeAgentBase,
+		clearedFields: make(map[string]struct{}),
+	}
+	for _, opt := range opts {
+		opt(m)
+	}
+	return m
+}
+
+// withAgentBaseID sets the ID field of the mutation.
+func withAgentBaseID(id string) agentbaseOption {
+	return func(m *AgentBaseMutation) {
+		var (
+			err   error
+			once  sync.Once
+			value *AgentBase
+		)
+		m.oldValue = func(ctx context.Context) (*AgentBase, error) {
+			once.Do(func() {
+				if m.done {
+					err = errors.New("querying old values post mutation is not allowed")
+				} else {
+					value, err = m.Client().AgentBase.Get(ctx, id)
+				}
+			})
+			return value, err
+		}
+		m.id = &id
+	}
+}
+
+// withAgentBase sets the old AgentBase of the mutation.
+func withAgentBase(node *AgentBase) agentbaseOption {
+	return func(m *AgentBaseMutation) {
+		m.oldValue = func(context.Context) (*AgentBase, error) {
+			return node, nil
+		}
+		m.id = &node.ID
+	}
+}
+
+// Client returns a new `ent.Client` from the mutation. If the mutation was
+// executed in a transaction (ent.Tx), a transactional client is returned.
+func (m AgentBaseMutation) Client() *Client {
+	client := &Client{config: m.config}
+	client.init()
+	return client
+}
+
+// Tx returns an `ent.Tx` for mutations that were executed in transactions;
+// it returns an error otherwise.
+func (m AgentBaseMutation) Tx() (*Tx, error) {
+	if _, ok := m.driver.(*txDriver); !ok {
+		return nil, errors.New("ent: mutation is not running in a transaction")
+	}
+	tx := &Tx{config: m.config}
+	tx.init()
+	return tx, nil
+}
+
+// SetID sets the value of the id field. Note that this
+// operation is only accepted on creation of AgentBase entities.
+func (m *AgentBaseMutation) SetID(id string) {
+	m.id = &id
+}
+
+// ID returns the ID value in the mutation. Note that the ID is only available
+// if it was provided to the builder or after it was returned from the database.
+func (m *AgentBaseMutation) ID() (id string, exists bool) {
+	if m.id == nil {
+		return
+	}
+	return *m.id, true
+}
+
+// IDs queries the database and returns the entity ids that match the mutation's predicate.
+// That means, if the mutation is applied within a transaction with an isolation level such
+// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated
+// or updated by the mutation.
+func (m *AgentBaseMutation) IDs(ctx context.Context) ([]string, error) {
+	switch {
+	case m.op.Is(OpUpdateOne | OpDeleteOne):
+		id, exists := m.ID()
+		if exists {
+			return []string{id}, nil
+		}
+		fallthrough
+	case m.op.Is(OpUpdate | OpDelete):
+		return m.Client().AgentBase.Query().Where(m.predicates...).IDs(ctx)
+	default:
+		return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
+	}
+}
+
+// SetQ sets the "q" field.
+func (m *AgentBaseMutation) SetQ(s string) {
+	m.q = &s
+}
+
+// Q returns the value of the "q" field in the mutation.
+func (m *AgentBaseMutation) Q() (r string, exists bool) {
+	v := m.q
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldQ returns the old "q" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldQ(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldQ is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldQ requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldQ: %w", err)
+	}
+	return oldValue.Q, nil
+}
+
+// ClearQ clears the value of the "q" field.
+func (m *AgentBaseMutation) ClearQ() {
+	m.q = nil
+	m.clearedFields[agentbase.FieldQ] = struct{}{}
+}
+
+// QCleared returns if the "q" field was cleared in this mutation.
+func (m *AgentBaseMutation) QCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldQ]
+	return ok
+}
+
+// ResetQ resets all changes to the "q" field.
+func (m *AgentBaseMutation) ResetQ() {
+	m.q = nil
+	delete(m.clearedFields, agentbase.FieldQ)
+}
+
+// SetA sets the "a" field.
+func (m *AgentBaseMutation) SetA(s string) {
+	m.a = &s
+}
+
+// A returns the value of the "a" field in the mutation.
+func (m *AgentBaseMutation) A() (r string, exists bool) {
+	v := m.a
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldA returns the old "a" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldA(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldA is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldA requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldA: %w", err)
+	}
+	return oldValue.A, nil
+}
+
+// ClearA clears the value of the "a" field.
+func (m *AgentBaseMutation) ClearA() {
+	m.a = nil
+	m.clearedFields[agentbase.FieldA] = struct{}{}
+}
+
+// ACleared returns if the "a" field was cleared in this mutation.
+func (m *AgentBaseMutation) ACleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldA]
+	return ok
+}
+
+// ResetA resets all changes to the "a" field.
+func (m *AgentBaseMutation) ResetA() {
+	m.a = nil
+	delete(m.clearedFields, agentbase.FieldA)
+}
+
+// SetChunkIndex sets the "chunk_index" field.
+func (m *AgentBaseMutation) SetChunkIndex(u uint64) {
+	m.chunk_index = &u
+	m.addchunk_index = nil
+}
+
+// ChunkIndex returns the value of the "chunk_index" field in the mutation.
+func (m *AgentBaseMutation) ChunkIndex() (r uint64, exists bool) {
+	v := m.chunk_index
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldChunkIndex returns the old "chunk_index" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldChunkIndex(ctx context.Context) (v uint64, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldChunkIndex is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldChunkIndex requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldChunkIndex: %w", err)
+	}
+	return oldValue.ChunkIndex, nil
+}
+
+// AddChunkIndex adds u to the "chunk_index" field.
+func (m *AgentBaseMutation) AddChunkIndex(u int64) {
+	if m.addchunk_index != nil {
+		*m.addchunk_index += u
+	} else {
+		m.addchunk_index = &u
+	}
+}
+
+// AddedChunkIndex returns the value that was added to the "chunk_index" field in this mutation.
+func (m *AgentBaseMutation) AddedChunkIndex() (r int64, exists bool) {
+	v := m.addchunk_index
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// ResetChunkIndex resets all changes to the "chunk_index" field.
+func (m *AgentBaseMutation) ResetChunkIndex() {
+	m.chunk_index = nil
+	m.addchunk_index = nil
+}
+
+// SetIndexes sets the "indexes" field.
+func (m *AgentBaseMutation) SetIndexes(s []string) {
+	m.indexes = &s
+	m.appendindexes = nil
+}
+
+// Indexes returns the value of the "indexes" field in the mutation.
+func (m *AgentBaseMutation) Indexes() (r []string, exists bool) {
+	v := m.indexes
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldIndexes returns the old "indexes" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldIndexes(ctx context.Context) (v []string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldIndexes is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldIndexes requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldIndexes: %w", err)
+	}
+	return oldValue.Indexes, nil
+}
+
+// AppendIndexes adds s to the "indexes" field.
+func (m *AgentBaseMutation) AppendIndexes(s []string) {
+	m.appendindexes = append(m.appendindexes, s...)
+}
+
+// AppendedIndexes returns the list of values that were appended to the "indexes" field in this mutation.
+func (m *AgentBaseMutation) AppendedIndexes() ([]string, bool) {
+	if len(m.appendindexes) == 0 {
+		return nil, false
+	}
+	return m.appendindexes, true
+}
+
+// ClearIndexes clears the value of the "indexes" field.
+func (m *AgentBaseMutation) ClearIndexes() {
+	m.indexes = nil
+	m.appendindexes = nil
+	m.clearedFields[agentbase.FieldIndexes] = struct{}{}
+}
+
+// IndexesCleared returns if the "indexes" field was cleared in this mutation.
+func (m *AgentBaseMutation) IndexesCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldIndexes]
+	return ok
+}
+
+// ResetIndexes resets all changes to the "indexes" field.
+func (m *AgentBaseMutation) ResetIndexes() {
+	m.indexes = nil
+	m.appendindexes = nil
+	delete(m.clearedFields, agentbase.FieldIndexes)
+}
+
+// SetDatasetID sets the "dataset_id" field.
+func (m *AgentBaseMutation) SetDatasetID(s string) {
+	m.dataset_id = &s
+}
+
+// DatasetID returns the value of the "dataset_id" field in the mutation.
+func (m *AgentBaseMutation) DatasetID() (r string, exists bool) {
+	v := m.dataset_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldDatasetID returns the old "dataset_id" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldDatasetID(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldDatasetID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldDatasetID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldDatasetID: %w", err)
+	}
+	return oldValue.DatasetID, nil
+}
+
+// ClearDatasetID clears the value of the "dataset_id" field.
+func (m *AgentBaseMutation) ClearDatasetID() {
+	m.dataset_id = nil
+	m.clearedFields[agentbase.FieldDatasetID] = struct{}{}
+}
+
+// DatasetIDCleared returns if the "dataset_id" field was cleared in this mutation.
+func (m *AgentBaseMutation) DatasetIDCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldDatasetID]
+	return ok
+}
+
+// ResetDatasetID resets all changes to the "dataset_id" field.
+func (m *AgentBaseMutation) ResetDatasetID() {
+	m.dataset_id = nil
+	delete(m.clearedFields, agentbase.FieldDatasetID)
+}
+
+// SetCollectionID sets the "collection_id" field.
+func (m *AgentBaseMutation) SetCollectionID(s string) {
+	m.collection_id = &s
+}
+
+// CollectionID returns the value of the "collection_id" field in the mutation.
+func (m *AgentBaseMutation) CollectionID() (r string, exists bool) {
+	v := m.collection_id
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCollectionID returns the old "collection_id" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldCollectionID(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCollectionID is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCollectionID requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCollectionID: %w", err)
+	}
+	return oldValue.CollectionID, nil
+}
+
+// ClearCollectionID clears the value of the "collection_id" field.
+func (m *AgentBaseMutation) ClearCollectionID() {
+	m.collection_id = nil
+	m.clearedFields[agentbase.FieldCollectionID] = struct{}{}
+}
+
+// CollectionIDCleared returns if the "collection_id" field was cleared in this mutation.
+func (m *AgentBaseMutation) CollectionIDCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldCollectionID]
+	return ok
+}
+
+// ResetCollectionID resets all changes to the "collection_id" field.
+func (m *AgentBaseMutation) ResetCollectionID() {
+	m.collection_id = nil
+	delete(m.clearedFields, agentbase.FieldCollectionID)
+}
+
+// SetSourceName sets the "source_name" field.
+func (m *AgentBaseMutation) SetSourceName(s string) {
+	m.source_name = &s
+}
+
+// SourceName returns the value of the "source_name" field in the mutation.
+func (m *AgentBaseMutation) SourceName() (r string, exists bool) {
+	v := m.source_name
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldSourceName returns the old "source_name" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldSourceName(ctx context.Context) (v string, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldSourceName is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldSourceName requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldSourceName: %w", err)
+	}
+	return oldValue.SourceName, nil
+}
+
+// ClearSourceName clears the value of the "source_name" field.
+func (m *AgentBaseMutation) ClearSourceName() {
+	m.source_name = nil
+	m.clearedFields[agentbase.FieldSourceName] = struct{}{}
+}
+
+// SourceNameCleared returns if the "source_name" field was cleared in this mutation.
+func (m *AgentBaseMutation) SourceNameCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldSourceName]
+	return ok
+}
+
+// ResetSourceName resets all changes to the "source_name" field.
+func (m *AgentBaseMutation) ResetSourceName() {
+	m.source_name = nil
+	delete(m.clearedFields, agentbase.FieldSourceName)
+}
+
+// SetCanWrite sets the "can_write" field.
+func (m *AgentBaseMutation) SetCanWrite(b []bool) {
+	m.can_write = &b
+	m.appendcan_write = nil
+}
+
+// CanWrite returns the value of the "can_write" field in the mutation.
+func (m *AgentBaseMutation) CanWrite() (r []bool, exists bool) {
+	v := m.can_write
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldCanWrite returns the old "can_write" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldCanWrite(ctx context.Context) (v []bool, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldCanWrite is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldCanWrite requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldCanWrite: %w", err)
+	}
+	return oldValue.CanWrite, nil
+}
+
+// AppendCanWrite adds b to the "can_write" field.
+func (m *AgentBaseMutation) AppendCanWrite(b []bool) {
+	m.appendcan_write = append(m.appendcan_write, b...)
+}
+
+// AppendedCanWrite returns the list of values that were appended to the "can_write" field in this mutation.
+func (m *AgentBaseMutation) AppendedCanWrite() ([]bool, bool) {
+	if len(m.appendcan_write) == 0 {
+		return nil, false
+	}
+	return m.appendcan_write, true
+}
+
+// ClearCanWrite clears the value of the "can_write" field.
+func (m *AgentBaseMutation) ClearCanWrite() {
+	m.can_write = nil
+	m.appendcan_write = nil
+	m.clearedFields[agentbase.FieldCanWrite] = struct{}{}
+}
+
+// CanWriteCleared returns if the "can_write" field was cleared in this mutation.
+func (m *AgentBaseMutation) CanWriteCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldCanWrite]
+	return ok
+}
+
+// ResetCanWrite resets all changes to the "can_write" field.
+func (m *AgentBaseMutation) ResetCanWrite() {
+	m.can_write = nil
+	m.appendcan_write = nil
+	delete(m.clearedFields, agentbase.FieldCanWrite)
+}
+
+// SetIsOwner sets the "is_owner" field.
+func (m *AgentBaseMutation) SetIsOwner(b []bool) {
+	m.is_owner = &b
+	m.appendis_owner = nil
+}
+
+// IsOwner returns the value of the "is_owner" field in the mutation.
+func (m *AgentBaseMutation) IsOwner() (r []bool, exists bool) {
+	v := m.is_owner
+	if v == nil {
+		return
+	}
+	return *v, true
+}
+
+// OldIsOwner returns the old "is_owner" field's value of the AgentBase entity.
+// If the AgentBase 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 *AgentBaseMutation) OldIsOwner(ctx context.Context) (v []bool, err error) {
+	if !m.op.Is(OpUpdateOne) {
+		return v, errors.New("OldIsOwner is only allowed on UpdateOne operations")
+	}
+	if m.id == nil || m.oldValue == nil {
+		return v, errors.New("OldIsOwner requires an ID field in the mutation")
+	}
+	oldValue, err := m.oldValue(ctx)
+	if err != nil {
+		return v, fmt.Errorf("querying old value for OldIsOwner: %w", err)
+	}
+	return oldValue.IsOwner, nil
+}
+
+// AppendIsOwner adds b to the "is_owner" field.
+func (m *AgentBaseMutation) AppendIsOwner(b []bool) {
+	m.appendis_owner = append(m.appendis_owner, b...)
+}
+
+// AppendedIsOwner returns the list of values that were appended to the "is_owner" field in this mutation.
+func (m *AgentBaseMutation) AppendedIsOwner() ([]bool, bool) {
+	if len(m.appendis_owner) == 0 {
+		return nil, false
+	}
+	return m.appendis_owner, true
+}
+
+// ClearIsOwner clears the value of the "is_owner" field.
+func (m *AgentBaseMutation) ClearIsOwner() {
+	m.is_owner = nil
+	m.appendis_owner = nil
+	m.clearedFields[agentbase.FieldIsOwner] = struct{}{}
+}
+
+// IsOwnerCleared returns if the "is_owner" field was cleared in this mutation.
+func (m *AgentBaseMutation) IsOwnerCleared() bool {
+	_, ok := m.clearedFields[agentbase.FieldIsOwner]
+	return ok
+}
+
+// ResetIsOwner resets all changes to the "is_owner" field.
+func (m *AgentBaseMutation) ResetIsOwner() {
+	m.is_owner = nil
+	m.appendis_owner = nil
+	delete(m.clearedFields, agentbase.FieldIsOwner)
+}
+
+// AddWxAgentIDs adds the "wx_agent" edge to the Wx entity by ids.
+func (m *AgentBaseMutation) AddWxAgentIDs(ids ...uint64) {
+	if m.wx_agent == nil {
+		m.wx_agent = make(map[uint64]struct{})
+	}
+	for i := range ids {
+		m.wx_agent[ids[i]] = struct{}{}
+	}
+}
+
+// ClearWxAgent clears the "wx_agent" edge to the Wx entity.
+func (m *AgentBaseMutation) ClearWxAgent() {
+	m.clearedwx_agent = true
+}
+
+// WxAgentCleared reports if the "wx_agent" edge to the Wx entity was cleared.
+func (m *AgentBaseMutation) WxAgentCleared() bool {
+	return m.clearedwx_agent
+}
+
+// RemoveWxAgentIDs removes the "wx_agent" edge to the Wx entity by IDs.
+func (m *AgentBaseMutation) RemoveWxAgentIDs(ids ...uint64) {
+	if m.removedwx_agent == nil {
+		m.removedwx_agent = make(map[uint64]struct{})
+	}
+	for i := range ids {
+		delete(m.wx_agent, ids[i])
+		m.removedwx_agent[ids[i]] = struct{}{}
+	}
+}
+
+// RemovedWxAgent returns the removed IDs of the "wx_agent" edge to the Wx entity.
+func (m *AgentBaseMutation) RemovedWxAgentIDs() (ids []uint64) {
+	for id := range m.removedwx_agent {
+		ids = append(ids, id)
+	}
+	return
+}
+
+// WxAgentIDs returns the "wx_agent" edge IDs in the mutation.
+func (m *AgentBaseMutation) WxAgentIDs() (ids []uint64) {
+	for id := range m.wx_agent {
+		ids = append(ids, id)
+	}
+	return
+}
+
+// ResetWxAgent resets all changes to the "wx_agent" edge.
+func (m *AgentBaseMutation) ResetWxAgent() {
+	m.wx_agent = nil
+	m.clearedwx_agent = false
+	m.removedwx_agent = nil
+}
+
+// Where appends a list predicates to the AgentBaseMutation builder.
+func (m *AgentBaseMutation) Where(ps ...predicate.AgentBase) {
+	m.predicates = append(m.predicates, ps...)
+}
+
+// WhereP appends storage-level predicates to the AgentBaseMutation builder. Using this method,
+// users can use type-assertion to append predicates that do not depend on any generated package.
+func (m *AgentBaseMutation) WhereP(ps ...func(*sql.Selector)) {
+	p := make([]predicate.AgentBase, len(ps))
+	for i := range ps {
+		p[i] = ps[i]
+	}
+	m.Where(p...)
+}
+
+// Op returns the operation name.
+func (m *AgentBaseMutation) Op() Op {
+	return m.op
+}
+
+// SetOp allows setting the mutation operation.
+func (m *AgentBaseMutation) SetOp(op Op) {
+	m.op = op
+}
+
+// Type returns the node type of this mutation (AgentBase).
+func (m *AgentBaseMutation) Type() string {
+	return m.typ
+}
+
+// Fields returns all fields that were changed during this mutation. Note that in
+// order to get all numeric fields that were incremented/decremented, call
+// AddedFields().
+func (m *AgentBaseMutation) Fields() []string {
+	fields := make([]string, 0, 9)
+	if m.q != nil {
+		fields = append(fields, agentbase.FieldQ)
+	}
+	if m.a != nil {
+		fields = append(fields, agentbase.FieldA)
+	}
+	if m.chunk_index != nil {
+		fields = append(fields, agentbase.FieldChunkIndex)
+	}
+	if m.indexes != nil {
+		fields = append(fields, agentbase.FieldIndexes)
+	}
+	if m.dataset_id != nil {
+		fields = append(fields, agentbase.FieldDatasetID)
+	}
+	if m.collection_id != nil {
+		fields = append(fields, agentbase.FieldCollectionID)
+	}
+	if m.source_name != nil {
+		fields = append(fields, agentbase.FieldSourceName)
+	}
+	if m.can_write != nil {
+		fields = append(fields, agentbase.FieldCanWrite)
+	}
+	if m.is_owner != nil {
+		fields = append(fields, agentbase.FieldIsOwner)
+	}
+	return fields
+}
+
+// Field returns the value of a field with the given name. The second boolean
+// return value indicates that this field was not set, or was not defined in the
+// schema.
+func (m *AgentBaseMutation) Field(name string) (ent.Value, bool) {
+	switch name {
+	case agentbase.FieldQ:
+		return m.Q()
+	case agentbase.FieldA:
+		return m.A()
+	case agentbase.FieldChunkIndex:
+		return m.ChunkIndex()
+	case agentbase.FieldIndexes:
+		return m.Indexes()
+	case agentbase.FieldDatasetID:
+		return m.DatasetID()
+	case agentbase.FieldCollectionID:
+		return m.CollectionID()
+	case agentbase.FieldSourceName:
+		return m.SourceName()
+	case agentbase.FieldCanWrite:
+		return m.CanWrite()
+	case agentbase.FieldIsOwner:
+		return m.IsOwner()
+	}
+	return nil, false
+}
+
+// OldField returns the old value of the field from the database. An error is
+// returned if the mutation operation is not UpdateOne, or the query to the
+// database failed.
+func (m *AgentBaseMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
+	switch name {
+	case agentbase.FieldQ:
+		return m.OldQ(ctx)
+	case agentbase.FieldA:
+		return m.OldA(ctx)
+	case agentbase.FieldChunkIndex:
+		return m.OldChunkIndex(ctx)
+	case agentbase.FieldIndexes:
+		return m.OldIndexes(ctx)
+	case agentbase.FieldDatasetID:
+		return m.OldDatasetID(ctx)
+	case agentbase.FieldCollectionID:
+		return m.OldCollectionID(ctx)
+	case agentbase.FieldSourceName:
+		return m.OldSourceName(ctx)
+	case agentbase.FieldCanWrite:
+		return m.OldCanWrite(ctx)
+	case agentbase.FieldIsOwner:
+		return m.OldIsOwner(ctx)
+	}
+	return nil, fmt.Errorf("unknown AgentBase field %s", name)
+}
+
+// SetField sets the value of a field with the given name. It returns an error if
+// the field is not defined in the schema, or if the type mismatched the field
+// type.
+func (m *AgentBaseMutation) SetField(name string, value ent.Value) error {
+	switch name {
+	case agentbase.FieldQ:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetQ(v)
+		return nil
+	case agentbase.FieldA:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetA(v)
+		return nil
+	case agentbase.FieldChunkIndex:
+		v, ok := value.(uint64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetChunkIndex(v)
+		return nil
+	case agentbase.FieldIndexes:
+		v, ok := value.([]string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetIndexes(v)
+		return nil
+	case agentbase.FieldDatasetID:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetDatasetID(v)
+		return nil
+	case agentbase.FieldCollectionID:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCollectionID(v)
+		return nil
+	case agentbase.FieldSourceName:
+		v, ok := value.(string)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetSourceName(v)
+		return nil
+	case agentbase.FieldCanWrite:
+		v, ok := value.([]bool)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetCanWrite(v)
+		return nil
+	case agentbase.FieldIsOwner:
+		v, ok := value.([]bool)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.SetIsOwner(v)
+		return nil
+	}
+	return fmt.Errorf("unknown AgentBase field %s", name)
+}
+
+// AddedFields returns all numeric fields that were incremented/decremented during
+// this mutation.
+func (m *AgentBaseMutation) AddedFields() []string {
+	var fields []string
+	if m.addchunk_index != nil {
+		fields = append(fields, agentbase.FieldChunkIndex)
+	}
+	return fields
+}
+
+// AddedField returns the numeric value that was incremented/decremented on a field
+// with the given name. The second boolean return value indicates that this field
+// was not set, or was not defined in the schema.
+func (m *AgentBaseMutation) AddedField(name string) (ent.Value, bool) {
+	switch name {
+	case agentbase.FieldChunkIndex:
+		return m.AddedChunkIndex()
+	}
+	return nil, false
+}
+
+// AddField adds the value to the field with the given name. It returns an error if
+// the field is not defined in the schema, or if the type mismatched the field
+// type.
+func (m *AgentBaseMutation) AddField(name string, value ent.Value) error {
+	switch name {
+	case agentbase.FieldChunkIndex:
+		v, ok := value.(int64)
+		if !ok {
+			return fmt.Errorf("unexpected type %T for field %s", value, name)
+		}
+		m.AddChunkIndex(v)
+		return nil
+	}
+	return fmt.Errorf("unknown AgentBase numeric field %s", name)
+}
+
+// ClearedFields returns all nullable fields that were cleared during this
+// mutation.
+func (m *AgentBaseMutation) ClearedFields() []string {
+	var fields []string
+	if m.FieldCleared(agentbase.FieldQ) {
+		fields = append(fields, agentbase.FieldQ)
+	}
+	if m.FieldCleared(agentbase.FieldA) {
+		fields = append(fields, agentbase.FieldA)
+	}
+	if m.FieldCleared(agentbase.FieldIndexes) {
+		fields = append(fields, agentbase.FieldIndexes)
+	}
+	if m.FieldCleared(agentbase.FieldDatasetID) {
+		fields = append(fields, agentbase.FieldDatasetID)
+	}
+	if m.FieldCleared(agentbase.FieldCollectionID) {
+		fields = append(fields, agentbase.FieldCollectionID)
+	}
+	if m.FieldCleared(agentbase.FieldSourceName) {
+		fields = append(fields, agentbase.FieldSourceName)
+	}
+	if m.FieldCleared(agentbase.FieldCanWrite) {
+		fields = append(fields, agentbase.FieldCanWrite)
+	}
+	if m.FieldCleared(agentbase.FieldIsOwner) {
+		fields = append(fields, agentbase.FieldIsOwner)
+	}
+	return fields
+}
+
+// FieldCleared returns a boolean indicating if a field with the given name was
+// cleared in this mutation.
+func (m *AgentBaseMutation) FieldCleared(name string) bool {
+	_, ok := m.clearedFields[name]
+	return ok
+}
+
+// ClearField clears the value of the field with the given name. It returns an
+// error if the field is not defined in the schema.
+func (m *AgentBaseMutation) ClearField(name string) error {
+	switch name {
+	case agentbase.FieldQ:
+		m.ClearQ()
+		return nil
+	case agentbase.FieldA:
+		m.ClearA()
+		return nil
+	case agentbase.FieldIndexes:
+		m.ClearIndexes()
+		return nil
+	case agentbase.FieldDatasetID:
+		m.ClearDatasetID()
+		return nil
+	case agentbase.FieldCollectionID:
+		m.ClearCollectionID()
+		return nil
+	case agentbase.FieldSourceName:
+		m.ClearSourceName()
+		return nil
+	case agentbase.FieldCanWrite:
+		m.ClearCanWrite()
+		return nil
+	case agentbase.FieldIsOwner:
+		m.ClearIsOwner()
+		return nil
+	}
+	return fmt.Errorf("unknown AgentBase nullable field %s", name)
+}
+
+// ResetField resets all changes in the mutation for the field with the given name.
+// It returns an error if the field is not defined in the schema.
+func (m *AgentBaseMutation) ResetField(name string) error {
+	switch name {
+	case agentbase.FieldQ:
+		m.ResetQ()
+		return nil
+	case agentbase.FieldA:
+		m.ResetA()
+		return nil
+	case agentbase.FieldChunkIndex:
+		m.ResetChunkIndex()
+		return nil
+	case agentbase.FieldIndexes:
+		m.ResetIndexes()
+		return nil
+	case agentbase.FieldDatasetID:
+		m.ResetDatasetID()
+		return nil
+	case agentbase.FieldCollectionID:
+		m.ResetCollectionID()
+		return nil
+	case agentbase.FieldSourceName:
+		m.ResetSourceName()
+		return nil
+	case agentbase.FieldCanWrite:
+		m.ResetCanWrite()
+		return nil
+	case agentbase.FieldIsOwner:
+		m.ResetIsOwner()
+		return nil
+	}
+	return fmt.Errorf("unknown AgentBase field %s", name)
+}
+
+// AddedEdges returns all edge names that were set/added in this mutation.
+func (m *AgentBaseMutation) AddedEdges() []string {
+	edges := make([]string, 0, 1)
+	if m.wx_agent != nil {
+		edges = append(edges, agentbase.EdgeWxAgent)
+	}
+	return edges
+}
+
+// AddedIDs returns all IDs (to other nodes) that were added for the given edge
+// name in this mutation.
+func (m *AgentBaseMutation) AddedIDs(name string) []ent.Value {
+	switch name {
+	case agentbase.EdgeWxAgent:
+		ids := make([]ent.Value, 0, len(m.wx_agent))
+		for id := range m.wx_agent {
+			ids = append(ids, id)
+		}
+		return ids
+	}
+	return nil
+}
+
+// RemovedEdges returns all edge names that were removed in this mutation.
+func (m *AgentBaseMutation) RemovedEdges() []string {
+	edges := make([]string, 0, 1)
+	if m.removedwx_agent != nil {
+		edges = append(edges, agentbase.EdgeWxAgent)
+	}
+	return edges
+}
+
+// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
+// the given name in this mutation.
+func (m *AgentBaseMutation) RemovedIDs(name string) []ent.Value {
+	switch name {
+	case agentbase.EdgeWxAgent:
+		ids := make([]ent.Value, 0, len(m.removedwx_agent))
+		for id := range m.removedwx_agent {
+			ids = append(ids, id)
+		}
+		return ids
+	}
+	return nil
+}
+
+// ClearedEdges returns all edge names that were cleared in this mutation.
+func (m *AgentBaseMutation) ClearedEdges() []string {
+	edges := make([]string, 0, 1)
+	if m.clearedwx_agent {
+		edges = append(edges, agentbase.EdgeWxAgent)
+	}
+	return edges
+}
+
+// EdgeCleared returns a boolean which indicates if the edge with the given name
+// was cleared in this mutation.
+func (m *AgentBaseMutation) EdgeCleared(name string) bool {
+	switch name {
+	case agentbase.EdgeWxAgent:
+		return m.clearedwx_agent
+	}
+	return false
+}
+
+// ClearEdge clears the value of the edge with the given name. It returns an error
+// if that edge is not defined in the schema.
+func (m *AgentBaseMutation) ClearEdge(name string) error {
+	switch name {
+	}
+	return fmt.Errorf("unknown AgentBase unique edge %s", name)
+}
+
+// ResetEdge resets all changes to the edge with the given name in this mutation.
+// It returns an error if the edge is not defined in the schema.
+func (m *AgentBaseMutation) ResetEdge(name string) error {
+	switch name {
+	case agentbase.EdgeWxAgent:
+		m.ResetWxAgent()
+		return nil
+	}
+	return fmt.Errorf("unknown AgentBase edge %s", name)
+}
+
 // BatchMsgMutation represents an operation that mutates the BatchMsg nodes in the graph.
 type BatchMsgMutation struct {
 	config

+ 82 - 0
ent/pagination.go

@@ -6,6 +6,7 @@ import (
 	"context"
 	"fmt"
 	"wechat-api/ent/agent"
+	"wechat-api/ent/agentbase"
 	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/category"
 	"wechat-api/ent/contact"
@@ -153,6 +154,87 @@ func (a *AgentQuery) Page(
 	return ret, nil
 }
 
+type AgentBasePager struct {
+	Order  agentbase.OrderOption
+	Filter func(*AgentBaseQuery) (*AgentBaseQuery, error)
+}
+
+// AgentBasePaginateOption enables pagination customization.
+type AgentBasePaginateOption func(*AgentBasePager)
+
+// DefaultAgentBaseOrder is the default ordering of AgentBase.
+var DefaultAgentBaseOrder = Desc(agentbase.FieldID)
+
+func newAgentBasePager(opts []AgentBasePaginateOption) (*AgentBasePager, error) {
+	pager := &AgentBasePager{}
+	for _, opt := range opts {
+		opt(pager)
+	}
+	if pager.Order == nil {
+		pager.Order = DefaultAgentBaseOrder
+	}
+	return pager, nil
+}
+
+func (p *AgentBasePager) ApplyFilter(query *AgentBaseQuery) (*AgentBaseQuery, error) {
+	if p.Filter != nil {
+		return p.Filter(query)
+	}
+	return query, nil
+}
+
+// AgentBasePageList is AgentBase PageList result.
+type AgentBasePageList struct {
+	List        []*AgentBase `json:"list"`
+	PageDetails *PageDetails `json:"pageDetails"`
+}
+
+func (ab *AgentBaseQuery) Page(
+	ctx context.Context, pageNum uint64, pageSize uint64, opts ...AgentBasePaginateOption,
+) (*AgentBasePageList, error) {
+
+	pager, err := newAgentBasePager(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	if ab, err = pager.ApplyFilter(ab); err != nil {
+		return nil, err
+	}
+
+	ret := &AgentBasePageList{}
+
+	ret.PageDetails = &PageDetails{
+		Page: pageNum,
+		Size: pageSize,
+	}
+
+	query := ab.Clone()
+	query.ctx.Fields = nil
+	count, err := query.Count(ctx)
+
+	if err != nil {
+		return nil, err
+	}
+
+	ret.PageDetails.Total = uint64(count)
+
+	if pager.Order != nil {
+		ab = ab.Order(pager.Order)
+	} else {
+		ab = ab.Order(DefaultAgentBaseOrder)
+	}
+
+	ab = ab.Offset(int((pageNum - 1) * pageSize)).Limit(int(pageSize))
+	list, err := ab.All(ctx)
+	if err != nil {
+		return nil, err
+	}
+	ret.List = list
+
+	return ret, nil
+}
+
 type BatchMsgPager struct {
 	Order  batchmsg.OrderOption
 	Filter func(*BatchMsgQuery) (*BatchMsgQuery, error)

+ 3 - 0
ent/predicate/predicate.go

@@ -9,6 +9,9 @@ import (
 // Agent is the predicate function for agent builders.
 type Agent func(*sql.Selector)
 
+// AgentBase is the predicate function for agentbase builders.
+type AgentBase func(*sql.Selector)
+
 // BatchMsg is the predicate function for batchmsg builders.
 type BatchMsg func(*sql.Selector)
 

+ 27 - 0
ent/runtime/runtime.go

@@ -5,6 +5,7 @@ package runtime
 import (
 	"time"
 	"wechat-api/ent/agent"
+	"wechat-api/ent/agentbase"
 	"wechat-api/ent/batchmsg"
 	"wechat-api/ent/category"
 	"wechat-api/ent/contact"
@@ -91,6 +92,32 @@ func init() {
 	agent.DefaultCollectionID = agentDescCollectionID.Default.(string)
 	// agent.CollectionIDValidator is a validator for the "collection_id" field. It is called by the builders before save.
 	agent.CollectionIDValidator = agentDescCollectionID.Validators[0].(func(string) error)
+	agentbaseFields := schema.AgentBase{}.Fields()
+	_ = agentbaseFields
+	// agentbaseDescQ is the schema descriptor for q field.
+	agentbaseDescQ := agentbaseFields[1].Descriptor()
+	// agentbase.DefaultQ holds the default value on creation for the q field.
+	agentbase.DefaultQ = agentbaseDescQ.Default.(string)
+	// agentbaseDescA is the schema descriptor for a field.
+	agentbaseDescA := agentbaseFields[2].Descriptor()
+	// agentbase.DefaultA holds the default value on creation for the a field.
+	agentbase.DefaultA = agentbaseDescA.Default.(string)
+	// agentbaseDescChunkIndex is the schema descriptor for chunk_index field.
+	agentbaseDescChunkIndex := agentbaseFields[3].Descriptor()
+	// agentbase.ChunkIndexValidator is a validator for the "chunk_index" field. It is called by the builders before save.
+	agentbase.ChunkIndexValidator = agentbaseDescChunkIndex.Validators[0].(func(uint64) error)
+	// agentbaseDescDatasetID is the schema descriptor for dataset_id field.
+	agentbaseDescDatasetID := agentbaseFields[5].Descriptor()
+	// agentbase.DefaultDatasetID holds the default value on creation for the dataset_id field.
+	agentbase.DefaultDatasetID = agentbaseDescDatasetID.Default.(string)
+	// agentbaseDescCollectionID is the schema descriptor for collection_id field.
+	agentbaseDescCollectionID := agentbaseFields[6].Descriptor()
+	// agentbase.DefaultCollectionID holds the default value on creation for the collection_id field.
+	agentbase.DefaultCollectionID = agentbaseDescCollectionID.Default.(string)
+	// agentbaseDescSourceName is the schema descriptor for source_name field.
+	agentbaseDescSourceName := agentbaseFields[7].Descriptor()
+	// agentbase.DefaultSourceName holds the default value on creation for the source_name field.
+	agentbase.DefaultSourceName = agentbaseDescSourceName.Default.(string)
 	batchmsgMixin := schema.BatchMsg{}.Mixin()
 	batchmsgMixinHooks1 := batchmsgMixin[1].Hooks()
 	batchmsg.Hooks[0] = batchmsgMixinHooks1[0]

+ 55 - 0
ent/schema/agent_base.go

@@ -0,0 +1,55 @@
+package schema
+
+import (
+	"entgo.io/ent"
+	"entgo.io/ent/dialect/entsql"
+	"entgo.io/ent/schema"
+	"entgo.io/ent/schema/edge"
+	"entgo.io/ent/schema/field"
+)
+
+type AgentBase struct {
+	ent.Schema
+}
+
+func (AgentBase) Fields() []ent.Field {
+	return []ent.Field{
+		field.String("id").Comment("id"),
+		field.String("q").Optional().Default("").Comment("q"),
+		field.String("a").Optional().Default("").Comment("a"),
+		field.Uint64("chunk_index").Positive().Comment("chunk_index"),
+		field.JSON("indexes", []string{}).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("indexes"),
+		field.String("dataset_id").Optional().Default("").Comment("dataset_id"),
+		field.String("collection_id").Optional().Default("").Comment("collection_id"),
+		field.String("source_name").Optional().Default("").Comment("source_name"),
+		field.JSON("can_write", []bool{}).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("can_write"),
+		field.JSON("is_owner", []bool{}).Optional().
+			Annotations(entsql.WithComments(true)).
+			Comment("is_owner"),
+	}
+}
+
+func (AgentBase) Mixin() []ent.Mixin {
+	return []ent.Mixin{}
+}
+
+func (AgentBase) Edges() []ent.Edge {
+	return []ent.Edge{
+		edge.To("wx_agent", Wx.Type),
+	}
+}
+
+func (AgentBase) Indexes() []ent.Index {
+	return []ent.Index{}
+}
+
+func (AgentBase) Annotations() []schema.Annotation {
+	return []schema.Annotation{
+		entsql.WithComments(true),
+		entsql.Annotation{Table: "agent_base"},
+	}
+}

+ 1 - 0
ent/server_query.go

@@ -412,6 +412,7 @@ func (sq *ServerQuery) loadWxs(ctx context.Context, query *WxQuery, nodes []*Ser
 			init(nodes[i])
 		}
 	}
+	query.withFKs = true
 	if len(query.ctx.Fields) > 0 {
 		query.ctx.AppendFieldOnce(wx.FieldServerID)
 	}

+ 216 - 0
ent/set_not_nil.go

@@ -248,6 +248,222 @@ func (a *AgentCreate) SetNotNilCollectionID(value *string) *AgentCreate {
 }
 
 // set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilQ(value *string) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetQ(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilQ(value *string) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetQ(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilQ(value *string) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetQ(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilA(value *string) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetA(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilA(value *string) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetA(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilA(value *string) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetA(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilChunkIndex(value *uint64) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetChunkIndex(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilChunkIndex(value *uint64) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetChunkIndex(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilChunkIndex(value *uint64) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetChunkIndex(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilIndexes(value []string) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetIndexes(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilIndexes(value []string) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetIndexes(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilIndexes(value []string) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetIndexes(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilDatasetID(value *string) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetDatasetID(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilDatasetID(value *string) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetDatasetID(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilDatasetID(value *string) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetDatasetID(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilCollectionID(value *string) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetCollectionID(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilCollectionID(value *string) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetCollectionID(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilCollectionID(value *string) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetCollectionID(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilSourceName(value *string) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetSourceName(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilSourceName(value *string) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetSourceName(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilSourceName(value *string) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetSourceName(*value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilCanWrite(value []bool) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetCanWrite(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilCanWrite(value []bool) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetCanWrite(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilCanWrite(value []bool) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetCanWrite(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdate) SetNotNilIsOwner(value []bool) *AgentBaseUpdate {
+	if value != nil {
+		return ab.SetIsOwner(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseUpdateOne) SetNotNilIsOwner(value []bool) *AgentBaseUpdateOne {
+	if value != nil {
+		return ab.SetIsOwner(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
+func (ab *AgentBaseCreate) SetNotNilIsOwner(value []bool) *AgentBaseCreate {
+	if value != nil {
+		return ab.SetIsOwner(value)
+	}
+	return ab
+}
+
+// set field if value's pointer is not nil.
 func (bm *BatchMsgUpdate) SetNotNilUpdatedAt(value *time.Time) *BatchMsgUpdate {
 	if value != nil {
 		return bm.SetUpdatedAt(*value)

+ 3 - 0
ent/tx.go

@@ -16,6 +16,8 @@ type Tx struct {
 	config
 	// Agent is the client for interacting with the Agent builders.
 	Agent *AgentClient
+	// AgentBase is the client for interacting with the AgentBase builders.
+	AgentBase *AgentBaseClient
 	// BatchMsg is the client for interacting with the BatchMsg builders.
 	BatchMsg *BatchMsgClient
 	// Category is the client for interacting with the Category builders.
@@ -184,6 +186,7 @@ func (tx *Tx) Client() *Client {
 
 func (tx *Tx) init() {
 	tx.Agent = NewAgentClient(tx.config)
+	tx.AgentBase = NewAgentBaseClient(tx.config)
 	tx.BatchMsg = NewBatchMsgClient(tx.config)
 	tx.Category = NewCategoryClient(tx.config)
 	tx.Contact = NewContactClient(tx.config)

+ 12 - 2
ent/wx.go

@@ -64,8 +64,9 @@ type Wx struct {
 	GroupBlockList []string `json:"group_block_list,omitempty"`
 	// Edges holds the relations/edges for other nodes in the graph.
 	// The values are being populated by the WxQuery when eager-loading is set.
-	Edges        WxEdges `json:"edges"`
-	selectValues sql.SelectValues
+	Edges               WxEdges `json:"edges"`
+	agent_base_wx_agent *string
+	selectValues        sql.SelectValues
 }
 
 // WxEdges holds the relations/edges for other nodes in the graph.
@@ -114,6 +115,8 @@ func (*Wx) scanValues(columns []string) ([]any, error) {
 			values[i] = new(sql.NullString)
 		case wx.FieldCreatedAt, wx.FieldUpdatedAt, wx.FieldDeletedAt:
 			values[i] = new(sql.NullTime)
+		case wx.ForeignKeys[0]: // agent_base_wx_agent
+			values[i] = new(sql.NullString)
 		default:
 			values[i] = new(sql.UnknownType)
 		}
@@ -269,6 +272,13 @@ func (w *Wx) assignValues(columns []string, values []any) error {
 					return fmt.Errorf("unmarshal field group_block_list: %w", err)
 				}
 			}
+		case wx.ForeignKeys[0]:
+			if value, ok := values[i].(*sql.NullString); !ok {
+				return fmt.Errorf("unexpected type %T for field agent_base_wx_agent", values[i])
+			} else if value.Valid {
+				w.agent_base_wx_agent = new(string)
+				*w.agent_base_wx_agent = value.String
+			}
 		default:
 			w.selectValues.Set(columns[i], values[i])
 		}

+ 11 - 0
ent/wx/wx.go

@@ -105,6 +105,12 @@ var Columns = []string{
 	FieldGroupBlockList,
 }
 
+// ForeignKeys holds the SQL foreign-keys that are owned by the "wx"
+// table and are not defined as standalone fields in the schema.
+var ForeignKeys = []string{
+	"agent_base_wx_agent",
+}
+
 // ValidColumn reports if the column name is valid (part of the table columns).
 func ValidColumn(column string) bool {
 	for i := range Columns {
@@ -112,6 +118,11 @@ func ValidColumn(column string) bool {
 			return true
 		}
 	}
+	for i := range ForeignKeys {
+		if column == ForeignKeys[i] {
+			return true
+		}
+	}
 	return false
 }
 

+ 5 - 0
ent/wx_query.go

@@ -25,6 +25,7 @@ type WxQuery struct {
 	predicates []predicate.Wx
 	withServer *ServerQuery
 	withAgent  *AgentQuery
+	withFKs    bool
 	// intermediate query (i.e. traversal path).
 	sql  *sql.Selector
 	path func(context.Context) (*sql.Selector, error)
@@ -404,12 +405,16 @@ func (wq *WxQuery) prepareQuery(ctx context.Context) error {
 func (wq *WxQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Wx, error) {
 	var (
 		nodes       = []*Wx{}
+		withFKs     = wq.withFKs
 		_spec       = wq.querySpec()
 		loadedTypes = [2]bool{
 			wq.withServer != nil,
 			wq.withAgent != nil,
 		}
 	)
+	if withFKs {
+		_spec.Node.Columns = append(_spec.Node.Columns, wx.ForeignKeys...)
+	}
 	_spec.ScanValues = func(columns []string) ([]any, error) {
 		return (*Wx).scanValues(nil, columns)
 	}

+ 44 - 0
internal/handler/agent_base/create_agent_base_handler.go

@@ -0,0 +1,44 @@
+package agent_base
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/agent_base"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /agent_base/create agent_base CreateAgentBase
+//
+// Create agent base information | 创建AgentBase
+//
+// Create agent base information | 创建AgentBase
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: CreateDataInfoReq
+//
+// Responses:
+//  200: BaseDataInfo
+
+func CreateAgentBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.CreateDataInfoReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := agent_base.NewCreateAgentBaseLogic(r.Context(), svcCtx)
+		resp, err := l.CreateAgentBase(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/agent_base/delete_agent_base_handler.go

@@ -0,0 +1,44 @@
+package agent_base
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/agent_base"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /agent_base/delete agent_base DeleteAgentBase
+//
+// Delete agent base information | 删除AgentBase信息
+//
+// Delete agent base information | 删除AgentBase信息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: DeleteDataReq
+//
+// Responses:
+//  200: BaseDataInfo
+
+func DeleteAgentBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.DeleteDataReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := agent_base.NewDeleteAgentBaseLogic(r.Context(), svcCtx)
+		resp, err := l.DeleteAgentBase(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/agent_base/get_agent_base_by_id_handler.go

@@ -0,0 +1,44 @@
+package agent_base
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/agent_base"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /agent_base agent_base GetAgentBaseById
+//
+// Get agent base by ID | 通过ID获取AgentBase
+//
+// Get agent base by ID | 通过ID获取AgentBase
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: DataDetailReq
+//
+// Responses:
+//  200: DataDetailResp
+
+func GetAgentBaseByIdHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.DataDetailReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := agent_base.NewGetAgentBaseByIdLogic(r.Context(), svcCtx)
+		resp, err := l.GetAgentBaseById(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/agent_base/get_agent_base_list_handler.go

@@ -0,0 +1,44 @@
+package agent_base
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/agent_base"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /agent_base/list agent_base GetAgentBaseList
+//
+// Get agent base list | 获取AgentBase列表
+//
+// Get agent base list | 获取AgentBase列表
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: DataListReq
+//
+// Responses:
+//  200: DataListResp
+
+func GetAgentBaseListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.DataListReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := agent_base.NewGetAgentBaseListLogic(r.Context(), svcCtx)
+		resp, err := l.GetAgentBaseList(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/agent_base/update_agent_base_handler.go

@@ -0,0 +1,44 @@
+package agent_base
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/agent_base"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /agent_base/update agent_base UpdateAgentBase
+//
+// Update agent base information | 更新AgentBase
+//
+// Update agent base information | 更新AgentBase
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: UpdateDataInfoReq
+//
+// Responses:
+//  200: BaseDataInfo
+
+func UpdateAgentBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.UpdateDataInfoReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := agent_base.NewUpdateAgentBaseLogic(r.Context(), svcCtx)
+		resp, err := l.UpdateAgentBase(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 35 - 0
internal/handler/routes.go

@@ -12,6 +12,7 @@ import (
 	Wx "wechat-api/internal/handler/Wx"
 	Wxhook "wechat-api/internal/handler/Wxhook"
 	agent "wechat-api/internal/handler/agent"
+	agent_base "wechat-api/internal/handler/agent_base"
 	base "wechat-api/internal/handler/base"
 	batch_msg "wechat-api/internal/handler/batch_msg"
 	category "wechat-api/internal/handler/category"
@@ -917,4 +918,38 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 		),
 		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
 	)
+
+	server.AddRoutes(
+		rest.WithMiddlewares(
+			[]rest.Middleware{serverCtx.Authority},
+			[]rest.Route{
+				{
+					Method:  http.MethodPost,
+					Path:    "/agent_base/create",
+					Handler: agent_base.CreateAgentBaseHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/agent_base/update",
+					Handler: agent_base.UpdateAgentBaseHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/agent_base/delete",
+					Handler: agent_base.DeleteAgentBaseHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/agent_base/list",
+					Handler: agent_base.GetAgentBaseListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/agent_base",
+					Handler: agent_base.GetAgentBaseByIdHandler(serverCtx),
+				},
+			}...,
+		),
+		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
+	)
 }

+ 1 - 1
internal/logic/WechatServer/delete_server_logic.go

@@ -32,6 +32,6 @@ func (l *DeleteServerLogic) DeleteServer(req *types.IDsReq) (*types.BaseMsgResp,
 	if err != nil {
 		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
 	}
-
+	l.svcCtx.Rds.Del(l.ctx, "crontask_wx_server_info")
 	return &types.BaseMsgResp{Msg: errormsg.DeleteSuccess}, nil
 }

+ 1 - 0
internal/logic/WechatServer/update_server_logic.go

@@ -42,5 +42,6 @@ func (l *UpdateServerLogic) UpdateServer(req *types.ServerInfo) (*types.BaseMsgR
 		"admin_port": req.AdminPort,
 	}
 	l.svcCtx.Rds.HSet(l.ctx, "server_info", req.Id, data)
+	l.svcCtx.Rds.Del(l.ctx, "crontask_wx_server_info")
 	return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
 }

+ 1 - 0
internal/logic/Wx/check_wx_logic.go

@@ -116,6 +116,7 @@ func (l *CheckWxLogic) CheckWx(req *types.WxInfo) (resp *types.BaseMsgResp, err
 				"group_block_list": wxInfo.GroupBlockList,
 			}
 			l.svcCtx.Rds.HSet(l.ctx, "wx_info", selfInfo.Wxid, data)
+			l.svcCtx.Rds.HDel(l.ctx, "crontask_wx_server_info", selfInfo.Wxid)
 		}
 		if dbErr != nil {
 			return nil, dberrorhandler.DefaultEntError(l.Logger, dbErr, req)

+ 6 - 0
internal/logic/Wx/get_wx_list_logic.go

@@ -116,6 +116,12 @@ func (l *GetWxListLogic) GetWxList(req *types.WxListReq) (*types.WxListResp, err
 			if err != nil {
 				l.Error("获取登录信息失败", err)
 			} else {
+				if wxid != wxInfo.Wxid {
+					l.svcCtx.Rds.HDel(l.ctx, "wx_info", wxid)
+					l.svcCtx.Rds.HDel(l.ctx, "wx_info", wxInfo.Wxid)
+					l.svcCtx.Rds.HDel(l.ctx, "crontask_wx_server_info", wxid)
+					l.svcCtx.Rds.HDel(l.ctx, "crontask_wx_server_info", wxInfo.Wxid)
+				}
 				processID = wxInfo.ProcessID
 				wxid = wxInfo.Wxid
 				account = wxInfo.Account

+ 54 - 0
internal/logic/agent_base/create_agent_base_logic.go

@@ -0,0 +1,54 @@
+package agent_base
+
+import (
+	"context"
+	"fmt"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/hook/fastgpt"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type CreateAgentBaseLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewCreateAgentBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateAgentBaseLogic {
+	return &CreateAgentBaseLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *CreateAgentBaseLogic) CreateAgentBase(req *types.CreateDataInfoReq) (*types.BaseDataInfo, error) {
+	params := fastgpt.CreateBulkDataReq{}
+	params.CollectionID = *req.CollectionId
+	params.TrainingMode = "chunk"
+	pair := make([]fastgpt.DataQuestion, 0, 1)
+	pair = append(pair, fastgpt.DataQuestion{
+		Q: *req.Q,
+		A: *req.A,
+	})
+	params.Data = append(params.Data, pair...)
+
+	resp, err := fastgpt.CreateBulkData(&params)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt create data failed " + err.Error())
+	}
+
+	if resp.Code == 200 {
+		return &types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+			Data: fmt.Sprintf("Insert %d rows", resp.Data.InsertLen),
+		}, nil
+	}
+
+	return nil, errorx.NewInvalidArgumentError(resp.StatusText)
+}

+ 43 - 0
internal/logic/agent_base/delete_agent_base_logic.go

@@ -0,0 +1,43 @@
+package agent_base
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/hook/fastgpt"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type DeleteAgentBaseLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewDeleteAgentBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteAgentBaseLogic {
+	return &DeleteAgentBaseLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *DeleteAgentBaseLogic) DeleteAgentBase(req *types.DeleteDataReq) (*types.BaseDataInfo, error) {
+	resp, err := fastgpt.DeleteData(*req.ID)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt create data failed " + err.Error())
+	}
+
+	if resp.Code == 200 {
+		return &types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+			Data: "",
+		}, nil
+	}
+
+	return nil, errorx.NewInvalidArgumentError(resp.StatusText)
+}

+ 66 - 0
internal/logic/agent_base/get_agent_base_by_id_logic.go

@@ -0,0 +1,66 @@
+package agent_base
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/hook/fastgpt"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetAgentBaseByIdLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetAgentBaseByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentBaseByIdLogic {
+	return &GetAgentBaseByIdLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetAgentBaseByIdLogic) GetAgentBaseById(req *types.DataDetailReq) (*types.DataDetailResp, error) {
+	resp, err := fastgpt.GetDataDetail(*req.ID)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt get data failed " + err.Error())
+	}
+
+	if resp.Code == 200 {
+		indexes := make([]types.Index, 0, len(resp.Data.Indexes))
+		for _, val := range resp.Data.Indexes {
+			indexes = append(indexes, types.Index{
+				DefaultIndex: &val.DefaultIndex,
+				Text:         &val.Text,
+				DataId:       &val.DataID,
+				ID:           &val.ID,
+			})
+		}
+
+		return &types.DataDetailResp{
+			BaseDataInfo: types.BaseDataInfo{
+				Code: 0,
+				Msg:  errormsg.Success,
+			},
+			Data: types.DataInfo{
+				ID:           &resp.Data.ID,
+				Q:            &resp.Data.Q,
+				A:            &resp.Data.A,
+				ChunkIndex:   &resp.Data.ChunkIndex,
+				DatasetId:    &resp.Data.DatasetID,
+				CollectionId: &resp.Data.CollectionID,
+				SourceName:   &resp.Data.SourceName,
+				CanWrite:     &resp.Data.CanWrite,
+				IsOwner:      &resp.Data.IsOwner,
+				Indexes:      indexes,
+			},
+		}, nil
+	}
+
+	return nil, errorx.NewInvalidArgumentError(resp.StatusText)
+}

+ 59 - 0
internal/logic/agent_base/get_agent_base_list_logic.go

@@ -0,0 +1,59 @@
+package agent_base
+
+import (
+	"context"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/hook/fastgpt"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type GetAgentBaseListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewGetAgentBaseListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetAgentBaseListLogic {
+	return &GetAgentBaseListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *GetAgentBaseListLogic) GetAgentBaseList(req *types.DataListReq) (*types.DataListResp, error) {
+	dataResp := types.DataListResp{}
+	dataResp.PageNum = req.PageNum
+	dataResp.PageSize = req.PageSize
+	var total int
+
+	var params fastgpt.GetDataListReq
+	params.CollectionId = *req.CollectionId
+	params.PageSize = *req.PageSize
+	params.PageNum = *req.PageNum
+	resp, err := fastgpt.GetDataList(&params)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt get data list failed " + err.Error())
+	}
+
+	dataResp.Data = make([]types.DataSimpleInfo, 0, 1)
+	dataResp.Total = &total
+	if resp.Code == 200 && resp.Data.Total > 0 {
+		for _, val := range resp.Data.Data {
+			dataResp.Data = append(dataResp.Data, types.DataSimpleInfo{
+				ID:           &val.ID,
+				Q:            &val.Q,
+				A:            &val.A,
+				ChunkIndex:   &val.ChunkIndex,
+				DatasetId:    &val.DatasetID,
+				CollectionId: &val.CollectionID,
+			})
+		}
+		dataResp.Total = &resp.Data.Total
+	}
+
+	return &dataResp, nil
+}

+ 47 - 0
internal/logic/agent_base/update_agent_base_logic.go

@@ -0,0 +1,47 @@
+package agent_base
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/hook/fastgpt"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type UpdateAgentBaseLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewUpdateAgentBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateAgentBaseLogic {
+	return &UpdateAgentBaseLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *UpdateAgentBaseLogic) UpdateAgentBase(req *types.UpdateDataInfoReq) (*types.BaseDataInfo, error) {
+	params := fastgpt.UpdateDataReq{}
+	params.DataId = *req.DataId
+	params.Q = *req.Q
+	params.A = *req.A
+	resp, err := fastgpt.UpdateData(&params)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("fastgpt update data failed " + err.Error())
+	}
+
+	if resp.Code == 200 {
+		return &types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+			Data: "",
+		}, nil
+	}
+
+	return nil, errorx.NewInvalidArgumentError(resp.Message)
+}

+ 62 - 0
internal/logic/base/init_api_data.go

@@ -6,6 +6,68 @@ import (
 )
 
 func (l *InitDatabaseLogic) insertApiData() (err error) {
+	// AgentBase
+
+	_, err = l.svcCtx.CoreRpc.CreateApi(l.ctx, &core.ApiInfo{
+		ServiceName: pointy.GetPointer("Wechat"),
+		Path:        pointy.GetPointer("/agent_base/create"),
+		Description: pointy.GetPointer("apiDesc.createAgentBase"),
+		ApiGroup:    pointy.GetPointer("agent_base"),
+		Method:      pointy.GetPointer("POST"),
+	})
+
+	if err != nil {
+		return err
+	}
+
+	_, err = l.svcCtx.CoreRpc.CreateApi(l.ctx, &core.ApiInfo{
+		ServiceName: pointy.GetPointer("Wechat"),
+		Path:        pointy.GetPointer("/agent_base/update"),
+		Description: pointy.GetPointer("apiDesc.updateAgentBase"),
+		ApiGroup:    pointy.GetPointer("agent_base"),
+		Method:      pointy.GetPointer("POST"),
+	})
+
+	if err != nil {
+		return err
+	}
+
+	_, err = l.svcCtx.CoreRpc.CreateApi(l.ctx, &core.ApiInfo{
+		ServiceName: pointy.GetPointer("Wechat"),
+		Path:        pointy.GetPointer("/agent_base/delete"),
+		Description: pointy.GetPointer("apiDesc.deleteAgentBase"),
+		ApiGroup:    pointy.GetPointer("agent_base"),
+		Method:      pointy.GetPointer("POST"),
+	})
+
+	if err != nil {
+		return err
+	}
+
+	_, err = l.svcCtx.CoreRpc.CreateApi(l.ctx, &core.ApiInfo{
+		ServiceName: pointy.GetPointer("Wechat"),
+		Path:        pointy.GetPointer("/agent_base/list"),
+		Description: pointy.GetPointer("apiDesc.getAgentBaseList"),
+		ApiGroup:    pointy.GetPointer("agent_base"),
+		Method:      pointy.GetPointer("POST"),
+	})
+
+	if err != nil {
+		return err
+	}
+
+	_, err = l.svcCtx.CoreRpc.CreateApi(l.ctx, &core.ApiInfo{
+		ServiceName: pointy.GetPointer("Wechat"),
+		Path:        pointy.GetPointer("/agent_base"),
+		Description: pointy.GetPointer("apiDesc.getAgentBaseById"),
+		ApiGroup:    pointy.GetPointer("agent_base"),
+		Method:      pointy.GetPointer("POST"),
+	})
+
+	if err != nil {
+		return err
+	}
+
 	// Category
 
 	_, err = l.svcCtx.CoreRpc.CreateApi(l.ctx, &core.ApiInfo{

+ 4 - 1
internal/logic/sop_task/get_sop_task_by_id_logic.go

@@ -2,6 +2,7 @@ package sop_task
 
 import (
 	"context"
+	"wechat-api/ent"
 	"wechat-api/ent/soptask"
 
 	"wechat-api/internal/svc"
@@ -32,7 +33,9 @@ func (l *GetSopTaskByIdLogic) GetSopTaskById(req *types.IDReq) (*types.SopTaskIn
 	organizationId := l.ctx.Value("organizationId").(uint64)
 	data, err := l.svcCtx.DB.SopTask.Query().
 		Where(soptask.ID(req.Id), soptask.OrganizationIDEQ(organizationId)).
-		WithTaskStages().
+		WithTaskStages(func(q *ent.SopStageQuery) {
+			q.Order(ent.Asc("index_sort"))
+		}).
 		Only(l.ctx)
 	if err != nil {
 		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)

+ 44 - 2
internal/types/types.go

@@ -642,7 +642,7 @@ type CollectionListResp struct {
 type DataListReq struct {
 	// required : true
 	// min : 0
-	PageNum *int `json:"pageNum" validate:"required,number,gt=0"`
+	PageNum *int `json:"page" validate:"required,number,gt=0"`
 	// required : true
 	// max : 100000
 	PageSize *int `json:"pageSize" validate:"required,number,lt=100000"`
@@ -687,7 +687,7 @@ type CreateDataInfoReq struct {
 type UpdateDataInfoReq struct {
 	// ID
 	// required : true
-	DataId *string `json:"dataId" validate:"required"`
+	DataId *string `json:"id" validate:"required"`
 	// Q
 	// required : true
 	Q *string `json:"q" validate:"required"`
@@ -1971,3 +1971,45 @@ type CategoryInfoResp struct {
 	// Category information | Category数据
 	Data CategoryInfo `json:"data"`
 }
+
+// The data of agent base information | AgentBase信息
+// swagger:model AgentBaseInfo
+type AgentBaseInfo struct {
+	Id *string `json:"id,optional"`
+}
+
+// The response data of agent base list | AgentBase列表数据
+// swagger:model AgentBaseListResp
+type AgentBaseListResp struct {
+	BaseDataInfo
+	// AgentBase list data | AgentBase列表数据
+	Data AgentBaseListInfo `json:"data"`
+}
+
+// AgentBase list data | AgentBase列表数据
+// swagger:model AgentBaseListInfo
+type AgentBaseListInfo struct {
+	BaseListInfo
+	// The API list data | AgentBase列表数据
+	Data []AgentBaseInfo `json:"data"`
+}
+
+// Get agent base list request params | AgentBase列表请求参数
+// swagger:model AgentBaseListReq
+type AgentBaseListReq struct {
+	PageInfo
+	// q
+	Q *string `json:"q,optional"`
+	// a
+	A *string `json:"a,optional"`
+	// dataset_id
+	DatasetId *string `json:"datasetId,optional"`
+}
+
+// AgentBase information response | AgentBase信息返回体
+// swagger:model AgentBaseInfoResp
+type AgentBaseInfoResp struct {
+	BaseDataInfo
+	// AgentBase information | AgentBase数据
+	Data AgentBaseInfo `json:"data"`
+}