Bläddra i källkod

升级token可选AI角色

宋伯文 4 månader sedan
förälder
incheckning
951e95f660

+ 18 - 0
desc/wechat/token.api

@@ -18,6 +18,20 @@ type (
 
 		// 租户ID
 		OrganizationId *uint64 `json:"organization_id,optional"`
+
+		OrganizationName *string `json:"organizationName,optional"`
+
+		AgentId *uint64 `json:"agent_id,optional"`
+
+		AgentInfo *AgentInfo `json:"agent_info,optional"`
+
+        CustomAgentBase *string `json:"custom_agent_base,optional"`
+
+        CustomAgentKey *string `json:"custom_agent_key,optional"`
+
+        OpenaiBase *string `json:"openai_base,optional"`
+
+        OpenaiKey *string `json:"openai_key,optional"`
     }
 
     // The response data of token list | Token列表数据
@@ -45,6 +59,10 @@ type (
 
         // Mac地址 
         Mac  *string `json:"mac,optional"`
+
+        OrganizationId *uint64 `json:"organization_id,optional"`
+
+        OrganizationName *string `json:"organizationName,optional"`
     }
 
     // Token information response | Token信息返回体

+ 17 - 1
ent/agent.go

@@ -49,9 +49,11 @@ type Agent struct {
 type AgentEdges struct {
 	// WxAgent holds the value of the wx_agent edge.
 	WxAgent []*Wx `json:"wx_agent,omitempty"`
+	// TokenAgent holds the value of the token_agent edge.
+	TokenAgent []*Token `json:"token_agent,omitempty"`
 	// loadedTypes holds the information for reporting if a
 	// type was loaded (or requested) in eager-loading or not.
-	loadedTypes [1]bool
+	loadedTypes [2]bool
 }
 
 // WxAgentOrErr returns the WxAgent value or an error if the edge
@@ -63,6 +65,15 @@ func (e AgentEdges) WxAgentOrErr() ([]*Wx, error) {
 	return nil, &NotLoadedError{edge: "wx_agent"}
 }
 
+// TokenAgentOrErr returns the TokenAgent value or an error if the edge
+// was not loaded in eager-loading.
+func (e AgentEdges) TokenAgentOrErr() ([]*Token, error) {
+	if e.loadedTypes[1] {
+		return e.TokenAgent, nil
+	}
+	return nil, &NotLoadedError{edge: "token_agent"}
+}
+
 // scanValues returns the types for scanning values from sql.Rows.
 func (*Agent) scanValues(columns []string) ([]any, error) {
 	values := make([]any, len(columns))
@@ -179,6 +190,11 @@ func (a *Agent) QueryWxAgent() *WxQuery {
 	return NewAgentClient(a.config).QueryWxAgent(a)
 }
 
+// QueryTokenAgent queries the "token_agent" edge of the Agent entity.
+func (a *Agent) QueryTokenAgent() *TokenQuery {
+	return NewAgentClient(a.config).QueryTokenAgent(a)
+}
+
 // Update returns a builder for updating this Agent.
 // Note that you need to call Agent.Unwrap() before calling this method if this Agent
 // was returned from a transaction, and the transaction was committed or rolled back.

+ 30 - 0
ent/agent/agent.go

@@ -39,6 +39,8 @@ const (
 	FieldCollectionID = "collection_id"
 	// EdgeWxAgent holds the string denoting the wx_agent edge name in mutations.
 	EdgeWxAgent = "wx_agent"
+	// EdgeTokenAgent holds the string denoting the token_agent edge name in mutations.
+	EdgeTokenAgent = "token_agent"
 	// Table holds the table name of the agent in the database.
 	Table = "agent"
 	// WxAgentTable is the table that holds the wx_agent relation/edge.
@@ -48,6 +50,13 @@ const (
 	WxAgentInverseTable = "wx"
 	// WxAgentColumn is the table column denoting the wx_agent relation/edge.
 	WxAgentColumn = "agent_id"
+	// TokenAgentTable is the table that holds the token_agent relation/edge.
+	TokenAgentTable = "token"
+	// TokenAgentInverseTable is the table name for the Token entity.
+	// It exists in this package in order to avoid circular dependency with the "token" package.
+	TokenAgentInverseTable = "token"
+	// TokenAgentColumn is the table column denoting the token_agent relation/edge.
+	TokenAgentColumn = "agent_id"
 )
 
 // Columns holds all SQL columns for agent fields.
@@ -188,6 +197,20 @@ func ByWxAgent(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
 		sqlgraph.OrderByNeighborTerms(s, newWxAgentStep(), append([]sql.OrderTerm{term}, terms...)...)
 	}
 }
+
+// ByTokenAgentCount orders the results by token_agent count.
+func ByTokenAgentCount(opts ...sql.OrderTermOption) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborsCount(s, newTokenAgentStep(), opts...)
+	}
+}
+
+// ByTokenAgent orders the results by token_agent terms.
+func ByTokenAgent(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborTerms(s, newTokenAgentStep(), append([]sql.OrderTerm{term}, terms...)...)
+	}
+}
 func newWxAgentStep() *sqlgraph.Step {
 	return sqlgraph.NewStep(
 		sqlgraph.From(Table, FieldID),
@@ -195,3 +218,10 @@ func newWxAgentStep() *sqlgraph.Step {
 		sqlgraph.Edge(sqlgraph.O2M, false, WxAgentTable, WxAgentColumn),
 	)
 }
+func newTokenAgentStep() *sqlgraph.Step {
+	return sqlgraph.NewStep(
+		sqlgraph.From(Table, FieldID),
+		sqlgraph.To(TokenAgentInverseTable, FieldID),
+		sqlgraph.Edge(sqlgraph.O2M, false, TokenAgentTable, TokenAgentColumn),
+	)
+}

+ 23 - 0
ent/agent/where.go

@@ -763,6 +763,29 @@ func HasWxAgentWith(preds ...predicate.Wx) predicate.Agent {
 	})
 }
 
+// HasTokenAgent applies the HasEdge predicate on the "token_agent" edge.
+func HasTokenAgent() predicate.Agent {
+	return predicate.Agent(func(s *sql.Selector) {
+		step := sqlgraph.NewStep(
+			sqlgraph.From(Table, FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, TokenAgentTable, TokenAgentColumn),
+		)
+		sqlgraph.HasNeighbors(s, step)
+	})
+}
+
+// HasTokenAgentWith applies the HasEdge predicate on the "token_agent" edge with a given conditions (other predicates).
+func HasTokenAgentWith(preds ...predicate.Token) predicate.Agent {
+	return predicate.Agent(func(s *sql.Selector) {
+		step := newTokenAgentStep()
+		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.Agent) predicate.Agent {
 	return predicate.Agent(sql.AndPredicates(predicates...))

+ 32 - 0
ent/agent_create.go

@@ -8,6 +8,7 @@ import (
 	"fmt"
 	"time"
 	"wechat-api/ent/agent"
+	"wechat-api/ent/token"
 	"wechat-api/ent/wx"
 
 	"entgo.io/ent/dialect/sql"
@@ -174,6 +175,21 @@ func (ac *AgentCreate) AddWxAgent(w ...*Wx) *AgentCreate {
 	return ac.AddWxAgentIDs(ids...)
 }
 
+// AddTokenAgentIDs adds the "token_agent" edge to the Token entity by IDs.
+func (ac *AgentCreate) AddTokenAgentIDs(ids ...uint64) *AgentCreate {
+	ac.mutation.AddTokenAgentIDs(ids...)
+	return ac
+}
+
+// AddTokenAgent adds the "token_agent" edges to the Token entity.
+func (ac *AgentCreate) AddTokenAgent(t ...*Token) *AgentCreate {
+	ids := make([]uint64, len(t))
+	for i := range t {
+		ids[i] = t[i].ID
+	}
+	return ac.AddTokenAgentIDs(ids...)
+}
+
 // Mutation returns the AgentMutation object of the builder.
 func (ac *AgentCreate) Mutation() *AgentMutation {
 	return ac.mutation
@@ -389,6 +405,22 @@ func (ac *AgentCreate) createSpec() (*Agent, *sqlgraph.CreateSpec) {
 		}
 		_spec.Edges = append(_spec.Edges, edge)
 	}
+	if nodes := ac.mutation.TokenAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges = append(_spec.Edges, edge)
+	}
 	return _node, _spec
 }
 

+ 86 - 12
ent/agent_query.go

@@ -9,6 +9,7 @@ import (
 	"math"
 	"wechat-api/ent/agent"
 	"wechat-api/ent/predicate"
+	"wechat-api/ent/token"
 	"wechat-api/ent/wx"
 
 	"entgo.io/ent/dialect/sql"
@@ -19,11 +20,12 @@ import (
 // AgentQuery is the builder for querying Agent entities.
 type AgentQuery struct {
 	config
-	ctx         *QueryContext
-	order       []agent.OrderOption
-	inters      []Interceptor
-	predicates  []predicate.Agent
-	withWxAgent *WxQuery
+	ctx            *QueryContext
+	order          []agent.OrderOption
+	inters         []Interceptor
+	predicates     []predicate.Agent
+	withWxAgent    *WxQuery
+	withTokenAgent *TokenQuery
 	// intermediate query (i.e. traversal path).
 	sql  *sql.Selector
 	path func(context.Context) (*sql.Selector, error)
@@ -82,6 +84,28 @@ func (aq *AgentQuery) QueryWxAgent() *WxQuery {
 	return query
 }
 
+// QueryTokenAgent chains the current query on the "token_agent" edge.
+func (aq *AgentQuery) QueryTokenAgent() *TokenQuery {
+	query := (&TokenClient{config: aq.config}).Query()
+	query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
+		if err := aq.prepareQuery(ctx); err != nil {
+			return nil, err
+		}
+		selector := aq.sqlQuery(ctx)
+		if err := selector.Err(); err != nil {
+			return nil, err
+		}
+		step := sqlgraph.NewStep(
+			sqlgraph.From(agent.Table, agent.FieldID, selector),
+			sqlgraph.To(token.Table, token.FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, agent.TokenAgentTable, agent.TokenAgentColumn),
+		)
+		fromU = sqlgraph.SetNeighbors(aq.driver.Dialect(), step)
+		return fromU, nil
+	}
+	return query
+}
+
 // First returns the first Agent entity from the query.
 // Returns a *NotFoundError when no Agent was found.
 func (aq *AgentQuery) First(ctx context.Context) (*Agent, error) {
@@ -269,12 +293,13 @@ func (aq *AgentQuery) Clone() *AgentQuery {
 		return nil
 	}
 	return &AgentQuery{
-		config:      aq.config,
-		ctx:         aq.ctx.Clone(),
-		order:       append([]agent.OrderOption{}, aq.order...),
-		inters:      append([]Interceptor{}, aq.inters...),
-		predicates:  append([]predicate.Agent{}, aq.predicates...),
-		withWxAgent: aq.withWxAgent.Clone(),
+		config:         aq.config,
+		ctx:            aq.ctx.Clone(),
+		order:          append([]agent.OrderOption{}, aq.order...),
+		inters:         append([]Interceptor{}, aq.inters...),
+		predicates:     append([]predicate.Agent{}, aq.predicates...),
+		withWxAgent:    aq.withWxAgent.Clone(),
+		withTokenAgent: aq.withTokenAgent.Clone(),
 		// clone intermediate query.
 		sql:  aq.sql.Clone(),
 		path: aq.path,
@@ -292,6 +317,17 @@ func (aq *AgentQuery) WithWxAgent(opts ...func(*WxQuery)) *AgentQuery {
 	return aq
 }
 
+// WithTokenAgent tells the query-builder to eager-load the nodes that are connected to
+// the "token_agent" edge. The optional arguments are used to configure the query builder of the edge.
+func (aq *AgentQuery) WithTokenAgent(opts ...func(*TokenQuery)) *AgentQuery {
+	query := (&TokenClient{config: aq.config}).Query()
+	for _, opt := range opts {
+		opt(query)
+	}
+	aq.withTokenAgent = query
+	return aq
+}
+
 // 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.
 //
@@ -370,8 +406,9 @@ func (aq *AgentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Agent,
 	var (
 		nodes       = []*Agent{}
 		_spec       = aq.querySpec()
-		loadedTypes = [1]bool{
+		loadedTypes = [2]bool{
 			aq.withWxAgent != nil,
+			aq.withTokenAgent != nil,
 		}
 	)
 	_spec.ScanValues = func(columns []string) ([]any, error) {
@@ -399,6 +436,13 @@ func (aq *AgentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Agent,
 			return nil, err
 		}
 	}
+	if query := aq.withTokenAgent; query != nil {
+		if err := aq.loadTokenAgent(ctx, query, nodes,
+			func(n *Agent) { n.Edges.TokenAgent = []*Token{} },
+			func(n *Agent, e *Token) { n.Edges.TokenAgent = append(n.Edges.TokenAgent, e) }); err != nil {
+			return nil, err
+		}
+	}
 	return nodes, nil
 }
 
@@ -433,6 +477,36 @@ func (aq *AgentQuery) loadWxAgent(ctx context.Context, query *WxQuery, nodes []*
 	}
 	return nil
 }
+func (aq *AgentQuery) loadTokenAgent(ctx context.Context, query *TokenQuery, nodes []*Agent, init func(*Agent), assign func(*Agent, *Token)) error {
+	fks := make([]driver.Value, 0, len(nodes))
+	nodeids := make(map[uint64]*Agent)
+	for i := range nodes {
+		fks = append(fks, nodes[i].ID)
+		nodeids[nodes[i].ID] = nodes[i]
+		if init != nil {
+			init(nodes[i])
+		}
+	}
+	if len(query.ctx.Fields) > 0 {
+		query.ctx.AppendFieldOnce(token.FieldAgentID)
+	}
+	query.Where(predicate.Token(func(s *sql.Selector) {
+		s.Where(sql.InValues(s.C(agent.TokenAgentColumn), fks...))
+	}))
+	neighbors, err := query.All(ctx)
+	if err != nil {
+		return err
+	}
+	for _, n := range neighbors {
+		fk := n.AgentID
+		node, ok := nodeids[fk]
+		if !ok {
+			return fmt.Errorf(`unexpected referenced foreign-key "agent_id" returned %v for node %v`, fk, n.ID)
+		}
+		assign(node, n)
+	}
+	return nil
+}
 
 func (aq *AgentQuery) sqlCount(ctx context.Context) (int, error) {
 	_spec := aq.querySpec()

+ 163 - 0
ent/agent_update.go

@@ -9,6 +9,7 @@ import (
 	"time"
 	"wechat-api/ent/agent"
 	"wechat-api/ent/predicate"
+	"wechat-api/ent/token"
 	"wechat-api/ent/wx"
 
 	"entgo.io/ent/dialect/sql"
@@ -214,6 +215,21 @@ func (au *AgentUpdate) AddWxAgent(w ...*Wx) *AgentUpdate {
 	return au.AddWxAgentIDs(ids...)
 }
 
+// AddTokenAgentIDs adds the "token_agent" edge to the Token entity by IDs.
+func (au *AgentUpdate) AddTokenAgentIDs(ids ...uint64) *AgentUpdate {
+	au.mutation.AddTokenAgentIDs(ids...)
+	return au
+}
+
+// AddTokenAgent adds the "token_agent" edges to the Token entity.
+func (au *AgentUpdate) AddTokenAgent(t ...*Token) *AgentUpdate {
+	ids := make([]uint64, len(t))
+	for i := range t {
+		ids[i] = t[i].ID
+	}
+	return au.AddTokenAgentIDs(ids...)
+}
+
 // Mutation returns the AgentMutation object of the builder.
 func (au *AgentUpdate) Mutation() *AgentMutation {
 	return au.mutation
@@ -240,6 +256,27 @@ func (au *AgentUpdate) RemoveWxAgent(w ...*Wx) *AgentUpdate {
 	return au.RemoveWxAgentIDs(ids...)
 }
 
+// ClearTokenAgent clears all "token_agent" edges to the Token entity.
+func (au *AgentUpdate) ClearTokenAgent() *AgentUpdate {
+	au.mutation.ClearTokenAgent()
+	return au
+}
+
+// RemoveTokenAgentIDs removes the "token_agent" edge to Token entities by IDs.
+func (au *AgentUpdate) RemoveTokenAgentIDs(ids ...uint64) *AgentUpdate {
+	au.mutation.RemoveTokenAgentIDs(ids...)
+	return au
+}
+
+// RemoveTokenAgent removes "token_agent" edges to Token entities.
+func (au *AgentUpdate) RemoveTokenAgent(t ...*Token) *AgentUpdate {
+	ids := make([]uint64, len(t))
+	for i := range t {
+		ids[i] = t[i].ID
+	}
+	return au.RemoveTokenAgentIDs(ids...)
+}
+
 // Save executes the query and returns the number of nodes affected by the update operation.
 func (au *AgentUpdate) Save(ctx context.Context) (int, error) {
 	if err := au.defaults(); err != nil {
@@ -417,6 +454,51 @@ func (au *AgentUpdate) sqlSave(ctx context.Context) (n int, err error) {
 		}
 		_spec.Edges.Add = append(_spec.Edges.Add, edge)
 	}
+	if au.mutation.TokenAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := au.mutation.RemovedTokenAgentIDs(); len(nodes) > 0 && !au.mutation.TokenAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.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 := au.mutation.TokenAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.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, au.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{agent.Label}
@@ -622,6 +704,21 @@ func (auo *AgentUpdateOne) AddWxAgent(w ...*Wx) *AgentUpdateOne {
 	return auo.AddWxAgentIDs(ids...)
 }
 
+// AddTokenAgentIDs adds the "token_agent" edge to the Token entity by IDs.
+func (auo *AgentUpdateOne) AddTokenAgentIDs(ids ...uint64) *AgentUpdateOne {
+	auo.mutation.AddTokenAgentIDs(ids...)
+	return auo
+}
+
+// AddTokenAgent adds the "token_agent" edges to the Token entity.
+func (auo *AgentUpdateOne) AddTokenAgent(t ...*Token) *AgentUpdateOne {
+	ids := make([]uint64, len(t))
+	for i := range t {
+		ids[i] = t[i].ID
+	}
+	return auo.AddTokenAgentIDs(ids...)
+}
+
 // Mutation returns the AgentMutation object of the builder.
 func (auo *AgentUpdateOne) Mutation() *AgentMutation {
 	return auo.mutation
@@ -648,6 +745,27 @@ func (auo *AgentUpdateOne) RemoveWxAgent(w ...*Wx) *AgentUpdateOne {
 	return auo.RemoveWxAgentIDs(ids...)
 }
 
+// ClearTokenAgent clears all "token_agent" edges to the Token entity.
+func (auo *AgentUpdateOne) ClearTokenAgent() *AgentUpdateOne {
+	auo.mutation.ClearTokenAgent()
+	return auo
+}
+
+// RemoveTokenAgentIDs removes the "token_agent" edge to Token entities by IDs.
+func (auo *AgentUpdateOne) RemoveTokenAgentIDs(ids ...uint64) *AgentUpdateOne {
+	auo.mutation.RemoveTokenAgentIDs(ids...)
+	return auo
+}
+
+// RemoveTokenAgent removes "token_agent" edges to Token entities.
+func (auo *AgentUpdateOne) RemoveTokenAgent(t ...*Token) *AgentUpdateOne {
+	ids := make([]uint64, len(t))
+	for i := range t {
+		ids[i] = t[i].ID
+	}
+	return auo.RemoveTokenAgentIDs(ids...)
+}
+
 // Where appends a list predicates to the AgentUpdate builder.
 func (auo *AgentUpdateOne) Where(ps ...predicate.Agent) *AgentUpdateOne {
 	auo.mutation.Where(ps...)
@@ -855,6 +973,51 @@ func (auo *AgentUpdateOne) sqlSave(ctx context.Context) (_node *Agent, err error
 		}
 		_spec.Edges.Add = append(_spec.Edges.Add, edge)
 	}
+	if auo.mutation.TokenAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := auo.mutation.RemovedTokenAgentIDs(); len(nodes) > 0 && !auo.mutation.TokenAgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.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 := auo.mutation.TokenAgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.O2M,
+			Inverse: false,
+			Table:   agent.TokenAgentTable,
+			Columns: []string{agent.TokenAgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(token.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
 	_node = &Agent{config: auo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 32 - 0
ent/client.go

@@ -540,6 +540,22 @@ func (c *AgentClient) QueryWxAgent(a *Agent) *WxQuery {
 	return query
 }
 
+// QueryTokenAgent queries the token_agent edge of a Agent.
+func (c *AgentClient) QueryTokenAgent(a *Agent) *TokenQuery {
+	query := (&TokenClient{config: c.config}).Query()
+	query.path = func(context.Context) (fromV *sql.Selector, _ error) {
+		id := a.ID
+		step := sqlgraph.NewStep(
+			sqlgraph.From(agent.Table, agent.FieldID, id),
+			sqlgraph.To(token.Table, token.FieldID),
+			sqlgraph.Edge(sqlgraph.O2M, false, agent.TokenAgentTable, agent.TokenAgentColumn),
+		)
+		fromV = sqlgraph.Neighbors(a.driver.Dialect(), step)
+		return fromV, nil
+	}
+	return query
+}
+
 // Hooks returns the client hooks.
 func (c *AgentClient) Hooks() []Hook {
 	hooks := c.hooks.Agent
@@ -3385,6 +3401,22 @@ func (c *TokenClient) GetX(ctx context.Context, id uint64) *Token {
 	return obj
 }
 
+// QueryAgent queries the agent edge of a Token.
+func (c *TokenClient) QueryAgent(t *Token) *AgentQuery {
+	query := (&AgentClient{config: c.config}).Query()
+	query.path = func(context.Context) (fromV *sql.Selector, _ error) {
+		id := t.ID
+		step := sqlgraph.NewStep(
+			sqlgraph.From(token.Table, token.FieldID, id),
+			sqlgraph.To(agent.Table, agent.FieldID),
+			sqlgraph.Edge(sqlgraph.M2O, true, token.AgentTable, token.AgentColumn),
+		)
+		fromV = sqlgraph.Neighbors(t.driver.Dialect(), step)
+		return fromV, nil
+	}
+	return query
+}
+
 // Hooks returns the client hooks.
 func (c *TokenClient) Hooks() []Hook {
 	hooks := c.hooks.Token

+ 11 - 2
ent/migrate/schema.go

@@ -638,19 +638,27 @@ var (
 		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "expire_at", Type: field.TypeTime, Nullable: true, Comment: "过期时间"},
 		{Name: "token", Type: field.TypeString, Nullable: true, Comment: "Token", Default: ""},
-		{Name: "mac", Type: field.TypeString, Comment: "Mac地址", Default: ""},
+		{Name: "mac", Type: field.TypeString, Nullable: true, Comment: "Mac地址", Default: ""},
 		{Name: "organization_id", Type: field.TypeUint64, Comment: "租户ID", Default: 0},
-		{Name: "agent_id", Type: field.TypeUint64, Comment: "智能体ID", Default: 0},
 		{Name: "custom_agent_base", Type: field.TypeString, Nullable: true, Comment: "定制agent服务地址", Default: ""},
 		{Name: "custom_agent_key", Type: field.TypeString, Nullable: true, Comment: "定制agent服务密钥", Default: ""},
 		{Name: "openai_base", Type: field.TypeString, Nullable: true, Comment: "大模型服务地址", Default: ""},
 		{Name: "openai_key", Type: field.TypeString, Nullable: true, Comment: "大模型服务密钥", Default: ""},
+		{Name: "agent_id", Type: field.TypeUint64, Comment: "智能体ID", Default: 0},
 	}
 	// TokenTable holds the schema information for the "token" table.
 	TokenTable = &schema.Table{
 		Name:       "token",
 		Columns:    TokenColumns,
 		PrimaryKey: []*schema.Column{TokenColumns[0]},
+		ForeignKeys: []*schema.ForeignKey{
+			{
+				Symbol:     "token_agent_token_agent",
+				Columns:    []*schema.Column{TokenColumns[12]},
+				RefColumns: []*schema.Column{AgentColumns[0]},
+				OnDelete:   schema.NoAction,
+			},
+		},
 		Indexes: []*schema.Index{
 			{
 				Name:    "token_token",
@@ -999,6 +1007,7 @@ func init() {
 	SopTaskTable.Annotation = &entsql.Annotation{
 		Table: "sop_task",
 	}
+	TokenTable.ForeignKeys[0].RefTable = AgentTable
 	TokenTable.Annotation = &entsql.Annotation{
 		Table: "token",
 	}

+ 167 - 44
ent/mutation.go

@@ -101,6 +101,9 @@ type AgentMutation struct {
 	wx_agent           map[uint64]struct{}
 	removedwx_agent    map[uint64]struct{}
 	clearedwx_agent    bool
+	token_agent        map[uint64]struct{}
+	removedtoken_agent map[uint64]struct{}
+	clearedtoken_agent bool
 	done               bool
 	oldValue           func(context.Context) (*Agent, error)
 	predicates         []predicate.Agent
@@ -753,6 +756,60 @@ func (m *AgentMutation) ResetWxAgent() {
 	m.removedwx_agent = nil
 }
 
+// AddTokenAgentIDs adds the "token_agent" edge to the Token entity by ids.
+func (m *AgentMutation) AddTokenAgentIDs(ids ...uint64) {
+	if m.token_agent == nil {
+		m.token_agent = make(map[uint64]struct{})
+	}
+	for i := range ids {
+		m.token_agent[ids[i]] = struct{}{}
+	}
+}
+
+// ClearTokenAgent clears the "token_agent" edge to the Token entity.
+func (m *AgentMutation) ClearTokenAgent() {
+	m.clearedtoken_agent = true
+}
+
+// TokenAgentCleared reports if the "token_agent" edge to the Token entity was cleared.
+func (m *AgentMutation) TokenAgentCleared() bool {
+	return m.clearedtoken_agent
+}
+
+// RemoveTokenAgentIDs removes the "token_agent" edge to the Token entity by IDs.
+func (m *AgentMutation) RemoveTokenAgentIDs(ids ...uint64) {
+	if m.removedtoken_agent == nil {
+		m.removedtoken_agent = make(map[uint64]struct{})
+	}
+	for i := range ids {
+		delete(m.token_agent, ids[i])
+		m.removedtoken_agent[ids[i]] = struct{}{}
+	}
+}
+
+// RemovedTokenAgent returns the removed IDs of the "token_agent" edge to the Token entity.
+func (m *AgentMutation) RemovedTokenAgentIDs() (ids []uint64) {
+	for id := range m.removedtoken_agent {
+		ids = append(ids, id)
+	}
+	return
+}
+
+// TokenAgentIDs returns the "token_agent" edge IDs in the mutation.
+func (m *AgentMutation) TokenAgentIDs() (ids []uint64) {
+	for id := range m.token_agent {
+		ids = append(ids, id)
+	}
+	return
+}
+
+// ResetTokenAgent resets all changes to the "token_agent" edge.
+func (m *AgentMutation) ResetTokenAgent() {
+	m.token_agent = nil
+	m.clearedtoken_agent = false
+	m.removedtoken_agent = nil
+}
+
 // Where appends a list predicates to the AgentMutation builder.
 func (m *AgentMutation) Where(ps ...predicate.Agent) {
 	m.predicates = append(m.predicates, ps...)
@@ -1110,10 +1167,13 @@ func (m *AgentMutation) ResetField(name string) error {
 
 // AddedEdges returns all edge names that were set/added in this mutation.
 func (m *AgentMutation) AddedEdges() []string {
-	edges := make([]string, 0, 1)
+	edges := make([]string, 0, 2)
 	if m.wx_agent != nil {
 		edges = append(edges, agent.EdgeWxAgent)
 	}
+	if m.token_agent != nil {
+		edges = append(edges, agent.EdgeTokenAgent)
+	}
 	return edges
 }
 
@@ -1127,16 +1187,25 @@ func (m *AgentMutation) AddedIDs(name string) []ent.Value {
 			ids = append(ids, id)
 		}
 		return ids
+	case agent.EdgeTokenAgent:
+		ids := make([]ent.Value, 0, len(m.token_agent))
+		for id := range m.token_agent {
+			ids = append(ids, id)
+		}
+		return ids
 	}
 	return nil
 }
 
 // RemovedEdges returns all edge names that were removed in this mutation.
 func (m *AgentMutation) RemovedEdges() []string {
-	edges := make([]string, 0, 1)
+	edges := make([]string, 0, 2)
 	if m.removedwx_agent != nil {
 		edges = append(edges, agent.EdgeWxAgent)
 	}
+	if m.removedtoken_agent != nil {
+		edges = append(edges, agent.EdgeTokenAgent)
+	}
 	return edges
 }
 
@@ -1150,16 +1219,25 @@ func (m *AgentMutation) RemovedIDs(name string) []ent.Value {
 			ids = append(ids, id)
 		}
 		return ids
+	case agent.EdgeTokenAgent:
+		ids := make([]ent.Value, 0, len(m.removedtoken_agent))
+		for id := range m.removedtoken_agent {
+			ids = append(ids, id)
+		}
+		return ids
 	}
 	return nil
 }
 
 // ClearedEdges returns all edge names that were cleared in this mutation.
 func (m *AgentMutation) ClearedEdges() []string {
-	edges := make([]string, 0, 1)
+	edges := make([]string, 0, 2)
 	if m.clearedwx_agent {
 		edges = append(edges, agent.EdgeWxAgent)
 	}
+	if m.clearedtoken_agent {
+		edges = append(edges, agent.EdgeTokenAgent)
+	}
 	return edges
 }
 
@@ -1169,6 +1247,8 @@ func (m *AgentMutation) EdgeCleared(name string) bool {
 	switch name {
 	case agent.EdgeWxAgent:
 		return m.clearedwx_agent
+	case agent.EdgeTokenAgent:
+		return m.clearedtoken_agent
 	}
 	return false
 }
@@ -1188,6 +1268,9 @@ func (m *AgentMutation) ResetEdge(name string) error {
 	case agent.EdgeWxAgent:
 		m.ResetWxAgent()
 		return nil
+	case agent.EdgeTokenAgent:
+		m.ResetTokenAgent()
+		return nil
 	}
 	return fmt.Errorf("unknown Agent edge %s", name)
 }
@@ -22212,13 +22295,13 @@ type TokenMutation struct {
 	mac                *string
 	organization_id    *uint64
 	addorganization_id *int64
-	agent_id           *uint64
-	addagent_id        *int64
 	custom_agent_base  *string
 	custom_agent_key   *string
 	openai_base        *string
 	openai_key         *string
 	clearedFields      map[string]struct{}
+	agent              *uint64
+	clearedagent       bool
 	done               bool
 	oldValue           func(context.Context) (*Token, error)
 	predicates         []predicate.Token
@@ -22578,9 +22661,22 @@ func (m *TokenMutation) OldMAC(ctx context.Context) (v string, err error) {
 	return oldValue.MAC, nil
 }
 
+// ClearMAC clears the value of the "mac" field.
+func (m *TokenMutation) ClearMAC() {
+	m.mac = nil
+	m.clearedFields[token.FieldMAC] = struct{}{}
+}
+
+// MACCleared returns if the "mac" field was cleared in this mutation.
+func (m *TokenMutation) MACCleared() bool {
+	_, ok := m.clearedFields[token.FieldMAC]
+	return ok
+}
+
 // ResetMAC resets all changes to the "mac" field.
 func (m *TokenMutation) ResetMAC() {
 	m.mac = nil
+	delete(m.clearedFields, token.FieldMAC)
 }
 
 // SetOrganizationID sets the "organization_id" field.
@@ -22641,13 +22737,12 @@ func (m *TokenMutation) ResetOrganizationID() {
 
 // SetAgentID sets the "agent_id" field.
 func (m *TokenMutation) SetAgentID(u uint64) {
-	m.agent_id = &u
-	m.addagent_id = nil
+	m.agent = &u
 }
 
 // AgentID returns the value of the "agent_id" field in the mutation.
 func (m *TokenMutation) AgentID() (r uint64, exists bool) {
-	v := m.agent_id
+	v := m.agent
 	if v == nil {
 		return
 	}
@@ -22671,28 +22766,9 @@ func (m *TokenMutation) OldAgentID(ctx context.Context) (v uint64, err error) {
 	return oldValue.AgentID, nil
 }
 
-// AddAgentID adds u to the "agent_id" field.
-func (m *TokenMutation) AddAgentID(u int64) {
-	if m.addagent_id != nil {
-		*m.addagent_id += u
-	} else {
-		m.addagent_id = &u
-	}
-}
-
-// AddedAgentID returns the value that was added to the "agent_id" field in this mutation.
-func (m *TokenMutation) AddedAgentID() (r int64, exists bool) {
-	v := m.addagent_id
-	if v == nil {
-		return
-	}
-	return *v, true
-}
-
 // ResetAgentID resets all changes to the "agent_id" field.
 func (m *TokenMutation) ResetAgentID() {
-	m.agent_id = nil
-	m.addagent_id = nil
+	m.agent = nil
 }
 
 // SetCustomAgentBase sets the "custom_agent_base" field.
@@ -22891,6 +22967,33 @@ func (m *TokenMutation) ResetOpenaiKey() {
 	delete(m.clearedFields, token.FieldOpenaiKey)
 }
 
+// ClearAgent clears the "agent" edge to the Agent entity.
+func (m *TokenMutation) ClearAgent() {
+	m.clearedagent = true
+	m.clearedFields[token.FieldAgentID] = struct{}{}
+}
+
+// AgentCleared reports if the "agent" edge to the Agent entity was cleared.
+func (m *TokenMutation) AgentCleared() bool {
+	return m.clearedagent
+}
+
+// AgentIDs returns the "agent" edge IDs in the mutation.
+// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use
+// AgentID instead. It exists only for internal usage by the builders.
+func (m *TokenMutation) AgentIDs() (ids []uint64) {
+	if id := m.agent; id != nil {
+		ids = append(ids, *id)
+	}
+	return
+}
+
+// ResetAgent resets all changes to the "agent" edge.
+func (m *TokenMutation) ResetAgent() {
+	m.agent = nil
+	m.clearedagent = false
+}
+
 // Where appends a list predicates to the TokenMutation builder.
 func (m *TokenMutation) Where(ps ...predicate.Token) {
 	m.predicates = append(m.predicates, ps...)
@@ -22947,7 +23050,7 @@ func (m *TokenMutation) Fields() []string {
 	if m.organization_id != nil {
 		fields = append(fields, token.FieldOrganizationID)
 	}
-	if m.agent_id != nil {
+	if m.agent != nil {
 		fields = append(fields, token.FieldAgentID)
 	}
 	if m.custom_agent_base != nil {
@@ -23131,9 +23234,6 @@ func (m *TokenMutation) AddedFields() []string {
 	if m.addorganization_id != nil {
 		fields = append(fields, token.FieldOrganizationID)
 	}
-	if m.addagent_id != nil {
-		fields = append(fields, token.FieldAgentID)
-	}
 	return fields
 }
 
@@ -23144,8 +23244,6 @@ func (m *TokenMutation) AddedField(name string) (ent.Value, bool) {
 	switch name {
 	case token.FieldOrganizationID:
 		return m.AddedOrganizationID()
-	case token.FieldAgentID:
-		return m.AddedAgentID()
 	}
 	return nil, false
 }
@@ -23162,13 +23260,6 @@ func (m *TokenMutation) AddField(name string, value ent.Value) error {
 		}
 		m.AddOrganizationID(v)
 		return nil
-	case token.FieldAgentID:
-		v, ok := value.(int64)
-		if !ok {
-			return fmt.Errorf("unexpected type %T for field %s", value, name)
-		}
-		m.AddAgentID(v)
-		return nil
 	}
 	return fmt.Errorf("unknown Token numeric field %s", name)
 }
@@ -23186,6 +23277,9 @@ func (m *TokenMutation) ClearedFields() []string {
 	if m.FieldCleared(token.FieldToken) {
 		fields = append(fields, token.FieldToken)
 	}
+	if m.FieldCleared(token.FieldMAC) {
+		fields = append(fields, token.FieldMAC)
+	}
 	if m.FieldCleared(token.FieldCustomAgentBase) {
 		fields = append(fields, token.FieldCustomAgentBase)
 	}
@@ -23221,6 +23315,9 @@ func (m *TokenMutation) ClearField(name string) error {
 	case token.FieldToken:
 		m.ClearToken()
 		return nil
+	case token.FieldMAC:
+		m.ClearMAC()
+		return nil
 	case token.FieldCustomAgentBase:
 		m.ClearCustomAgentBase()
 		return nil
@@ -23283,19 +23380,28 @@ func (m *TokenMutation) ResetField(name string) error {
 
 // AddedEdges returns all edge names that were set/added in this mutation.
 func (m *TokenMutation) AddedEdges() []string {
-	edges := make([]string, 0, 0)
+	edges := make([]string, 0, 1)
+	if m.agent != nil {
+		edges = append(edges, token.EdgeAgent)
+	}
 	return edges
 }
 
 // AddedIDs returns all IDs (to other nodes) that were added for the given edge
 // name in this mutation.
 func (m *TokenMutation) AddedIDs(name string) []ent.Value {
+	switch name {
+	case token.EdgeAgent:
+		if id := m.agent; id != nil {
+			return []ent.Value{*id}
+		}
+	}
 	return nil
 }
 
 // RemovedEdges returns all edge names that were removed in this mutation.
 func (m *TokenMutation) RemovedEdges() []string {
-	edges := make([]string, 0, 0)
+	edges := make([]string, 0, 1)
 	return edges
 }
 
@@ -23307,25 +23413,42 @@ func (m *TokenMutation) RemovedIDs(name string) []ent.Value {
 
 // ClearedEdges returns all edge names that were cleared in this mutation.
 func (m *TokenMutation) ClearedEdges() []string {
-	edges := make([]string, 0, 0)
+	edges := make([]string, 0, 1)
+	if m.clearedagent {
+		edges = append(edges, token.EdgeAgent)
+	}
 	return edges
 }
 
 // EdgeCleared returns a boolean which indicates if the edge with the given name
 // was cleared in this mutation.
 func (m *TokenMutation) EdgeCleared(name string) bool {
+	switch name {
+	case token.EdgeAgent:
+		return m.clearedagent
+	}
 	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 *TokenMutation) ClearEdge(name string) error {
+	switch name {
+	case token.EdgeAgent:
+		m.ClearAgent()
+		return nil
+	}
 	return fmt.Errorf("unknown Token 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 *TokenMutation) ResetEdge(name string) error {
+	switch name {
+	case token.EdgeAgent:
+		m.ResetAgent()
+		return nil
+	}
 	return fmt.Errorf("unknown Token edge %s", name)
 }
 

+ 1 - 0
ent/schema/agent.go

@@ -39,6 +39,7 @@ func (Agent) Mixin() []ent.Mixin {
 func (Agent) Edges() []ent.Edge {
 	return []ent.Edge{
 		edge.To("wx_agent", Wx.Type),
+		edge.To("token_agent", Token.Type),
 	}
 }
 

+ 9 - 2
ent/schema/token.go

@@ -1,6 +1,7 @@
 package schema
 
 import (
+	"entgo.io/ent/schema/edge"
 	"wechat-api/ent/schema/localmixin"
 
 	"entgo.io/ent"
@@ -19,7 +20,7 @@ func (Token) Fields() []ent.Field {
 	return []ent.Field{
 		field.Time("expire_at").Optional().Default(nil).Comment("过期时间"),
 		field.String("token").Optional().Default("").Comment("Token"),
-		field.String("mac").Default("").Comment("Mac地址"),
+		field.String("mac").Optional().Default("").Comment("Mac地址"),
 		field.Uint64("organization_id").Default(0).Comment("租户ID"),
 		field.Uint64("agent_id").Default(0).Comment("智能体ID"),
 		field.String("custom_agent_base").Optional().Default("").Comment("定制agent服务地址"),
@@ -43,7 +44,13 @@ func (Token) Indexes() []ent.Index {
 }
 
 func (Token) Edges() []ent.Edge {
-	return nil
+	return []ent.Edge{
+		edge.From("agent", Agent.Type).
+			Ref("token_agent").
+			Unique().
+			Field("agent_id").
+			Required(),
+	}
 }
 
 func (Token) Annotations() []schema.Annotation {

+ 30 - 1
ent/token.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"strings"
 	"time"
+	"wechat-api/ent/agent"
 	"wechat-api/ent/token"
 
 	"entgo.io/ent"
@@ -40,10 +41,33 @@ type Token struct {
 	// 大模型服务地址
 	OpenaiBase string `json:"openai_base,omitempty"`
 	// 大模型服务密钥
-	OpenaiKey    string `json:"openai_key,omitempty"`
+	OpenaiKey string `json:"openai_key,omitempty"`
+	// Edges holds the relations/edges for other nodes in the graph.
+	// The values are being populated by the TokenQuery when eager-loading is set.
+	Edges        TokenEdges `json:"edges"`
 	selectValues sql.SelectValues
 }
 
+// TokenEdges holds the relations/edges for other nodes in the graph.
+type TokenEdges struct {
+	// Agent holds the value of the agent edge.
+	Agent *Agent `json:"agent,omitempty"`
+	// loadedTypes holds the information for reporting if a
+	// type was loaded (or requested) in eager-loading or not.
+	loadedTypes [1]bool
+}
+
+// AgentOrErr returns the Agent value or an error if the edge
+// was not loaded in eager-loading, or loaded but was not found.
+func (e TokenEdges) AgentOrErr() (*Agent, error) {
+	if e.Agent != nil {
+		return e.Agent, nil
+	} else if e.loadedTypes[0] {
+		return nil, &NotFoundError{label: agent.Label}
+	}
+	return nil, &NotLoadedError{edge: "agent"}
+}
+
 // scanValues returns the types for scanning values from sql.Rows.
 func (*Token) scanValues(columns []string) ([]any, error) {
 	values := make([]any, len(columns))
@@ -161,6 +185,11 @@ func (t *Token) Value(name string) (ent.Value, error) {
 	return t.selectValues.Get(name)
 }
 
+// QueryAgent queries the "agent" edge of the Token entity.
+func (t *Token) QueryAgent() *AgentQuery {
+	return NewTokenClient(t.config).QueryAgent(t)
+}
+
 // Update returns a builder for updating this Token.
 // Note that you need to call Token.Unwrap() before calling this method if this Token
 // was returned from a transaction, and the transaction was committed or rolled back.

+ 24 - 0
ent/token/token.go

@@ -7,6 +7,7 @@ import (
 
 	"entgo.io/ent"
 	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
 )
 
 const (
@@ -38,8 +39,17 @@ const (
 	FieldOpenaiBase = "openai_base"
 	// FieldOpenaiKey holds the string denoting the openai_key field in the database.
 	FieldOpenaiKey = "openai_key"
+	// EdgeAgent holds the string denoting the agent edge name in mutations.
+	EdgeAgent = "agent"
 	// Table holds the table name of the token in the database.
 	Table = "token"
+	// AgentTable is the table that holds the agent relation/edge.
+	AgentTable = "token"
+	// AgentInverseTable is the table name for the Agent entity.
+	// It exists in this package in order to avoid circular dependency with the "agent" package.
+	AgentInverseTable = "agent"
+	// AgentColumn is the table column denoting the agent relation/edge.
+	AgentColumn = "agent_id"
 )
 
 // Columns holds all SQL columns for token fields.
@@ -168,3 +178,17 @@ func ByOpenaiBase(opts ...sql.OrderTermOption) OrderOption {
 func ByOpenaiKey(opts ...sql.OrderTermOption) OrderOption {
 	return sql.OrderByField(FieldOpenaiKey, opts...).ToFunc()
 }
+
+// ByAgentField orders the results by agent field.
+func ByAgentField(field string, opts ...sql.OrderTermOption) OrderOption {
+	return func(s *sql.Selector) {
+		sqlgraph.OrderByNeighborTerms(s, newAgentStep(), sql.OrderByField(field, opts...))
+	}
+}
+func newAgentStep() *sqlgraph.Step {
+	return sqlgraph.NewStep(
+		sqlgraph.From(Table, FieldID),
+		sqlgraph.To(AgentInverseTable, FieldID),
+		sqlgraph.Edge(sqlgraph.M2O, true, AgentTable, AgentColumn),
+	)
+}

+ 34 - 20
ent/token/where.go

@@ -7,6 +7,7 @@ import (
 	"wechat-api/ent/predicate"
 
 	"entgo.io/ent/dialect/sql"
+	"entgo.io/ent/dialect/sql/sqlgraph"
 )
 
 // ID filters vertices based on their ID field.
@@ -424,6 +425,16 @@ func MACHasSuffix(v string) predicate.Token {
 	return predicate.Token(sql.FieldHasSuffix(FieldMAC, v))
 }
 
+// MACIsNil applies the IsNil predicate on the "mac" field.
+func MACIsNil() predicate.Token {
+	return predicate.Token(sql.FieldIsNull(FieldMAC))
+}
+
+// MACNotNil applies the NotNil predicate on the "mac" field.
+func MACNotNil() predicate.Token {
+	return predicate.Token(sql.FieldNotNull(FieldMAC))
+}
+
 // MACEqualFold applies the EqualFold predicate on the "mac" field.
 func MACEqualFold(v string) predicate.Token {
 	return predicate.Token(sql.FieldEqualFold(FieldMAC, v))
@@ -494,26 +505,6 @@ func AgentIDNotIn(vs ...uint64) predicate.Token {
 	return predicate.Token(sql.FieldNotIn(FieldAgentID, vs...))
 }
 
-// AgentIDGT applies the GT predicate on the "agent_id" field.
-func AgentIDGT(v uint64) predicate.Token {
-	return predicate.Token(sql.FieldGT(FieldAgentID, v))
-}
-
-// AgentIDGTE applies the GTE predicate on the "agent_id" field.
-func AgentIDGTE(v uint64) predicate.Token {
-	return predicate.Token(sql.FieldGTE(FieldAgentID, v))
-}
-
-// AgentIDLT applies the LT predicate on the "agent_id" field.
-func AgentIDLT(v uint64) predicate.Token {
-	return predicate.Token(sql.FieldLT(FieldAgentID, v))
-}
-
-// AgentIDLTE applies the LTE predicate on the "agent_id" field.
-func AgentIDLTE(v uint64) predicate.Token {
-	return predicate.Token(sql.FieldLTE(FieldAgentID, v))
-}
-
 // CustomAgentBaseEQ applies the EQ predicate on the "custom_agent_base" field.
 func CustomAgentBaseEQ(v string) predicate.Token {
 	return predicate.Token(sql.FieldEQ(FieldCustomAgentBase, v))
@@ -814,6 +805,29 @@ func OpenaiKeyContainsFold(v string) predicate.Token {
 	return predicate.Token(sql.FieldContainsFold(FieldOpenaiKey, v))
 }
 
+// HasAgent applies the HasEdge predicate on the "agent" edge.
+func HasAgent() predicate.Token {
+	return predicate.Token(func(s *sql.Selector) {
+		step := sqlgraph.NewStep(
+			sqlgraph.From(Table, FieldID),
+			sqlgraph.Edge(sqlgraph.M2O, true, AgentTable, AgentColumn),
+		)
+		sqlgraph.HasNeighbors(s, step)
+	})
+}
+
+// HasAgentWith applies the HasEdge predicate on the "agent" edge with a given conditions (other predicates).
+func HasAgentWith(preds ...predicate.Agent) predicate.Token {
+	return predicate.Token(func(s *sql.Selector) {
+		step := newAgentStep()
+		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.Token) predicate.Token {
 	return predicate.Token(sql.AndPredicates(predicates...))

+ 46 - 27
ent/token_create.go

@@ -7,6 +7,7 @@ import (
 	"errors"
 	"fmt"
 	"time"
+	"wechat-api/ent/agent"
 	"wechat-api/ent/token"
 
 	"entgo.io/ent/dialect/sql"
@@ -196,6 +197,11 @@ func (tc *TokenCreate) SetID(u uint64) *TokenCreate {
 	return tc
 }
 
+// SetAgent sets the "agent" edge to the Agent entity.
+func (tc *TokenCreate) SetAgent(a *Agent) *TokenCreate {
+	return tc.SetAgentID(a.ID)
+}
+
 // Mutation returns the TokenMutation object of the builder.
 func (tc *TokenCreate) Mutation() *TokenMutation {
 	return tc.mutation
@@ -290,15 +296,15 @@ func (tc *TokenCreate) check() error {
 	if _, ok := tc.mutation.UpdatedAt(); !ok {
 		return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "Token.updated_at"`)}
 	}
-	if _, ok := tc.mutation.MAC(); !ok {
-		return &ValidationError{Name: "mac", err: errors.New(`ent: missing required field "Token.mac"`)}
-	}
 	if _, ok := tc.mutation.OrganizationID(); !ok {
 		return &ValidationError{Name: "organization_id", err: errors.New(`ent: missing required field "Token.organization_id"`)}
 	}
 	if _, ok := tc.mutation.AgentID(); !ok {
 		return &ValidationError{Name: "agent_id", err: errors.New(`ent: missing required field "Token.agent_id"`)}
 	}
+	if _, ok := tc.mutation.AgentID(); !ok {
+		return &ValidationError{Name: "agent", err: errors.New(`ent: missing required edge "Token.agent"`)}
+	}
 	return nil
 }
 
@@ -360,10 +366,6 @@ func (tc *TokenCreate) createSpec() (*Token, *sqlgraph.CreateSpec) {
 		_spec.SetField(token.FieldOrganizationID, field.TypeUint64, value)
 		_node.OrganizationID = value
 	}
-	if value, ok := tc.mutation.AgentID(); ok {
-		_spec.SetField(token.FieldAgentID, field.TypeUint64, value)
-		_node.AgentID = value
-	}
 	if value, ok := tc.mutation.CustomAgentBase(); ok {
 		_spec.SetField(token.FieldCustomAgentBase, field.TypeString, value)
 		_node.CustomAgentBase = value
@@ -380,6 +382,23 @@ func (tc *TokenCreate) createSpec() (*Token, *sqlgraph.CreateSpec) {
 		_spec.SetField(token.FieldOpenaiKey, field.TypeString, value)
 		_node.OpenaiKey = value
 	}
+	if nodes := tc.mutation.AgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   token.AgentTable,
+			Columns: []string{token.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_node.AgentID = nodes[0]
+		_spec.Edges = append(_spec.Edges, edge)
+	}
 	return _node, _spec
 }
 
@@ -510,6 +529,12 @@ func (u *TokenUpsert) UpdateMAC() *TokenUpsert {
 	return u
 }
 
+// ClearMAC clears the value of the "mac" field.
+func (u *TokenUpsert) ClearMAC() *TokenUpsert {
+	u.SetNull(token.FieldMAC)
+	return u
+}
+
 // SetOrganizationID sets the "organization_id" field.
 func (u *TokenUpsert) SetOrganizationID(v uint64) *TokenUpsert {
 	u.Set(token.FieldOrganizationID, v)
@@ -540,12 +565,6 @@ func (u *TokenUpsert) UpdateAgentID() *TokenUpsert {
 	return u
 }
 
-// AddAgentID adds v to the "agent_id" field.
-func (u *TokenUpsert) AddAgentID(v uint64) *TokenUpsert {
-	u.Add(token.FieldAgentID, v)
-	return u
-}
-
 // SetCustomAgentBase sets the "custom_agent_base" field.
 func (u *TokenUpsert) SetCustomAgentBase(v string) *TokenUpsert {
 	u.Set(token.FieldCustomAgentBase, v)
@@ -760,6 +779,13 @@ func (u *TokenUpsertOne) UpdateMAC() *TokenUpsertOne {
 	})
 }
 
+// ClearMAC clears the value of the "mac" field.
+func (u *TokenUpsertOne) ClearMAC() *TokenUpsertOne {
+	return u.Update(func(s *TokenUpsert) {
+		s.ClearMAC()
+	})
+}
+
 // SetOrganizationID sets the "organization_id" field.
 func (u *TokenUpsertOne) SetOrganizationID(v uint64) *TokenUpsertOne {
 	return u.Update(func(s *TokenUpsert) {
@@ -788,13 +814,6 @@ func (u *TokenUpsertOne) SetAgentID(v uint64) *TokenUpsertOne {
 	})
 }
 
-// AddAgentID adds v to the "agent_id" field.
-func (u *TokenUpsertOne) AddAgentID(v uint64) *TokenUpsertOne {
-	return u.Update(func(s *TokenUpsert) {
-		s.AddAgentID(v)
-	})
-}
-
 // UpdateAgentID sets the "agent_id" field to the value that was provided on create.
 func (u *TokenUpsertOne) UpdateAgentID() *TokenUpsertOne {
 	return u.Update(func(s *TokenUpsert) {
@@ -1194,6 +1213,13 @@ func (u *TokenUpsertBulk) UpdateMAC() *TokenUpsertBulk {
 	})
 }
 
+// ClearMAC clears the value of the "mac" field.
+func (u *TokenUpsertBulk) ClearMAC() *TokenUpsertBulk {
+	return u.Update(func(s *TokenUpsert) {
+		s.ClearMAC()
+	})
+}
+
 // SetOrganizationID sets the "organization_id" field.
 func (u *TokenUpsertBulk) SetOrganizationID(v uint64) *TokenUpsertBulk {
 	return u.Update(func(s *TokenUpsert) {
@@ -1222,13 +1248,6 @@ func (u *TokenUpsertBulk) SetAgentID(v uint64) *TokenUpsertBulk {
 	})
 }
 
-// AddAgentID adds v to the "agent_id" field.
-func (u *TokenUpsertBulk) AddAgentID(v uint64) *TokenUpsertBulk {
-	return u.Update(func(s *TokenUpsert) {
-		s.AddAgentID(v)
-	})
-}
-
 // UpdateAgentID sets the "agent_id" field to the value that was provided on create.
 func (u *TokenUpsertBulk) UpdateAgentID() *TokenUpsertBulk {
 	return u.Update(func(s *TokenUpsert) {

+ 81 - 2
ent/token_query.go

@@ -6,6 +6,7 @@ import (
 	"context"
 	"fmt"
 	"math"
+	"wechat-api/ent/agent"
 	"wechat-api/ent/predicate"
 	"wechat-api/ent/token"
 
@@ -21,6 +22,7 @@ type TokenQuery struct {
 	order      []token.OrderOption
 	inters     []Interceptor
 	predicates []predicate.Token
+	withAgent  *AgentQuery
 	// intermediate query (i.e. traversal path).
 	sql  *sql.Selector
 	path func(context.Context) (*sql.Selector, error)
@@ -57,6 +59,28 @@ func (tq *TokenQuery) Order(o ...token.OrderOption) *TokenQuery {
 	return tq
 }
 
+// QueryAgent chains the current query on the "agent" edge.
+func (tq *TokenQuery) QueryAgent() *AgentQuery {
+	query := (&AgentClient{config: tq.config}).Query()
+	query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
+		if err := tq.prepareQuery(ctx); err != nil {
+			return nil, err
+		}
+		selector := tq.sqlQuery(ctx)
+		if err := selector.Err(); err != nil {
+			return nil, err
+		}
+		step := sqlgraph.NewStep(
+			sqlgraph.From(token.Table, token.FieldID, selector),
+			sqlgraph.To(agent.Table, agent.FieldID),
+			sqlgraph.Edge(sqlgraph.M2O, true, token.AgentTable, token.AgentColumn),
+		)
+		fromU = sqlgraph.SetNeighbors(tq.driver.Dialect(), step)
+		return fromU, nil
+	}
+	return query
+}
+
 // First returns the first Token entity from the query.
 // Returns a *NotFoundError when no Token was found.
 func (tq *TokenQuery) First(ctx context.Context) (*Token, error) {
@@ -249,12 +273,24 @@ func (tq *TokenQuery) Clone() *TokenQuery {
 		order:      append([]token.OrderOption{}, tq.order...),
 		inters:     append([]Interceptor{}, tq.inters...),
 		predicates: append([]predicate.Token{}, tq.predicates...),
+		withAgent:  tq.withAgent.Clone(),
 		// clone intermediate query.
 		sql:  tq.sql.Clone(),
 		path: tq.path,
 	}
 }
 
+// WithAgent tells the query-builder to eager-load the nodes that are connected to
+// the "agent" edge. The optional arguments are used to configure the query builder of the edge.
+func (tq *TokenQuery) WithAgent(opts ...func(*AgentQuery)) *TokenQuery {
+	query := (&AgentClient{config: tq.config}).Query()
+	for _, opt := range opts {
+		opt(query)
+	}
+	tq.withAgent = query
+	return tq
+}
+
 // 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.
 //
@@ -331,8 +367,11 @@ func (tq *TokenQuery) prepareQuery(ctx context.Context) error {
 
 func (tq *TokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Token, error) {
 	var (
-		nodes = []*Token{}
-		_spec = tq.querySpec()
+		nodes       = []*Token{}
+		_spec       = tq.querySpec()
+		loadedTypes = [1]bool{
+			tq.withAgent != nil,
+		}
 	)
 	_spec.ScanValues = func(columns []string) ([]any, error) {
 		return (*Token).scanValues(nil, columns)
@@ -340,6 +379,7 @@ func (tq *TokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Token,
 	_spec.Assign = func(columns []string, values []any) error {
 		node := &Token{config: tq.config}
 		nodes = append(nodes, node)
+		node.Edges.loadedTypes = loadedTypes
 		return node.assignValues(columns, values)
 	}
 	for i := range hooks {
@@ -351,9 +391,45 @@ func (tq *TokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Token,
 	if len(nodes) == 0 {
 		return nodes, nil
 	}
+	if query := tq.withAgent; query != nil {
+		if err := tq.loadAgent(ctx, query, nodes, nil,
+			func(n *Token, e *Agent) { n.Edges.Agent = e }); err != nil {
+			return nil, err
+		}
+	}
 	return nodes, nil
 }
 
+func (tq *TokenQuery) loadAgent(ctx context.Context, query *AgentQuery, nodes []*Token, init func(*Token), assign func(*Token, *Agent)) error {
+	ids := make([]uint64, 0, len(nodes))
+	nodeids := make(map[uint64][]*Token)
+	for i := range nodes {
+		fk := nodes[i].AgentID
+		if _, ok := nodeids[fk]; !ok {
+			ids = append(ids, fk)
+		}
+		nodeids[fk] = append(nodeids[fk], nodes[i])
+	}
+	if len(ids) == 0 {
+		return nil
+	}
+	query.Where(agent.IDIn(ids...))
+	neighbors, err := query.All(ctx)
+	if err != nil {
+		return err
+	}
+	for _, n := range neighbors {
+		nodes, ok := nodeids[n.ID]
+		if !ok {
+			return fmt.Errorf(`unexpected foreign-key "agent_id" returned %v`, n.ID)
+		}
+		for i := range nodes {
+			assign(nodes[i], n)
+		}
+	}
+	return nil
+}
+
 func (tq *TokenQuery) sqlCount(ctx context.Context) (int, error) {
 	_spec := tq.querySpec()
 	_spec.Node.Columns = tq.ctx.Fields
@@ -379,6 +455,9 @@ func (tq *TokenQuery) querySpec() *sqlgraph.QuerySpec {
 				_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
 			}
 		}
+		if tq.withAgent != nil {
+			_spec.Node.AddColumnOnce(token.FieldAgentID)
+		}
 	}
 	if ps := tq.predicates; len(ps) > 0 {
 		_spec.Predicate = func(selector *sql.Selector) {

+ 121 - 26
ent/token_update.go

@@ -7,6 +7,7 @@ import (
 	"errors"
 	"fmt"
 	"time"
+	"wechat-api/ent/agent"
 	"wechat-api/ent/predicate"
 	"wechat-api/ent/token"
 
@@ -108,6 +109,12 @@ func (tu *TokenUpdate) SetNillableMAC(s *string) *TokenUpdate {
 	return tu
 }
 
+// ClearMAC clears the value of the "mac" field.
+func (tu *TokenUpdate) ClearMAC() *TokenUpdate {
+	tu.mutation.ClearMAC()
+	return tu
+}
+
 // SetOrganizationID sets the "organization_id" field.
 func (tu *TokenUpdate) SetOrganizationID(u uint64) *TokenUpdate {
 	tu.mutation.ResetOrganizationID()
@@ -131,7 +138,6 @@ func (tu *TokenUpdate) AddOrganizationID(u int64) *TokenUpdate {
 
 // SetAgentID sets the "agent_id" field.
 func (tu *TokenUpdate) SetAgentID(u uint64) *TokenUpdate {
-	tu.mutation.ResetAgentID()
 	tu.mutation.SetAgentID(u)
 	return tu
 }
@@ -144,12 +150,6 @@ func (tu *TokenUpdate) SetNillableAgentID(u *uint64) *TokenUpdate {
 	return tu
 }
 
-// AddAgentID adds u to the "agent_id" field.
-func (tu *TokenUpdate) AddAgentID(u int64) *TokenUpdate {
-	tu.mutation.AddAgentID(u)
-	return tu
-}
-
 // SetCustomAgentBase sets the "custom_agent_base" field.
 func (tu *TokenUpdate) SetCustomAgentBase(s string) *TokenUpdate {
 	tu.mutation.SetCustomAgentBase(s)
@@ -230,11 +230,22 @@ func (tu *TokenUpdate) ClearOpenaiKey() *TokenUpdate {
 	return tu
 }
 
+// SetAgent sets the "agent" edge to the Agent entity.
+func (tu *TokenUpdate) SetAgent(a *Agent) *TokenUpdate {
+	return tu.SetAgentID(a.ID)
+}
+
 // Mutation returns the TokenMutation object of the builder.
 func (tu *TokenUpdate) Mutation() *TokenMutation {
 	return tu.mutation
 }
 
+// ClearAgent clears the "agent" edge to the Agent entity.
+func (tu *TokenUpdate) ClearAgent() *TokenUpdate {
+	tu.mutation.ClearAgent()
+	return tu
+}
+
 // Save executes the query and returns the number of nodes affected by the update operation.
 func (tu *TokenUpdate) Save(ctx context.Context) (int, error) {
 	if err := tu.defaults(); err != nil {
@@ -277,7 +288,18 @@ func (tu *TokenUpdate) defaults() error {
 	return nil
 }
 
+// check runs all checks and user-defined validators on the builder.
+func (tu *TokenUpdate) check() error {
+	if _, ok := tu.mutation.AgentID(); tu.mutation.AgentCleared() && !ok {
+		return errors.New(`ent: clearing a required unique edge "Token.agent"`)
+	}
+	return nil
+}
+
 func (tu *TokenUpdate) sqlSave(ctx context.Context) (n int, err error) {
+	if err := tu.check(); err != nil {
+		return n, err
+	}
 	_spec := sqlgraph.NewUpdateSpec(token.Table, token.Columns, sqlgraph.NewFieldSpec(token.FieldID, field.TypeUint64))
 	if ps := tu.mutation.predicates; len(ps) > 0 {
 		_spec.Predicate = func(selector *sql.Selector) {
@@ -310,18 +332,15 @@ func (tu *TokenUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if value, ok := tu.mutation.MAC(); ok {
 		_spec.SetField(token.FieldMAC, field.TypeString, value)
 	}
+	if tu.mutation.MACCleared() {
+		_spec.ClearField(token.FieldMAC, field.TypeString)
+	}
 	if value, ok := tu.mutation.OrganizationID(); ok {
 		_spec.SetField(token.FieldOrganizationID, field.TypeUint64, value)
 	}
 	if value, ok := tu.mutation.AddedOrganizationID(); ok {
 		_spec.AddField(token.FieldOrganizationID, field.TypeUint64, value)
 	}
-	if value, ok := tu.mutation.AgentID(); ok {
-		_spec.SetField(token.FieldAgentID, field.TypeUint64, value)
-	}
-	if value, ok := tu.mutation.AddedAgentID(); ok {
-		_spec.AddField(token.FieldAgentID, field.TypeUint64, value)
-	}
 	if value, ok := tu.mutation.CustomAgentBase(); ok {
 		_spec.SetField(token.FieldCustomAgentBase, field.TypeString, value)
 	}
@@ -346,6 +365,35 @@ func (tu *TokenUpdate) sqlSave(ctx context.Context) (n int, err error) {
 	if tu.mutation.OpenaiKeyCleared() {
 		_spec.ClearField(token.FieldOpenaiKey, field.TypeString)
 	}
+	if tu.mutation.AgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   token.AgentTable,
+			Columns: []string{token.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := tu.mutation.AgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   token.AgentTable,
+			Columns: []string{token.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.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, tu.driver, _spec); err != nil {
 		if _, ok := err.(*sqlgraph.NotFoundError); ok {
 			err = &NotFoundError{token.Label}
@@ -446,6 +494,12 @@ func (tuo *TokenUpdateOne) SetNillableMAC(s *string) *TokenUpdateOne {
 	return tuo
 }
 
+// ClearMAC clears the value of the "mac" field.
+func (tuo *TokenUpdateOne) ClearMAC() *TokenUpdateOne {
+	tuo.mutation.ClearMAC()
+	return tuo
+}
+
 // SetOrganizationID sets the "organization_id" field.
 func (tuo *TokenUpdateOne) SetOrganizationID(u uint64) *TokenUpdateOne {
 	tuo.mutation.ResetOrganizationID()
@@ -469,7 +523,6 @@ func (tuo *TokenUpdateOne) AddOrganizationID(u int64) *TokenUpdateOne {
 
 // SetAgentID sets the "agent_id" field.
 func (tuo *TokenUpdateOne) SetAgentID(u uint64) *TokenUpdateOne {
-	tuo.mutation.ResetAgentID()
 	tuo.mutation.SetAgentID(u)
 	return tuo
 }
@@ -482,12 +535,6 @@ func (tuo *TokenUpdateOne) SetNillableAgentID(u *uint64) *TokenUpdateOne {
 	return tuo
 }
 
-// AddAgentID adds u to the "agent_id" field.
-func (tuo *TokenUpdateOne) AddAgentID(u int64) *TokenUpdateOne {
-	tuo.mutation.AddAgentID(u)
-	return tuo
-}
-
 // SetCustomAgentBase sets the "custom_agent_base" field.
 func (tuo *TokenUpdateOne) SetCustomAgentBase(s string) *TokenUpdateOne {
 	tuo.mutation.SetCustomAgentBase(s)
@@ -568,11 +615,22 @@ func (tuo *TokenUpdateOne) ClearOpenaiKey() *TokenUpdateOne {
 	return tuo
 }
 
+// SetAgent sets the "agent" edge to the Agent entity.
+func (tuo *TokenUpdateOne) SetAgent(a *Agent) *TokenUpdateOne {
+	return tuo.SetAgentID(a.ID)
+}
+
 // Mutation returns the TokenMutation object of the builder.
 func (tuo *TokenUpdateOne) Mutation() *TokenMutation {
 	return tuo.mutation
 }
 
+// ClearAgent clears the "agent" edge to the Agent entity.
+func (tuo *TokenUpdateOne) ClearAgent() *TokenUpdateOne {
+	tuo.mutation.ClearAgent()
+	return tuo
+}
+
 // Where appends a list predicates to the TokenUpdate builder.
 func (tuo *TokenUpdateOne) Where(ps ...predicate.Token) *TokenUpdateOne {
 	tuo.mutation.Where(ps...)
@@ -628,7 +686,18 @@ func (tuo *TokenUpdateOne) defaults() error {
 	return nil
 }
 
+// check runs all checks and user-defined validators on the builder.
+func (tuo *TokenUpdateOne) check() error {
+	if _, ok := tuo.mutation.AgentID(); tuo.mutation.AgentCleared() && !ok {
+		return errors.New(`ent: clearing a required unique edge "Token.agent"`)
+	}
+	return nil
+}
+
 func (tuo *TokenUpdateOne) sqlSave(ctx context.Context) (_node *Token, err error) {
+	if err := tuo.check(); err != nil {
+		return _node, err
+	}
 	_spec := sqlgraph.NewUpdateSpec(token.Table, token.Columns, sqlgraph.NewFieldSpec(token.FieldID, field.TypeUint64))
 	id, ok := tuo.mutation.ID()
 	if !ok {
@@ -678,18 +747,15 @@ func (tuo *TokenUpdateOne) sqlSave(ctx context.Context) (_node *Token, err error
 	if value, ok := tuo.mutation.MAC(); ok {
 		_spec.SetField(token.FieldMAC, field.TypeString, value)
 	}
+	if tuo.mutation.MACCleared() {
+		_spec.ClearField(token.FieldMAC, field.TypeString)
+	}
 	if value, ok := tuo.mutation.OrganizationID(); ok {
 		_spec.SetField(token.FieldOrganizationID, field.TypeUint64, value)
 	}
 	if value, ok := tuo.mutation.AddedOrganizationID(); ok {
 		_spec.AddField(token.FieldOrganizationID, field.TypeUint64, value)
 	}
-	if value, ok := tuo.mutation.AgentID(); ok {
-		_spec.SetField(token.FieldAgentID, field.TypeUint64, value)
-	}
-	if value, ok := tuo.mutation.AddedAgentID(); ok {
-		_spec.AddField(token.FieldAgentID, field.TypeUint64, value)
-	}
 	if value, ok := tuo.mutation.CustomAgentBase(); ok {
 		_spec.SetField(token.FieldCustomAgentBase, field.TypeString, value)
 	}
@@ -714,6 +780,35 @@ func (tuo *TokenUpdateOne) sqlSave(ctx context.Context) (_node *Token, err error
 	if tuo.mutation.OpenaiKeyCleared() {
 		_spec.ClearField(token.FieldOpenaiKey, field.TypeString)
 	}
+	if tuo.mutation.AgentCleared() {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   token.AgentTable,
+			Columns: []string{token.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
+	}
+	if nodes := tuo.mutation.AgentIDs(); len(nodes) > 0 {
+		edge := &sqlgraph.EdgeSpec{
+			Rel:     sqlgraph.M2O,
+			Inverse: true,
+			Table:   token.AgentTable,
+			Columns: []string{token.AgentColumn},
+			Bidi:    false,
+			Target: &sqlgraph.EdgeTarget{
+				IDSpec: sqlgraph.NewFieldSpec(agent.FieldID, field.TypeUint64),
+			},
+		}
+		for _, k := range nodes {
+			edge.Target.Nodes = append(edge.Target.Nodes, k)
+		}
+		_spec.Edges.Add = append(_spec.Edges.Add, edge)
+	}
 	_node = &Token{config: tuo.config}
 	_spec.Assign = _node.assignValues
 	_spec.ScanValues = _node.scanValues

+ 1 - 0
internal/logic/token/check_token_logic.go

@@ -73,6 +73,7 @@ func (l *CheckTokenLogic) CheckToken(req *types.CheckTokenReq) (resp *types.Chec
 		customAgentKey = tokenItem.CustomAgentKey
 		openaiBase = tokenItem.OpenaiBase
 		openaiKey = tokenItem.OpenaiKey
+
 		if tokenItem.AgentID == 0 {
 			agentInfo = types.AgentInfo{
 				BaseIDInfo: types.BaseIDInfo{

+ 10 - 0
internal/logic/token/create_token_logic.go

@@ -30,6 +30,11 @@ func NewCreateTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Creat
 }
 
 func (l *CreateTokenLogic) CreateToken(req *types.TokenInfo) (*types.BaseMsgResp, error) {
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+	if !isAdmin {
+		l.Error("没有权限,请联系管理员", nil)
+		return nil, errorx.NewDefaultError("没有权限,请联系管理员")
+	}
 	var (
 		expireAt time.Time
 		err      error
@@ -52,6 +57,11 @@ func (l *CreateTokenLogic) CreateToken(req *types.TokenInfo) (*types.BaseMsgResp
 		SetNotNilToken(req.Token).
 		SetNotNilMAC(req.Mac).
 		SetNotNilOrganizationID(req.OrganizationId).
+		SetNotNilAgentID(req.AgentId).
+		SetNotNilCustomAgentBase(req.CustomAgentBase).
+		SetNotNilCustomAgentKey(req.CustomAgentKey).
+		SetNotNilOpenaiBase(req.OpenaiBase).
+		SetNotNilOpenaiKey(req.OpenaiKey).
 		Save(l.ctx)
 
 	if err != nil {

+ 10 - 5
internal/logic/token/get_token_by_id_logic.go

@@ -45,11 +45,16 @@ func (l *GetTokenByIdLogic) GetTokenById(req *types.IDReq) (*types.TokenInfoResp
 				CreatedAt: pointy.GetPointer(data.CreatedAt.UnixMilli()),
 				UpdatedAt: pointy.GetPointer(data.UpdatedAt.UnixMilli()),
 			},
-			ExpireAt:       pointy.GetUnixMilliPointer(data.ExpireAt.UnixMilli()),
-			ExpireAtStr:    &expireAtStr,
-			Token:          &data.Token,
-			Mac:            &data.MAC,
-			OrganizationId: &data.OrganizationID,
+			ExpireAt:        pointy.GetUnixMilliPointer(data.ExpireAt.UnixMilli()),
+			ExpireAtStr:     &expireAtStr,
+			Token:           &data.Token,
+			Mac:             &data.MAC,
+			OrganizationId:  &data.OrganizationID,
+			AgentId:         &data.AgentID,
+			CustomAgentBase: &data.CustomAgentBase,
+			CustomAgentKey:  &data.CustomAgentKey,
+			OpenaiBase:      &data.OpenaiBase,
+			OpenaiKey:       &data.OpenaiKey,
 		},
 	}, nil
 }

+ 59 - 7
internal/logic/token/get_token_list_logic.go

@@ -2,7 +2,7 @@ package token
 
 import (
 	"context"
-
+	"github.com/suyuan32/simple-admin-core/rpc/types/core"
 	"wechat-api/ent/predicate"
 	"wechat-api/ent/token"
 	"wechat-api/internal/svc"
@@ -30,14 +30,33 @@ func NewGetTokenListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetT
 }
 
 func (l *GetTokenListLogic) GetTokenList(req *types.TokenListReq) (*types.TokenListResp, error) {
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	isAdmin := l.ctx.Value("isAdmin").(bool)
+
 	var predicates []predicate.Token
+	if !isAdmin {
+		predicates = append(predicates, token.OrganizationIDEQ(organizationId))
+	} else {
+		if req.OrganizationId != nil {
+			predicates = append(predicates, token.OrganizationIDEQ(*req.OrganizationId))
+		}
+		if req.OrganizationName != nil {
+			departmentList, _ := l.svcCtx.CoreRpc.GetDepartmentList(l.ctx, &core.DepartmentListReq{Name: req.OrganizationName})
+			organizationIds := make([]uint64, 0)
+			for _, department := range departmentList.Data {
+				organizationIds = append(organizationIds, *department.Id)
+			}
+			predicates = append(predicates, token.OrganizationIDIn(organizationIds...))
+		}
+	}
+
 	if req.Token != nil {
 		predicates = append(predicates, token.TokenContains(*req.Token))
 	}
 	if req.Mac != nil {
 		predicates = append(predicates, token.MACContains(*req.Mac))
 	}
-	data, err := l.svcCtx.DB.Token.Query().Where(predicates...).Page(l.ctx, req.Page, req.PageSize)
+	data, err := l.svcCtx.DB.Token.Query().Where(predicates...).WithAgent().Page(l.ctx, req.Page, req.PageSize)
 
 	if err != nil {
 		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
@@ -48,6 +67,32 @@ func (l *GetTokenListLogic) GetTokenList(req *types.TokenListReq) (*types.TokenL
 	resp.Data.Total = data.PageDetails.Total
 
 	for _, v := range data.List {
+		departmentInfo, err := l.svcCtx.CoreRpc.GetDepartmentById(l.ctx, &core.IDReq{Id: v.OrganizationID})
+		if err != nil {
+			l.Error("获取部门信息失败", err)
+		}
+		var agent types.AgentInfo
+		if v.AgentID == 0 {
+			agentName := "定制 AI 角色"
+			agent = types.AgentInfo{
+				Name: &agentName,
+			}
+		} else {
+			if v.Edges.Agent != nil {
+				agent = types.AgentInfo{
+					BaseIDInfo: types.BaseIDInfo{
+						Id:        &v.AgentID,
+						CreatedAt: pointy.GetPointer(v.Edges.Agent.CreatedAt.UnixMilli()),
+						UpdatedAt: pointy.GetPointer(v.Edges.Agent.UpdatedAt.UnixMilli()),
+					},
+					Name:       &v.Edges.Agent.Name,
+					Role:       &v.Edges.Agent.Role,
+					Status:     &v.Edges.Agent.Status,
+					Background: &v.Edges.Agent.Background,
+					Examples:   &v.Edges.Agent.Examples,
+				}
+			}
+		}
 		expireAtStr := v.ExpireAt.Format("2006-01-02 15:04:05")
 		resp.Data.Data = append(resp.Data.Data,
 			types.TokenInfo{
@@ -56,11 +101,18 @@ func (l *GetTokenListLogic) GetTokenList(req *types.TokenListReq) (*types.TokenL
 					CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
 					UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
 				},
-				ExpireAt:       pointy.GetUnixMilliPointer(v.ExpireAt.UnixMilli()),
-				ExpireAtStr:    &expireAtStr,
-				Token:          &v.Token,
-				Mac:            &v.MAC,
-				OrganizationId: &v.OrganizationID,
+				ExpireAt:         pointy.GetUnixMilliPointer(v.ExpireAt.UnixMilli()),
+				ExpireAtStr:      &expireAtStr,
+				Token:            &v.Token,
+				Mac:              &v.MAC,
+				OrganizationId:   &v.OrganizationID,
+				OrganizationName: departmentInfo.Name,
+				AgentId:          &v.AgentID,
+				AgentInfo:        &agent,
+				CustomAgentBase:  &v.CustomAgentBase,
+				CustomAgentKey:   &v.CustomAgentKey,
+				OpenaiBase:       &v.OpenaiBase,
+				OpenaiKey:        &v.OpenaiKey,
 			})
 	}
 

+ 30 - 13
internal/logic/token/update_token_logic.go

@@ -6,7 +6,6 @@ import (
 	"time"
 	"wechat-api/ent"
 	"wechat-api/ent/token"
-
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
 	"wechat-api/internal/utils/dberrorhandler"
@@ -30,28 +29,46 @@ func NewUpdateTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Updat
 }
 
 func (l *UpdateTokenLogic) UpdateToken(req *types.TokenInfo) (*types.BaseMsgResp, error) {
+	//isAdmin := l.ctx.Value("isAdmin").(bool)
+	//if !isAdmin {
+	//	l.Error("没有权限,请联系管理员", nil)
+	//	return nil, errorx.NewDefaultError("没有权限,请联系管理员")
+	//}
 	var (
-		expireAt time.Time
+		expireAt *time.Time
 		err      error
 	)
-	expireAt, err = time.Parse("2006-01-02 15:04:05", *req.ExpireAtStr)
-	if err != nil {
-		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	if req.ExpireAtStr != nil {
+		expireAtdata, err := time.Parse("2006-01-02 15:04:05", *req.ExpireAtStr)
+		if err != nil {
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+		expireAt = &expireAtdata
 	}
+	l.Logger.Errorf("------------------------item--------------------------- %+v", expireAt)
 
-	item, err := l.svcCtx.DB.Token.Query().Where(token.TokenEQ(*req.Token)).Where(token.IDNEQ(*req.Id)).First(l.ctx)
-	if err != nil && !ent.IsNotFound(err) {
-		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
-	}
-	if item != nil && item.ID > 0 {
-		return nil, errorx.NewCodeInvalidArgumentError("Token已经存在")
+	if req.Token != nil {
+		item, err := l.svcCtx.DB.Token.Query().Where(token.IDNEQ(*req.Id)).Where(token.TokenEQ(*req.Token)).First(l.ctx)
+		l.Logger.Errorf("------------------------err--------------------------- %+v", err)
+		l.Logger.Errorf("------------------------item--------------------------- %+v", item)
+		if err != nil && !ent.IsNotFound(err) {
+			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+		}
+		if item != nil && item.ID > 0 {
+			return nil, errorx.NewCodeInvalidArgumentError("Token已经存在")
+		}
 	}
-
+	l.Logger.Errorf("------------------------item2--------------------------- %+v")
 	err = l.svcCtx.DB.Token.UpdateOneID(*req.Id).
-		SetNotNilExpireAt(&expireAt).
+		SetNotNilExpireAt(expireAt).
 		SetNotNilToken(req.Token).
 		SetNotNilMAC(req.Mac).
 		SetNotNilOrganizationID(req.OrganizationId).
+		SetNotNilAgentID(req.AgentId).
+		SetNotNilCustomAgentBase(req.CustomAgentBase).
+		SetNotNilCustomAgentKey(req.CustomAgentKey).
+		SetNotNilOpenaiBase(req.OpenaiBase).
+		SetNotNilOpenaiKey(req.OpenaiKey).
 		Exec(l.ctx)
 
 	if err != nil {

+ 11 - 2
internal/types/types.go

@@ -2015,7 +2015,14 @@ type TokenInfo struct {
 	// Mac地址
 	Mac *string `json:"mac,optional"`
 	// 租户ID
-	OrganizationId *uint64 `json:"organization_id,optional"`
+	OrganizationId   *uint64    `json:"organization_id,optional"`
+	OrganizationName *string    `json:"organizationName,optional"`
+	AgentId          *uint64    `json:"agent_id,optional"`
+	AgentInfo        *AgentInfo `json:"agent_info,optional"`
+	CustomAgentBase  *string    `json:"custom_agent_base,optional"`
+	CustomAgentKey   *string    `json:"custom_agent_key,optional"`
+	OpenaiBase       *string    `json:"openai_base,optional"`
+	OpenaiKey        *string    `json:"openai_key,optional"`
 }
 
 // The response data of token list | Token列表数据
@@ -2041,7 +2048,9 @@ type TokenListReq struct {
 	// Token
 	Token *string `json:"token,optional"`
 	// Mac地址
-	Mac *string `json:"mac,optional"`
+	Mac              *string `json:"mac,optional"`
+	OrganizationId   *uint64 `json:"organization_id,optional"`
+	OrganizationName *string `json:"organizationName,optional"`
 }
 
 // Token information response | Token信息返回体